I've just started to use Org-Mode as a way to manage my configs. Previously I've kept my configs in a git repo and just had a post-install script to put all the configs in the right place.

For now, I'm testing using Org-Mode for this purpose and I think I like the results.

I have a config.org file that is arranged something like this:

#+TITLE: Configs

 - Tangle a single block with =C-u C-c C-v t=
 - Tangle all blocks with =C-v C-c t=

#+name: secret
#+begin_src emacs-lisp :var name="", fld=""
(if (string-equal fld "password")
    (password-store-get name)
  (password-store-get-field name fld))

* tmux
#+begin_src bash :noweb tangle :tangle ~/.tmux.conf
# start window numbering at 1 for easier switching
set -g base-index 1

# colors
set -g default-terminal "screen-256color"

# Need that longer tmux display time
set -g display-panes-time 2000

# status bar config
set -g status-left "#h:[#S]"
set -g status-left-length 50
set -g status-right-length 100
if-shell "uname | grep -q Darwin" "set -g status-right \"#[fg=white] ⚡#[fg=yellow] #(battery) #[fg=white][✉#(curl icanhazip.com)] %H:%M %d-%h-%Y\""
setw -g window-status-current-format "|#I:#W|"


* mopidy
#+begin_src conf :noweb tangle  :tangle  ~/.config/mopidy/mopidy.conf
enabled = true
hostname =
port = 6600
password =
max_connections = 20
connection_timeout = 60
zeroconf = Mopidy MPD server on $hostname

username = <<secret("Internet/mopidy", "Username")>>
password = <<secret("Internet/mopidy", "password")>>
bitrate = 320
all_access = true
radio_stations_in_browse = true
radio_stations_as_playlists = true
refresh_token = <<secret("Internet/mopidy", "RefreshToken")>>

** etc...

What's going on here?

Firstly I have some hints at the top of my file to remind of of the hotkeys I need to use to manage my configs

  • Tangle a single block with C-u C-c C-v t
  • Tangle all blocks with C-v C-c t

I'm taking advantage of Org's tangle feature to actually write the configs to the location where they belong. For example my tmux config source block has the header :tangle ~/.tmux.conf which means when I tangle the file write it out to ~/.tmux.conf . This means I can make quick edits in the config file then just tangle that block to install it on my system

I also have a little helper function which allows me to combine Orgs noweb syntax and pass to include secrets in my configs without exposing them in my configs.

#+name: secret
#+begin_src emacs-lisp :var name="", fld=""
(if (string-equal fld "password")
    (password-store-get name)
  (password-store-get-field name fld))


With this defined I can just add snippets like this <<secret("Internet/mopidy", "Username")>> to my configs which will call out to password-store and retrieve these secrets before writing them out to a file

All this allows me some added control over how I write my configs, allows me to manage and annotate them in the same file, and still provides me with per config type syntax highlighting thanks to org-babel.