Organizing my Emacs config with Org-Babel
Golden, CO
In my previous post, I completely redid my emacs configuration from scratch, building it around the use of evil mode and use-package. As I was wrapping up, I learned of yet another emacs package that wil forever change how I maintain my emacs configuration… org-babel.
Org Babel
Org-babel is an emacs package, that lets take an
org-mode file, and evaluates all of the code
blocks contained
within it. This means I can write an annotated org file, filled with
emacs-lisp
code blocks, and export just the emacs-lisp code. After
testing it out, I realized that the main emacs lisp file I use is… my
.emacs
file…
Setup
Installing babel couldn’t be simpler. If you are running Emacs version
24 or higher, and a current version of Org-mode, Babel is already
available by default. In order to generate an .emacs
config from an
.org
file, we need to first setup a config.org
file, and then tell
.emacs
to load it with org-babel.
config.org
First, start by creating an .org
file to use for all of the
configuration content. This can be named anything, and exist anywhere,
but I like to keep mine in the emacs section of my dotfiles
repo, named
config.org
. This file functions like any other org file, so I added
a small header section at the top… because why not?
#+TITLE: My Emacs Configuration
#+AUTHOR: Ryan Himmelwright
#+EMAIL: ryan@himmelwright.net
#+OPTIONS: num:nil
After that, I broke down my file by creating org headings for the
different groups of the configuration. For example, I started with the
headings Repos & Core Packages
, Core Setup
, Evil Mode
, Ivy
,
Writing
, Development
… etc.
Note: In org-mode, use “*” to create headings. Each contiguous “*”
corresponds to the equivalent HTML heading level. Ex: *
== <h1>
,
**
== <h2>
, and so on.
I started transferring the emacs-lisp code from my previous .emacs
file, to under each heading in config.org
. As I transferred text, I
transformed the comments that described each code snippet into normal
org text, and wrapped the emacs-lisp
inside an org code block.
To create a code block, use the #+BEGIN_SRC emacs-lisp
and
#+END_SRC
org tags to encapsulate the emacs-lisp
code. Continue to
do this until all of the desired emacs-lisp code is contained inside
org code blocks.
Side Note: Easy Org Code Blocks
In org-mode, you can write <s
, then hit TAB
and it will expand
into the BEGIN_SRC
and END_SRC
tags. Just don’t forget to add
emacs-lisp
to the BEGIN_SRC
tag!
.emacs
For the contents of .emacs
, call package-initialize
and then have
org-babel
load the config.org
file.
(package-initialize)
(org-babel-load-file "~/dotfiles/emacs/config.org")
That’s it. Assuming the config.org
is complete, emacs should now
initialize using the code snippets from it. While these are the only
two required lines, do note that emacs will still write the
#'custom-set-variables
to the bottom of the .emacs
file. That’s
fine. If anything, it makes it easier to source control the actual
configuration file, since emacs isn’t constantly adding to it,
changing the diff.
What I like
Organized
Org mode’s hierarchical structure inherently organizes the content of
files. Using it for my emacs configuration is no different. I can use
org headers to easily break down my file into sections and
sub-sections, which I can then expand and collapse as needed. For
example, my config.org
is currently over 500 lines long, but with
all the headers collapsed, it displays in less than 20. From there I
can just expand to the section I need.
Maintainable
Being so organized, the config.org
file is very easy to maintain. If
I want to edit a setting, I can just search through the headers for
the section, and then edit the code block and/or text. If I want to
add a new item, I can just insert a new header, add the code block I
want, and maybe some explanatory text. Done. Most importantly, the
structure helps prevent it from turning into an in-production
“scratch code” file…
Easy to Read
It should go without saying that the organization and maintainability of org-mode configurations make them extremely readable. Not only is the source code easier to read, but org files can be exported to all sorts of outputs (HTML, LaTeX, OpenDocument, etc). Combined with a style-sheet, these outputs can look quite professional.
Beyond normal org
exporting, Github does
something awesome… they render org
files as a known markup
language on their website! This means that if you click an *.org
file on Gihub’s web interface, it will display a rendered version of
the content, instead of defaulting to the raw org text.
Speaking of Github…
While I have always maintained my emacs configuration in my dotfiles
repo, org-babel has helped
me step up my game. My current dotfile
system has all of my
emacs files in a separate emacs
folder. On Github, each directory in
a repo can contain a README
file (or…. a symlink to another
file…) to be displayed below the list of files.
My Maintained Config
In the emacs section of my dotfiles, I have created a symlink,
README.org
, to my config.org
file:
sudo ln -s config.org README.org
Github recognizes this, so my README
file “contains” whatever the
contents of config.org
are. Now, when one visits the emacs
section
of my dotfiles repo, an organized, annotated, and always up-to-date
version of my “.emacs
” file is displayed as the README
.
The Github support was the cherry on top of a new emacs configuration system I am already ecstatic about. I’ve been a fan of org-mode for years, and org-babel is one more feature to add to the growing list of reasons why I love it. I highly recommend checking it out.
Nginx as a Reverse Proxy to Forward Sub-Domains Emacs Config Redo - Evil & Use-Package