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:

(require 'package)
(package-initialize)
</p>

<p>
(require 'org)
(org-babel-load-file
 (expand-file-name "settings.org"
                   user-emacs-directory))

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 function add-to-list to append a specified repository to the variable package-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 bootstrap

      When installing packages using package-install, Emacs adds the package name to the variable package-selected-packages. This serves as a point of reference for package-autoremove, but what's worth noting is that package-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.

      (unless (package-installed-p 'use-package)
              (package-refresh-contents)
              (package-install 'use-package))

      The unless statement first refreshes package contents and then installs use-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:

      (org-babel-load-file
       (expand-file-name "file.org"
                         user-emacs-directory))

      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.