rw-r--r--

chown -R toon blog/ && chmod -R u=rw,go=r $_

Introducing Literate dotfiles

posted on 2018-12-19

Dotfiles

Not so long ago I started putting my dotfiles in git. For those who aren’t familiar with dotfiles, dotfiles are a collection of small configuration files which reside in your $HOME directory. These files can configure any program you use on your computer, like your desktop environment, your favorite editor, command line utils, and what not…

I used to put my dotfiles on my Dropbox. This worked well, but I wanted to keep history and I also wanted to share them publicly. By putting them in a git repo I would resolve that.

Using GNU Stow

When my dotfiles were still in Dropbox I manually created symbolic links from Dropbox/dot/xyz.conf to the location where the program was expecting them. With putting them in git I wanted to automate the process of symlinking. I had a look at several options, and eventually I decided to use GNU Stow.

GNU Stow is a pretty simple program. It just creates symlinks, if they do not exist already. That’s it! And it works as expected.

To create the symlinks, I just needed to run this command:

stow --target=$(HOME) *

The files in all subdirectories of current working path then get symlinked to $HOME.

Then i3wm came

But around the time I started my dotfiles git repo, I also started using i3wm. This is a tiling window manager that is highly configurable. While I was tuning all the features to my liking, I wanted to keep good documentation to go with that. So I explored one of my favorite weapons of choice: Org mode.

Org mode

I’m a huge fan of Org mode and I already use Org mode to configure my Emacs. Using Org mode for Emacs configuration is not new and used by many Emacs users. But I haven’t seen (m)any people use Org mode to assemble their dotfiles.

Sorry, your browser does not support SVG.

After a lot of fiddling, but I ended up with the result: Literate dotfiles.

This project employs two features of Org mode:

  • Tangling
  • Publishing

Org mode tangling

Tangling is the Org mode feature that handles the blocks between BEGIN_SRC and END_SRC. You can execute those pieces of source code, or you can write them to other files. This is how the actual dotfiles get written to their correct location.

I’ve created a Makefile and elisp/tangle.el which make it possible to tangle files from the command line. But it’s just some magic around (org-babel-tangle). So when I’m modifying the file in Emacs, I just run that command directly with the keybinding C-c C-v t.

Org mode properties

On the project README I’ve described which Org mode properties are used to configure the output files. There are a lot of possibilities, and git.org uses several techniques in one source file.

Org mode publishing

Publishing is the part how the web pages for to1ne.gitlab.io/literate-dotfiles are generated. I kept the configuration and styling of the publishing pretty bare, but you can find all the details in elisp/publish.el.

The project webpages are put online using GitLab Pages. The details can be found in .gitlab-ci.yml, which are based on pages/org-mode.

Problems

There are still a few minor problems I might need to resolve one day.

Because Org mode tangles to another file on disk, I need to make sure tangling the source file does not overwrite changes made to the output file directly. But as long as I keep a good habit of only editing the source file, this is no real issue.

I tried to overcome this problem by writing .out files to a .cache directory. The idea was to compare timestamps. If the output file is newer than the .out file, the output was modified by hand and Org mode tangling should not blindly overwrite the file. But since I mostly tangle files directly from Emacs, these .out files are never written. So the idea isn’t fully thought through yet.


Comments are welcome on Reddit.

EDIT

Also announced at Irreal.