A wiki for Doom Emacs
Doom is a configuration framework for GNU Emacs. It focuses on performance and customizability. It can be a foundation for your own config or a resource for Emacs enthusiasts to learn more about our favorite OS.
Doom Emacs is considered the fastest Emacs ‘distribution’ at the expense of being more ‘hardcore’ than some alternatives (for example: Spacemacs)
This wiki will provide guides and tips to get you up and running with Emacs for Elixir development.
https://github.com/hlissner/doom-emacs - Official Doom Emacs site
https://github.com/tonini/alchemist.el - Alchemist Elixir site
https://github.com/elixir-lsp/elixir-ls - Elixir LS site
Prelude
There is no such thing as a ‘Doom Emacs’ app. You just run regular Emacs which loads the configuration generated by Doom using doom sync
.
Doom Emacs configures Emacs by default uses keybindings like Vim. If you are not familiar with Vim, it’s best to have some basic understanding about the keys, actions and motions.
For now, just remember that
- you can save a file using
:w
(press colon, press w) - SPC means
spacebar
- You can search in a file with
/
- You can search in all files of a project with
SPC /
- You can search and start a lot of functionality using
SPC :
In the list you will also see which keys are bound to certain actions. For example typeSPC : find
.
Installation
1) Emacs and Doom Emacs installation
Instructions how to install Doom Emacs can be found at it’s own Getting Started Guide.
2) Enabling Elixir support
To enable the support for Elixir, you have to adapt the ~/.doom.d/init.yml
. You can easily open this file in Emacs by pressing SPC f p
and selecting it from the list.
Uncomment the Elixir recipe by removing the ;;
from the beginning of the line:
elixir
tip: Search for elixir
using SPC /
, put the cursor on the ;
press x
to remove the character, then save with :w
Important
Every time you make changes to the init.el
file or packages.el
file, you have to run ~/.emacs.d/bin/doom sync
in the terminal and restart Emacs. This synchronizes your config with Doom Emacs. It ensures that needed packages are installed, orphaned packages are removed and necessary metadata correctly generated.
tip: you can also press SPC h r r
to initiate doom sync && emacs restart
in the background.
3) Optional: Enabling Elixir Language Server support
The Elixir Language Server provides a server that runs in the background, providing Emacs information about Elixir Mix projects. This enables code completion and more.
3a. Install the LSP server
First we install Elixir LSP by cloning the repo, compiling the package and creating a release.
git clone https://github.com/elixir-lsp/elixir-ls.git ~/.elixir-ls
cd ~/.elixir-ls
mix deps.get
mix compile
mix elixir_ls.release -o release
Next we add elixir-ls to the PATH variable. This is usually done in ~/.bashrc
or ~/.zshrc
. Add this line:
export PATH=$PATH:$HOME/.elixir-ls/release
When you start Emacs from another environment (for example: the desktop GUI) the shell environment variables are not available. Doom can sync shell environment variables to Emacs environment variables in ~/.emacs.d/.local/env
. Run:
~/.emacs.d/bin/doom env
3b. Enable LSP in Doom Emacs
To enable LSP mode when editing Elixir files, you have to do open init.el
again using SPC f p
and change the line of elixir to
(elixir +lsp)
Also uncomment lsp
in the tools
section. I recommend to also enable the LSP peak function so the line looks like:
(lsp +peek) ; M-x vscode
Now sync the configuration and restart Emacs (using SPC h r r
) and it should be working as expected. That is: once you open an Elixir file the LSP server will be started and you get code completion etc. As the LSP server has to index your project code first, it might take up to 15 minutes before it kicks in.
WARNING: Using Credo with LSP
If you use Credo, you should add this snippet in config.el
so it works together with LSP:
;; Workaround to enable running credo after lsp
(defvar-local my/flycheck-local-cache nil
(defun my/flycheck-checker-get (fn checker property)
(or (alist-get property (alist-get checker my/flycheck-local-cache))
(funcall fn checker property)))
(advice-add 'flycheck-checker-get :around 'my/flycheck-checker-get)
(add-hook 'lsp-managed-mode-hook
(lambda ()
(when (derived-mode-p 'elixir-mode)
(setq my/flycheck-local-cache '((lsp . ((next-checkers . (elixir-credo)))))))
))
Optional: Configuration snippets
This snippet or parts of it can be placed in config.el
without installing additional packages.
;; Configure elixir-lsp
;; replace t with nil to disable.
(setq lsp-elixir-fetch-deps nil)
(setq lsp-elixir-suggest-specs t)
(setq lsp-elixir-signature-after-complete t)
(setq lsp-elixir-enable-test-lenses t)
;; Compile and test on save
(setq alchemist-hooks-test-on-save t)
(setq alchemist-hooks-compile-on-save t)
;; Disable popup quitting for Elixir’s REPL
;; Default behaviour of doom’s treating of Alchemist’s REPL window is to quit the
;; REPL when ESC or q is pressed (in normal mode). It’s quite annoying so below
;; code disables this and set’s the size of REPL’s window to 30% of editor frame’s
;; height.
(set-popup-rule! "^\\*Alchemist-IEx" :quit nil :size 0.3)
;; Do not select exunit-compilation window
(setq shackle-rules '(("*exunit-compilation*" :noselect t))
shackle-default-rule '(:select t))
;; Set global LSP options
(after! lsp-mode (
setq lsp-lens-enable t
lsp-ui-peek-enable t
lsp-ui-doc-enable nil
lsp-ui-doc-position 'bottom
lsp-ui-doc-max-height 70
lsp-ui-doc-max-width 150
lsp-ui-sideline-show-diagnostics t
lsp-ui-sideline-show-hover nil
lsp-ui-sideline-show-code-actions t
lsp-ui-sideline-diagnostic-max-lines 20
lsp-ui-sideline-ignore-duplicate t
lsp-ui-sideline-enable t))
Installing packages
This is done differently than native Emacs and Spacemacs!