2015-12-02 14:23:39 +00:00
#+TITLE : Elixir layer
2015-06-10 16:44:30 +00:00
2019-05-07 08:53:56 +00:00
#+TAGS : general|layer|multi-paradigm|programming
2019-05-05 17:26:40 +00:00
2019-08-27 10:21:24 +00:00
[[file:img/elixir.png ]]
2015-06-10 16:44:30 +00:00
2019-05-07 20:05:06 +00:00
* Table of Contents :TOC_5_gh:noexport:
2017-05-22 14:16:12 +00:00
- [[#description ][Description ]]
2017-08-06 02:14:10 +00:00
- [[#features ][Features: ]]
2017-05-22 14:16:12 +00:00
- [[#install ][Install ]]
2019-08-27 10:21:24 +00:00
- [[#layer ][Layer ]]
- [[#choosing-a-backend ][Choosing a backend ]]
- [[#feature-comparison-in-backends ][Feature comparison in backends ]]
2017-05-22 14:16:12 +00:00
- [[#configuration ][Configuration ]]
- [[#flycheck ][Flycheck ]]
2017-05-24 12:37:39 +00:00
- [[#credo ][Credo ]]
2017-05-22 14:16:12 +00:00
- [[#dogma ][Dogma ]]
- [[#mix-compile ][mix compile ]]
2019-08-27 10:21:24 +00:00
- [[#language-server-protocol ][Language server protocol ]]
- [[#debugger ][Debugger ]]
2017-05-22 14:16:12 +00:00
- [[#key-bindings ][Key bindings ]]
2019-08-27 10:21:24 +00:00
- [[#alchemist ][Alchemist ]]
- [[#refcard ][Refcard ]]
- [[#help ][Help ]]
- [[#mix ][Mix ]]
- [[#project ][Project ]]
- [[#evaluation-in-place ][Evaluation in place ]]
- [[#repl-interactions ][REPL interactions ]]
- [[#tests ][Tests ]]
- [[#compile ][Compile ]]
- [[#execute ][Execute ]]
- [[#code-definition-jump ][Code Definition Jump ]]
- [[#hex-packages ][Hex (packages) ]]
- [[#macro-expand ][Macro expand ]]
- [[#formatting ][Formatting ]]
2019-09-06 08:00:51 +00:00
- [[#debugging ][Debugging ]]
2019-08-27 10:21:24 +00:00
- [[#lsp ][LSP ]]
2019-09-30 01:30:53 +00:00
- [[#debugging-1 ][Debugging ]]
2015-06-10 16:44:30 +00:00
* Description
2018-09-19 03:54:47 +00:00
This layer adds support for [[http://elixir-lang.org/ ][Elixir ]].
2015-06-10 16:44:30 +00:00
2017-08-06 02:14:10 +00:00
[[https://github.com/tonini/alchemist.el ][Alchemist ]] brings the Elixir tooling to Emacs and comes with a bunch of features.
2019-08-27 10:21:24 +00:00
[[https://github.com/emacs-lsp/lsp-mode ][Lsp-mode ]] brings IDE like features following Language Server Protocol, through [[https://github.com/JakeBecker/elixir-ls ][elixir-ls ]]
As Alchemist is no longer maintained, elixir-ls is a preferred solution, even though it has less features at the moment.
2017-02-03 09:10:40 +00:00
2017-08-06 02:14:10 +00:00
** Features:
2019-08-31 22:49:15 +00:00
- Powerful IEx integration
- Mix integration
- Compile & Execution of Elixir code
- Inline code evaluation
- Documentation lookup
- Definition lookup
- Smart code completion
- Elixir project management
- Integration with [[http://company-mode.github.io/ ][company-mode ]]
- Flycheck support for mix compile
- Flycheck support for [[https://github.com/rrrene/credo ][credo ]]
- Flycheck support for test results
2019-09-30 01:30:53 +00:00
- Interactive debugger using [[https://github.com/emacs-lsp/dap-mode ][dap-mode ]]
2015-06-10 16:44:30 +00:00
* Install
2019-08-27 10:21:24 +00:00
** Layer
2019-08-31 22:49:15 +00:00
To use this configuration layer, add it to your =~/.spacemacs= . You will need to
add =elixir= to the existing =dotspacemacs-configuration-layers= list in this
file.
2019-08-27 10:21:24 +00:00
** Choosing a backend
2019-08-31 22:49:15 +00:00
To choose a default backend set the layer variable =elixir-backend= :
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
#+BEGIN_SRC elisp
(elixir :variables elixir-backend 'alchemist)
#+END_SRC
2019-08-27 10:21:24 +00:00
2019-09-30 04:49:44 +00:00
Alternatively the =lsp= backend will be automatically chosen if the layer =lsp=
is used and you did not specify any value for =elixir-backend= .
2019-08-31 22:49:15 +00:00
Backend can be chosen on a per project basis using directory local variables
(files named =.dir-locals.el= at the root of a project), an example to use the
=lsp= backend:
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
#+BEGIN_SRC elisp
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
((elixir-mode (elixir-backend . lsp)))
#+END_SRC
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
*Note:* you can easily add a directory local variable with ~SPC f v d~ .
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
The available options are:
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
| symbol | description |
|------------+-------------------|
| 'alchemist | Default |
| 'lsp | elixir-ls package |
2019-08-27 10:21:24 +00:00
*** Feature comparison in backends
2019-08-31 22:49:15 +00:00
| features | Alchemist | Lsp |
|------------------------------------+-----------+-----|
| Powerful IEx integration | yes | no |
| Mix integration | yes | no |
| Compile & Execution of Elixir code | yes | no |
| Inline code evaluation | yes | no |
| Documentation lookup | yes | yes |
| Definition lookup | yes | yes |
| Smart code completion | yes | yes |
| Elixir project management | yes | no |
| Integration with =company-mode= | yes | yes |
| Flycheck support | yes | yes |
2015-06-10 16:44:30 +00:00
2016-06-01 01:34:51 +00:00
* Configuration
2016-06-01 01:51:49 +00:00
** Flycheck
2016-06-01 02:23:18 +00:00
*Note:* since flycheck checkers are slow, the checks are enabled only at save
time.
2017-05-24 12:37:39 +00:00
*** Credo
You need to install [[https://github.com/rrrene/credo ][credo ]] into your project. For this, add the following snippet
to dependencies of your project (in file =mix.exs= ):
2018-01-27 14:01:18 +00:00
#+BEGIN_SRC elixir
2018-09-19 03:54:47 +00:00
{:credo, "~> 0.5", only: [:dev, :test]}
2017-05-24 12:37:39 +00:00
#+END_SRC
Then run in your shell:
#+BEGIN_SRC shell
2018-09-19 03:54:47 +00:00
$ mix deps.get
2017-05-24 12:37:39 +00:00
#+END_SRC
For more info about mix [[http://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html ][see ]].
2019-05-26 20:58:52 +00:00
You can tell flycheck-credo to call credo with the '--strict' argument.
2017-05-24 12:37:39 +00:00
#+BEGIN_SRC elisp
2018-09-19 03:54:47 +00:00
(setq flycheck-elixir-credo-strict t)
2017-05-24 12:37:39 +00:00
#+END_SRC
2017-03-24 02:16:24 +00:00
*** Dogma
2017-03-26 17:22:43 +00:00
In order to lint your code, you also need to install [[https://github.com/lpil/dogma ][dogma ]] into your project.
For this, add the following snippet to the dependencies in your =mix.exs= file:
2018-01-27 14:01:18 +00:00
#+BEGIN_SRC elixir
2018-09-19 03:54:47 +00:00
{:dogma, "~> 0.1", only: [:dev]}
2017-03-26 17:22:43 +00:00
#+END_SRC
Then run in your shell:
2017-03-24 02:16:24 +00:00
#+BEGIN_SRC shell
2018-09-19 03:54:47 +00:00
$ mix deps.get
2017-03-24 02:16:24 +00:00
#+END_SRC
2016-06-01 01:51:49 +00:00
*** mix compile
2016-06-01 01:34:51 +00:00
*Important:*
2017-02-03 09:10:40 +00:00
2016-06-08 03:51:33 +00:00
Elixir compiler is based on macros and can execute arbitrary during compilation.
Therefore Spacemacs disable flycheck compilation checker by default.
2017-02-03 09:10:40 +00:00
To enable flycheck support for compilation errors *globally* the variable
2016-06-08 03:51:33 +00:00
=elixir-enable-compilation-checking= can be set explicitly to =t= in your
dotfile but it is not recommended to do so because of the limitation described
above.
Instead you should use directory local variables in order to enable the flycheck
checker only for certain projects. Directory local variables are stored in a
2018-01-20 14:42:28 +00:00
file named =.dir-locals.el= usually at the root of a project. To easily add a
2016-06-08 03:51:33 +00:00
directory local variable use the key binding ~SPC f v d~ then choose the
2017-02-03 09:10:40 +00:00
=elixir-mode= and the variable name =elixir-enable-compilation-checking= with a
2018-01-20 14:42:28 +00:00
value of t. The result is a new file =.dir-locals.el= with the following
2016-06-08 03:51:33 +00:00
contents:
#+BEGIN_SRC elisp
2018-09-19 03:54:47 +00:00
;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
2016-06-08 03:51:33 +00:00
2018-09-19 03:54:47 +00:00
((elixir-mode
(elixir-enable-compilation-checking . t)))
2016-06-08 03:51:33 +00:00
#+END_SRC
2016-06-01 01:34:51 +00:00
Spacemacs marks the variable =elixir-enable-compilation-checking= as safe so
2019-05-26 20:58:52 +00:00
Emacs won't ask you if the variable is safe whenever an elixir file is opened.
2016-06-01 01:34:51 +00:00
2016-06-08 03:51:33 +00:00
Remember that you can verify the flycheck checkers status with ~SPC e v~ .
2016-06-01 01:34:51 +00:00
2019-08-27 10:21:24 +00:00
** Language server protocol
2019-08-31 22:49:15 +00:00
The =lsp= backend uses [[https://github.com/JakeBecker/elixir-ls ][elixir-ls ]] as its language server implementation
Clone the project to your system and follow the building instructions [[https://github.com/JakeBecker/elixir-ls#building-and-running ][here ]]
Or the lsp-elixir [[https://github.com/elixir-lsp/elixir-ls ][fork ]], which is actively maintained as well
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
set the =elixir-ls-path= to the release folder of =elixir-ls= in .spacemacs =dotspacemacs/user-config=
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
#+BEGIN_SRC elisp
(setq elixir-ls-path "*path to folder* /elixir-ls/release")
#+END_SRC
or in the layer definition
#+BEGIN_SRC elisp
2019-09-03 17:38:36 +00:00
(elixir :variables elixir-backend 'lsp elixir-ls-path "*path to folder* /elixir-ls/release")
2019-08-31 22:49:15 +00:00
#+END_SRC
by default =elixir-ls-path= is equal to ="~/elixir-ls/release"=
2019-08-27 10:21:24 +00:00
** Debugger
2019-08-31 22:49:15 +00:00
For =lsp= backend only
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
=lsp= backend supports debugging of your elixir project through [[https://github.com/emacs-lsp/dap-mode ][dap ]]
simply follow [[https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Btools/dap#layer-installation ][dap layer ]] installation and configuration instructions
as well as make sure to read this elixir-ls [[https://github.com/elixir-lsp/elixir-ls#debugger-support ][debugger support note ]]
2019-08-27 10:21:24 +00:00
2015-06-10 16:44:30 +00:00
* Key bindings
2019-08-27 10:21:24 +00:00
** Alchemist
*** Refcard
2019-08-31 22:49:15 +00:00
You find and overview of all the key bindings on the [[https://github.com/tonini/alchemist.el/blob/master/doc/alchemist-refcard.pdf ][Alchemist-Refcard ]].
2019-08-27 10:21:24 +00:00
*** Help
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+-------------------------------------|
| ~SPC m h :~ | Run custom search for help |
| ~SPC m h h~ | Show help of the current expression |
| ~SPC m h H~ | Toggle through search history |
| ~SPC m h r~ | Show help for current region |
2019-08-27 10:21:24 +00:00
*** Mix
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+------------------------------------------------------------|
| ~SPC m m :~ | Prompt for a =mix= command |
| ~SPC m m c~ | Compile the whole application |
| ~SPC m m h~ | Show help for a specific =mix= command |
| ~SPC m m x~ | Run the given expression in the Elixir application context |
2019-08-27 10:21:24 +00:00
*** Project
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+------------------------------------------------------------|
| ~SPC m g t~ | Toggle between a file and its tests in the current window. |
| ~SPC m g T~ | Toggle between a file and its tests in other window. |
2019-08-27 10:21:24 +00:00
*** Evaluation in place
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+-----------------------------------------|
| ~SPC m e b~ | Evaluate buffer |
| ~SPC m e B~ | Evaluate buffer and insert result |
| ~SPC m e l~ | Evaluate current line |
| ~SPC m e L~ | Evaluate current line and insert result |
| ~SPC m e r~ | Evaluate region |
| ~SPC m e R~ | Evaluate region and insert result |
2019-08-27 10:21:24 +00:00
*** REPL interactions
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+-----------------------------------------------------------------|
| ~SPC m s c~ | Compiles the current buffer in the IEx process. |
| ~SPC m s i~ | Start an =iex= inferior process |
| ~SPC m s I~ | Start an IEx process with mix (=iex -S mix=) |
| ~SPC m s l~ | Send current line to REPL buffer |
| ~SPC m s L~ | Send current line to REPL buffer and focus it in =insert state= |
| ~SPC m s m~ | Reloads the module in the current buffer in your IEx process |
| ~SPC m s r~ | Send region to REPL buffer |
| ~SPC m s R~ | Send region to REPL buffer and focus it in =insert state= |
2019-08-27 10:21:24 +00:00
*** Tests
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+---------------------------------------------------------------------------------------|
| ~SPC m g t~ | Open the test file for current buffer |
| ~SPC m t a~ | Run all the tests |
| ~SPC m t b~ | Run all the tests from current buffer |
| ~SPC m t B~ | Run all the tests from current file; if test file not found, after confirm, create it |
| ~SPC m t f~ | Choose test file to run |
| ~SPC m t t~ | Run test under point |
| ~SPC m t r~ | Rerun the last test |
| ~SPC m t n~ | Jump to next test |
| ~SPC m t N~ | Jump to previous test |
| ~SPC m t s~ | Run stale tests (~mix test --stale~) |
| ~SPC m t R~ | Toggle test report window |
| ~SPC m t F~ | Open project test directory and list all test files. |
2019-08-27 10:21:24 +00:00
*** Compile
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+----------------------------------------------------|
| ~SPC m c :~ | Run a custom compile command with =elixirc= |
| ~SPC m c b~ | Compile the current buffer with elixirc. =elixirc= |
| ~SPC m c f~ | Compile the given filename with =elixirc= |
2019-08-27 10:21:24 +00:00
*** Execute
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+--------------------------------------------|
| ~SPC m x :~ | Run a custom execute command with =elixir= |
| ~SPC m x b~ | Run the current buffer through =elixir= |
| ~SPC m x f~ | Run =elixir= with the given filename |
2019-08-27 10:21:24 +00:00
*** Code Definition Jump
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+----------------------------------------------------|
| ~SPC m g g~ | Jump to the elixir expression definition at point. |
| ~SPC m .~ | Jump to the elixir expression definition at point. |
| ~SPC m g b~ | Pop back to where ~SPC m g g~ was last invoked. |
| ~SPC m ,~ | Pop back to where ~SPC m g g~ was last invoked. |
| ~SPC m g n~ | Jump to next symbol definition |
| ~SPC m g N~ | Jump to previous symbol definition |
| ~SPC m g j~ | Choose which symbol definition to jump to |
2019-08-27 10:21:24 +00:00
*** Hex (packages)
2019-08-31 22:49:15 +00:00
Hex is the package manager for Elixir & Erlang ecosystem. See [[https://hex.pm ]].
2019-08-27 10:21:24 +00:00
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+----------------------------------------------------------|
| ~SPC m X i~ | Display Hex package information for the package at point |
| ~SPC m X r~ | Display Hex package releases for the package at point |
| ~SPC m X R~ | Display Hex package releases for a certain package |
| ~SPC m X I~ | Display Hex package info for a certain package |
| ~SPC m X s~ | Search for Hex packages |
2019-08-27 10:21:24 +00:00
*** Macro expand
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+-----------------------------------------------------------------------------------|
| ~SPC m o l~ | Macro expand once the Elixir code on the current line |
| ~SPC m o L~ | Macro expand once the Elixir code on the current line and insert the result |
| ~SPC m o k~ | Macro expand completely the Elixir code on the current line |
| ~SPC m o K~ | Macro expand completely the Elixir code on the current line and insert the result |
| ~SPC m o i~ | Macro expand once the Elixir code on marked region |
| ~SPC m o I~ | Macro expand once the Elixir code on marked region once and insert the result |
| ~SPC m o r~ | Macro expand completely the Elixir code on marked region |
| ~SPC m o R~ | Macro expand completely the Elixir code on marked region and insert the result |
2019-08-27 10:21:24 +00:00
*** Formatting
2019-08-31 22:49:15 +00:00
| Key binding | Description |
|-------------+---------------------------|
| ~SPC m =~ | Format the current buffer |
2019-09-06 08:00:51 +00:00
*** Debugging
| Key binding | Description |
|-------------+---------------------------|
| ~SPC m d b~ | Toggle IEx.pry breakpoint |
2019-08-27 10:21:24 +00:00
** LSP
2019-08-31 22:49:15 +00:00
You find and overview of all the key bindings on the [[https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Btools/lsp#key-bindings ][lsp layer description ]].
2019-09-30 01:30:53 +00:00
*** Debugging
Using the =dap= layer you'll get access to all the DAP key bindings, see the
complete list of key bindings on the [[https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Btools/dap#key-bindings ][dap layer description ]].