BartOtten

BartOtten

Doom Emacs - Elixir Wiki

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 type SPC : 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!

Package management Doom Emacs

Most Liked

slouchpie

slouchpie

The OP is a good intro to setting up emacs.

One other thing I would add is this. If you are getting some warning like “lsp is scanning 5000 files in current project…consider adding to ignore list”, try adding this to config.el:

(setq lsp-file-watch-ignored
      '(".idea" ".ensime_cache" ".eunit" "node_modules"
        ".git" ".hg" ".fslckout" "_FOSSIL_"
        ".bzr" "_darcs" ".tox" ".svn" ".stack-work"
        "build" "_build" "deps" "postgres-data")
      )

That’s just some files/directories that LSP will now ignore.

Note that in doom emacs you can easily get to config.el with key command SPC f P (doom/open-private config). You could have found this key command using ALT+X and typing, e.g. “doom config”.

Once you’re up and running, there are some really really nice things you can do.

For example, in an elixir file you should be in elixir-mode and you can use this key command: SPC m t b to run all tests in project (it runs mix test).

This is pretty cool - it will run the tests in a “compilation window” which you can browse like a normal buffer. Press enter on any file:line_number stacktrace to jump to that part of the code.

One final thing - the main reason I still love emacs so much. Press SPC u. This is a special command called universal-argument. It lets you add arbitrary arguments after any command.

For example, if you do SPC u SPC m t b then it will bring up a prompt where you can enter extra args, e.g. “–failed --max-failures=1”. This will then run mix test --failed --max-failures=1.

You can re-run the previous test command with SPC m t r.

This can all be done headlessly, because emacs can run in the shell.

BartOtten

BartOtten

As my girlfriend has just released son 3.0 and I want to finalize a lib for this young man I postpone further extension of the OP for a week. Just so you all know I don’t forget this topic, just have to limit my investments :slight_smile:

tj0

tj0

A bit of a necro, but I’ve been using Doom for a while. And I use Emacs for almost everything - The Way of Emacs .

Been using alchemist since 2016 and just upgraded to use eglot and elixir-ls. It’s much better than alchemist and eglot will ship by default with Emacs 29.

Configuration below:

packages.el

(package! elixir-mode)
(package! eglot)
(package! exunit)
(package! inf-elixir)

config.el

;; eglot configuration
(use-package elixir-mode)
(use-package eglot)
(use-package exunit)

(add-to-list
 'eglot-server-programs
 '(elixir-mode . ("sh" "/home/YOUR_HOME_DIR/.elixir-ls/release/language_server.sh")))

(add-hook
 'elixir-mode-hook
 (lambda ()
   (subword-mode)
   (eglot-ensure)
   (company-mode)
   (flymake-mode)
   (add-hook 'before-save-hook 'eglot-format nil t)
   ))
(setq inf-elixir-project-command "iex -S mix phx.server")


Where Next?

Popular in Wikis Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48342 226
New
BartOtten
A wiki for Doom Emacs Doom is a configuration framework for GNU Emacs. It focuses on performance and customizability. It can be a founda...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41989 114
New
ibgib
Popular Elixir Packages List of popular Atom.io Elixir Packages. These can be installed via atom’s package center or a command line with ...
New
anildigital
Here is list of plugins for different editors Sublime Text 3 — Elixir.tmbundle - GitHub - elixir-editors/elixir-tmbundle: A TextMate a...
New
Rich_Morin
I’d like to start a discussion of data serialization formats, in the context of Elixir. The rest of this note is a combination of persona...
New
nicbet
Introduction Now that the language is picking up support and maturing nicely, I’d like to start a collection of common and recurring Elix...
New
blackode
Hi and Hello Every Elixirian. After Learning the Elixir basics, I struck then. I have no idea of how to put my Elixir Knowledge in pract...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
jdumont
Guide Using an iPad for web development can be easily split into two main parts: Setting up the iPad as a thin client Working in a remo...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement