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.
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 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 or Lobsters.
EDIT
This was also announced by Irreal.
Mike Hostetler took inspiration to use literate dotfiles.
And other similar projects: