# 1 Introduction

Welcome! In this booklet I will introduce you to Literate Configuration, which is the application of Literate Programming to configuration files. If you are already familiar with Literate Programming you might find most of the basic concepts familiar. Literate Programming is a beautiful concept, but it is ambitious and hard to apply in general software development. However, I have found that it can be especially applicable to configuration files, for several reasons:

• Configuration files are inherently focused, since they correspond to a single application, program or set of programs, all related. This makes it easier to draw a narrative for them;
• Most configuration files are self-contained but their structure and syntax may not be immediately evident, so they benefit from a human-readable explanation of their contents;
• Configuration files are often shared and read by others, as we all like to learn by reading the config files of other people. Applying Literate Programming to config files makes them much easier to share, since their explanation is naturally woven into the code;
• Org-mode has emerged in the last few years as a powerful and simple markup language for general writing, but with unique features that make it easy to include code within the text, and even further, to easily extract that code into stand-alone source files which can be interpreted by their corresponding programs.

Whether you already use Emacs and org-mode or not, I hope you will find value in this book by seeing how uniquely Literate Programming can help you better write, maintain, understand and share your config files.

## Literate Programming

Literate programming was first proposed by Donald Knuth in 1984 (Literate Programming, The Computer Journal, 27 (2): 97–111) as a technique of producing computer code from prose. The general idea is that you write code as you would write a story or an article, describing what you want to do and how to solve it. The code gets interweaved with the code as you explain it. Ultimately, you can produce one of two outputs from the same file:

• A human-readable version of the code, nicely typeset with all the explanations and code, through a process called weaving;
• A computer-executable version of the code, which extracts only the code and puts it in the correct order for the computer to run, through a process called tangling.

The idea of literate programming has been around since then, and a number of tools have been created, starting from Knuth’s own CWEB, Ramsey’s noweb, and others. However, the lack of a standard set of tools has made its adoption slow and limited to specialized instances.

During my first encounter with literate programming I used noweb, but beyond some school projects and homeworks, I could never get Literate Programming to “stick”, until I encountered Org mode.

## Org-mode

Org mode is a markup format and corresponding toolset developed originally within the Emacs text editor. Org provides a wide range of functionality, including text formatting, agenda and todo tracking, and much more. For our purposes, we are interested in the combination of two of its functions:

• Text formatting and exporting. This is one of Org-mode’s core functionalities, and which provides the weaving aspect of Literate Programming by allowing us to produce nicely rendered versions of our document in any of Org’s supported output formats (out of the box Org supports LaTeX, PDF, HTML and others, but many more are available through third-party modules), including both the text narration and the code. The output document may even include syntax highlighting appropriate for the language in which it is written.
• Code block evaluation and exporting. This is enabled by org-babel, one of Org’s built-in modules, which allows flexible manipulation, execution and exporting of code embedded within an Org document. Babel supports tangling code blocks into one or more separate files which include only the code portions of the document.

Using Org-mode with Babel for literate programming is, of course, not a new idea. However, most cases of Literate Configuration that I have seen focus on using Literate Programming for configuring Emacs itself. This is a good use case, but limited in my opinion. In this booklet we will explore how you can use Literate Programming for all your configuration files.

# 2 The Tools and Process

## Emacs and Org-mode

The basic tools in our setup will be Emacs and Org-mode. I assume you have at least a basic knowledge of Emacs, but if you don’t: don’t worry! It takes very little to get started. If you want a gentle introduction, check out the Guided Tour of Emacs. If you have already installed Emacs, you can start an interactive tutorial within Emacs itself by pressing C-h followed by t (if you are using a graphical version of Emacs, this is likely also available from within the Help menu). If you currently use vi or vim, check out Spacemacs, which will allow you to start using Emacs without having to relearn any new keybindings.

Org-mode is included with all recent versions of Emacs, so chances are you already have it installed. Emacs 26.3 (the one I use as oft his writing) includes org-mode 9.1.9, which is quite recent and more than enough for the uses I describe here. If you want to upgrade to the latest version, see the Org-mode Installation Instructions.

## How it works

In general, the process of generating config files from Org files can be illustrated as follows:

Org mode is very flexible, so you can decide how to structure and organize both your source (Org) and destination (config) files in the way that suits you best. Here are some options:

• Org file stored in the same directory as the resulting config file. Usually one org file corresponds to one config file, but multiple related config files (e.g. for the same program or application) could be combined in the same Org file, from which all of them are generated. The advantage of this method is that the source Org files and the configuration files they produce are stored in the same location, which makes it easier to relate them for your own use, and to share them if you put them, for example, in a Github repository. The disadvantage is that the config directory gets “polluted” by the source files, and some applications might even produce errors or complain about having extraneous files in their configuration directories. However, this is very uncommon. This is the setup I use and recommend, and which is described in this booklet.
• All the org files stored in a single directory (or directory tree, or even in a single file), separate from the final destinations of the config files they contain. This has the advantage of giving you a central location for all your org files, regardless of the config files they produce. The drawback is that it makes it harder to selectively share the configuration files for a single program.
• Of course, you can combine the two approaches if it makes sense for you. For example, you might choose to have all your shell’s config files produced from a single Org file, while having separate Org files for other, individual config files.

Ultimately it is up to you to decide which scheme to use. The basic techniques are the same, and the point of literate config is to make things easier for you to understand and maintain.

## Configuring Emacs and org-mode for literate programming

To get started with literate config, the only really indispensable package is org, which can be loaded without prior installation since it is included with Emacs:possible use of literate config:

As you write your config file, you can use the org-babel-tangle command (bound by default to C-c C-v t) to extract the code from the current file into the corresponding code files. Conversely, you can use org-export-dispatch (C-c C-e) to export your file to any of Org’s supported output formats.

There are other optional configurations which you can use to make the experience more efficient and pleasant. You can find these below.

### Automatic tangle on save

After some time, it can get tedious to press C-c C-v t to tangle your files, and you run the risk of forgetting to do it after a change, resulting in a discrepancy between your Org file and your config files. To avoid this, you can configure a hook that automatically runs org-babel-tangle upon saving any org-mode buffer, which means the resulting files will be automatically kept up to date.

### Language-specific org-babel support

You can load and enable org-babel language-specific packages. Many are included in org-mode, while others can be found online. Most org-babel support packages are named ob-<language>. For example, these are some of the ones I use:

• CFEngine, used extensively for my book Learning CFEngine.
• Elvish, my favorite shell.

After you load any necessary packages, you should configure the languages for which to load org-babel support. Note that this does not affect the ability to export/tangle code, but allows you to execute snippets of code from within the Org buffer by pressing C-c C-c on them, and have the results automatically inserted into the buffer.

### Beautifying org-mode

Org-mode allows extensive configuration of its fonts and colors, and doing so can significantly improve the experience of editing literate code with Emacs. In the end, you can have an Emacs setup for editing org documents which looks very nice, with proportional fonts for text and monospaced fonts for code blocks, examples and other elements. For example, here is what a fragment of my Emacs config file looks like:

Instead of describing the configuration here, I’ll just point you to the Beautifying org-mode section of my Emacs config - you can find all the details there.

## Structure of a literate config file

A literate config file is simply an org file which has source code blocks in it with the :tangle option to specify the file to which they should be extracted. If more than one source block specifies the same file, they will be appended in the order they appear. For example, a very simple bash config file can be produced as follows:

If your whole org file gets tangled to a single config file, you can specify the :tangle header globally to avoid having to specify it for every code block. To do this, you specify a header-args global property corresponding to the language of the source blocks you want to export. For example, I have the following line at the top my init.org Hammerspoon config source file:

If the basename of your org file is the same as the exported source file (for example, init.org produces init.lua), you can even use a bit of Emacs Lisp magic to avoid having to specify the output filename by hand, just the extension (shown here in two lines, make sure you type everything in a single line):

Even if you specify the tangle filename globally, you can still change its value for individual code blocks. For example, you can prevent a code block from being tangled by specifying :tangle no, or specify a different filename to write it to a file different from the global one.

# 3 Tips and tricks

We now look at some useful tips that will make your life easier when writing literate config files.

## Converting your existing config files

You probably already have a number of long and complex config files. The beauty of literate config is that you don’t have to do a lot of work to start using it. As a first step, you can simply include your whole file into a single source block. For example, if you already have a /.profile file, you can create /.profile.org with the following:

You can then start breaking it up in logical blocks, adding commentary and other structure as you see fit. For this, you may find useful the org-babel-demarcate-block command, bound by default to C-c C-v C-d. When invoked within a source block, this command splits the block at that point, creating two source blocks with the same language and any other header arguments as the original one.

## Using noweb references to structure your code

Exporting source blocks in the sequence in which they appear in the Org file is useful, but ultimately little more than extensively documenting your file with comments. The real power of literate programming comes from being able to express the logic of your code in a way that makes sense to a human reading it. This does not necessarily match the order or structure in which the code needs to be read by the computer.

This is possible in Org by using noweb references, so called because they follow the same convention introduced by the early noweb literate programming tool. In this convention, a code block can have an arbitrary name, and be referenced (included) in other blocks by specifying its name inside double angle brackets: <<code block name>>.

Processing of noweb references is enabled by the :noweb header argument in source blocks. This argument can have multiple values, but I have found the following to be the most useful:

• :noweb yes enables Noweb processing in the block, both for tangling and for exporting (i.e. when you export the code block to HTML, LaTeX or some other format, the noweb references will be expanded as well);
• :noweb no-export enables Noweb processing in the block when tangling, but not when exporting. This is useful for leaving the noweb indicators in the human-readable exports of your file, which can make it easier to understand.

The name of an individual code block can be specified with the :noweb-ref header argument. If multiple blocks have the same :noweb-ref value, they will be concatenated when referenced. You can also specify the name of a block using a #+name: property line before the source block, but in this case there can be only one block with the given name.

Consider the following org code:

Here we can see that the first block references the two other by their names, and they get combined to produce the final tangled output. This is of course a very simple example, but in complex config files, this technique can make it much easier to see the overall structure of the code before delving in the details. For a more realistic example, see the Org mode section of my Emacs config. Here you can see a top-level block as follows:

The different noweb references get “filled in” throughout the rest of the configuration by assigning them to the corresponding :noweb-ref values. This makes it possible to specify keybindings, variables, faces, hooks and custom config code in the sections where it makes logical sense, rather than where they need to be included in the code.

## Multiple config files per org file

Most Literate Config Org-mode files will probably generate a single config file. However, as illustrated in How it works, you can easily produce multiple config files from a single org file. For this, you can use one of the following techniques:

• Manually specify the file to which each source block should be tangled, using the :tangle header argument to specify it;
• Specify a main tangle target globally, as described in Structure of a literate config file, and specify the :tangle argument for the blocks that should be written to a different file;
• If the different files are produced from within different sections of the Org document, you can specify the :tangle argument per section, by specifying it within a :PROPERTIES drawer of the corresponding headline. For example, in the following source, each section gets tangled to a different output file:

# 4 Literate config examples

In this chapter you will find three real-world examples of literate configuration files created, maintained and used by me. These are the real thing—what you see here is included directly from the Org files that contain the configuration I use for Emacs, Hammerspoon and Elvish, respectively. You can find the latest version of these files, both in Org and in their corresponding tangled output, in Github at the locations specified in each of the sections.

Note also that each section links to a post in my blog containing the corresponding config file. This illustrates another advantage of literate configuration: that the same Org file can be used to produce the output in multiple formats. Each one of the literate config files you see below are rendered in the following places:

• This book, produced by exporting the Org files in Leanpub’s Markua format using the ox-leanpub package;
• The corresponding blog posts in my blog, produced by exporting in Hugo Markdown format using the ox-hugo package;
• Directly in Github, thanks to Github’s support for rendering Org files.

## Emacs config

This is my Emacs configuration file.

This file is written in literate programming style using org-mode. See init.el for the generated file. You can see this in a nicer format on my blog post My Emacs Configuration, With Commentary.

### References

Emacs config is an art, and I have learned a lot by reading through other people’s config files, and from many other resources. These are some of the best ones (several are also written in org mode). You will find snippets from all of these (and possibly others) throughout my config.

### Performance optimization

Lately I’ve been playing with optimizing my Emacs load time. I have found a couple of useful resources, including:

Based on these, I have added the code below.

First, a hook that reports how long and how many garbage collections the startup took. We use a hook to run it at the very end, so the message doesn’t get clobbered by other messages during startup.

Next, we wrap the whole init file in a block that sets file-name-handler-alist to nil to prevent any special-filename parsing of files loaded from the init file (e.g. remote files loaded through tramp, etc.). The let block gets closed in the Epilogue.

Optionally enable debug-on-error - I do this only when I’m trying to figure out some problem in my config.

We set gc-cons-threshold to its maximum value, to prevent any garbage collection from happening during load time. We also reset this value in the Epilogue.

### Customized variables

Emacs has its own Customization mechanism for easily customizing many parameters. To make it easier to manage, I keep the customized variables and faces in a separate file and load it from the main file. A lot of my custom settings are configured from this init file as well, but there are always some which I change by hand for added flexibility.

My current custom.el file can be found at https://github.com/zzamboni/dot-emacs/blob/master/custom.el.

Password management using auth-sources and pass (I normally use 1Password, but I have not found a good command-line/Emacs interface for it, so I am using pass for now for some items I need to add to my Emacs config file).

### Package management

I use the wonderful use-package to manage most of the packages in my installation (one exception is org-mode, see below). As this is not bundled yet with Emacs, the first thing we do is install it by hand. All other packages are then declaratively installed and configured with use-package. This makes it possible to fully bootstrap Emacs using only this config file, everything else is downloaded, installed and configured automatically.

First, we declare the package repositories to use.

Then we initialize the package system, refresh the list of packages and install use-package if needed.

Finally, we load use-package.

We set some configuration for use-package:

• The use-package-always-ensure variable indicates that use-package should always try to install missing packages. For some libraries this is not appropriate, and in those cases you see the :ensure nil declaration as part of the use-package statement. This applies mainly to libraries which are installed as part of some other package (happens mostly with some libraries that come with org-mode).
• The use-package-always-defer sets :defer true as the default for all package declarations. This makes Emacs startup much faster by preventing packages from being loaded when Emacs starts, and only doing so when they are needed. Some packages don’t work well with this, so you’ll see some declarations when I explicitly set :defer nil to force the package to be loaded at startup, or :defer n to load the package, but only n seconds after startup.
• The use-package-verbose variable enables verbose loading of packages, useful for debugging. I set/unset this according to need.

Testing quelpa and to install packages directly from their github repositories (and other places). I install quelpa using use-package first, and then install quelpa-use-package to allow using quelpa from within use-package declarations. Very recursive.

This variable tells Emacs to prefer the .el file if it’s newer, even if there is a corresponding .elc file. Also, use auto-compile to autocompile files as needed.

Set the load path to the directories from where I sometimes load things outside the package system. Note that the path for org-mode (which I load from a checkout of its git repository) is set as part of its use-package declaration, so it doesn’t appear here.

Giving a try to Paradox for an enhanced package management interface. We set paradox-github-token to t to disable GitHub integration (I don’t want to star repos).

### Settings

#### Proxy settings

These are two short functions I wrote to be able to set/unset proxy settings within Emacs. I haven’t bothered to improve or automate this, as I pretty much only need it to be able to install packages sometimes when I’m at work. For now I just call them manually with M-x zz/(un)set-proxy when I need to.

#### Miscellaneous settings

• Load the cl library to enable some additional macros (e.g. lexical-let).
• Start the Emacs server
• This is probably one of my oldest settings - I remember adding it around 1993 when I started learning Emacs, and it has been in my config ever since. When time-stamp is run before every save, the string Time-stamp: <> in the first 8 lines of the file will be updated with the current timestamp.
• When at the beginning of the line, make Ctrl-K remove the whole line, instead of just emptying it.
• Paste text where the cursor is, not where the mouse is.
• Make completion case-insensitive.
• Show line numbers. I used linum-mode before, but it caused severe performance issues on large files. Emacs 26 introduces display-line-numbers-mode, which has no perceivable performance impact even on very large files. Disabled for now.
• Highlight trailing whitespace in red, so it’s easily visible (disabled for now as it created a lot of noise in some modes, e.g. the org-mode export screen)
• Highlight matching parenthesis
• Don’t use hard tabs
• Emacs automatically creates backup files, by default in the same folder as the original file, which often leaves backup files behind. This tells Emacs to put all backups in ~/.emacs.d/backups.
• WinnerMode makes it possible to cycle and undo window configuration changes (i.e. arrangement of panels, etc.)
• Add “unfill” commands to parallel the “fill” ones, bind A-q to unfill-paragraph and rebind M-q to the unfill-toggle command, which fills/unfills paragraphs alternatively.
• Save the place of the cursor in each file, and restore it upon opening it again.
• Provide mode-specific “bookmarks” - press M-i and you will be presented with a list of elements to which you can navigate - they can be headers in org-mode, function names in emacs-lisp, etc.
• Smooth scrolling (line by line) instead of jumping by half-screens.
• Delete trailing whitespace before saving a file.
• Suppress “ad-handle-definition: .. redefined” warnings during Emacs startup.

### System-specific configuration

Some settings maybe OS-specific, and this is where we set them. For now I only use Emacs on my Mac, so only the Mac section is filled out, but there are sections for Linux and Windows as well.

#### Mac

First, we set the key modifiers correctly to my preferences: Make Command (⌘) act as Meta, Option as Alt, right-Option as Super

We also make it possible to use the familiar ⌘-+ and ⌘-- to increase and decrease the font size. ⌘-= is also bound to “increase” because it’s on the same key in an English keyboard.

Somewhat surprisingly, there seems to be no “reset” function, so I define my own and bind it to ⌘-0.

We also use the exec-path-from-shell to make sure the path settings from the shell are loaded into Emacs (usually it starts up with the default system-wide path).

#### Linux

There are no Linux-specific settings for now.

#### Windows

There are no Windows-specific settings for now.

### Keybindings

The which-key package makes Emacs functionality much easier to discover and explore: in short, after you start the input of a command and stop, pondering what key must follow, it will automatically open a non-intrusive buffer at the bottom of the screen offering you suggestions for completing the command. Extremely useful.

I use the bind-key package to more easily keep track and manage user keybindings. bind-key comes with use-package so we just load it.

The main advantage of using this over define-key or global-set-key is that you can use M-x describe-personal-keybindings to see a list of all the customized keybindings you have defined.

#### Miscellaneous keybindings

• M-g interactively asks for a line number and jump to it (goto-line).
• M- focuses the next frame, if multiple ones are active (emulate the Mac “next app window” keybinding)
• Interactive search key bindings - visual-regexp-steroids provides sane regular expressions and visual incremental search. We make C-s and C-r run the visual-regexp functions. We leave C-M-s and C-M-r to run the default isearch-forward/backward functions, as a fallback. I use the pcre2el package to support PCRE-style regular expressions.
• Key binding to use “hippie expand” for text autocompletion

#### Emulating vi’s % key

One of the few things I missed in Emacs from vi was the % key, which jumps to the parenthesis, bracket or brace which matches the one below the cursor. This function implements the functionality. Inspired by http://www.emacswiki.org/emacs/NavigatingParentheses, but modified to use smartparens instead of the default commands, and to work on brackets and braces.

We bind this function to the % key.

### Org mode

I have started using org-mode to writing, blogging, coding, presentations and more, thanks to the hearty recommendations and information from Nick and many others. I am duly impressed. I have been a fan of the idea of literate programming for many years, and I have tried other tools before (most notably noweb, which I used during grad school for many of my homeworks and projects), but org-mode is the first tool I have encountered which seems to make it practical. Here are some of the resources I have found useful in learning it:

This is the newest and most-in-flux section of my Emacs config, since I’m still learning org-mode myself.

I use use-package to load the org package, and put its configuration inside the corresponding sections for keybindings (:bind), custom variables (:custom), custom faces (:custom-face), hooks (:hook) and general configuration code (:config), respectively. The contents of each section is populated with the corresponding snippets that follow. See the sections below for the details on what goes into each configuration section, and some other configuration code that ends up outside this declaration.

#### General Org Configuration

Note that mode-specific configuration variables are defined under their corresponding packages, this section defines only global org-mode configuration variables, which are inserted in the main use-package declaration for org-mode.

• Default directory for org files (not all are stored here).
• Automatically log done times in todo items.
• Keep the indentation well structured by setting org-startup-indented to t. This is a must have. Makes it feel less like editing a big text file and more like a purpose built editor for org-mode that forces the indentation. Thanks Nick for the tip!

By default, org-indent produces an indicator "Ind" in the modeline. We use diminish to hide it. I also like to increase the indentation a bit so that the levels are more visible.

• Log stuff into the LOGBOOK drawer by default

#### General Org Keybindings

Note that other keybindings are configured under their corresponding packages, this section defines only global org-mode keybindings, which are inserted in the main use-package declaration for org-mode.

• Set up C-c l to store a link to the current org object, in counterpart to the default C-c C-l to insert a link.
• The default keybinding for org-mark-element is M-h, which in macOS hides the current application, so I bind it to A-h.

Enable Speed Keys, which allows quick single-key commands when the cursor is placed on a heading. Usually the cursor needs to be at the beginning of a headline line, but defining it with this function makes them active on any of the asterisks at the beginning of the line (useful with the font highlighting I use, as all but the last asterisk are sometimes not visible).

Org-Agenda is the umbrella for all todo, journal, calendar, and other views. I set up C-c a to call up agenda mode.

I also provide some customization for the holidays package, since its entries are included in the Org Agenda through the org-agenda-include-diary integration.

org-super-agenda provides great grouping and customization features to make agenda mode easier to use.

I configure org-archive to archive completed TODOs by default to the archive.org file in the same directory as the source file, under the “date tree” corresponding to the task’s CLOSED date - this allows me to easily separate work from non-work stuff. Note that this can be overridden for specific files by specifying the desired value of org-archive-location in the #+archive: property at the top of the file.

#### Capturing stuff

First, I define some global keybindings to open my frequently-used org files (original tip from Learn how to take notes more efficiently in Org Mode).

I define a helper function to define keybindings that open files. Since I use the which-key package, it also defines the description of the key that will appear in the which-key menu. Note the use of lexical-let so that the lambda creates a closure, otherwise the keybindings don’t work.

Now I define keybindings to access my commonly-used org files.

org-capture provides a generic and extensible interface to capturing things into org-mode in different formats. I set up C-c c as the default keybinding for triggering org-capture. Usually setting up a new capture template requires some custom code, which gets defined in the corresponding package config sections and included in the :config section below.

#### Building presentations

org-reveal is an awesome package for building presentations with org-mode. The MELPA version of the package gives me a conflict with my hand-installed version of org-mode, so I also install it by hand and load it directly from its checked-out repository.

#### Various exporters

One of the big strengths of org-mode is the ability to export a document in many different formats. Here I load some of the exporters I have found useful.

• HTML
• Markdown
• GitHub Flavored Markdown
• Jira markup. I also load org-jira, which provides a full interface to Jira through org-mode.
• Confluence markup.
• AsciiDoc
• TexInfo. I have found that the best way to produce a PDF from an org file is to export it to a .texi file, and then use texi2pdf to produce the PDF.
• Some customizations for the LaTeX exporter. ox-latex gets loaded automatically, but we use use-package anyway so that the config code is only executed after the package is loaded. I add a pseudo-class which uses the document class book but without parts (only chapters at the top level).
• ox-clip to export HTML-formatted snippets.

#### Blogging with Hugo

ox-hugo is an awesome way to blog from org-mode. It makes it possible for posts in org-mode format to be kept separate, and it generates the Markdown files for Hugo. Hugo supports org files, but using ox-hugo has multiple advantages:

• Parsing is done by org-mode natively, not by an external library. Although goorgeous (used by Hugo) is very good, it still lacks in many areas, which leads to text being interpreted differently as by org-mode.
• Hugo is left to parse a native Markdown file, which means that many of its features such as shortcodes, TOC generation, etc., can still be used on the generated file.
• I am intrigued by ox-hugo’s “one post per org subtree” proposed structure. So far I’ve always had one file per post, but with org-mode’s structuring features, it might make sense to give it a try.

Configure a capture template for creating new ox-hugo blog posts, from ox-hugo’s Org Capture Setup.

#### Encryption

First, load the built-in EasyPG support. By calling (epa-file-enable), Emacs automatically encrypts/decrypts files with a .gpg extension. By default it asks about the key to use, but I configure it to always use my own GPG key.

Then, load org-crypt to enable selective encryption/decryption using GPG within org-mode.

#### Keeping a Journal

I use 750words for my personal Journal, and I used to write my entries locally using Scrivener. Now I am using org-journal for this, works quite well together with wc-mode to keep a count of how many words I have written.

In order to keep my journal entries encrypted there are two separate but confusingly named mechanisms:

• org-journal-encrypt-journal, if set to t has the effect of transparently encrypting/decrypting the journal files as they are written to disk. This is what I use.
• org-journal-enable-encryption, if set to t, enables integration with org-crypt (see above), so it automatically adds a :crypt: tag to new journal entries. This has the effect of automatically encrypting those entries upon save, replacing them with a blob of gpg-encrypted text which has to be further decrypted with org-decrypt-entry in order to read or edit them again. I have disabled it for now to make it more transparent to work with my journal entries while I am editing them.

#### Literate programming

Org-mode is the first literate programming tool that seems practical and useful, since it’s easy to edit, execute and document code from within the same tool (Emacs) using all of its existing capabilities (i.e. each code block can be edited in its native Emacs mode, taking full advantage of indentation, completion, etc.)

First, we load the necessary programming language support. The base features and literate programming for Emacs LISP is built-in, but the ob-* packages provide the ability to execute code in different languages directly from within the Org buffer, beyond those included with org-mode. I load the modules for some of the languages I use frequently:

• CFEngine, used extensively for my book Learning CFEngine.
• Elvish, my favorite shell.
• The PlantUML graph language.

We determine the location of the PlantUML jar file automatically from the installed Homebrew formula.

Which in my current setup results in the following:

The command defined above is used to define the value of the homebrew-plantuml-jar-path variable. If you don’t use Homebrew of have installed PlantUML some other way, you need to modify this command, or hard-code the path.

Finally, we use this value to configure both plantuml-mode (for syntax highlighting) and ob-plantuml (for evaluating PlantUML code and inserting the results in exported Org documents).

• Define shell-script-mode as an alias for console-mode, so that console src blocks can be edited and are fontified correctly.
• Finally, from all the available languages, we configure the ones for which to load org-babel support.

Now, we configure some other org-babel settings:

• This little snippet has revolutionized my literate programming workflow. It automatically runs org-babel-tangle upon saving any org-mode buffer, which means the resulting files will be automatically kept up to date.
• This is potentially dangerous: it suppresses the query before executing code from within org-mode. I use it because I am very careful and only press C-c C-c on blocks I absolutely understand.
• This makes it so that code within src blocks is fontified according to their corresponding Emacs mode, making the file much more readable.
• In principle this makes it so that indentation in src blocks works as in their native mode, but in my experience it does not always work reliably. For full proper indentation, always edit the code in a native buffer by pressing C-c '.
• Automatically show inline images, useful when executing code that produces them, such as PlantUML or Graphviz.
• I add hooks to measure and report how long the tangling took. I first define a function to compute and report the elapsed time:

And this function is used in the corresponding hooks before and after org-babel-tangle:

#### Beautifying org-mode

These settings make org-mode much more readable by using different fonts for headings, hiding some of the markup, etc. This was taken originally from Howard Abrams’ Org as a Word Processor, and subsequently tweaked and broken up in the different parts of the use-package declaration by me.

First, we set org-hid-emphasis-markers so that the markup indicators are not shown.

We add an entry to the org-mode font-lock table so that list markers are shown with a middle dot instead of the original character.

We use the org-bullets package to display the titles with nice unicode bullets instead of the text ones.

We choose a nice font for the document title and the section headings. The first one found in the system from the list below is used, and the same font is used for the different levels, in varying sizes.

I use proportional fonts in org-mode for the text, while keeping fixed-width fonts for blocks, so that source code, tables, etc. are shown correctly. These settings include:

• Setting up the variable-pitch face to the proportional font I like to use. I’m currently alternating between my two favorites, Source Sans Pro and Avenir Next.
• Setting up the fixed-pitch face to be the same as my usual default face. My current one is Inconsolata.
• Configure org-indent to inherit from fixed-pitch to fix the vertical spacing in code blocks. Thanks to Ben for the tip!
• Configure org-fontify-done-headline to apply a special face to DONE items in org-mode, and configure the org-done face to be used. Note that org-done only applies to the “DONE” keyword itself, the face for the rest of a “done” headline is defined above as the org-headline-done face.
• Configuring the corresponding org-mode faces for blocks, verbatim code, and maybe a couple of other things. As these change more frequently, I do them directly from the customize-face interface, you can see their current settings in the Customized variables section.
• Setting up visual-line-mode and making all my paragraphs one single line, so that the lines wrap around nicely in the window according to their proportional-font size, instead of at a fixed character count, which does not work so nicely when characters have varying widths. I set up a hook that automatically enables visual-line-mode and variable-pitch-mode when entering org-mode.
• In variable-pitch mode, the default right-alignment for headline tags doesn’t work, and results in the tags being misaligned (as it uses character positions to do the alignment). This setting positions the tags right after the last character of the headline, so at least they are more consistent.
• I also set org-todo-keyword-faces to highlight different types of org-mode TODO items with different colors.

These two modes produce modeline indicators, which I disable using diminish.

• Prettify checkbox lists - courtesy of https://blog.jft.rocks/emacs/unicode-for-orgmode-checkboxes.html. First, we add special characters for checkboxes:

Second, we define a special face for checked items.

The toc-org package allows us to insert a table of contents in headings marked with :TOC:. This is useful for org files that are to be viewed directly on GitHub, which renders org files correctly, but does not generate a table of contents at the top. For an example, see this file on GitHub.

Note that this breaks HTML export by default, as the links generated by toc-org cannot be parsed properly by the html exporter. The workaround is to use :TOC:noexport: as the marker, which removed the generated TOC from the export, but still allows ox-html to insert its own TOC at the top.

org-mac-link (included in contrib) implements the ability to grab links from different Mac apps and insert them in the file. Bind C-c g to call org-mac-grab-link to choose an application and insert a link.

#### Reformatting an Org buffer

I picked up this little gem in the org mailing list. A function that reformats the current buffer by regenerating the text from its internal parsed representation. Quite amazing.

Remove a link. For some reason this is not part of org-mode. From https://emacs.stackexchange.com/a/10714/11843, I bind it to C-c C-M-u.

#### Code for org-mode macros

Here I define functions which get used in some of my org-mode macros

The first is a support function which gets used in some of the following, to return a string (or an optional custom string) only if it is a non-zero, non-whitespace string, and nil otherwise.

This function receives three arguments, and returns the org-mode code for a link to the Hammerspoon API documentation for the link module, optionally to a specific function. If desc is passed, it is used as the display text, otherwise section.function is used.

Split STR at spaces and wrap each element with the ~ char, separated by +. Zero-width spaces are inserted around the plus signs so that they get formatted correctly. Envisioned use is for formatting keybinding descriptions. There are two versions of this function: “outer” wraps each element in ~, the “inner” wraps the whole sequence in them.

Links to a specific section/function of the Lua manual.

#### Publishing project configuration

Define a publishing function based on org-latex-publish-to-pdf but which opens the resulting file at the end.

Sample project configuration - disabled for now because this configuration has been incorporated into the structure.tex file and in the general ox-latex configuration, but kept here as a sample.

#### Publishing to LeanPub

I use LeanPub for self-publishing my books Learning Hammerspoon and Learning CFEngine. Fortunately, it is possible to export from org-mode to LeanPub-flavored Markdown.

Some references:

First, load ox-leanpub-markdown. This is based on Juan’s ox-leanpub, but with many changes of my own, including a rename. You can get it from my fork at https://github.com/zzamboni/ox-leanpub/tree/book-and-markua.

Next, load my ox-leanpub-book module (also available at https://github.com/zzamboni/ox-leanpub/tree/book-and-markua). It defines a new export backend called leanpub-book, which adds three additional items in the LeanPub export section:

• “Multifile: Whole book”, which exports the whole book as one-file-per-chapter;
• “Multifile: Subset”, which exports only the chapters that should be included in Subset.txt (if any), according to the rules listed below. I use this together with #+LEANPUB_WRITE_SUBSET: current in my files to quickly export only the current chapter, to be able to quickly preview it using LeanPub’s subset-preview feature;
• “Multifile: Current chapter” to explicitly export only the current chapter to its own file. This also updates Subset.txt, so it can be used to preview the current chapter without having to set #+LEANPUB_WRITE_SUBSET: current.

The book files are populated as follows:

• Book.txt with all chapters, except those tagged with noexport.
• Sample.txt with all chapters tagged with sample.
• Subset.txt with chapters depending on the value of the #+LEANPUB_WRITE_SUBSET file property (if set):
• Default or none: not created.
• tagged: use all chapters tagged subset.
• all: use the same chapters as Book.txt.
• sample: use same chapters as Sample.txt.
• current: export the current chapter (where the cursor is at the moment of the export) as the contents of Subset.txt.

If a heading has the frontmatter, mainmatter or backmatter tags, the corresponding markup is inserted in the output, before the headline. This way, you only need to tag the first chapter of the front, main, and backmatter, respectively.

Note that the org-leanpub-book-setup-menu-markdown function gets called in the :config section. This is because I am working on ox-markua to export Leanpub’s new Markua format, and I plan for ox-leanpub-book to also support it.

#### Miscellaneous org functions and configuration

Utility org-get-keyword function (from the org-mode mailing list) to get the value of file-level properties.

org-sidebar provides a configurable sidebar to org buffers, showing the agenda, headlines, etc.

### Appearance, buffer/file management and theming

Here we take care of all the visual, UX and desktop-management settings.

You’ll notice that many of the packages in this section have :defer nil. This is because some of these package are never called explicitly because they operate in the background, but I want them loaded when Emacs starts so they can perform their necessary customization.

Emacs 26 (which I am trying now) introduces pixel-level scrolling.

The diminish package makes it possible to remove clutter from the modeline. Here we just load it, it gets enabled for individual packages in their corresponding declarations.

I have been playing with different themes, and I have settled for now in gruvbox. Some of my other favorites are also here so I don’t forget about them.

Install smart-mode-line for modeline goodness, including configurable abbreviation of directories, and other things.

Enable desktop-save mode, which saves the current buffer configuration on exit and reloads it on restart.

Desktop mode also includes the desktop-clear function, which can be used to kill all open buffers. I bind it to Control-Meta-super-k.

The uniquify package makes it much easier to identify different open files with the same name by prepending/appending their directory or some other information to them. I configure it to add the directory name after the filename. uniquify is included with Emacs, so I specify :ensure nil so that use-package doesn’t try to install it, and just loads and configures it.

I like to highlight the current line. For this I use the built-in hl-line.

I also provide a custom value for hl-line-range-function (thanks to Eric on the org-mode mailing list for the tip) which highlights only the current visual line in visual-line-mode, which I use for Org-mode files (see Beautifying org-mode).

I have also experimented with highlighting the current column. At the moment the code below is all disabled because I find it too distracting, but I’m leaving it here for reference. I found two options to achieve this:

• The col-highlight package, which highlights the column only after a defined interval has passed
• The crosshairs package, which always highlights both the column and the line. It also has a “highlight crosshairs when idle” mode, but I prefer to have the current line always highlighted.

I also use recentf to keep a list of recently open buffers. These are visible in helm’s open-file mode.

The ibuffer package allows all sort of useful operations on the list of open buffers. I haven’t customized it yet, but I have a keybinding to open it. (Disabled for now as I am using helm’s helm-buffer-list).

The smex package is incredibly useful, adding IDO integration and some other very nice features to M-x, which make it easier to discover and use Emacs commands. Highly recommended. (Disabled for now as I’m using helm’s helm-M-x).

midnight-mode purges buffers which haven’t been displayed in 3 days. We configure the period so that the cleanup happens every 2 hours (7200 seconds).

For distraction-free writing, I’m testing out writeroom-mode.

NeoTree shows a navigation tree on a sidebar, and allows a number of operations on the files and directories. I’m not much of a fan of this type of interface in Emacs, but I have set it up to check it out.

wc-mode allows counting characters and words, both on demand and continuously. It also allows setting up a word/character goal.

The all-the-icons package provides a number of useful icons.

#### Completion: IDO or Helm?

The battle rages on - helm or IDO? Both are nice completion frameworks for Emacs, and both integrate nicely with most main Emacs functions, including file opening, command and buffer selection, etc. I was using IDO for some time but are now giving helm a try. Both my configs are shown below, but only Helm is enabled at the moment.

Should I also look at ivy?

##### IDO

I use IDO mode to get better matching capabilities everywhere in Emacs (disabled while I give helm a try, see below).

##### Helm

This config came originally from Uncle Dave’s Emacs config, thought I have tweaked it a bit.

### Coding

Coding is one of my primary uses for Emacs, although lately it has shifted toward more general writing. This used to be the largest section in my config until Org mode overtook it :)

#### General settings and modules

When enabled, subword allows navigating “sub words” individually in CamelCaseIdentifiers. For now I only enable it in clojure-mode.

With aggressive-indent, indentation is always kept up to date in the whole buffer. Sometimes it gets in the way, but in general it’s nice and saves a lot of work, so I enable it for all programming modes except for Python mode, where I explicitly disable as it often gets the indentation wrong and messes up existing code.

Disabled for now while I test how much I miss it (I often find it gets in the way, but I’m not sure how often it helps and I don’t even notice it)

With company-mode, we get automatic completion - when there are completions available, a popup menu will appear when you stop typing for a moment, and you can either continue typing or accept the completion using the Enter key. I enable it globally.

projectile-mode allows us to perform project-relative operations such as searches, navigation, etc.

I find iedit absolutely indispensable when coding. In short: when you hit Ctrl-:, all occurrences of the symbol under the cursor (or the current selection) are highlighted, and any changes you make on one of them will be automatically applied to all others. It’s great for renaming variables in code, but it needs to be used with care, as it has no idea of semantics, it’s a plain string replacement, so it can inadvertently modify unintended parts of the code.

Turn on the online documentation mode for all programming modes (not all of them support it) and for the Clojure REPL cider mode.

On-the-fly spell checking. I enable it for all text modes.

#### Clojure and LISP coding

I dabble in Clojure and Emacs LISP, and Emacs has some fantastic support for them. There’s a number of packages and configuration related to this, so I have a whole section for it.

The centerpiece is of course clojure-mode. In addition to files ending in .clj, I bind it automatically to .boot files (both by extension and by shebang line) and to the Riemann config files.

Enable some additional fontification for Clojure code.

The cider package provides a fantastic REPL built into Emacs. We configure a few aspects, including pretty printing, fontification, history size and others.

We use clj-refactor for supporting advanced code refactoring in Clojure.

Use emr for supporting refactoring in Emacs LISP and some other languages.

When coding in LISP-like languages, rainbow-delimiters is a must-have - it marks each concentric pair of parenthesis with different colors, which makes it much easier to understand expressions and spot mistakes.

Another useful addition for LISP coding - smartparens enforces parenthesis to match, and adds a number of useful operations for manipulating parenthesized expressions. I map M-( to enclose the next expression as in paredit using a custom function. Prefix argument can be used to indicate how many expressions to enclose instead of just 1. E.g. C-u 3 M-( will enclose the next 3 sexps.

Minor mode for highlighting the current sexp in LISP modes.

Trying out lispy for LISP code editing (disabled for now).

#### Other programming languages

Many other programming languages are well served by a single mode, without so much setup as Clojure/LISP.

• CFEngine policy files.
• Perl.
• Fish shell.
• Lua, which I use for Hammerspoon configuration.
• YAML, generally useful
• AppleScript
• Go
• Build and check MELPA package definitions
• Elvish shell
• Racket
• Nix package files
• Dockerfile files
• The Dhall configuration language

### Other tools

• Use helm-pass as an interface to pass.
• git interface with some simple configuration I picked up somewhere. When you press C-c C-g, magit-status runs full-screen, but when you press q, it restores your previous window setup. Very handy.
• Interface to use the silver-searcher
• Publishing with Hugo. I don’t use this anymore since I started blogging with ox-hugo. I keep it loaded, but without its keybinding, because it makes it easy sometimes to see the history of my Markdown posts.
• Function to randomize the order of lines in a region, from https://www.emacswiki.org/emacs/RandomizeBuffer.
• auto-insert mode for automatically inserting user-defined templates for certain file types. It’s included with Emacs, so I just configure its directory to one inside my Dropbox, and set the hook to run it automatically when opening a file.
• Create and manage GitHub gists. Setting gist-view-gist to t makes it open new gists in the web browser automatically after creating them.
• Emacs Startup Profiler, to get detailed stats of what’s taking time during initialization.
• Macro to measure how long a command takes, from https://stackoverflow.com/questions/23622296/emacs-timing-execution-of-function-calls-in-emacs-lisp
• Trying out Deft
• Ability to restart Emacs from within Emacs:
• Multiple cursors

### General text editing

In addition to coding, I configure some modes that can be used for text editing.

• AsciiDoc, which I use for my book and some other text. I also set up visual-line-mode and variable-pitch-mode here. adoc-mode is not so granular as org-mode with respect to face assignments, so the variable/fixed distinction does not always work, but it’s still pretty good for long-text editing.
• Markdown, generally useful. I also set up variable pitch and visual line mode.
• When typopunct is enabled (needs to be enabled by hand), automatically inserts “pretty” quotes of the appropriate type.
• undo-tree visualises undo history as a tree for easy navigation (found about this from Jamie’s config)

### Cheatsheet and experiments

Playground and how to do different things, not necessarily used in my Emacs config but useful sometimes.

This is how we get a global header property in org-mode

Testing formatting org snippets to look like noweb-rendered output (disabled for now).

An experiment to reduce file tangle time, from https://www.wisdomandwonder.com/article/10630/how-fast-can-you-tangle-in-org-mode. In my tests it doesn’t have a noticeable impact.

A work-in-progress Hammerspoon shell for Emacs, posted on the Hammerspoon mailing list.

### Epilogue

Here we close the let expression from the preface.

We also reset the value of gc-cons-threshold, not to its original value, we still leave it larger than default so that GCs don’t happen so often.

## Hammerspoon config

This is my Hammerspoon configuration file.

This file is written in literate programming style using org-mode. See init.lua for the generated file. You can see this in a nicer format on my blog post My Hammerspoon Configuration, With Commentary.

If you want to learn more about Hammerspoon, check out my book Learning Hammerspoon!

### General variables and configuration

Global log level. Per-spoon log level can be configured in each Install:andUse block below.

I use hyper and shift_hyper as the modifiers for most of my key bindings, so I define them as variables here for easier referencing.

Set up an abbreviation for hs.drawing.color.x11 since I use it repeatedly later on.

Work’s logo, which I use in some of my Seal shortcuts later on.

### Spoon Management

Set up SpoonInstall - this is the only spoon that needs to be manually installed (it is already there if you check out this repository), all the others are installed and configured automatically.

Configuration of my personal spoon repository, which contains Spoons that have not been merged in the main repo. See the descriptions at https://zzamboni.github.io/zzSpoons/.

I prefer sync notifications, makes them easier to read.

This is just a shortcut to make the declarations below look more readable, i.e. Install:andUse instead of spoon.SpoonInstall:andUse.

### BetterTouchTool

I’m currently working on a new BetterTouchTool.spoon which provides integration with the BetterTouchTool AppleScript API. This is in heavy development! See the configuration for the Hammer spoon in System and UI for an example of how to use it.

### URL Dispatching to site-specific browsers

The URLDispatcher spoon makes it possible to open URLs with different browsers. I have created different site-specific browsers using Epichrome, which allows me to keep site-specific bookmarks, search settings, etc.

### Window and screen manipulation

The WindowHalfsAndThirds spoon sets up multiple key bindings for manipulating the size and position of windows.

The WindowScreenLeftAndRight spoon sets up key bindings for moving windows between multiple screens.

The WindowGrid spoon sets up a key binding (Hyper-g here) to overlay a grid that allows resizing windows by specifying their opposite corners.

The ToggleScreenRotation spoon sets up a key binding to rotate the external screen (the spoon can set up keys for multiple screens if needed, but by default it rotates the first external screen).

### Organization and Productivity

The UniversalArchive spoon sets up a single key binding (Ctrl-Cmd-a) to archive the current item in Evernote, Mail and Outlook.

The SendToOmniFocus spoon sets up a single key binding (Hyper-t) to send the current item to OmniFocus from multiple applications. We use the fn attribute of Install:andUse to call a function which registers some of the Epichrome site-specific-browsers I use, so that the Spoon knows how to collect items from them.

The EvernoteOpenAndTag spoon sets up some missing key bindings for note manipulation in Evernote. I no longer use Evernote for GTD, so I have disabled the shortcuts for tagging notes.

The TextClipboardHistory spoon implements a clipboard history, only for text items. It is invoked with Cmd-Shift-v.

This is disabled for the moment as I experiment with BetterTouchTool’s built-in clipboard history, which I have bound to the same key combination for consistency in my workflow.

### System and UI

The BTT_restart_Hammerspoon function sets up a BetterTouchTool widget which also executes the config_reload action from the spoon. This gets assigned to the fn config parameter in the configuration of the Hammer spoon below, which has the effect of calling the function with the Spoon object as its parameter.

This is still very manual - the uuid parameter contains the ID of the BTT widget to configure, and for now you have to get it by hand from BTT and paste it here.

The Hammer spoon (get it? hehe) is a simple wrapper around some common Hamerspoon configuration variables. Note that this gets loaded from my personal repo, since it’s not in the official repository.

The Caffeine spoon allows preventing the display and the machine from sleeping. I use it frequently when playing music from my machine, to avoid having to unlock the screen whenever I want to change the music. In this case we also create a function BTT_caffeine_widget to configure the widget to both execute the corresponding function, and to set its icon according to the current state.

The MenubarFlag spoon colorizes the menubar according to the selected keyboard language or layout (functionality inspired by ShowyEdge). I use English, Spanish and German, so those are the colors I have defined.

The MouseCircle spoon shows a circle around the mouse pointer when triggered. I have it disabled for now because I have the macOS shake-to-grow feature enabled.

One of my original bits of Hammerspoon code, now made into a spoon (although I keep it disabled, since I don’t really use it). The ColorPicker spoon shows a menu of the available color palettes, and when you select one, it draws swatches in all the colors in that palette, covering the whole screen. You can click on any of them to copy its name to the clipboard, or cmd-click to copy its RGB code.

I use Homebrew, and when I run brew update, I often wonder about what some of the formulas shown are (names are not always obvious). The BrewInfo spoon allows me to point at a Formula or Cask name and press Hyper-b or Hyper-c (for Casks) to have the output of the info command in a popup window, or the same key with Shift-Hyper to open the URL of the Formula/Cask.

The KSheet spoon traverses the current application’s menus and builds a cheatsheet of the keyboard shortcuts, showing it in a nice popup window.

The TimeMachineProgress spoon shows an indicator about the progress of the ongoing Time Machine backup. The indicator disappears when there is no backup going on.

### Other applications

The ToggleSkypeMute spoon sets up the missing keyboard bindings for toggling the mute button on Skype and Skype for Business. I’m not fully happy with this spoon - it should auto-detect the application instead of having separate keys for each application, and it could be extended to more generic use.

The HeadphoneAutoPause spoon implements auto-pause/resume for iTunes, Spotify and others when the headphones are unplugged.

### Seal

The Seal spoon is a powerhouse - it implements a Spotlight-like launcher, but which allows for infinite configurability of what can be done or searched from the launcher window. I use Seal as my default launcher, triggered with Cmd-space, although I still keep Spotlight around under Hyper-space, mainly for its search capabilities.

We start by loading the spoon, and specifying which plugins we want.

The useractions Seal plugin allows me to define my own shortcuts. For example, a bookmark to the Hammerspoon documentation page:

Or to manually trigger my work/non-work transition scripts (see below):

Or to translate things using dict.leo.org:

### Network transitions

The WiFiTransitions spoon allows triggering arbitrary actions when the SSID changes. I am interested in the change from my work network (corpnet01) to other networks, mainly because at work I need a proxy for all connections to the Internet. I have two applications which don’t handle these transitions gracefully on their own: Spotify and Adium. So I have written a couple of functions for helping them along.

The reconfigSpotifyProxy function quits Spotify, updates the proxy settings in its config file, and restarts it.

The reconfigAdiumProxy function uses AppleScript to tell Adium about the change without having to restart it - only if Adium is already running.

Functions to stop applications that are disallowed in the work network.

The configuration for the WiFiTransitions spoon invoked these functions with the appropriate parameters.

### Pop-up translation

I live in Switzerland, and my German is far from perfect, so the PopupTranslateSelection spoon helps me a lot. It allows me to select some text and, with a keystroke, translate it to any of three languages using Google Translate. Super useful! Usually, Google’s auto-detect feature works fine, so the translate_to_<lang> keys are sufficient. I have some translate_<from>_<to> keys set up for certain language pairs for when this doesn’t quite work (I don’t think I’ve ever needed them).

I am now testing DeepLTranslate, based on PopupTranslateSelection but which uses the DeepL translator.

### Leanpub integration

The Leanpub spoon provides monitoring of book build jobs.

In init-local.lua I keep experimental or private stuff (like API tokens) that I don’t want to publish in my main config. This file is not committed to any publicly-accessible git repositories.

### End-of-config animation

The FadeLogo spoon simply shows an animation of the Hammerspoon logo to signal the end of the config load.

If you don’t want to use FadeLogo, you can have a regular notification.

## Elvish config

This is my main config file for Elvish.

This file is written in literate programming style using org-mode. See rc.elv for the generated file. You can see this in a nicer format on my blog post My Elvish Configuration With Commentary.

### Paths

First we set up the executable paths. We set the GOPATH environment variable while we are at it, since we need to use it as part of the path.

### Package installation

The bundled epm module allows us to install and manage Elvish packages.

For now I use these packages:

The modules within each package get loaded individually below.

### Automatic proxy settings

When I am in the office, I need to use a proxy to access the Internet. For macOS applications, the proxy is set automatically using a company-provided PAC file. For the environment variables http_proxy and https_proxy, commonly used by command-line programs, the proxy module allows me to define a test which determines when the proxy should be used, so that the change is done automatically. We load this early on so that other modules which need to access the network get the correct settings already.

First, we load the module and set the proxy host.

Next, we set the test function to enable proxy auto-setting. In my case, the /etc/resolv.conf file contains the corproot.net domain (set through DHCP) when I’m in the corporate network, so I can check for that.

We run an initial check so that other commands in rc.org get the correctd settings already, even before the first prompt.

### Base modules

Load the bundled re module to have access to regular expression functions.

The bundled readline-binding module associates some Emacs-like keybindings for manipulation of the command line.

I add a couple of keybindings which are missing from the default readline-binding module:

• Alt-backspace to delete small-word
• Alt-d to delete the small-word under the cursor

### Aliases

Elvish does not have built-in alias functionality, but this is implemented easily using the alias module, which stores the alias definitions as functions under ~/.elvish/aliases/ and loads them automatically.

For reference, I define here a few of my commonly-used aliases:

### Completions

The smart-matcher module tries prefix match, smart-case prefix match, substring match, smart-case substring match, subsequence match and smart-case subsequence match automatically.