Migrating To Doom Emacs
Yesterday, I spent some time migrating my vanilla Emacs configuration to Doom Emacs. The whole process took me about 2 hours, and then today I spent another hour or so figuring out why my original configurations felt different, and tweaked it back to my liking.
Why Doom Emacs?
Why did I bother? I was in the midst of configuring my LaTeX editing environment for writing my Final Year Project report, and wasn’t having a good time. Despite my attempts at being careful, the company completion backends weren’t added in the order that I wanted. I’m no beginner at Emacs. I’ve been using it for a while, and it’s still frustrating that I can’t get these little things right.
I needed a configuration that worked, so I studied Doom Emacs’ LaTeX module for inspiration. I figured it’d be easier if I just gave Doom Emacs a try, and see if I liked it.
Doom and Spacemacs are configuration kits, which allows one to use a heavily customized Emacs that works out of the box. I don’t belong in that category: I prefer a small configuration, with only the things I need. My configuration started out with a large number of additional packages, but I’ve been gradually removing them in favour of in-built Emacs functionality. For example, improvements to
isearch in Emacs 27 has allowed me to replace heavier options like
But Doom offers more than a nice, loaded starting configuration. There’s a lot of machinery underneath that makes Doom Emacs fast. When I first loaded Doom, I was surprised at how much faster it was in terms of responsiveness and load speed. I couldn’t go back. I decided to use Doom for this machinery, choosing only a small subset of its provided modules.
A big factor in making this decision was that Doom’s organization is how similar it is to how I originally managed my configuration:
- Doom uses straight.el to manage packages, which was also my practice
- Doom uses use-package heavily, and so do I
This made the migration seem less daunting . Using Doom has brought me these benefits:
- Doom starts up really quickly, which means less waiting time. This is especially important for me because I use exwm, and the time Emacs loads is the time I can start using my computer.
- Doom has awesome default modules, including for writing, and programming. With Doom I’m able to par down my own configuration even further, and focus on customizing the things I really care about, like my Org workflow.
- Everything works the same, but feels snappier, and with less config! All pros and no cons!
The Migration Process
First, I followed the instructions in the README to install Doom Emacs:
git clone https://github.com/hlissner/doom-emacs ~/.emacs.d ~/.emacs.d/bin/doom install
Next, I looked through Doom’s generated
init.el. Doom starts out with a configuration using
evil-mode everywhere. I played around with it for a while, but figured that I’m still much more efficient with just the usual Emacs keybindings, so I ended up turning it off. I’m pleasantly surprised that Doom works just as well without
evil-mode. I tweaked
init.el to contain only modules that I use.
It took me a while to understand how Doom worked, but it became clear that
packages.el contains packages and their recipes, and everything else should go into
config.el. I began slowly copying things from my configuration over into the
.doom.d/config.el file, following a small mental checklist.
- Is this really necessary?
- Is this already handled by a Doom module (glancing at
- Are the keybindings I’m using here important to me? Doom places most of the configuration behind its leader key
C-c, but that also makes certain frequent interactive commands (like my agenda) further away than I hoped.
When I decide to copy something over, the basic process goes like this:
- Copy the
use-package!, Doom’s own macro.
- Move the recipe into
- Migrate bindings to the
:initsection of the
use-package!macro, using Doom’s
- Make sure the package is lazy loaded, by adding autoloads via
use-package, or similar. I find inspiration for these by looking through the modules Doom ships with.
- Reload and test my configuration with
C-h r r, or
Configuring Doom’s Defaults
Doom’s defaults can be a bit strange, and it’s important to know where these settings are set, and how to have them changed. For example, I noticed that when composing mail using Doom’s
notmuch module, hard line breaks are added in paragraphs. This makes for a terrible mobile reading experience. How do we figure out what’s going on?
First, I look at what modes are enabled via
C-h m. That quickly reveals the culprit to be
auto-fill-mode, which doesn’t occur in my
config.el. To figure out what’s turning it on, I navigate to the
.emacs.d folder and do a project-wide search for “auto-fill-mode”. Doom exposes its search functionality on prefix key “s”, so for me this is
C-c s s. I quickly found that Doom’s
core-editor module turns on
auto-fill-mode on all text-based modes. Doom provides an alternative
word-wrap module that uses soft line-breaks, so I added the following to remove
auto-fill-mode, and enable
(remove-hook 'text-mode-hook #'auto-fill-mode) (add-hook 'message-mode-hook #'word-wrap-mode)
Migrating to Doom has increased the speed of my Emacs configuration, despite it behaving nearly the same. My configuration reduced from 1800 lines to 600 lines, containing the (Org-mode-related) tweaks that make this Emacs configuration truly mine. My experience with Doom on Emacs keybindings so far has been good, and things work just like I expect them to!