Doom Emacs Documentation

A compilation of resources for Doom Emacs users

Our online documentation is a work in progress. Do not use it. Large portions of it is incomplete and many links are broken.

Instead, read the current (more complete) documentation on Github or within Doom Emacs (with M-x doom/help).

1. Introduction

Doom Emacs is a configuration framework for GNU Emacs tailored for bankruptcy veterans who want less framework in their frameworks, a reproducible package manager, and the performance of a hand-rolled config or better. It can be a foundation for your own config, a reference for enthusiasts building their own, or anywhere in between.

To help you along, below is an outline of our best learning resources for using, abusing, and confusing Doom Emacs. If at any time you don’t understand what you’re reading, visit our help page to explain the conventions behind our docs.

Users reading our documentation inside Emacs should check out our mini-tutorial on how to navigate our docs.

1.1. Where do I go from here?

Here are a couple suggestions:

1.2. Following project development

Doom Emacs is an active project. These resources were set up to help you track its development:

1.3. Frequently asked questions

Visit our FAQ for answers to common usage, config, and project questions. If you have your own, please post them on Discourse or Discord.

2. Release notes

3. User manual

Our user manual is a 0-to-100 guide for setting up, maintaining, and troubleshooting Doom Emacs. These are the absolute essentials all Doom users should know, including a soft introduction to concepts that may be alien to beginners, especially those coming from another editor.

3.1. Introduction

This is a test

3.1.1. Philosophy

3.1.2. Author

3.1.3. Community

3.1.4. Why use Doom?

3.1.5. Ways to use Doom

3.2. Quickstart

  1. Install Emacs.
  2. Install Git and Ripgrep.
  3. Clone doom-emacs.
  4. Modify $DOOMDIR/init.el and customize what modules you want enabled.
  5. Run $ doom install

3.3. Install

3.3.1. Emacs & Dependencies MacOS
With Homebrew
With MacPorts Windows
  • Emacs is inherently slower on Windows.
  • There are more steps to setting up Emacs (and Doom) on Windows.
  • Windows support will always lag behind macOS/Linux support, because I (and many of Doom’s users) don’t use Windows. That means fewer guinea p–I mean, pioneers, willing to test Doom on Windows.

That said, Doom does have happy Windows users (using WSL or scoop/chocolatey). [BROKEN LINK: No match for fuzzy expression: On Windows] will walk you through what we know.

Help us improve our documentation if you managed to get Doom running on Windows!

With WSL2 + Ubuntu
With a precompiled binary + Git Bash
With chocolatey / scoop Linux
Arch Linux
Void Linux

Everything you need is in Gentoo’s official ::gentoo repository.

Emacs 27

To use Emacs graphically, enable the gui USE flag. And enable the xft USE flag to render fonts correctly (see issue #4876):

echo "app-editors/emacs gui xft" >> /etc/portage/package.use/emacs

To install the latest unmasked version compatible with Doom:

emerge '>=app-editors/emacs-27.0'
  • native-comp

    Alternatively, to install gccemacs/native-comp, use the live ebuild for version 28.0 with the jit USE flag:

    Unmask the desired ebuild by adding the following to package.accept_keywords:

    =app-editors/emacs-28.0.9999 **

    Add the jit USE flag to package.use:

    =app-editors/emacs-28.0.9999 jit

    And emerge:

    emerge =app-editors/emacs-28.0.9999
Other Dependencies
# required
emerge '>=dev-vcs/git-2.23' '>=sys-apps/ripgrep-11.0' sys-apps/findutils
# optional
emerge '>=sys-apps/fd-7.3.0'

3.3.2. Doom Emacs Quick install Manual install Alongside another config
With doom run
With Chemacs v2
With Chemacs v1

3.3.3. Module dependencies

3.4. Update

3.4.1. Rollback

3.4.2. Best practices

3.5. Concepts

Emacs is old. Real old. Some familiar concepts may have names that will catch newcomers off guard.

3.5.1. Emacs Terminology User interface

A buffer is a [space in Emacs memory] containing text to be edited. Buffers are used to hold the contents of files that are being [edited or opened]; there may also be buffers that are not visiting files [they display other information like Dired that shows the content of a directory]. […] Each buffer, including the current buffer, may or may not be displayed in any windows.

Echo area

The echo area is the last line of the frame. Unless the minibuffer is active, this is the zone that shows all the messages Emacs sends to the user

The echo area is used for displaying error messages (see Errors), for messages made with the `message` primitive, and for echoing keystrokes. It is not the same as the minibuffer, despite the fact that the minibuffer appears (when active) in the same place on the screen as the echo area.


What the rest of the world calls windows


On graphical displays, Emacs draws fringes next to each window: thin vertical strips down the sides which can display bitmaps indicating truncation, continuation, horizontal scrolling, and so on.

Header line

The header line is like a modeline (extra information line about Emacs current state), that is displayed at the top of each window instead of the bottom of them.

Notable examples include N. Rougier displaying filename in the header line, and LSP-mode powered context information (“breadcrumbs”)

A window can have a header line at the top, just as it can have a mode line at the bottom. The header line feature works just like the mode line feature[…]


A buffer can have blank areas called display margins on the left and on the right. Ordinary text never appears in these areas, but you can put things into the display margins using the `display` property.

Margins tend to be a lot larger than fringes, as margins are at least as wide as characters that you’d want to display there. It is almost always disabled: relevant information can be almost always also be shown in fringes, and fringes take way less screen real estate.


The Minibuffer is the buffer that takes over the last line of your Emacs frame whenever Emacs prompts you (the user) for input.

A minibuffer is a special buffer that Emacs commands use to read arguments more complicated than the single numeric prefix argument. These arguments include file names, buffer names, and command names (as in <kbd>M-x</kbd>). The minibuffer is displayed on the bottom line of the frame, in the same place as the echo area (see The Echo Area), but only while it is in use for reading an argument.

Mode line

What vimmers know as the status line

Each Emacs window (aside from minibuffer windows) typically has a mode line at the bottom, which displays status information about the buffer displayed in the window. The mode line contains information about the buffer, such as its name, associated file, depth of recursive editing, and major and minor modes.


A window is an area of the screen that is used to display a buffer (see Buffers). Editing

Cut (in the Cut/Copy/Paste sense)

Kill functions delete text like the deletion functions, but save it so that the user can reinsert it by yanking . Most of these functions have ‘kill-’ in their name. […] Killed text is saved for later yanking in the kill ring.

Major mode

File types/modes to vimmers/others

Major modes specialize Emacs for editing or interacting with particular kinds of text. Each buffer has exactly one major mode at a time.


The other cursor

The mark specifies a position to bound a range of text for many commands

The mark is also a buffer position like point, but it is only used to mark a region of text in the buffer (between point and mark).

Minor mode

A minor mode provides optional features that users may enable or disable independently of the choice of major mode. Minor modes can be enabled individually or in combination.

Most minor modes implement features that are independent of the major mode, and can thus be used with most major modes. For example, Auto Fill mode works with any major mode that permits text insertion.


Qhat everyone knows as the cursor

point corresponds to the offset in the buffer where the “cursor” is: if point is 3, then text will be inserted at the 3rd character if you type text.

Point is a special buffer position used by many editing commands, including the self-inserting typed characters and text insertion functions. Other commands move point through the text to allow editing and insertion at different places.

Like other positions, point designates a place between two characters (or before the first character, or after the last character), rather than a particular character. Usually terminals display the cursor over the character that immediately follows point; point is actually before the character on which the cursor sits.


The “region” is the active selection.

The text between point and the mark is known as the region . Various functions operate on text delimited by point and the mark, but only those functions specifically related to the region itself are described here.


Paste (contrary to vim)

The most common pitfall to avoid when coming from Vim, is that in Emacs, yanking_ is pasting.

Yanking means inserting text from the kill ring Emacs Lisp

An association list is one of the main datatype used in elisp. It’s a list of key-value cons cells (essentially tuples). Its API can be found in the manual.

An association list or alist is a specially-constructed list whose elements are cons cells. In each element, the CAR is considered a key , and the <small>CDR</small> is considered an associated value. (In some cases, the associated value is stored in the CAR of the CDR.) Association lists are often used as stacks, since it is easy to add or remove associations at the front of the list. For example,

(setq alist-of-colors '((rose . red) (lily . white) (buttercup . yellow)))

sets the variable alist-of-colors to an alist of three elements. In the first element, rose is the key and red is the value.

Doc string

Short for documentation string is information that is embedded in a variable or function. Their docstring can be read when looking up functions with C-h f or variables with C-h v. Keybinds
Universal (prefix) argument

This is a special key you use to modify the command you invoke directly afterwards.

For example, if you take a command called delete-stuff, bound to C-c d that tells you it will “delete the current line, or delete the whole buffer if prefix argument is set”; then

  • C-c d will delete a line
  • M-x delete-stuff RET will delete a line
  • C-u C-c d will delete the whole buffer
  • C-u M-x delete-stuff RET will delete the whole buffer.

The goal of universal and prefix argument is to get a slightly different behaviour for known commands.

Doom users with evil enabled will find the universal argument on SPC u instead than C-u.

Prefix key

A “prefix” is a key that begins a key sequence. For instance, the key sequence C-x C-k b]] is comprised of three distinct input events. Both C-x and C-x C-k can be considered prefixes.

Prefix keys allow to store and move keybindings in groups. For example by default all `LSP-mode` commands are under `SPC c l …`, but if you want to change that prefix to `SPC L …` for all `LSP-mode` commands, it is a one liner in your configuration; you do not have to rebind each command manually to its new `SPC L …` variant.

A prefix key is a key sequence whose binding is a keymap. The keymap defines what to do with key sequences that extend the prefix key. For example, C-x is a prefix key, and it uses a keymap that is also stored in the variable ctl-x-map. This keymap defines bindings for key sequences starting with C-x.

3.5.2. TODO Keybind notation

The Meta key

3.5.3. Special keys The <help> prefix Leader / localleader keys

Doom strives for a totally keyboard driven environment, but there are more commands out there than there are keys on anyone’s keyboard, so many of them are bound under one of two common prefixes, called the leader and local leader keys (these terms are borrowed from Vim):

  • The leader key is a global prefix under which the most common commands are centralized. This is the keyboard analog for the menu bar and ought to be available anywhere.
  • The local leader key (or buffer/mode-local leader key) is a contextual leader prefix. In other words, a prefix whose sub-bindings change depending on what major mode (language) or minor modes you have active.

These two are often referred to in technical writing (and our documentation) as <leader> and <localleader>.

In Doom Emacs, these keys can be found on different prefixes depending on whether you have evil (our vim emulation layer) enabled or not.

  • If evil is enabled:
    • SPC and SPC m in any mode but insert mode, respectively.
    • M-SPC and M-SPC m in insert or emacs mode. (A separate key is needed as not to override the default behavior of SPC to insert whitespace).
  • If evil is disabled: C-c and C-c l instead.

Veteran vimmers may prefer their leader keys on , or \ As with anything in Emacs, this can be customized.

3.5.4. Doom-specific TODO Doom modules TODO $DOOMDIR TODO Envvar file bin/doom (Doom’s CLI)

doom is your best friend. It’ll keep all your secrets (mostly because it’s a shell script incapable of sentience and thus incapable of retaining, much less divulging, your secrets to others).

You can run $ doom help to see what it’s capable of, but here are some commands that you may find particularly useful:

$ doom doctor
Diagnose common issues in your environment and list missing external dependencies for your enabled modules.
$ doom sync
Ensures that all missing packages are installed, orphaned packages are removed, and metadata properly generated.
$ doom install
Install any missing packages.
$ doom update
Update all packages that Doom’s (enabled) modules use.
$ doom env
Regenerates your envvar file, which contains a snapshot of your shell environment for Doom Emacs to load on startup. You need to run this for changes to your shell environment to take effect.
$ doom purge -g
Purge orphaned packages (i.e. ones that aren’t needed anymore) and regraft your repos.
$ doom upgrade

Upgrade Doom to the latest version (then update your packages). This is equivalent to:

$ git pull
$ doom sync
$ doom update

3.6. Environment

3.7. Configure

3.7.1. Toggling modules

3.7.2. Package management Installing packages Changing an existing recipe Package pinning Disabling packages Registering local packages Recipe specifications

3.7.3. Reconfiguring packages

3.7.4. Major modes

3.7.5. Color themes

There are two ways to load a theme. Both assume the theme is installed and available. You either set doom-theme or manually load a theme with the load-theme function:

;;; add to $DOOMDIR/config.el
(setq doom-theme 'doom-tomorrow-night)
;; or
(load-theme 'doom-tomorrow-night t)

The only difference between the two is when the theme is loaded. Doom loads doom-theme later in the startup process, while calling load-theme will load the theme immediately. If you don’t know which to use, set doom-theme. Installing a third party theme

To install a theme from a third party plugin, say, solarized, you need only install it, then load it:

;;; add to $DOOMDIR/packages.el
(package! solarized-theme)

;;; add to $DOOMDIR/config.el
(setq doom-theme 'solarized-dark)

Don’t forget to run $ doom sync after adding that package! statement to ensure the package is installed. Themes and color schemes

Technically, a theme is a single group of customizations (i.e. variable settings) that are set together.

In practice, themes almost exclusively change the faces of Emacs, that means the ways Emacs chooses fonts and colors for the text it displays.

what CSS devs call styles. A Face in Emacs is a style (font, size, color etc.) applied to text in various places. If some text does not look good to you, it means one of 2 things:
  • It’s applied the wrong face (e.g. font-lock-comments-face instead of vertical-border), so it doesn’t blend with the rest. Usually that means there’s an issue with the package/major-mode you are currently using.
  • The face it has is ill-configured (vertical-border has a bright pink foreground) and it needs change in the theme.
Text properties
Each character in a buffer can have any arbitrary data attached to it, called text properties. The most common one is the face, but you can have any property with any value, if it pleases you. The most common way to set and use text properties is to use overlays, but you can click the link to text properties manual section if you want to go deeper.

Overlays are like highlighting inside a buffer, with extra features.

Like highlighting in a text, an overlay is a zone in a buffer (it has a beginning and an end, and is attached to the buffer it was created for).

On top of that, an overlay can add arbitrary feature to that zone:

  • Change the face of the text in the zone (it can add an actual highlight, or underline the text, or make it red…)
  • Add on-click/hover effects

Possible usages include:

  • recognizing a color in a css file (red, #DEA901), and applying the parsed color as a background to give a live preview
  • add a spell checker that will underline a word and correct it on click
  • show a diagnostic from a compilation error at the correct location and provide a websearch on the error message with a right click
Font Lock
fontification/syntax highlighting

3.7.6. Fonts

Doom exposes five (optional) variables for controlling fonts in Doom, they are:

  • doom-font
  • doom-variable-pitch-font
  • doom-serif-font
  • doom-unicode-font (the fallback font for unicode symbols that your default font doesn’t support)
  • doom-big-font (used for doom-big-font-mode)

They all accept either a font-spec, font string ("Input Mono-12"), or xlfd font string.


;;; Add to $DOOMDIR/config.el
(setq doom-font (font-spec :family "Input Mono Narrow" :size 12 :weight 'semi-light)
      doom-variable-pitch-font (font-spec :family "Fira Sans") ; inherits `doom-font''s :size
      doom-unicode-font (font-spec :family "Input Mono Narrow" :size 12)
      doom-big-font (font-spec :family "Fira Mono" :size 19))

3.7.7. (Re)Binding keys Changing your leader keys

Four variables control what prefixes Doom uses for its leader and localleader keys:

  • For Evil users:

    Variable Default key
    doom-leader-key SPC
    doom-localleader-key SPC m
  • For Emacs and Insert state (evil users), and non-evil users:

    Variable Default evil key Default non-evil key
    doom-leader-key M-SPC C-c
    doom-localleader-key M-SPC m C-c l

When evil is disabled neither doom-leader-key and doom-localleader-key are used. Change doom-leader-alt-key and doom-localleader-alt-key instead.

For example, to change your leader keys to comma and backslash:

;;; add to $DOOMDIR/config.el
(setq doom-leader-key ","
      doom-localleader-key "\\") Binding new leader keys

To add your own leader keybinds use the map! macro:

(map! :leader 
      ;; <leader> x will invoke the dosomething command
      "x" #'dosomething
      ;; <leader> y will print "Hello world" in the minibuffer
      "y" (cmd! (message "Hello world"))
      ;; This unbinds what was previously bound to <leader> f
      "f" nil)

Local leaders keys, on the other hand, require a :map to be specified:

(map! :after python
      :map python-mode-map
      ;; <localleader> x will invoke the dosomething command
      "x" #'dosomething

You’ll notice :after python in the example above. It is important that your keys are bound after the keymap is loaded. In this case, python-mode-map is defined in the python package. See (Re)Binding keys below.“

3.7.8. Code formatting

3.7.9. User interface Popup windows

The :ui popup module tries to standardize how Emacs handles “temporary” windows. It includes a set of default rules that tell Emacs where to open them (and how big they should be). Check out its documentation for details on defining your own rules, and documentation on the set-popup-rule! function with <help> f. TODO Line numbers

3.7.10. TODO Keyboard layout

3.7.11. TODO Dashboard

3.7.12. TODO File/directory-local variables

3.7.13. Turning Emacs into an IDE

Doom supports LSP, but it is not enabled by default. To enable it, you must:

  1. Enable the :tools lsp module,
  2. Enable the +lsp flag for the appropriate modules you want LSP support for (e.g. :lang python +lsp or :lang rust +lsp),
  3. Install one of the supported LSP servers through your package manager or other means. That module’s documentation will tell you how to install them, otherwise consult the server table on the lsp-mode project page.
  4. Run $ doom sync on the command line and restart Emacs.

Some language modules may lack LSP support (either because it hasn’t been implemented yet or I’m not aware of it yet – let us know!). To enable LSP for these languages, add this to $DOOMDIR/config.el:

(add-hook 'MAJOR-MODE-local-vars-hook #'lsp!)
;; Replace MAJOR-MODE. e.g. `lisp-mode-local-vars-hook'

3.7.14. Reloading your config

Short answer: You can, but you shouldn’t.

Long answer: Restarting Emacs is always your safest bet, but Doom provides a few tools for experienced Emacs users to skirt around it (most of the time):

  • Evaluate your changes on-the-fly with M-x +eval/region (bound to the gr operator for evil users) or M-x eval-last-sexp (bound to C-x C-e). Changes take effect immediately.
  • On-the-fly evaluation won’t work for all changes. e.g. Changing your doom! block in =$DOOMDIR/init.el.

    But rather than running $ doom sync and restarting Emacs, Doom provides M-x doom/reload for your convenience (bound to <help> r r). This runs $ doom sync, restarts the Doom initialization process and re-evaluates your personal config. However, this won’t clear pre-existing state; Doom won’t unload modules/packages that have already been loaded and it can’t anticipate complications arising from your private config.

  • You can quickly restart Emacs and restore the last session with M-x doom/restart-and-restore (bound to <leader> q r).

3.7.15. TODO Common mistakes

3.8. Troubleshoot

3.8.1. TODO The *Messages* buffer

3.8.2. TODO Debug mode

3.8.3. TODO Hard crashes

3.8.4. TODO Freezing and hangs

3.8.5. TODO Dealing with errors TODO Producing a backtrace TODO Startup failures TODO CLI failures TODO Package failures TODO Common error messages
void-function: XYZ
void-variable: XYZ
commandp: XYZ
Key sequence ... starts with non-prefix key ...
unable to find theme file for XYZ
Cannot open load file: No such file or directory, ...
Error in private config: ...
end-of-file ...

3.8.6. TODO Testing in Doom’s sandbox TODO Generating a minimal test case

3.8.7. TODO Bisecting your private config

3.8.8. TODO Bisecting Doom Emacs

4. Migration guides

Are you here from another editor? Perhaps another Emacs config? Do things seem too different here? Perhaps our migration guides can soothe those transition pains:

4.1. Introduction

4.2. TODO From vanilla

4.2.1. Comparison

4.2.2. Gotchas

4.3. TODO From Spacemacs

4.3.1. Comparison

To paraphrase (and expand upon) a reddit answer to this question by @gilbertw1:

  • Doom is lighter than Spacemacs. Doom starts up faster and is better optimized, but Spacemacs has more features.
  • Doom is thinner than Spacemacs. There are fewer abstractions between you and vanilla Emacs, and what abstractions do exist are thin by design. This means there’s less to understand and it’s easier to hack.
  • Doom is much more opinionated than Spacemacs. Doom does not strive to be a one-size-fits-all, beginner-friendly solution, nor is it configured by consensus. It is [mostly] the work of one developer and caters to his vim-slanted tastes. Doom’s defaults enforce very particular (albeit optional) workflows.
  • Doom lacks manpower. Bugs stick around longer, documentation is lighter and development is at the mercy of it’s maintainer’s schedule, health and whims.
  • Doom is not beginner friendly. Doom lacks a large community to constantly improve and produce tutorials/guides for it. Spacemacs is more likely to work right out of the box. Doom also holds your hand less. A little elisp, shell and git-fu will go a long way to ease you into Doom.
  • Doom is managed through it’s command line interface. The bin/doom script allows you to script package management, manage your config, or utilize elisp functionality externally, like org tangling or batch processing.
  • Doom’s package manager is declarative and rolling release is opt-in. Doom takes a little after nix, striving for as much config reproducibility as Emacs (and git) will permit. Spacemacs uses package.el, which is only rolling release.

4.3.2. Gotchas

4.4. TODO From (Neo)Vim

4.4.1. Comparison

4.4.2. Gotchas

4.5. TODO From VSCode

4.5.1. Comparison

4.5.2. Gotchas

5. Modules

Doom’s features are divided into modules; a module is a collection of packages, configuration, and commands, organized into a unit that can be easily enabled or disabled by adding or removing them from your doom! block in $DOOMDIR/init.el (remember to run $ doom sync and restart Emacs whenever changing your doom! block).

Looking for technical insight into how Doom’s modules work and are designed? That’s in our developer’s manual.

5.1. :app

Application modules are complex and opinionated modules that transform Emacs toward a specific purpose. They may have additional dependencies and should be loaded last, before :config modules.

5.1.1. calendar

Adds a calendar view for Emacs, with org and google calendar sync support.

5.1.2. emms

This module enables Emacs to be used as a music player. It uses mpd as a backend server and mpc to update your music database.

5.1.3. everywhere

This module adds system-wide popup Emacs windows for quick edits.

5.1.4. irc

This module turns Emacs into an IRC client, capable of OS notifications.

5.1.5. rss

Flags: +org

Read RSS feeds in the comfort of Doom Emacs.

5.1.6. twitter

Enjoy twitter from emacs.

  • View various timelines side by side, e.g. user’s timeline, home, etc.
  • Post new tweets
  • Send direct messages
  • Retweet
  • Follow and un-follow users
  • Favorite tweets

5.2. :checkers

For modules dedicated to linting text.

5.2.1. grammar

This module adds grammar checking to Emacs to aid your writing by combining lang-tool and writegood-mode.

5.2.2. spell

Flags: +aspell +enchant +everywhere +flyspell +hunspell

This modules provides spellchecking powered by aspell, hunspell or enchant.

Spellcheck is automatically loaded in many text-mode derivatives, which includes org-mode, markdown-mode, the Git Commit buffer (from magit), mu4e-compose-mode, and others.

5.2.3. syntax

Flags: +childframe

This module provides syntax checking and error highlighting, powered by flycheck

  • If possible, include a brief list of feature highlights here
  • Like code completion, syntax checking or available snippets
  • Include links to packages & external things where possible

5.3. :completion

These modules provide interfaces and frameworks completion, including code completion.

5.3.1. company

Flags: +childframe +tng

This module provides code completion, powered by company-mode. It is required for code completion in many of Doom’s :lang modules.

5.3.2. helm

Flags: +childframe +fuzzy +icons

This module provides Helm integration for a variety of Emacs commands, as well as a unified interface for project search and replace, powered by ripgrep.

5.3.3. ido

(No description)

5.3.4. ivy

Flags: +childframe +fuzzy +icons +prescient

This module provides Ivy integration for a variety of Emacs commands, as well as a unified interface for project search and replace, powered by ripgrep.

5.3.5. vertico

Flags: +icons

This module enhances the Emacs search and completion experience, and also provides a united interface for project search and replace, powered by ripgrep.

It does this with several modular packages focused on enhancing the built-in completing-read interface, rather than replacing it with a parallel ecosystem like ivy and helm do. The primary packages are:

  • Vertico, which provides the vertical completion user interface.
  • Consult, which provides a suite of useful commands using completing-read.
  • Embark, which provides a set of minibuffer actions.
  • Marginalia, which provides annotations to completion candidates.
  • Orderless, which provides better filtering methods.

5.4. :config

Modules that configure Emacs one way or another, or focus on making it easier for you to customize it yourself. It is best to load these last.

5.4.1. default

Flags: +bindings +smartparens

The defaults module is intended as a “reasonable-defaults” module, but also as a reference for your own private config.

  • A Spacemacs-esque keybinding scheme.
  • Extra Ex commands for evil-mode users.
  • A yasnippet snippets library tailored to Doom emacs.
  • A configuration for (almost) universally repeating searches with ; and ,.

5.4.2. literate

This module enables support for a literate config.

5.5. :editor

For modules concerned with the insertion, manipulation, and general editing of text. Amen.

5.5.1. evil

Flags: +everywhere

A holy module that brings the best vim emulation you’ll find in any editor and, sometimes, even vim itself.

5.5.2. file-templates

This module pre-fills new, empty files with a file template, powered by yasnippet.

5.5.3. fold

This module marries hideshow, vimish-fold, and outline-minor-mode to bring you marker, indent and syntax-based code folding for as many languages as possible.

5.5.4. format

Flags: +onsave

This module integrates code formatters into Emacs. Here are some of the formatters that it currently supports:

asmfmt, black, brittany, cabal-fmt, clang-format, cmake-format, dartfmt, dfmt, dhall format, dockfmt, elm-format, emacs, fishindent, fprettify, gleam format, gofmt, iStyle, jsonnetfmt, ktlint, latexindent, ledger-mode, lua-fmt, mix format, nixfmt, node-cljfmt, ocp-indent, perltidy, prettier, purty, rufo, rustfmt, scalafmt, script shfmt, snakefmt, sqlformat, styler, swiftformat, tidy

5.5.5. god

(No description)

5.5.6. lispy

This module adds lispy key functionality in Lisp languages.

This includes:

  • Common Lisp
  • Emacs Lisp
  • Scheme
  • Racket
  • Hy
  • LFE
  • Clojure
  • Fennel

If evil is enabled, lispyville would also be activated for every mode where lispy is active.

The default key themes that are set are as follows:

'((operators normal)
  (prettify insert)
  (atom-movement normal visual)

To change the key themes set lispyville-key-theme. Think of lispyville-key-theme as the equivalent of parinfer-extensions. See lispyville’s README for more info on the specific keybindings of each key theme (starting here).

5.5.7. multiple-cursors

(No description)

5.5.8. objed

Flags: +manual

This modules adds objed, a global minor-mode for navigating and manipulating text objects. It combines the ideas of versor-mode and other editors like Vim or Kakoune and tries to align them with regular Emacs conventions.

This module is incompatible with the :editor evil module. Enabling them both will cause errors.

See the objed project README for information on keybinds and usage.

5.5.9. parinfer

Flags: +rust

Parinfer is a proof-of-concept editor mode for Lisp programming languages. It will infer some changes to keep Parens and Indentation inline with one another.


More information can be found about it in the project’s documentation.

5.5.10. rotate-text

(No description)

5.5.11. snippets

This module adds snippets to Emacs, powered by yasnippet.

5.5.12. word-wrap

This module adds a minor-mode +word-wrap-mode, which intelligently wraps long lines in the buffer without modifying the buffer content.

5.6. :emacs

Modules in this category augment and extend the built-in features of Emacs.

5.6.1. dired

Flags: +icons +ranger

This module extends and improves on dired; a directory browser built into Emacs.

5.6.2. electric

(No description)

5.6.3. ibuffer

Flags: +icons

This module augments ibuffer.

  • Adds project-based grouping of buffers
  • Support for file-type icons
  • Uses human-readable file-size

5.6.4. tramp

(No description)

5.6.5. undo

Flags: +tree

This module augments Emacs’ built-in undo system to be more intuitive and to persist across Emacs sessions.

5.6.6. vc

This module augments Emacs builtin version control support and provides better integration with git

5.7. :email

(No description)

5.7.1. mu4e

Flags: +gmail +org

This module makes Emacs an email client, using mu4e.

I want to live in Emacs, but as we all know, living is incomplete without email. So I prayed to the text editor gods and they (I) answered. Emacs+evil’s editing combined with org-mode for writing emails? Yes please.

It uses mu4e to read my email, but depends on offlineimap (to sync my email via IMAP) and mu (to index my mail into a format mu4e can understand).

5.7.2. notmuch

Flags: +afew +org

This module turns Emacs into an email client using notmuch.

5.7.3. wanderlust

(No description)

5.8. :input

(No description)

5.8.1. chinese

Help is needed to maintain this module, translate it’s documentation, and lazy load its packages.

This module adds support for traditional Chinese script by introducing two input methods: Pinyin and Wubi.

5.8.2. japanese

Help is needed to maintain this module, translate it’s documentation, and lazy load its packages.

This module adds support for Japanese script.

5.8.3. layout

Flags: +azerty +bepo

This module provides barebones support for using Doom with non-qwerty layouts.

5.9. :lang

These modules specialize in adding language support to Emacs.

5.9.1. agda

This module adds support for the agda programming language. The Emacs support exists directly in the agda repository but not in melpa.

5.9.2. beancount

Flags: +lsp

This module adds support for Beancount to Emacs. Beancount, like ledger, lets you manage your money in plain text.

5.9.3. cc

Flags: +lsp

This module adds support for the C-family of languages: C, C++, and Objective-C.

  • Code completion (company-irony)
  • eldoc support (irony-eldoc)
  • Syntax-checking (flycheck-irony)
  • Code navigation (rtags)
  • File Templates (c-mode, c++-mode)
  • Snippets (cc-mode, c-mode, c++-mode)
  • Several improvements to C++11 indentation and syntax highlighting.

5.9.4. clojure

Flags: +lsp

This module adds support for the Clojure(Script) language.

  • Interactive development environment (cider): REPL, compilation, debugging, running tests, definitions & documentation lookup, code completion, and much more
  • Refactoring (clj-refactor)
  • Linting (clj-kondo), requires :checkers syntax
  • LSP support (clojure-lsp)

5.9.5. common-lisp

(No description)

5.9.6. coq

This module adds coq support to Emacs, powered by Proof General.

5.9.7. crystal

This modules adds crystal support.

  • Syntax-checking (flycheck)
  • REPL (inf-crystal)

5.9.8. csharp

Flags: +dotnet +lsp +unity

This module adds C# support to Emacs. Powered by omnisharp (through LSP).

5.9.9. dart

Flags: +flutter +lsp

Dart is a client-optimized language by Google for fast apps on any platform. It is fast and optimized for UI, famous for the Flutter framework, also made by Google. Both Flutter and Dart are free and open-source.

This module wraps dart-mode, with LSP features like code completion for .dart files, syntax highlighting, debugging, closing labels, etc.

5.9.10. data

(No description)

5.9.11. dhall

This module adds Dhall language support to Doom Emacs.

Dhall is a programmable configuration language that you can think of as: JSON + functions + types + imports.

5.9.12. elixir

Flags: +lsp

This module provides support for Elixir programming language via alchemist.el or elixir-ls.

5.9.13. elm

(No description)

5.9.14. emacs-lisp

This module extends support for Emacs Lisp in Doom Emacs.

  • Macro expansion
  • Go-to-definitions or references functionality

5.9.15. erlang

Flags: +lsp

This module provides support Erlang programming language. Support for the sourcer language server is optional.

5.9.16. ess

This module adds support for various statistics languages, including R, S-Plus, SAS, Julia and Stata.

5.9.17. factor

This module adds support to the factor programming language and its associated fuel emacs plugin.

5.9.18. faust

Add support to Faust language inside emacs.

  • Faust code syntax hightlighting and indentation
  • Project-based (inter-linked Faust files)
  • Build/compile with output window
  • Graphic diagrams generation and vizualisation in the (default) browser
  • Browse generated C++ code inside Emacs
  • Inter-linked files/buffers :
    • From “component” to Faust file
    • From “include” to Faust library file
  • From error to line number
  • From function name to online documentation
  • Fully configurable (build type/target/architecture/toolkit, keyboard shortcuts, etc.)
  • Automatic keyword completion (if Auto-Complete is installed)
  • Automatic objets (functions, operators, etc.) template insertion with default sensible values (if Yasnippet is installed)
  • Modeline indicator of the state of the code

5.9.19. fsharp

Flags: +lsp

Adds F# support.

  • Code completion
  • eldoc support
  • Syntax checking

5.9.20. fstar

This module adds F* support, powered by fstar-mode.el.

  • Syntax highlighting.
  • Interactively process F* files one definition at a time.
  • Query the running F* process to look up definitions, documentation, and theorems.

5.9.21. gdscript

Flags: +lsp

This module adds support for GDScript, the scripting language of the Godot game engine, to Doom Emacs, powered by gdscript-mode.

5.9.22. go

Flags: +lsp

This module adds Go support, with optional (but recommended) LSP support via gopls.

  • Code completion (gocode)
  • Documentation lookup (godoc)
  • Eldoc support (go-eldoc)
  • REPL (gore)
  • Syntax-checking (flycheck)
  • Auto-formatting on save (gofmt) (requires :editor (format +onsave))
  • Code navigation & refactoring (go-guru)
  • File templates
  • Snippets
  • Generate testing code (go-gen-test)
  • Code checking (flycheck-golangci-lint)

5.9.23. haskell

Flags: +dante +ghcide +lsp

This module adds Haskell support, powered by either dante (the default) or LSP (haskell-language-server or ghcide).

  • Code completion (company-ghc)
  • Look up documentation (hoogle)
  • eldoc support (dante)
  • REPL (ghci)
  • Syntax-checking (flycheck)
  • Code navigation (dante)
  • Snippets

5.9.24. hy

(No description)

5.9.25. idris

This module adds rudimentary Idris support to Emacs.

5.9.26. java

Flags: +eclim +lsp +meghanada

This module adds java support to Doom Emacs, including android-mode and groovy-mode.

5.9.27. javascript

Flags: +lsp

This module adds JavaScript and TypeScript support.

  • Code completion (tide)
  • REPL support (nodejs-repl)
  • Refactoring commands (js2-refactor)
  • Syntax checking (flycheck)
  • Browser code injection with skewer-mode
  • Coffeescript & JSX support
  • Jump-to-definitions and references support (xref)

5.9.28. json

Flags: +lsp

This module adds JSON support to Emacs.

5.9.29. julia

Flags: +lsp

This module adds support for the Julia language to Doom Emacs.

  • Syntax highlighting and latex symbols from julia-mode
  • REPL integration from julia-repl
  • Code completion and syntax checking, requires :tools lsp and +lsp

5.9.30. kotlin

Flags: +lsp

This module adds Kotlin support to Emacs.

5.9.31. latex

Flags: +cdlatex +fold +latexmk +lsp

Provide a helping hand when working with LaTeX documents.

  • Sane defaults
  • Fontification of many popular commands
  • Pretty indentation of wrapped lines using the adaptive-wrap package
  • Spell checking with flycheck
  • Change PDF viewer to Okular or latex-preview-pane
  • Bibtex editor
  • Autocompletion using company-mode
  • Compile your .tex code only once using LatexMk

5.9.32. lean

(No description)

5.9.33. ledger

This module adds support for ledger files. Ledger is a command line double-entry accounting system that works with simple text files holding transactions in the following format:

2015/10/12 * "Exxon"
    Expenses:Auto:Gas                         $10.00
    Liabilities:MasterCard                   $-10.00

This modules enables the following features:

  • Syntax and indentation support for ledger files
  • Add, edit, and delete transactions
  • Generate reports
  • Schedule transactions
  • Sort transactions
  • Display statistics about transactions
  • Display balance up to a point

5.9.34. lua

Flags: +fennel +lsp +moonscript

Adds Lua support to Emacs.

  • REPL
  • Love2D specific functions
  • Moonscript support

5.9.35. markdown

Flags: +grip

This module provides Markdown support for Emacs.

Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML).

Thus, “Markdown” is two things: (1) a plain text formatting syntax; and (2) a software tool, written in Perl, that converts the plain text formatting to HTML. See the Syntax page for details pertaining to Markdown’s formatting syntax. You can try it out, right now, using the online Dingus.

The overriding design goal for Markdown’s formatting syntax is to make it as readable as possible. The idea is that a Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions. While Markdown’s syntax has been influenced by several existing text-to-HTML filters, the single biggest source of inspiration for Markdown’s syntax is the format of plain text email. – John Gruber

5.9.36. nim

This module adds Nim support to Emacs.

  • Code completion (nimsuggest + company)
  • Syntax checking (nimsuggest + flycheck)
  • Babel support (ob-nim)

5.9.37. nix

Adds many tools for Nix(OS) users in nice package for Doom users.

  • Syntax highlighting
  • Completion through company / helm
  • Nix option lookup
  • Formatting (nixfmt)

5.9.38. ocaml

This module adds OCaml support to Doom Emacs, powered by tuareg-mode.

5.9.39. org

Flags: +brain +dragndrop +gnuplot +hugo +ipython +journal +jupyter +noter +pandoc +pomodoro +present +pretty +roam +roam2

This module adds org-mode support to Doom Emacs, along with a number of adjustments, extensions and reasonable defaults to make it more performant and intuitive out of the box:

  • A custom, centralized attachment system that stores files in one place, rather than in the same directory as the input file(s) (only applies to attachments from files in/under org-directory).
  • Executable code blocks with support for a variety of languages and tools (depending on what :lang modules are enabled).
  • Supports an external org-capture workflow through the bin/org-capture shell script and +org-capture/open-frame.
  • A configuration for using org-mode for slide-show presentations or exporting org files to reveal.js slideshows.
  • Drag-and-drop support for images (with inline preview) and media files (drops a file icon and a short link) (requires +dragndrop flag).
  • Integration with pandoc, ipython, jupyter, reveal.js, beamer, and others (requires flags).
  • Export-to-clipboard functionality, for copying text into formatted html, markdown or rich text to the clipboard (see +org/export-to-clipboard and +org/export-to-clipboard-as-rich-text).

Org is a system for writing plain text notes with syntax highlighting, code execution, task scheduling, agenda management, and many more. The whole idea is that you can write notes and mix them with references to things like articles, images, and example code combined with the output of that code after it is executed.

5.9.40. php

Flags: +hack +lsp

This module adds support for PHP 5.3+ (including PHP7).

  • ctags-based code completion (company-php and phpctags)
  • eldoc support (ac-php and php-extras)
  • REPL (php-boris)
  • Code refactoring commands (php-refactor-mode)
  • Unit-test commands (phpunit)
  • Support for laravel and composer projects (with project-specific snippets)
  • File templates
  • Snippets

PHP was the first programming language I got paid to code in, back in the Cretaceous period (2003). My sincerest apologies go out to all the programmers who inherited my earliest PHP work. I know you’re out there, writhing in your straitjackets.

Save a programmer today. Stop a friend from choosing PHP as their first language.

5.9.41. plantuml

This module adds plantuml support to Emacs; allowing you to generate diagrams from plain text.

5.9.42. purescript

(No description)

5.9.43. python

Flags: +conda +cython +lsp +poetry +pyenv +pyright

Adds Python support to Doom Emacs.

  • Syntax checking (flycheck)
  • Snippets
  • Run tests (nose, pytest)
  • Auto-format (black), requires :editor format
  • LSP integration (mspyls, pyls, or pyright)

5.9.44. qt

This module provides language functionality for Qt specific files.

  • Syntax highlighting for qml files
  • Syntax highlighting for .pro and .pri files used by qmake

5.9.45. racket

Flags: +lsp +xp

This module provides integration for racket-mode.

5.9.46. raku

This module adds a major mode and flycheck for Raku.

5.9.47. rest

This module adds REST support.

restclient-mode is tremendously useful for automated or quick testing REST APIs. My workflow is to open an org-mode buffer, create a restclient source block and hack away. restclient-mode and company-restclient power this arcane wizardry.

5.9.48. rst

(No description)

5.9.49. ruby

Flags: +chruby +lsp +rails +rbenv +rvm

This module add Ruby (and optional Ruby on Rails) support to Emacs.

  • Code completion (robe)
  • Syntax checking (flycheck)
  • Jump-to-definitions (robe)
  • Bundler
  • Rubocop integration (flycheck)

5.9.50. rust

Flags: +lsp

This module adds support for the Rust language and integration for its tools, e.g. cargo.

  • Code completion (racer or an LSP server)
  • Syntax checking (flycheck)
  • LSP support (for rust-analyzer and rls) (rustic)
  • Snippets

5.9.51. scala

Flags: +lsp

This module adds scala and sbt support to Emacs.

5.9.52. scheme

Flags: +chez +chibi +chicken +gambit +gauche +guile +kawa +mit +racket

This module adds support for the Scheme family of LISPs; powered by geiser.

5.9.53. sh

Flags: +fish +lsp +powershell

This module adds support for shell scripting languages.

5.9.54. sml

This module has no description yet.

5.9.55. solidity

This module adds Solidity support through solidity-mode

  • Syntax-checking (flycheck)
  • Code completion (company-solidity)
  • Gas estimation (C-c C-g)

5.9.56. swift

(No description)

5.9.57. terra

(No description)

5.9.58. web

(No description)

5.9.59. yaml

Flags: +lsp

This module provides support for the YAML file format.

5.9.60. zig

Flags: +lsp

This module adds Zig support to Doom Emacs, with optional (but recommended) LSP support via zls.

  • Syntax highlighting
  • Syntax-checking (flycheck)
  • Code completion and LSP integration (zls)

5.10. :os

(No description)

5.10.1. macos

This module provides extra functionality and support for macOS.

5.10.2. tty

Flags: +osc

This module configures Emacs for use in the terminal, by providing:

  • System clipboard integration (through an external clipboard program or OSC-52 escape codes in supported terminals).
  • Cursor-shape changing across evil states (requires a terminal that supports it).
  • Mouse support in the terminal.

5.11. :term

What’s an operating system without a terminal? The moduels in this category bring varying degrees of terminal emulation into Emacs.

If you can’t decide which to choose, I recommend vterm or eshell. :term vterm offers that best terminal emulation available but requires a few extra steps to get going. :term eshell works everywhere that Emacs runs, even Windows, and provides a shell entirely implemented in Emacs Lisp.

5.11.1. eshell

This module extends the built-in Emacs Shell (eshell).

The Emacs Shell or eshell is a shell-like command interpreter implemented in Emacs Lisp. It is an alternative to traditional shells such as bash, zsh, fish, etc. that is built into Emacs and entirely cross-platform.

It’s stable, works anywhere Emacs runs (on any OS), and has no external dependencies. The downside is it lacks features some features you’d expect from mature shells (and a tiny community around it), tends to be slower in some cases, and does not support command line tools with TUIs (e.g. curses, ncdu, nmtui, top, etc).

Eshell would be perfect if you didn’t have to reinvent all the wheels in the dealership.

5.11.2. shell

Provides a REPL for your shell.

shell is more REPL than terminal emulator. You can edit your command line like you would any ordinary text in Emacs – something you can’t do in term (without term-line-mode, which can be unstable) or vterm.

Due to shell’s simplicity, you’re less likely to encounter edge cases (e.g. against your shell config), but it’s also the least capable. TUI programs like htop or vim won’t work in shell directly, but will be launched in a term buffer – which handles them reasonably well.

5.11.3. term

(No description)

5.11.4. vterm

This module provides a terminal emulator powered by libvterm. It is still in alpha and requires a component be compiled (

vterm is as good as terminal emulation gets in Emacs (at the time of writing) and the most performant, as it is implemented in C. However, it requires extra steps to set up:

  • Emacs must be built with dynamic modules support
  • You must compile, which has external dependencies (libvterm, cmake and libtool-bin).

vterm will try to automatically build when you first open it, but this will fail on Windows, NixOS and Guix out of the box. Install instructions for nix/guix can be found in the :term vterm module’s documentation. There is no way to install vterm on Windows that I’m aware of (but perhaps with WSL?).

5.12. :tools

Replace this with a description of what modules in this category are for, including any important information (like load order constraints).

5.12.1. ansible

(No description)

5.12.2. biblio

(No description)

5.12.3. debugger

Flags: +lsp

Introduces a code debugger to Emacs, powered by realgud or DAP (LSP).

This document will help you to configure dap-mode Native Debug(GDB/LLDB) as there is still not enough documentation for it.

5.12.4. direnv

This module integrates direnv into Emacs.

direnv is an environment switcher for the shell. It knows how to hook into bash, zsh, tcsh, fish shell and elvish to load or unload environment variables depending on the current directory. This allows project-specific environment variables without cluttering the ~/.profile file.

Before each prompt, direnv checks for the existence of a “.envrc” file in the current and parent directories. If the file exists (and is authorized), it is loaded into a bash sub-shell and all exported variables are then captured by direnv and then made available to the current shell.

5.12.5. docker

Flags: +lsp

This module allows you to manipulate Docker images, containers & more from within Emacs and provides the dockerfile-mode major mode to edit Dockerfiles. Additional convenience functions are provided to make building images easier.

Also, docker-tramp offers a TRAMP method for Docker containers.

5.12.6. editorconfig

This module integrates EditorConfig into Emacs, allowing users to dictate code style on a per-project basis with an .editorconfig file (formal specification).

5.12.7. ein

Adds Jupyter notebook integration into emacs.

5.12.8. eval

Flags: +overlay

This modules adds inline code evaluation support to Emacs and a universal interface for opening and interacting with REPLs.

5.12.9. gist

(No description)

5.12.10. lookup

Flags: +dictionary +docsets +offline

This module adds code navigation and documentation lookup tools to help you quickly look up definitions, references, documentation, dictionary definitions or synonyms.

  • Jump-to-definition and find-references implementations that just work.
  • Powerful xref integration for languages that support it.
  • Search online providers like, stackoverflow, google, duckduckgo or youtube (duckduckgo and google have live suggestions).
  • Integration with docsets.
  • Support for online (and offline) dictionaries and thesauruses.

5.12.11. lsp

Flags: +eglot +peek

This module integrates language servers into Doom Emacs. They provide features you’d expect from IDEs, like code completion, realtime linting, language-aware imenu/xref integration, jump-to-definition/references support, and more.

To get LSP working, you’ll need to do three things:

  1. Enable this module,
  2. Install a language server appropriate for your targeted language(s) (a table mapping languages to supported servers can be found in lsp-mode’s README).
  3. Enable the +lsp flag on the :lang modules you want to enable LSP support for. If your language’s module doesn’t have LSP support, and you know it can (or should), please let us know! In the meantime, you must configure it yourself (described in the Configuration section).

As of this writing, this is the state of LSP support in Doom Emacs:

Module Major modes Default language server
:lang cc c-mode, c++-mode, objc-mode ccls
:lang clojure clojure-mode clojure-lsp
:lang csharp csharp-mode omnisharp
:lang elixir elixir-mode elixir-ls
:lang fsharp fsharp-mode Mono, .NET core
:lang go go-mode go-langserver
:lang haskell haskell-mode haskell-language-server
:lang java java-mode lsp-java
:lang javascript js2-mode, rjsx-mode, typescript-mode typescript-language-server
:lang julia julia-mode LanguageServer.jl
:lang ocaml tuareg-mode ocaml-language-server
:lang php php-mode php-language-server
:lang python python-mode lsp-python-ms
:lang ruby ruby-mode solargraph
:lang rust rust-mode rls
:lang scala scala-mode metals
:lang sh sh-mode bash-language-server
:lang swift swift-mode sourcekit
:lang web web-mode, css-mode, scss-mode, sass-mode, less-css-mode vscode-css-languageserver-bin, vscode-html-languageserver-bin
:lang purescript purescript-mode purescript-language-server
:lang zig zig-mode zls

5.12.12. magit

Flags: +forge

This module provides Magit, an interface to the Git version control system.

5.12.13. make

(No description)

5.12.14. pass

Flags: +auth

Manage passwords in Emacs with the power of pass.

5.12.15. pdf

This module improves support for reading and interacting with PDF files in Emacs.

It uses pdf-tools, which is a replacement for the built-in doc-view-mode for PDF files. The key difference being pages are not pre-rendered, but instead rendered on-demand and stored in memory; a much faster approach, especially for larger PDFs.

See pdf-tools’ project website for details and videos.

5.12.16. prodigy

(No description)

5.12.17. rgb

This module is deprecated. The module is too trivially small (it’s just one hydra, and :ui hydra is deprecated).

Highlights color hex values and names with the color itself, and provides tools to easily modify color values or formats.

5.12.18. taskrunner

This module is deprecated. The module is too trivially small and development on taskrunner has stopped upstream.

This module integrates Taskrunner into Doom Emacs, which scraps runnable tasks from build systems like make, gradle, npm and the like.

5.12.19. terraform

This module adds support for working with Terraform files in Doom Emacs. This includes syntax highlighting, intelligent code completion, and the ability to run Terraform commands directly from Emacs.

5.12.20. tmux

(No description)

5.12.21. upload

Uses ssh-deploy to map a local folder to a remote one.

From the ssh-deploy README:

The ssh-deploy plug-in for Emacs makes it possible to effortlessly deploy local files and directories to remote hosts via Tramp (including but not limited to SSH, SFTP, FTP). It tries to provide functions that can be easily used by custom scripts.

The idea for this plug-in was to mimic the behavior of PhpStorm deployment functionality.

5.13. :ui

For modules who specialize in changing Emacs’ appearance or providing interfaces for its features, like sidebars, tabs, or fonts.

5.13.1. deft

Deft is a major mode for creating, browsing, and filtering notes written in plain text formats, such as org-mode, markdown, and LaTeX. It enables you to quickly jot down thoughts and easily retrieve them later.

5.13.2. doom

This module gives Doom its signature look: powered by the doom-one theme (inspired by Atom’s One Dark theme) and solaire-mode.

  • A colorscheme inspired by Atom’s One Dark theme.
  • A custom folded-region indicator for hideshow.
  • “Thin bar” fringe bitmaps for git-gutter-fringe.
  • File-visiting buffers are slightly brighter (thanks to solaire-mode).

5.13.3. doom-dashboard

This module adds a minimalistic, Atom-inspired dashboard to Emacs.

Besides eye candy, the dashboard serves two other purposes:

  1. To improve Doom’s startup times (the dashboard is lighter than the scratch buffer in many cases).
  2. And to preserve the “last open directory” you were in. Occasionally, I kill the last buffer in my project and I end up who-knows-where (in the working directory of another buffer/project). It can take some work to find my way back to where I was. Not with the Dashboard.

    Since the dashboard cannot be killed, and it remembers the working directory of the last open buffer, M-x find-file will work from the directory I expect.

5.13.4. doom-quit

A silly module that prompts you with quotes when you exit Emacs, like DOOM (the game) did. Some quotes are from the classic game, others are random, nerdy references that no decent human being has any business recognising.

5.13.5. emoji

Flags: +ascii +github +unicode

Displays and inserts emojis (ASCII, Github style, unicode).

  • Converts recognized text to emojis.
  • Enables inserting emojis.

5.13.6. hl-todo

This module adds syntax highlighting for TODO/FIXME/NOTE tags in programming major-modes.

5.13.7. hydra

This module is deprecated. The module is too trivially small, and it’s always been unclear how hydra fits into Doom’s vision for its UI. It’s been decided that Doom will head toward Embark, transient, or hercules instead.

This module adds hydra to Doom Emacs, as well as a few custom built hydras to start with:

5.13.8. indent-guides

\(No description yet\)

5.13.9. ligatures

Flags: +extra

This module enables ligatures and arbitrary symbol substitutions with mac-auto-operator-composition-mode (on supported macOS systems) or composition tables (harfbuzz on Emacs 28), falling back on prettify-symbols-mode otherwise.

5.13.10. minimap

This module adds a minimap to the right side of Emacs, similar to the feature found in many other editors.

5.13.11. modeline

Flags: +light

This module provides an Atom-inspired, minimalistic modeline for Doom Emacs, powered by the doom-modeline package (where you can find screenshots).

5.13.12. nav-flash

This module flashes the line around the cursor after any significant motion, to make it easy to follow after big operations.

Tremendously helpful on large, 1600p+ or 4K displays.

5.13.13. neotree

This module brings a side panel for browsing project files, inspired by vim’s NERDTree.

5.13.14. ophints

This module provides op-hints (operation hinting), i.e. visual feedback for certain operations. It highlights regions of text that the last operation (like yank) acted on.

Uses evil-goggles for evil users and goggles otherwise.

5.13.15. popup

Flags: +all +defaults

This module provides a customizable popup window management system.

Not all windows are created equally. Some are less important. Some I want gone once they have served their purpose, like code output or a help buffer. Others I want to stick around, like a scratch buffer or org-capture popup.

More than that, popups ought to be the second class citizens of my editor; spawned off to the side, discarded with the push of a button (e.g. ESC or C-g), and easily restored if I want to see them again. Of course, this system should clean up after itself and kill off buffers I mark as transient.

5.13.16. tabs

This module adds an Atom-esque tab bar to the Emacs UI.

5.13.17. treemacs

Flags: +lsp

Treemacs is a file and project explorer similar to NeoTree or vim’s NerdTree, but largely inspired by the Project Explorer in Eclipse. It shows the file system outlines of your projects in a simple tree layout allowing quick navigation and exploration, while also possessing basic file management utilities. It includes:

5.13.18. unicode

This module extends Doom’s ability to display non-English unicode. It is primarily useful for non-English Emacs users, for whom Doom’s built-in unicode support in insufficient.

This module relies on the unicode-fonts package. It tries to setup the default emacs fontset to cover as many unicode glyphs as possible by scanning all available glyphs from all available fonts.

When this module is enabled…

  • Emacs will prefer to use the doom-unicode-font font to display non-latin glyphs if it provides coverage for them.
  • The first time you run Emacs a unicode cache will be generated – this will take a while!
  • The cache will be regenerated every time Emacs is made aware of new fonts or you change the font configuration e.g. by modifying doom-unicode-font.
  • The cache will be stored and should not be regenerated unless font-related configuration or the versions of relevant packages changes.

5.13.19. vc-gutter

(No description)

5.13.20. vi-tilde-fringe

Displays a tilde(~) in the left fringe to indicate an empty line, similar to Vi.

5.13.21. window-select

Flags: +numbers +switch-window

This module provides several methods for selecting windows without the use of the mouse or spatial navigation (e.g. C-w {h,j,k,l}).

The command other-window is remapped to either switch-window or ace-window, depending on which backend you’ve enabled. It is bound to C-x o (and C-w C-w for evil users).

It also provides numbered windows and selection with the winum package, if desired. Evil users can jump to window N in C-w <N> (where N is a number between 0 and 9). Non-evil users have C-x w <N> instead.

5.13.22. workspaces

This module adds support for workspaces, powered by persp-mode, as well as a API for manipulating them.

5.13.23. zen

This module provides two minor modes that make Emacs into a more comfortable writing or coding environment. Folks familiar with “distraction-free” or “zen” modes from other editors – or olivetti, sublimity, and tabula-rasa – will feel right at home.

These modes are:

Which renders (most) text in a variable pitch font (see doom-variable-pitch-font). Unlike variable-pitch-mode, this will not affect segments of text that are intended to remain in a fixed pitch font, such as code blocks or ASCII tables.
Our all-in-one “zen” mode that will:
  1. Center the current buffer.
  2. Remove superfluous UI elements (like the modeline).
  3. Activate mixed-pitch-mode.
  4. Scale up the buffer’s text slightly (see +zen-text-scale).
  5. And make the window’s borders slightly thicker (see +zen-window-divider-size).

6. Tutorials

Now that Doom is installed, your next battle is figuring out how to use it. It’s dangerous to go alone, take these:

This section is a work-in-progress.

6.1. TODO Discovery

6.1.1. Keybinds Which-key Describe bindings

6.1.2. Modules

6.1.3. Commands

6.1.4. Packages

6.2. TODO Navigating

6.2.1. Cursor motions

6.2.2. Window manipulation

6.2.3. Opening files

6.2.4. Switching buffers


6.3. TODO Editing

6.3.1. Copy/Paste

6.3.2. Text manipulation

6.3.3. Resize fonts on-the-fly

6.3.4. Region selection

6.3.5. Narrowing

6.3.6. Replacing text

6.3.7. Replacing text in multiple files

6.3.8. Commenting

6.3.9. Deleting, renaming, or moving files

6.3.10. Keyboard macros

6.3.11. Scratch buffer

6.3.12. Reformatting

6.3.13. Expandable snippets

6.4. TODO Searching

6.4.1. Search in current buffer

6.4.2. Search multiple files

6.4.3. Search online

6.4.4. Look up in dictionary/thesaurus

6.4.5. Look up documentation

6.5. TODO Projects

6.6. TODO Programming

6.6.1. LSP and servers

6.6.2. Jump to definition/references

6.6.3. Compiling

6.6.4. Executing code on-the-fly

6.6.5. REPLs

6.6.6. Code completion

6.6.7. Debugger

6.7. TODO Org

6.8. TODO Magit

6.9. TODO Emacs server

6.10. TODO External tools

6.10.1. EditorConfig

6.10.2. Environment managers (conda, virtualenv, direnv, etc)

6.10.3. NixOS

6.11. TODO Workspaces

7. Developer’s manual

Interested in the twigs and glues that hold the project together? Our developer’s manual goes over our conventions and includes guides to walk hackers and contributors through our infrastructure and internal design.

7.1. TODO Releases

Doom Emacs follows the CalVer versioning scheme (YY.0M[.PATCH][MODIFIER]) and a loose, monthly release schedule.

7.1.1. The process

  1. A release-YY.0M

7.2. TODO Conventions

7.2.1. TODO Documentation

Welcome to our documentation about the documentation. Here I’ll walk you through how best to navigate our docs and the conventions we use for them – and in such painstaking detail that you’ll memorize it all simply to avoid the horror of revisiting it. You’re welcome.

Our docs are also available from within Doom Emacs. If you already know your way around Doom, its search and navigation facilities can provide a more powerful way to consume them. Access them with M-x doom/help (on <help> d h), if you prefer, otherwise, read on. Formatting

Our documentation consists of a series of Org files living in the project’s docs/* directory. Each file should consist of (at the very least):

  • A standardized navigation bar followed by a 80-character sequence of dashes (do not design thes by hand, use $ doom make docs:menu to generate them). See the doom-cli-docs-menu and doom-cli-docs-common-menu variables to customize this.
    • The left side is reserved for temporal navigation (generally, “back to…” links).
    • The right side is reserved for absolute links to external resources.
  • A #+TITLE. Should be capitalized as per sentence case rules.
  • A #+SUBTITLE to summarize the contents of that file. It should be capitalized as per sentence case rules.
  • A #+SETUPFILE with a relative link to docs/.setupfile (automatically generated with $ doom make docs:conform).
  • A table of contents (except for modules/ with :toc:noexport: tags).
  • The contents of the file, which should never be more than 6 headings deep.
Special tags

Doom treats certain heading tags especially. They are:

  • :ignore: – This heading will be hidden when doom-docs-mode is active or when the file is exported. It will be as if the contents of that header belonged to its parent tree.
  • :hidden: – This whole tree will be hidden when doom-docs-mode is active. Use this on trees that should only be displayed in the HTML/PDF versions of our documentation.
  • :noexport: – This whole tree will be excluded during HTML/PDF export. Use these to display content only to users reading the docs within Doom Emacs.

Doom also uses #+begin_comment ... #+end_comment blocks to hide content from the exported versions of our docs. These lines (i.e. excluding their content) will be hidden when doom-docs-mode is active.


Our documentation is peppered with asides, indicated by an icon. Depending on the icon, their meaning may change, like so:

These are for “under construction” notices or contribution call-to-actions.

These are for technical details, examples, and external references that build on the current subject.

These are for “Did you know?” tangents and the opinions of the maintainer or a code contributor.

These are temporary or time-sensitive annotations that may be edited, removed, or acted upon soon, such as a deprecation notice.

These are urgent warnings to help users avoid causing damage or getting in trouble.

Notices should be indented as shown above, with four columns of leading space, including two columns reserved for the icon.

  • Inline verbatim blocks for:
    • File paths (e.g. ~/.emacs.d/init.el or $DOOMDIR/config.el)
    • Technical nouns (references to [external] packages, programs, libraries, concepts, versions, etc). e.g.
      • zls is the name of an external package.
      • “Please install git so you can use git” – The first git refers to the system package, the second refers to the executable.
      • Do not use this for proper product names. e.g. Windows 10 vs win10-x86. One is a product name (which should be linked to its homepage), the other is a technical reference to a particular build of Windows.
    • Meta annotations (like DEPRECATED):
    • Referring to org syntax literally. e.g. ~this would normally be a code block~ and this would be *bolded*.
  • Inline code blocks are used for special syntax or
    • ~rg~ or ~doom~ – refers to shell commands.
    • ~M-x some-command~ – is special syntax for issuing a command in Emacs
    • ~+flag~ – is the syntax for a Doom module flag. However, use [[doom-module:][+flag]] instead for references of actual Doom flags.
    • ~display-buffer-alist~ – is a reference to a elisp symbol.
    • [[doom-package:][js2-mode]] installs ~js2-mode~ – first js2-mode refers to an elisp package, the second is a major mode symbol.
  • Complete shell commands should be prefixed with a $ (and never with sudo, unless root access is absolutely necessary), e.g.
    • ~$ doom sync~
    • ~$ git clone ~/.emacs.d~
    • ~rg~ – Not a complete command! Simply a reference to the executable.
  • The verbatim : operator should only be used to inhibit org from interpreting org syntax (i.e. to display text verbatim):

    This *has* /org/ ~syntax~ that we want displayed as-is. TODO Changelogs TODO Modules

If you’re here wondering what a Doom module is, check out our introduction to the concept in the manual.

If you’re here wondering how to enable a Doom module, check out the Toggling Modules section.

If you’re here to better understand a module’s documentation; its structure and formatting, or something else about it, that’s what this section is all about!

TODO Description

A module’s description is an introduction to what the module does and provides. It should stand on its own; with links to any relevant projects. The description will be copied to the module index when running $ doom make module-index, so its contents should remain concise and surface level. Depth should be reserved for its other sections.

The most common components of the description are:

  • A short summary of what it adds to Doom Emacs.
  • A long summary of the features it provides (Code completion, snippets, integration for a particular tool – they should be listed along with any key Emacs packages that provide that functionality).
  • A list of maintainers.
  • A list of module flags.
  • A list of plugins.
  • A list of hacks.
TODO Prerequisites
TODO Usage
TODO Troubleshooting

7.2.2. TODO Emacs lisp TODO Style guide

Doom conforms to @bbatsov’s emacs-lisp style guide with the following exceptions:

  • Use mapc instead of seq-do.
  • No hanging parentheses.
  • We use DEPRECATED to indicate code that will eventually be removed.

In addition to our other conventions:

  • Top-level use-package! and after! blocks should be separated with two blank lines. Naming conventions

Doom has a number of naming conventions that it uses in addition to the standard lisp conventions. Third party packages may use their own conventions as well.

Lisp conventions

The lisp conventions are simple. Symbols follow NAMESPACE-SYMBOLNAME for public variables/functions (e.g. bookmark-default-file or electric-indent-mode) and NAMESPACE--SYMBOLNAME for private ones (e.g. byte-compile--lexical-environment and yas--tables).

NAMESPACE is usually the name of the containing file or package. E.g. the company plugin prefixes all its variables/functions with company-.

Doom conventions
Denotes a public command designed to be used interactively, via M-x or a keybinding. e.g. doom/info, +popup/other, +ivy/rg.
A public evil operator, motion or command. e.g. +evil:align, +ivy:rg.
doom-[-]NAME-h or +MODULE-[-]NAME-h
A non-interactive function meant to be used (exclusively) as a hook. e.g. +cc-fontify-constants-h, +flycheck-buffer-h.
doom-[-]NAME-a or +MODULE-[-]NAME-a
Functions designed to be used as advice for other functions. e.g. doom-set-jump-a, doom--fix-broken-smie-modes-a, +org--babel-lazy-load-library-a
doom-[-]NAME-fn or +MODULE-[-]NAME-fn
Indicates an strategy function. A good rule of thumb for what makes a strategy function is: is it interchangeable? Can it be replaced with another function with a matching signature? e.g. +lookup-dumb-jump-backend-fn, +magit-display-buffer-fn, +workspaces-set-project-action-fn

A public Doom “autodef” function or macro. An autodef should always be defined, even if its containing module is disabled (i.e. they will not throw a void-function error). The purpose of this is to avoid peppering module configs with conditionals or after! blocks before using their APIs. They should noop if their module is disabled, and should be zero-cost in the case their module is disabled.

Autodefs usually serve to configure Doom or a module. e.g. after!, set-company-backends!, set-evil-initial-state!

7.2.3. TODO Git branches

Our development (i.e. nightly) branch. Development happens rapidly here; often seeing ~10 commits a day.
Our stable branch. develop is merged into main once all tests are passed.

7.2.4. Git commits

Doom has adopted its own spin-off of conventional commits:




As of 074b9eb0, use $ doom ci lint-commits HEAD~1 to lint your last commit locally against these rules. Types

For updating pinned packages, including changes to code to reflect changes upstream. Replace bump with revert when downgrading packages.


user/repo@a1b2c3da1b2c -> user/repo@z9y8x7wz9y8x
user/repo@a1b2c3da1b2c -> user/repo@z9y8x7wz9y8x
user/repo@a1b2c3da1b2c -> user/repo@z9y8x7wz9y8x



Work on project infrastructure and development tools: build scripts, CI/CD config files (e.g. .github/*), ignore files, etc.


Changes to documentation, docstrings, and help output from CLI commands (e.g. the output of $ doom help or $ doom doctor).

  • This includes user-facing changes to doctor checks.
  • Use nit for code comments instead.

For changes that introduce a new feature, a major UI/UX change, or add integration support in production code. For example, adding magit-gitflow to the :tools magit module introduces brand new functionality.

However, changes that are minor, or present little-to-no user-facing change, should use the tweak type.


A fix for a bug or misbehavior in production code. Also applicable when updating stale code that was missed last bump.


A merge commit, merging a pull request or branch.

  • Never specify a scope.
  • The bang is meaningless for this type.
  • The SUMMARY should only contain one or more (comma-delimited) pull request references or a branch’s name. e.g. merge: #4129, merge: develop.

These commits reflect changes to our module list. e.g. Adding, removing, renaming, or deprecating modules.

  • Don’t use this for changes within modules.
  • Scope goes after the colon.


module: add :lang zig
module: move :feature evil to :editor evil
module: move :feature vc to :emacs vc, :ui vc-gutter
module: remove :ui fill-column

With Emacs 26.x support dropped and `display-fill-column-indicator-mode'
introduced in Emacs 27.1, this module is reduced to a single line, and
so has become too trivial to warrant remaining a module.
module: deprecate :tools rgb

The module is too trivially small; it's simply one hydra, and :ui hydra
is deprecated, so this module will be next to go.

Nitpick changes that have no effect on the code, such as changes to whitespace, formatting, or comments.


A refactor explicitly for improving startup or runtime performance.


Changes to the code base that does not add a feature nor fix a bug; such as removing redundant code, simplifying code, renaming variables, or swapping one package for a near-enough drop-in replacement.

For example: replacing git-link with browse-at-remote is a refactor because they do the same thing, with slightly different interfaces.


Where VERSION is the new version. A commit of this type marks a version bump. Should only be used by maintainers.


For reverting changes. SUBJECT should consist of:

  • Doom modules or categories (reverting bumps),
  • Packages (reverting bumps),
  • The full subject of the reverted commit (requires a Revert HASH in FOOTER),

If you revert another commit in a same PR, please rebase the earlier commit out instead before it is merged.


Changes to unit tests, but not testing infrastructure (use dev for that).


For minor UX improvements or tweaks to variables and defaults with subtle or no user-facing changes.

For example: changing the button face’s :box attribute, inserting drop-in functionality (e.g. (setq prefix-help-command 'embark-prefix-helm-command)), or tuning the garbage collector.

Breaking changes
  1. Append a ! (aka bang) to the TYPE to indicate a breaking change.
  2. Prepend BREAKING CHANGE: to BODY, followed by an explanation of what is broken and how to get around it.


refactor!: remove X functionality

BREAKING CHANGE: Without X, A and B will not work. Enable Y to get
similar behavior.
fix!(zig): remove lsp support

BREAKING CHANGE: removing LSP support reduces how much Microsoft you
must ingest to write Zig, but it means no more LSP. Only workaround is
to meme on the internet, especially in obscure git convention guides
that only a handful of people will ever read. Scope

The SCOPE should be one of the following:

  • A module minus the category: nit(python), test(doom-dashboard), dev(popup), docs(everywhere)
  • A category without the module, implying it affects all modules inside: fix(:lang), feat(:editor), …
  • An arbitrary scope prefixed with &: fix(&feature), dev(&org-roam2), feat(&org-knit). Useful for PRs and pending features.
  • One of these special scopes:
    • cli: when it concerns changes to Doom’s CLI: core-cli.el, core/cli/**, or bin/**.
    • For docs commits, these additional scopes are available:
      • The basename (no directory, no extension) of a file in docs/*.org. e.g. for changes to docs/ -> docs(migrate): .... docs/ -> docs(tutorials): ....
      • install (referring to our installation guide)
  • One or more of the above, separated with a comma: feat(python,rust), fix(lsp,debugger), docs(:lang,&org-roam):. However, this is discouraged.

The scope may be omitted if:

  • Is a change to Doom’s global defaults, larger design decisions, or core.
  • Using the bump:, revert:, release:, module:, or merge: types. Their scope belongs in their SUBJECT.

Does your change touch many modules? Only mention the target scope(s). For example, a fix for :tools lsp that affects LSP implementations in other modules only needs to specify lsp as its scope.

Do not put issue/PR references in the commit SUBJECT. See [BROKEN LINK: footer] below. Subject
  • Can’t be shorter than 10 characters or longer than 72 (<= 50 is ideal).
  • Should be present tense and imperative voice.
    • feat: add X instead of feat: added Y
    • fix: replace A with B instead of fix: replaced A with B
    • When TYPE is a verb, it may be used as part of the SUBJECT:
      • Bad: fix: fix TAB breaking when focus is lost
      • Good: fix: TAB breaking when focus is lost
  • The first word in SUBJECT should not be capitalized – unless it’s a key reference, e.g.
    • Good: fix: TAB breaks when focus is lost
    • Good: fix: remove buggy code
    • Bad: feat: Add new shenanigans
  • Do not quote symbol references and inline code: tweak: gc-cons-threshold = (* 128 1024 1024)
  • Key sequences that are ambiguous in their context should be single quoted:

    • Good: feat: add C-; keybind
    • Good: refactor!: remove C-c C-; keybind
    • Bad: fix: make SPC s m a reality
    • Good: fix: make 'SPC s m' a reality
    • Bad: fix: bind 'SPC '' to ivy-resume
    • Good: fix: bind "SPC '" to ivy-resume

    A single quote is preferred. Switch to double quote if ' is present in sequence, otherwise backquote. If all three characters are present, know that the ancient ones don’t take kindly to your summoning methods (i.e. you should rethink your subject line). Body

BODY is optional. There are no restrictions on tense or voice, but must be grammatically correct and must adhere to the following:

  • Standard grammar and formatting rules apply:
    • Sentences are separated with one space.
    • Paragraphs are not indented and separated with a blank line.
  • Line width must not exceed 72 characters, except for machine-generated lines (e.g. bump commit lines) or long URLs.
  • A BREAKING CHANGE: line and explanation is required if you use a banged type (e.g. feat!: ..., fix!: ...).
  • Include user/repo@HASH -> user/repo@HASH lines in bump commits (or revert commits where packages are “un”-bumped).
  • Key sequences that are ambiguous in their context should be single quoted:
    • Bad: I changed SPC s m a to...
    • Good: I changed 'SPC s m a' to...
    • Good: The TAB key was fixed Footer

The FOOTER consists of two sections: the references then git meta lines, separated by a blank line.

Each reference line should be comprised of:

  • A keyword followed by a single space:
    • Ref: a reference for readers to consult for more information
    • Fix: use for issues/commits
    • Close: use for PRs
    • Revert: required for revert: ... commits
  • Then a single reference:
    • An issue or PR reference: #123, user/repo#123, https://git.forge.fake/repo#123
    • A 12-character commit: 3bedae38dd9f, user/repo@3bedae38dd9f, https://git.forge.fake/repo@3bedae38dd9f
    • An URL to an external resource.


Close #55
Close user/repo#952
Fix #1
Fix #25
Fix https://git.forge.fake/repo#123
Fix user/repo#84
Ref #4
Ref #5
Ref 3bedae38dd9f
Ref https://git.forge.fake/repo#123
Ref user/repo#25
Ref user/repo@3bedae38dd9f
Revert 3bedae38dd9f

Co-authored-by: John Doe <>
Signed-off-by: Jane Doe <>

Lines should be grouped by keyword, but precise order is unimportant.

7.2.5. TODO Keybinds TODO Modifiers TODO Leader TODO Localleader TODO Evil TODO Vanilla

7.3. TODO Forking

7.4. TODO Modules

Functionality in Doom is divided into collections of code called modules (à la Spacemacs’ layers). A module is a bundle of packages, configuration and commands, organized into a unit that can be enabled or disabled by adding or removing them from your doom! block in $DOOMDIR/init.el.

7.4.1. Introduction Concepts
  • features
  • autoloading
  • autodefs
  • deferred loading
  • use-package Module notation Load order Conventions

7.4.2. TODO Anatomy of a module TODO TODO init.el TODO config.el TODO packages.el TODO cli.el TODO doctor.el TODO autoload.el TODO autoload/ TODO test/ TODO patches/ TODO Other files

7.4.3. TODO Doom Emacs loading process

7.4.4. TODO Examples

7.4.5. TODO Best practices

7.5. TODO Command line interface


  • Current stack
  • CI files & directories

7.6.1. TODO Workflows TODO Testing TODO Linting commits TODO Bumping packages TODO Building docs TODO Github triage

7.6.2. TODO Possible improvements

8. Community

Doom Emacs has a large, active, and friendly community across several platforms. You don’t have to use Doom to be on them, but they are treated as an extension of our documentation.

This is our official nexus for discussion, support, and announcements. It also seconds as our community wiki; where we keep guides, tutorials, cheat sheets, and more. There is no better place to track the state of the project or ask for help using Doom and/or Emacs.
Our Discord is a less formal environment for talking shop, being social, or engaging with @hlissner (Doom’s maintainer). Come say hi!
An alternative channel for announcements.

Please don’t contact Henrik or moderators directly (by email or DM) for assistance with [Doom] Emacs. Present your issue to the community on Discourse or Discord instead, to avoid inundating them and to give others a chance to chime in.

9. Contribute

Doom is what happens when you combine incurable madness, poor naming sense, and a Factorio addiction. However, it is the work of mostly one guy; there are always gaps in its documentation, bugs lurking in dusty corners, and new features that need implementing.

If Doom has been helpful to you, convert a little caffeine into a pull request, bug report, or a helpful voice in our community. Our contributing manual lists all the ways you can help and how to go about them, but don’t forget to consult our do not PR and do not bump lists before you do – where I track contributions that won’t be accepted and why.

9.1. TODO How can I help?

Now that you’ve set aside from caffiene to convert into a contribution, what do you do? There’s no shortage of things to do, but here are a couple suggestions:

  • Reporting bugs
  • Suggesting enhancements
  • Contributing code or documentation
    • Our issue tracker has many open issues.
    • Issues tagged backlog are on the backburner due to lack of time; we could use your help there!
    • Issues tagged good first issue have a low barrier of entry.
    • Issues tagged help wanted tend to be more specialized.
    • Our development roadmap shows a timeline of what’s being worked on and when; a good place to get ideas for your own contributions.
    • Our packages under review lists packages we’re considering for inclusion (or removal). Approved packages are open for you to implement yourself.
    • Our upstream bugs board lists known issues with external causes. Help us address these at the source.
  • Helping out in the community
    • Helping out with issue triage
    • As a module maintainer
    • Answering questions on Discord/Discourse
    • Or just being around
  • Supporting the project

That said, before you contribute, please consult our Do not PR and Do not bump lists (and often; they change from time to time).

9.1.1. Do not PR

Last updated 2021-08-01

There are contributions that will be immediately refused, either due to project policy or an external factor blocking development in that area. A list of these is maintained here and is likely to change from time to time. It’s recommended that you consult it each time you prepare to file a pull request.

  • Feature-gate keybinds in the :config default module. That is to say, PRs to wrap keybinds in (:when (featurep! ...) ...) checks will not be accepted. I explain why in this issue.
  • Directly modify modules/ this file is automatically generated by doom make module-index and should not be modified by hand.
  • Add questions to docs/ without prior approval. Selecting questions for the FAQ requires the insight of our maintainer and community leaders. Please discuss it with them beforehand.
  • Correct less than 5 non-technical spelling and grammar errors. These are popular, especially during Hacktoberfest, but their value don’t justify the time cost of reviewing them all so a minimum of 5 errors is required to be accepted. Otherwise, we’d prefer you ping us on Discord or simply wait until it is discovered by a maintainer (or a user with enough errors to correct).

    Of course, any correction that impacts the technical correctness of our documentation is exempt from this rule. e.g. Misspelling the name of a package in a shell command.

9.1.2. Do not bump

Last updated 2021-08-01

These are packages whose pins should not be updated:

  • format-all: a rewrite of the :editor format module is in the works and updates upstream have introduced breaking changes to the package that are incompatible with our module.

9.2. TODO Reporting issues

You’ve found a problem and you’re ready to fire off that bug report. [BROKEN LINK: No match for fuzzy expression: *Troubleshoot] can help you figure it out, but if that doesn’t pan out, then it is time to file a bug report.

Please do not file or answer Doom Emacs issues on Reddit, Twitter, or StackOverflow. Kindly refer them to this section.

Questions posted on other platforms are difficult to track, difficult for posterity to find, and rarely include enough information to investigate.

9.2.1. TODO Before you create that report

An effective bug report is informative. Please try to provide:

  • A backtrace of all mentioned errors.
  • A step-by-step reproduction of the issue.
  • Information about your Doom config and system environment.
  • Screenshots/casts of the issue (if possible).

This section will show you how to collect this information.

9.2.2. TODO How to write a good bug report

9.3. TODO Suggesting enhancements

9.3.1. TODO Before you submit your suggestion

9.3.2. TODO How to write an effective suggestion

9.4. TODO Contributing code

There’s much to be done around here! We need bugfixes, new features, and documentation. If you’d like to convert some caffeine into Emacs Lisp, here are a few considerations before starting that PR:

  • Make sure your contribution isn’t in our Do Not PR list
  • Read our code style guide and conventions.

There are contributions that will be immediately refused, either due to project policy or an external factor blocking development in that area. A list of these kinds of contributions is maintained in two separate lists we call our do-not-PR lists.

They are: one below, which lists our do-not-PRs motivated by project policy, and one on our Discourse, which are blocked by external factors.

9.4.1. TODO Your first code contribution

9.4.2. TODO Submitting pull requests

  1. Now you wait for a code review:
    • If your PR is approved, you don’t need to do anything. It will be merged soon (the maintainer approves PRs ahead of time, then merges them in bulk later).
    • Your PR may acquire one of these labels:
      • status:needs-work: I’m interested in your PR, but it needs some changes to be accepted. Keep in mind there may be a delay between getting this tag and getting an explanation for it.
      • status:moved: the PR won’t be merged because it will be addressed elsewhere, in another PR or a future commit.
  2. The PR is either merged or closed.

9.4.3. TODO Contributing to Doom core

9.4.4. TODO Contributing to an existing module

9.4.5. TODO Contributing a new module

9.5. TODO Contributing documentation

Doom Emacs’ documentation is an ongoing effort. If you have suggestions, improvements, tutorials and/or articles to submit, don’t hesitate to get in contact via our Discord server or email. I appreciate any help I can get!

9.5.1. TODO Correcting or reporting mistakes

9.5.2. TODO Contributing to Doom’s manual

9.5.3. TODO Contributing module documentation

9.6. TODO Help keep packages up-to-date

Doom pins all its packages to reduce the likelihood of upstream breakage leaking into Doom Emacs. However, we may miss when a package releases hotfixes for critical issues. Let us know or PR a bump to our pinned packages.

9.7. TODO Become a module maintainer

9.8. TODO Become a community regular

9.9. TODO Support the project

Consider becoming a Github Sponsor (there are perks!) or buying @hlissner a drink on LiberaPay or Paypal. Every little bit helps Henrik allocate more time to Doom, Emacs, and his open-source capers.

9.10. TODO Special thanks

10. Thank you

In the beginning Doom was just some dude’s Emacs config, then a wild userbase appeared. Little of this would be possible (or nearly as fun) without Emacs, its ecosystem of plugin developers, and you, its users. Thank you!