GNU Emacs configuration
Switch branches/tags
Nothing to show
Clone or download

Tonic ⚗

This is my over-engineered Emacs configuration.

Things are sorted into sub-folders of tonic based on general function, and then into files based on some narrower theme.

Although using the entire package probably isn’t feasible without some serious changes, I hope some of the material here is instructive or inspirational for people developing their own configuration files.


  • Full Emacs/EXWM workflow based around Evil, Org, Raven, and Hydra.
  • No modifiers other than Shift.
  • All non-editing functionality accessed from q prefix using Hydra and Raven.
  • All work I perform in my academic and personal life is within Emacs, which provides a cohesive modal interface and keybindings: mail, feeds, file management, shell, multimedia, web browsing, IRC/IM (through bitlbee), scheduling, note taking, reference management, and even academic publication.
  • Of course, text-editing and programming are not neglected, especially programming in functional languages and using proof assistants, but this is typical of an editor configuration.
  • Context-aware functionality for various major modes.
  • Raven navigation system integrating an IRC alert system, browser bookmarks, and project files.
  • Optimized for single window display, popup windows held back by Shackle. Multi-window configurations managed by Eyebrowse.


Pressing q outside of Insert Mode in any major mode opens the Quinine, the top-level menu from which all other functionality is accessible. Basic functionality is assigned to punctuation and particularly convenient keys. For example, q <SPC> kills the current buffer, q : invokes raven-M-x, q ! runs an external command, and q w writes the buffer to disk.

Other features are accessed using pairs of lowercase and capital letters. The lowercase letter leads to another Hydra with more specific bindings, while the uppercase letter runs the most common command associated with the feature. This common command is also bound within the feature Hydra to the same key that initiated that Hydra. For example, the common command for mail (viewing unread mail) can be invoked with either q E or q e e. q e alone will conjure a menu detailing all the other common mail commands: q e u will update mail, q e r will reply to a message, etc.

As much as possible, keybindings are kept consistent across multiple domains. For example, one can view unread RSS feeds using q D or q d d, update the feeds with q d u, etc. This establishes a generic mnemonic “vocabulary” for non-editing functionality (indeed all functionality that I use regularly) in the same manner as vi’s editing commands.

Contextual Commands

q i invokes a buffer-local Hydra (usually bound in a major mode hook). This allows the same bindings to be used for similar functionality across languages. For example, q i i evaluates the current expression in Emacs Lisp mode and advances Proof General to the current statement when editing Coq source. There are similar contextual hooks for accessing documentation, saving files to disk, killing buffers, and closing windows, many of which are used to seamlessly integrate language-specific functionality into an Org-Babel-centric workflow.

Even further, there is a context-specific Evil state, Hyper. The Hyper state is accessible with Q, and provides specialized movement and editing faculties. In Org mode Hyper state, j and k move between headings, while in Lisp mode Hyper state, they move between current-level expressions with Lispy.

Constantly Evolving

Rarely does a day go by where I fail to update this configuration. However, these updates may or may not manifest as actual commits. If you pull something from one of these files and find an irritating quirk, it’s quite possible that I’ve already fixed the problem since the last commit. I encourage you to post an issue in such cases, even for simple bugs: I’m not interested in having anything broken in my workflow.