Install Doom Emacs as explained in the readme.

Alongside it, you’ll want to install ripgrep and fd for better search integrations, and possibly ttf-font-awesome for better icons.


Instead of the default ~/emacs.d/ and ~/doom.d/ config directories, you can also use ~/.config/emacs/ and ~/.config/doom/.


My init.el is mostly default, and enables the languages I regularly use, with LSP support where possible:

       (format +onsave)  ; automated prettiness


       (cc +lsp)         ; C > C++ == 1
       markdown          ; writing docs for people to ignore
       (python +lsp)     ; beautiful is better than ugly
       sh                ; she sells {ba,z,fi}sh shells on the C xor
       (yaml +lsp)       ; JSON, but readable

Note that some of these need additional programs to be installed, like clangd for C++, black for Python formatting, and prettier for more formatting.

I use the treemacs project drawer, and (ivy +icons +prescient) for searching. Add +fuzzy for fuzzy searching. (I found it too fuzzy for my taste.)

For git integration, magit is great.

To install additional packages from MELPA, add them to packages.el:

(package! pkgbuild-mode)
(package! bazel)


Some highlights from my config.el. (Remember, SPC f p quickly opens files in your emacs config directory.)

  • Always keep 10 lines of buffer above/below the cursor: (setq scroll-margin 10)
  • Save buffer and exit insert mode on focus loss

    ;; Auto save buffers on focus lost
    (add-function :after after-focus-change-function (lambda () (save-some-buffers t)))
    ;; Exit insert mode on focus loss
    (add-function :after after-focus-change-function (lambda () (evil-normal-state)))
  • Improve default C++ indenting to be more in line with the LSP/clang-format auto formatting

    ; Better default indent style
    (setq c-default-style "user")
    ; disable indenting namespaces
    (c-set-offset 'innamespace 0)
  • There is a bug currently where LSP provided formatting does not work. This is the workaround.

    ; Use clang-format instead of the lsp provided formatter, which doesn't appear to work.
    (setq +format-with-lsp nil)
  • Unlike Vim, Emacs treats _ as a word separator. To still be able to quickly jump over them, we can rebind the word-based motions to be symbol-based motions instead:

    (with-eval-after-load 'evil (defalias #'forward-evil-word #'forward-evil-symbol))

Running as server and client

Emacs can run in server client mode by using a systemd unit. The ArchWiki explains how.

Note that when changing the configuration, doom/reload is not always sufficient. Restarting the server using systemctl --user restart emacs is usually necessary.


I’m using the emacs-gcc-wayland-devel-bin AUR package, based on this git repo. After installing this, set the GDK_BACKEND=wayland environment variable and you should be good to go.

Useful commands

  • SPC p p to switch project
  • SPC SPC to switch file within project
  • SPC : search and execute a command (alternative for M-x) Whenever you are looking for some functionality, this is a great way to discover it. It also shows which keys are already bound to the command, if any.
  • SPC f p open emacs config file
  • SPC g g to open Magit
    • ? show keybindings
    • s stage files
    • c c commit
    • C-c C-c confirm commit
    • C-c C-k abort commit
  • SPC TAB 1-9 switch workspace
  • SPC TAB . switch workspace by name
  • SPC o p toggle treemacs
    • ? show keybindings
    • C-? show more keybindings
    • create file/dir: c f c d
    • rename: R

Emacs as mail client

  • notmuch + lieer