skip to main content

Literate Dotfiles

Motivation

Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.

In Donald Knuth's 1984 paper "Literate Programming", he argued that code is not enough. That is to say it is not enough to only tell a computational device how to behave. The cognitive energy of the humans who maintain such code also need to be considered. Such was the conundrum I found myself in while trying to maintain my 'dotfiles' - my user-specific system configuration files for *nix-like hosts. I've struggled to find a balance of organization, readability, and documentation.

Early on, I treated these configuration files as write-only repositories of code snippets. As a result, they were difficult to reason about so I didn't try to change them too often. They were 'code' in the deepest sense of the word - I never intended them to read well. As such, the few times a friend or colleague would ask about a particular piece of behavior while pairing, it was almost impossible to discuss with colleagues - the configuration itself was a lousy example.

A step toward literacy

What if, with a little reorganization, we could document intent, in a human readable format, and provide executable examples from which our actually-on-disk dotfiles could be generated?

Enter Emacs' Babel package; a sub-system of Emacs org-mode which allows us to embed code blocks inside of natural language documents. Exporting the code is great, but what about the reader's experience? Naturally, emacs handles the display of org-mode documents rather well. When working with the dotfiles org-mode document, one has access to all of the normal Emacs and org-mode document editing features: org's easy to use document syntax, section/hader folding, search, etc. But what about our non-emacs friends? Popular git forges like Github and Gitlab have us covered. In addition to markdown, org-mode tends to be supported as a source format for documentation and static HTML generation on popular code hosting platforms. As a result, the woven/human-readable version of the dotfiles render rather well.

Making the move

Organizing a scattered collection of dotfiles configuration into a literate document and generating/tangling the code examples into usable configuration can be described as follows:

  1. First, organize and copy each logical group of configuration code the existing dotfiles into org-mode code blocks.
  2. Then add intention revealing documentation for each block.
  3. Next, add metadata about the tangling/export process. These properties tell babel that the code blocks under the .bashrc header should be exported to the file at ~/.bashrc.
  4. And finally we need to tangle/export the code by running M-x org-babel-tangle - in my dotfiles repository I include a dotfiles generation and installation script that will automatically tangle/export all of the code blocks.

Conclusion

I've used this literate approach to generate my personal dot-files and Emacs configuration for a few months. I find it to be much easier to manage and reason about and maintain confidently. Though I wouldn't recommend Literate Programming for every task, I find that "prose first development" works great for clarifying the scope and intent of a task when modifying system configuration.

UPDATES:

  • <2021-07-11 Sun> Update links to Emacs configuration. Since the original posting of this article, I've consolidated my .emacs.d configuration into my .files repository - IE they're all one repository. This change updates the hyperlinks to make sure the reader lands in the correct location.