Creating a Literate Config for Spacemacs

A guide to creating and correctly loading an org-mode file as a literate configuration for Spacemacs

Olav Pedersen
CodeX
4 min readMar 26, 2021

--

Photo by Nicolas Hoizey on Unsplashed

Why create a “literate configuration”?

In a previous post, I explained the concept and origin of literate programming. A literate configuration is simply applying the literate programming concept to configurations files. This is useful for configuration files typically require more context around the settings and why you chose to do something in a particular manner. Sometimes this could include links to where you found the configuration settings or ‘work in progress’ settings. Another reason literate configurations are useful is because configuration files are not necessarily modified every day. When jumping back into your config to fix, add, or modify a feature it might be useful to have a short explanation to quickly catch yourself up.

For this particular post the goal is to create a literate configuration for Spacemacs. It is a heavily modded distribution of Emacs. This is mainly because I use Spacemacs myself and find having a literate configuration for it very useful. Literate configuration itself is an.org file where the weaved code is defined in code blocks. Using org-mode headings also makes it much easier to navigate your configuration file. Extracting the file code from the literate configuration, or tangling the literate configuration, will yield an elisp file.

Spacemacs is also well suited for a literate configuration since it by default loads a single .spacemacs file, which tends to steadily grow as it increasingly takes over your life. At the time of writing this my current 'tangled' spacemacs.el configuration (just the code) is 1500 lines long.

Correctly loading a Spacemacs literate config

When I was attempting to create a literate Spacemacs config, there were several helpful links to figure out how to tangle and generate output files from an.org file. I struggled to figure out the best way to load the file itself. There are two default locations for your Spacemacs configurations with the following loading priority:

  1. ~/.spacemacs: A single dotfile in the home directory
  2. ~/.spacemacs.d/init.el: A dotfile directory in the home directory

For a literate configuration we will need to have multiple files, therefore I find it more orderly to go with the second option and create a ~/.spacemacs.d directory.

Initially, it seemed to make sense to create a spacemacs.org literate configuration file, and tangle directly to either .spacemacs or init.el file. It could be done this way, but Spacemacs adds custom content at the end of the init.el (or ~/.spacemacs) file in the following function:

This is where Emacs stores custom-set-variables and custom-set-faces generated during runtime. If we were to tangle our literate configuration file directly to the init.el file it would overwrite this function and variables every time it was generated. Therefore, instead the literate configuration can be tangled to an intermediate file, for example spacemacs.el, and then the init.el file can load its contents:

  • spacemacs.org: The literate configuration file
  • spacemacs.el: The tangled configuration file
  • init.el: The file that Spacemacs loads as a default configuration file.

An overview of how this works is shown in figure 1.

Figure 1: An overview of the concept of how to make a literate config for spacemacs that doesn’t overwrite the auto generated settings from Spacemacs. Created in Krita.

The ‘spacemacs.org’ file

This is the literate configuration file itself. When creating this you have to ensure every part of your configuration file is copied over in the code snippets. Below is the start of my configuration file. Most of these settings are not particularly important for generating the configuration file, but has served me well thus far.

An example of a code block from a part of my configuration below. The important part is the that the configuration is in the code blocks.

What defines the code block:

The emacs-lisp option indicates what language the code block is written in. The:tangle spacemacs.el sets the output target file to spacemacs.el when the file is tangled. My complete spacemacs.org, with all its warts, can be found in my dotfiles repository on github.

The ‘spacemacs.el’ file

In order to generate the tangled file, spacmacs.el, the function org-bable-tangle() has to be run on the literate configuration. For this function to be run every time you save the file, the following 'local variables' can be added to the bottom of spacmacs.org. This will add a function to the after-save-hook. A hook is a variable that holds a list of functions at a specific time.

The ‘init.el’ file

This is the file Spacemacs loads as the configuration. You only have to add the following line to the file.

Spacemacs should then load your configuration and you should be up and running! As you continue to use Spacemacs, it will populate the init.el file:

That’s it!

Now when you change your spacemacs.org file and tangle the output to spacemacs.el, it will not overwrite the variables generated by Spacemacs in init.el. It is not that complicated, but I hope this helps someone fairly new to org-babel or Spacemacs.

Resources

Originally published at https://www.olavpedersen.com on March 26, 2021.

--

--

Olav Pedersen
CodeX

Software Engineer with a background in Cybernetics and Biochemistry. Interested in anything “techy” from Linux and Emacs, Data Science, to Electronics