Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/echosa/emacs.d
My personal emacs setup.
https://github.com/echosa/emacs.d
emacs emacs-configuration emacs-lisp evil org-mode projectile
Last synced: 3 months ago
JSON representation
My personal emacs setup.
- Host: GitHub
- URL: https://github.com/echosa/emacs.d
- Owner: echosa
- Created: 2012-04-17T17:28:23.000Z (almost 13 years ago)
- Default Branch: master
- Last Pushed: 2019-06-27T20:32:09.000Z (over 5 years ago)
- Last Synced: 2023-03-23T10:58:18.251Z (almost 2 years ago)
- Topics: emacs, emacs-configuration, emacs-lisp, evil, org-mode, projectile
- Language: Emacs Lisp
- Homepage:
- Size: 4.03 MB
- Stars: 27
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
Awesome Lists containing this project
README
#+TITLE: Echosa's Emacs Configuration
#+AUTHOR: Echosa
#+OPTIONS: toc:4 h:4
* Introduction
Inspired by [[http://sachachua.com/blog/2012/06/literate-programming-emacs-configuration-file/][Sacha Chua]], I have moved my Emacs configuration into an
organized and descriptive [[http://orgmode.org][org-mode]] file. What you are reading now
is, in fact, my Emacs configuration file.Well, sort of.
How this works is based around a part of ~org-mode~ called
~org-babel~. ~org-babel~ allows ~org-mode~ to execute code that is
embedded into a .org file. If you look at the [[https://github.com/echosa/emacs.d/blob/master/init.el][actual init.el file]]
that my Emacs loads, you'll see that all it does is load the .org
file containing my configuration (the one you're reading now) and
parse it through org-babel to execute only the blocks of elisp that
make up the actual configuration, while ignoring the extra
documentation and narrative, like this introduction section.If you're wondering about performance, org-babel doesn't do this
parse every time I open Emacs. Instead, it sees that I'm trying to
load ~emacs-config.org~ and checks for the existence of
~emacs-config.el~. If it doesn't find that file, or finds an out of
date version, only then does it parse the .org file to create a new
.el file. This means there's a bit of a slow startup the first time
after the org-mode file is changes, but after that there's no
noticeable change in performance (at least on my machine). I have
accounted for this one-off performance hit, however, by
automatically regenerating ~emacs-config.el~ when I save
~emacs-config.org~. You'll see this later.The only other source of major slowdown, usually only on the first
run, is the installation of packages. On a fresh install of Emacs
using this configuration, the first time Emacs is run ~org-babel~
parses the .org file and also installs all the external packages
required by my config. This makes for a slow first-time startup, but
the benefit is that all of the configuration, installation, and
setup is done for me automatically. I don't have to manually set
anything up, which, when setting up other editors, can often take
much longer than the first run of this config. Plus, it's more work
to have to manually set things up, so I'll take a one-time slowdown
in trade of automatically having my Emacs setup installed and ready
for me.Anyway, what follows is my actual Emacs configuration, embedded into
a descriptive narrative.* Installation
** Get from GitHub
First, you need to get the config from GitHub. I recommend actually cloning
instead of just downloading a zip file, because a cloned repo will be
easier to update.First, delete, move, or rename your existing Emacs configuration
(both the ~.emacs.d/~ directory and your ~.emacs~ init file). Next,
clone the repository into your home directory:~$ git clone [email protected]:echosa/emacs.d.git ~/.emacs.d~
** Start Emacs
Simply run Emacs and wait a bit! All the necessary packages will
download and install automatically and everything will be
configured. This is because of the ~use-package~ package's ~:ensure~
flag. That flag tells Emacs to download and install the package if
it is not already installed. Because of this, the first time you
start Emacs make take a few seconds as all the packages are
downloaded and installed. Subsequent starts will not take so long.* Configuration Maintenance
In order to make maintaining this config easier, I've made this
~echosa-export-config~ function which will export the proper
~emacs-config.el~ and ~README.org~ files when ~emacs-config.org~ is
updated and saved.
#+BEGIN_SRC emacs-lisp
(defun echosa-export-config ()
(when (string= (buffer-name (current-buffer)) "emacs-config.org")
(let ((org-file "~/.emacs.d/emacs-config.org")
(elisp-file "~/.emacs.d/emacs-config.el")
(readme-file "~/.emacs.d/README.org"))
(org-babel-tangle-file org-file elisp-file "emacs-lisp")
(copy-file org-file readme-file t)
(message "Config export complete!"))))
(add-hook 'after-save-hook 'echosa-export-config)
#+END_SRC
* Packages
External and third-party packages are great. They make adding new things to
Emacs much nicer and less complicated.
** Repositories
We need to set up the package repositories for Emacs' package manager.
#+BEGIN_SRC emacs-lisp
(setq package-archives
'(("gnu" . "http://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/")
("melpa-stable" . "https://stable.melpa.org/packages/")))
#+END_SRC** use-package
I've come to appreciate the [[https://github.com/jwiegley/use-package][use-package]] way of handling package
management. Everything is nice, clean, and compact. Best of all, all
setup for a package is self-contained within a ~use-package~
declaration, so no need to hunt through your whole config to find
related parts (hooks in one place, key bindings in another, etc.)Since I use ~use-package~ to install all the other packages, this is
the only place where I pull in and use package.el. I only do that to
ensure that ~use-package~ is installed and ready to go.
#+BEGIN_SRC emacs-lisp
(require 'package)
(package-initialize)
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))(eval-when-compile
(require 'use-package))
#+END_SRC* General Setup
Here, I change some generic Emacs behavior. These are all things
that aren't tied to a specific mode or programming language. Most of
these are self-explanatory. However, for more info, you can look
them up with Emacs' built-in help. That will do a better job of
explaining that I can, plus there's no need for me to reiterate it
all here.
#+BEGIN_SRC emacs-lisp
(temp-buffer-resize-mode 0)
(add-hook 'before-save-hook 'time-stamp)
(setq fill-column 80)
(setq scroll-conservatively 101)
(setq case-fold-search t)
(setq case-replace t)
(setq display-buffer-reuse-frames t)
(setq display-time-24hr-format nil)
(setq display-time-day-and-date t)
(setq large-file-warning-threshold nil)
(setq truncate-partial-width-windows nil)
#+END_SRC
Allow ~a~ to be used in dired to reuse the buffer instead of creating new buffers for every
directory.
#+BEGIN_SRC emacs-lisp
(put 'dired-find-alternate-file 'disabled nil)
#+END_SRC
Don't load outdated complied files.
#+BEGIN_SRC emacs-lisp
(setq load-prefer-newer t)
#+END_SRC
Make sure Emacs can find and run commands on the PATH.
#+BEGIN_SRC emacs-lisp
(when (memq window-system '(mac ns x))
(setenv "PATH" (concat "/usr/local/bin:" (getenv "PATH")))
(setq exec-path (append '("/usr/local/bin") exec-path)))
#+END_SRC
Remember open files and buffers between sessions.
#+BEGIN_SRC emacs-lisp
(desktop-save-mode 1)
#+END_SRC
** Backup and Auto Save
I don't like Emacs littering and leaving a bunch of temporary
files all over the place, so here I tell it to keep all those files
in one place.
#+BEGIN_SRC emacs-lisp
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/.tmp/" nil)))
(setq auto-save-list-file-prefix "~/.emacs.d/.tmp/.saves-")
(setq backup-directory-alist '(("" . "~/.emacs.d/.tmp")))
#+END_SRC
** Things I don't want to see
*** Scroll bars
#+BEGIN_SRC emacs-lisp
(when (fboundp 'toggle-scroll-bar) (toggle-scroll-bar nil))
#+END_SRC
*** Tool bar
#+BEGIN_SRC emacs-lisp
(tool-bar-mode -1)
#+END_SRC
*** Menu bar
#+BEGIN_SRC emacs-lisp
(menu-bar-mode -1)
#+END_SRC
*** Splash screen
It's unnecessary, really.
#+BEGIN_SRC emacs-lisp
(setq inhibit-startup-screen t)
#+END_SRC
** Things I do want to see
*** Highlight current region/selection
#+BEGIN_SRC emacs-lisp
(transient-mark-mode t)
#+END_SRC
*** Syntax highlighting
#+BEGIN_SRC emacs-lisp
(global-font-lock-mode t)
#+END_SRC
*** Column number
#+BEGIN_SRC emacs-lisp
(column-number-mode t)
#+END_SRC
*** Show matching parenthesis
#+BEGIN_SRC emacs-lisp
(show-paren-mode t)
#+END_SRC
*** Blinking cursor
#+BEGIN_SRC emacs-lisp
(setq blink-cursor-mode t)
#+END_SRC
*** Show empty lines
#+BEGIN_SRC emacs-lisp
(setq indicate-empty-lines t)
#+END_SRC
*** Highlight the current light
#+BEGIN_SRC emacs-lisp
(global-hl-line-mode 1)
#+END_SRC
*** Line Numbers
I like line numbers. They help quite a bit with moving around.
#+BEGIN_SRC emacs-lisp
(global-display-line-numbers-mode)
#+END_SRC
*** Visible Bell
I don't want to hear a blip every time I do something wrong, so I'm
turning on the visible bell.
#+BEGIN_SRC emacs-lisp
(setq visible-bell t)
#+END_SRC
* Uniquify
If I have two buffers open with two files that have the same name, (e.g. two
different README files from two different projects), Emacs will, by default,
name the buffers ~README~ and ~README<1>~. This is useless. Therefore, I turn on
uniquify and use it to name buffers with the same file name based on their
parent directories: ~README~ and ~README~.
#+BEGIN_SRC emacs-lisp
(use-package uniquify
:defer t
:config
(setq uniquify-buffer-name-style 'post-forward-angle-brackets))
#+END_SRC
* Ido and Icomplete
Here I configure Ido and Icomplete. Ido gives improved file finding
and buffer switching. Icomplete gives improved command execution
with ~M-x~.
#+BEGIN_SRC emacs-lisp
(use-package icomplete
:config
(icomplete-mode))
(use-package ido
:config
(ido-mode 1)
(ido-everywhere 1)
(setq ido-enable-flex-matching t))
#+END_SRC* Evil
Update: At the moment, I have Evil disabled. I'm seeing how I get
by without it. I might learn that I no longer need or want
it. However, just in case, I leaving my config here, disabled
through ~use-package~. (Have I mentioned how awesome ~use-package~
is?)Call me heathen if you wish, but I prefer Vim navigation keys. Also,
I want Ido buffer switching and file finding when using Vim's ~:b~ and ~:e~.[[https://gitorious.org/evil/pages/Home][Evil website]]
#+BEGIN_SRC emacs-lisp
(use-package evil
:disabled
:ensure t
:after (key-chord)
:config
(setq evil-default-cursor '(t))
(evil-mode 1)
(define-key evil-ex-map "b " 'ido-switch-buffer)
(define-key evil-ex-map "e " 'ido-find-file)
(key-chord-define evil-insert-state-map "jk" 'evil-normal-state)
(key-chord-define evil-motion-state-map "jk" 'evil-normal-state)
(key-chord-define evil-visual-state-map "jk" 'evil-normal-state)
(key-chord-define evil-emacs-state-map "jk" 'evil-normal-state))
#+END_SRC
Using ~key-chord-mode~, I have the vim equivalent of ~imap jk ~, which
allows me to use ~jk~ instead of ~Esc~ to get out of insert mode.
#+BEGIN_SRC emacs-lisp
(use-package key-chord
:disabled
:ensure t
:config
(key-chord-mode 1))
#+END_SRC
To make things even easier, I set up a "leader key" of ~Space~, so that I can
type ~Space ~ to run a command. For instance, ~Space x~ instead of
~M-x~ to execute commands.
#+BEGIN_SRC emacs-lisp
(use-package evil-leader
:disabled
:ensure t
:after (evil)
:config
(evil-leader/set-leader "")
(evil-leader/set-key "x" 'execute-extended-command)
(evil-leader/set-key ":" 'eval-expression)
(evil-leader/set-key "k" 'ido-kill-buffer)
(evil-leader/set-key "p" 'projectile-commander)
(evil-leader/set-key "d" 'dired)
(evil-leader/set-key "e" 'er/expand-region)
(evil-leader/set-key "m" 'mc/mark-more-like-this-extended)
(evil-leader/set-key "s" 'string-inflection-toggle)
(evil-leader/set-key "r" 'xref-find-definitions)
(evil-leader/set-key "?" 'xref-find-references)
(global-evil-leader-mode))
#+END_SRC
Let's make sure we have "surround" support.
#+BEGIN_SRC emacs-lisp
(use-package evil-surround
:disabled
:ensure t
:config
(global-evil-surround-mode 1))
#+END_SRC
Finally, there are some modes that I want to always be in Emacs mode instead
of Evil.Major modes:
#+BEGIN_SRC emacs-lisp
(setq evil-emacs-state-modes
'(archive-mode bbdb-mode bookmark-bmenu-mode bookmark-edit-annotation-mode browse-kill-ring-mode bzr-annotate-mode calc-mode cfw:calendar-mode completion-list-mode Custom-mode debugger-mode delicious-search-mode desktop-menu-blist-mode desktop-menu-mode doc-view-mode dvc-bookmarks-mode dvc-diff-mode dvc-info-buffer-mode dvc-log-buffer-mode dvc-revlist-mode dvc-revlog-mode dvc-status-mode dvc-tips-mode ediff-mode ediff-meta-mode efs-mode Electric-buffer-menu-mode emms-browser-mode emms-mark-mode emms-metaplaylist-mode emms-playlist-mode etags-select-mode fj-mode gc-issues-mode gdb-breakpoints-mode gdb-disassembly-mode gdb-frames-mode gdb-locals-mode gdb-memory-mode gdb-registers-mode gdb-threads-mode gist-list-mode git-rebase-mode gnus-article-mode gnus-browse-mode gnus-group-mode gnus-server-mode gnus-summary-mode google-maps-static-mode ibuffer-mode jde-javadoc-checker-report-mode magit-popup-mode magit-popup-sequence-mode magit-commit-mode magit-revision-mode magit-diff-mode magit-key-mode magit-log-mode magit-mode magit-reflog-mode magit-show-branches-mode magit-branch-manager-mode magit-stash-mode magit-status-mode magit-wazzup-mode magit-refs-mode mh-folder-mode monky-mode mu4e-main-mode mu4e-headers-mode mu4e-view-mode notmuch-hello-mode notmuch-search-mode notmuch-show-mode occur-mode org-agenda-mode package-menu-mode proced-mode rcirc-mode rebase-mode recentf-dialog-mode reftex-select-bib-mode reftex-select-label-mode reftex-toc-mode sldb-mode slime-inspector-mode slime-thread-control-mode slime-xref-mode sr-buttons-mode sr-mode sr-tree-mode sr-virtual-mode tar-mode tetris-mode tla-annotate-mode tla-archive-list-mode tla-bconfig-mode tla-bookmarks-mode tla-branch-list-mode tla-browse-mode tla-category-list-mode tla-changelog-mode tla-follow-symlinks-mode tla-inventory-file-mode tla-inventory-mode tla-lint-mode tla-logs-mode tla-revision-list-mode tla-revlog-mode tla-tree-lint-mode tla-version-list-mode twittering-mode urlview-mode vc-annotate-mode vc-dir-mode vc-git-log-view-mode vc-svn-log-view-mode vm-mode vm-summary-mode w3m-mode wab-compilation-mode xgit-annotate-mode xgit-changelog-mode xgit-diff-mode xgit-revlog-mode xhg-annotate-mode xhg-log-mode xhg-mode xhg-mq-mode xhg-mq-sub-mode xhg-status-extra-mode cider-repl-mode emacsagist-mode elfeed-show-mode elfeed-search-mode notmuch-tree term-mode xref--xref-buffer-mode))
#+END_SRC
* Winner-mode
Winner-mode makes it really easy to handle window changes in
Emacs. ~C-c left-arrow~ goes back to the previous window
configuration (undo), and ~C-c right-arrow~ goes forward
(redo). This is especially helpful for when a popup window ruins
your layout. Simply ~C-c left-arrow~ to get back to where you were.
#+BEGIN_SRC emacs-lisp
(use-package winner
:defer 5
:config
(winner-mode 1))
#+END_SRC* pbcopy
Clipboard sharing. Copy in Emacs, paste in OS X, and vice versa.[[https://github.com/jkp/pbcopy.el][pbcopy source]]
#+BEGIN_SRC emacs-lisp
(use-package pbcopy
:ensure t
:defer t
:config
(turn-on-pbcopy))
#+END_SRC* Minibuffer
This little snippet adds eldoc support to the minibuffer. Requires
Emacs 24.4 or later.
[[http://endlessparentheses.com/sweet-new-features-in-24-4.html][Found on EndlessParenthesis.com.]]
#+BEGIN_SRC emacs-lisp
(add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode)
#+END_SRC* Expand Region
This package makes it easy to select regions based on various
bounds: words, braces, etc.
#+BEGIN_SRC emacs-lisp
(use-package expand-region
:ensure t
:bind (("C-=" . er/expand-region)))
#+END_SRC
* Programming
** General
Indent with 4 spaces, not a tab stop.
#+BEGIN_SRC emacs-lisp
(setq-default c-basic-offset 4)
(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)
#+END_SRC
** Git
Magit is awesome.#+BEGIN_SRC emacs-lisp
(use-package magit
:ensure t)
#+END_SRCShow changes in the gutter/fringe.
#+BEGIN_SRC emacs-lisp
(use-package git-gutter-fringe
:ensure t
:if window-system
:config
(global-git-gutter-mode))(use-package git-gutter
:ensure t
:if (not window-system)
:config
(global-git-gutter-mode 1))
#+END_SRC
** Projectile
Projectile is, quite simply and objectively, the shit. There's no other way to
put it. I consider it pretty much necessary for working with full
projects (as opposed to individual, unrelated files).[[https://github.com/bbatsov/projectile][Projectile on Github]]
#+BEGIN_SRC emacs-lisp
(use-package projectile
:ensure t
:defer 5
:init
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
:config
(projectile-global-mode))
#+END_SRC
** Completion
Who doesn't like a little auto-completion? I choose to use ~company~
instead of ~auto-complete~ (aka ~ac~). This decision is based on
lots of reading about both and comparing/trying out both.
#+BEGIN_SRC emacs-lisp
(use-package company
:ensure t
:bind (("C-" . company-complete))
:config
(global-company-mode)
(setq company-dabbrev-downcase nil)
(setq company-dabbrev-ignore-case t))
#+END_SRC
** Search
The Silver Searcher (ag) is awesome. Using it, Emacs is even more
awesome! Also, with this installed, Projectile can use it, as
well. What a perfect match!This requires that you have [[https://github.com/ggreer/the_silver_searcher][The Silver Searcher]] installed on your
computer.
#+BEGIN_SRC emacs-lisp
(use-package ag
:ensure t)
#+END_SRC
** Paredit
If you write any form of Lisp and don't use paredit, change that. It
does so much for you and helps out in so many ways. I highly
recommend it, even though it is quite weird (and, honestly,
sometimes frustrating) at first.[[http://mumble.net/~campbell/emacs/paredit.el][Paredit website]]
[[http://emacsrocks.com/e14.html][Emacs Rocks episode on paredit]]
#+BEGIN_SRC emacs-lisp
(use-package paredit
:ensure t
:defer t
:hook ((emacs-lisp-mode clojure-mode) . paredit-mode))
#+END_SRC
** PHP
Let's start with adding basic PHP handling.
#+BEGIN_SRC emacs-lisp
(use-package php-mode
:ensure t
:config
(add-hook 'php-mode-hook 'flymake-mode)
(add-hook 'php-mode-hook 'php-enable-symfony2-coding-style))
#+END_SRC
Next, let's improve completion. This sets up [[https://github.com/xcwen/ac-php][ac-php]] to give better
PHP specific completions with ~company~.
#+BEGIN_SRC emacs-lisp
(use-package company-php
:ensure t)(use-package ac-php
:ensure t
:after (php-mode company-php)
:init
(bind-key "C-c ]" 'ac-php-find-symbol-at-point php-mode-map)
(bind-key "C-c [" 'ac-php-location-stack-back php-mode-map)
:config
(add-hook 'php-mode-hook
'(lambda ()
(require 'company-php)
(company-mode t)
(ac-php-core-eldoc-setup)
(make-local-variable 'company-backends)
(add-to-list 'company-backends 'company-ac-php-backend))))
#+END_SRC
Now, let's set up [[https://github.com/FriendsOfPhp/PHP-CS-Fixer][php-cs-fixer]] so that it automatically fixes our
PHP files on save.Note that I have a config file for this set with ~M-x customize~,
not seen in this config.
#+BEGIN_SRC emacs-lisp
(use-package php-cs-fixer
:ensure t
:config
(require 'cl)
(add-hook 'before-save-hook 'php-cs-fixer-before-save))
#+END_SRC
Of course, we want to be able to debug our PHP files. That's where
[[https://github.com/ahungry/geben][geben]] comes in.Note that some geben config, like path mappings, I have done with
~M-x customize~, so they do not appear in this file.
#+BEGIN_SRC emacs-lisp
(use-package geben
:ensure t
:defer t)
#+END_SRC
Finally, let's get a lot more detailed and IDE-like functionality
with [[https://github.com/emacs-lsp/lsp-mode][LSP in Emacs]].I currently have this disabled because it isn't working properly.
#+BEGIN_SRC emacs-lisp
(use-package lsp-mode
:disabled
:ensure t
:commands lsp
:init
(add-hook 'php-mode-hook #'lsp)
)(use-package lsp-ui
:disabled
:ensure t
:commands lsp-ui-mode)(use-package company-lsp
:disabled
:ensure t
:commands company-lsp)
#+END_SRC
** JavaScript
The built-in JS support in Emacs is lacking.
#+BEGIN_SRC emacs-lisp
(use-package js2-mode
:ensure t
:defer t
:mode "\\.js\\'")(use-package json-mode
:ensure t
:defer t
:mode "\\.json\\'")
#+END_SRC
** Web
As far as I can tell, ~web-mode~ is the best mode for dealing with
web files like HTML, Twig, etc.
#+BEGIN_SRC emacs-lisp
(use-package web-mode
:ensure t
:mode (("\\.html\\'" . web-mode)
("\\.twig\\'" . web-mode)))
#+END_SRC
** YAML
Syntax highlighting for YAML files is nice, too.
#+BEGIN_SRC emacs-lisp
(use-package yaml-mode
:ensure t
:mode "\\.ya?ml\\'")
#+END_SRC
** Clojure
The ultimate experience for [[https://clojure.org/][Clojure]] development: [[https://github.com/clojure-emacs/cider][cider]]!
#+BEGIN_SRC emacs-lisp
(use-package cider
:ensure t)
#+END_SRC
* Org-mode
This customizes ~org-mode~ a bit. For instance, I like my org files
to have ~auto-fill~ turned on.
#+BEGIN_SRC emacs-lisp
(defun my-org-mode-hook ()
(auto-fill-mode))
(add-hook 'org-mode-hook 'my-org-mode-hook)
#+END_SRC
* Fun Packages
** Encouragement
#+BEGIN_SRC emacs-lisp
(use-package encourage-mode
:ensure t
:config
(encourage-mode t))
#+END_SRC* Miscellaneous Functions
** Toggle Window Split
This is a quite useful function that will change a frame with two
horizontal windows into a frame with two vertical windows and vice
versa.
#+BEGIN_SRC emacs-lisp
;; http://www.emacswiki.org/emacs/ToggleWindowSplit
(defun toggle-window-split ()
(interactive)
(if (= (count-windows) 2)
(let* ((this-win-buffer (window-buffer))
(next-win-buffer (window-buffer (next-window)))
(this-win-edges (window-edges (selected-window)))
(next-win-edges (window-edges (next-window)))
(this-win-2nd (not (and (<= (car this-win-edges)
(car next-win-edges))
(<= (cadr this-win-edges)
(cadr next-win-edges)))))
(splitter
(if (= (car this-win-edges)
(car (window-edges (next-window))))
'split-window-horizontally
'split-window-vertically)))
(delete-other-windows)
(let ((first-win (selected-window)))
(funcall splitter)
(if this-win-2nd (other-window 1))
(set-window-buffer (selected-window) this-win-buffer)
(set-window-buffer (next-window) next-win-buffer)
(select-window first-win)
(if this-win-2nd (other-window 1))))))
(define-key ctl-x-4-map "t" 'toggle-window-split)
#+END_SRC
* Individual Customization
Any customization that is machine specific or does not belong in git
can go in ~custom.el~. This file is ignored from git and is where all
changes from ~M-x customize~ are saved.
#+BEGIN_SRC emacs-lisp
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerror)
#+END_SRC
** Theme
I set my theme through ~M-x customize~. That way, it doesn't require
changes to this init file.