Emacs, part 1 - init files and configuration.
Introduction
It was once the case that I didn't know anything about text editors. Though I wasn't aware at the time,
Microsoft Windows's notepad.exe
was probably my first interaction with a plain text editor.
Once I endeavored to familiarize myself with the ways of the command line, tutorials inevitably
instructed using a text editor of one variety or another. Typically, it went something like:
Open <text-file> in vi or nano.
My first time trying vi
was every bit of the typical meme about how it's impossible to figure
out how to exit and so on. I of course defaulted to nano
because it was simple and got the job
done for just editing a text file.
Through equal parts influence from peer pressure and Internet culture, I decided I was done with
my philistine ways and would elevate my self through the use of a true editor. I followed the
vi
tutorial and slowly learned the ways of navigation and text editing. I grew accustomed to
its home row ways and ultimately enjoyed using vi
and found myself wishing I could use the
same editing patterns for every instance I found myself editing text.
Fast forward some amount of time and I was once again influenced by external forces to consider
greater things. This time it was the allure of Emacs's org-mode
. I didn't at first understand
why I wanted to learn to use it other than that the cool kids used it. I understood some notion
that it greatly contributed to increased productivity, and that's what I wanted.
After reading a little about org-mode
, I was mentally exhausted and unready for the commitment.
A bit more time later, I decided to give it another go and installed Emacs. I chose the easy way
out (for me, anyway) and installed Emacs's e*xtensible *vi *l*ayer, aptly known as evil-mode
.
This helped immensely. Little did I know, I had many sisyphian hills to climb before tackling
org-mode
. The first was management of Emacs's configuration.
Influences and learning resources
My initial battle strategy was an old fashioned melee. Emacs, despite its reputation for being
labyrinthine and abstruse, enables an easy to use method for package management with commands
such as package-list-packages
and package-install
. Being enabled in such a way, I installed
packages willy-nilly. With each package, configuration naturally follows. Here's an example of one
of my first init.el
attempts. There's no real rhyme or reason. It became a mess very quickly. In
hindsight, it's no surprise. It was basically a copy-paste-fest of trying to get stuff to work.
It goes without saying that some things worked, but it was always a pain trying to track down one variable or another when I wanted to change something. Vim was an old habit that was easy to fall back to, so I did. I resolved to start over again and ended up with a lot more comments, but it was still a million lines long and I was always too lazy to track down whatever it was I wanted to change (or whatever caused a warning or error when reading the init file).
I eventually figured out that I'd be well served to split an unmanageably large file into
separate, smaller files organized to be topically consistent. I ended up with something influenced
directly by this Stack Overflow answer. This was an improvement. Even then, it still left much to
be desired in terms of readability and navigability. By this point I'd become accustomed to note
taking in org-mode
and came to love Org's structure editing commands. I wanted that in my init
files.
Thankfully, smart people have already figured this out, allowing me to reap the benefits of their
work. My first influence was this example. Through some trial and error, I found a way to marry
a modular approach to init files with org-mode
-style markup.
It all starts with the following few lines in init.el
.
Structure
When Emacs starts, it looks for a series of possible init file candidates and loads whatever
it finds. In my case, I've elected to use ~/.emacs.d/init.el
.
init.el
My init.el
essentially looks like this:
package-initialize
, according to its docstring (M-x describe-function RET package-initialize
),
"Load[s] Emacs Lisp packages, and activate[s] them." Next, (require 'org)
ensures org-mode
has been loaded if it hasn't already. After these two lines, the table is set for org-babel-load-file
;
this function essentially turns Org source bloacks into Lisp programs that Emacs can load. Using this
strategy, we can load source blocks from Org files as Lisp programs. In this case, however, org-babel-load-file
loads only settings.org
.
settings.org
The intent of settings.org
is to define default behaviors for package management and built-
in Emacs functionality. (As with many intentions, the intentions of these files may have gone astray in some ways and it's
hard to keep the scope of each file well defined and confined.)
- Package management
This section specifies the repositories Emacs's
package.el
should use when looking for and installing packages. It uses the functionadd-to-list
to append a specified repository to the variablepackage-archives
. By default,package-archives
contains only the GNU Emacs package repository. It's worth pointing out that adding a repository to the list is inherintly risky (then again, so is running any code you've never reviewed!).use-package
bootstrapWhen installing packages using
package-install
, Emacs adds the package name to the variablepackage-selected-packages
. This serves as a point of reference forpackage-autoremove
, but what's worth noting is thatpackage-install-selected-packages
uses this variable when a user wants to install the same list of packages on a new system. This is certainly convenient.use-package
offers an alternative (and more) to package installation on new systems.use-package
enables declaratively defining what packages should be installed and how they should be configured.New systems won't have
use-package
installed, so it needs to be bootstrapped. I found this recommendation here.The
unless
statement first refreshes package contents and then installsuse-package
if it's not installed.- Include statements
Next, the same strategy from
init.el
is used to load any additional Org files. That's pretty much it. It uses the following form:This can be done ad infinitum.
- The rest of
settings.org
The rest of the file is for tweaks to Emacs's standard behaviors such as line numbers everywhere,e, disabling the scroll bar, and so forth.
Other files
I keep use-package
statements in packages.org
unless configuration becomes exceptionally
lengthy, as in the case of org-mode
. Everything else will be explained in other posts, but this
fairly well suffices for a description of how I organize my Emacs init files.
Potential for improvement
I'm sure there's a lot that could be better about how I've organized my init files, but I don't
know what I don't know (which is unfortunate). Even in writing this post I realized that certain
things were out of order. This will change over time as I learn how things work. I'll almost
certainly learn to use use-package
more effectively. I'll also use hooks to make loading more
efficient and to avoid unnecessary init file loading.