Emacs Setup for Elixir and Vue22 Oct 2019
I had been an avid user of Spacemacs for a long time. However, it could sometimes be time-consuming to get the setup just right in Emacs land. I would like to share some of my configurations here for a satisfactory editing experience for Elixir and Vue.
Language Server Protocol
Language Server Protocol (LSP) was created by Microsoft to define a common standard for providing editor-agnostic code intelligence support. It has become widely popular since its creation.
# In `dotspacemacs/layers`: lsp
The landscape surrounding Vue support on Emacs has been quite confusing.
There had been an old
vue-mode package, which is likely to be the first result on Google. However, the package lacks many features compared to Vetur (a popular VSCode extension) such as autocompletion, and is not being actively developed anymore.
Actually, the new
lsp-mode already ships with a
lsp-vetur.el, which provides support for Vue via
vue-language-server. There is even a non-official Vue layer for Spacemacs that integrates with ESLint and Prettier to provide a complete editing experience similar to Vetur in VSCode. I have been using this layer for a while and it works great. The author has mentioned submitting a MR to Spacemacs to incorporate it into the list of official layers, but hasn’t done so yet. That partly explains why it might take one some digging to find it.
To install the layer:
# Folder for private layers cd ~/.emacs.d/private git clone email@example.com:thanhvg/vue.git # Install the necessary tools manually # vue-language-server is the language server developed by vetur npm install -g eslint prettier vue-language-server
To configure the layer in your
If you want to format the Vue file with prettier automatically upon saving, add the following:
# In dotspacemacs/user-config (add-hook 'vue-mode-hook (lambda () (add-hook 'before-save-hook #'prettier-js nil t)))
You can then enjoy Vetur-like editing capabilities in Emacs. You can find default shortcuts in the layer README.
alchemist.el had been the go-to code intelligence tool for Elixir a couple of years ago. However, its development has stalled, and
elixir-ls, which provides more complete code intelligence out of the box, is currently the recommended IDE server for Elixir.
vscode-elixir-ls downloads and builds
elixir-ls automatically, we can also manually clone and build the project, so that it can be used by Emacs (and other editors), similar to what we did with
git clone firstname.lastname@example.org:elixir-lsp/elixir-ls.git cd elixir-ls mix compile # For example, when the target Elixir version is 1.9.0 mix elixir_ls.release -o release-1.9.0
Since we have several projects with different Elixir versions, I also made sure to compile several versions of
asdf, each corresponding to one of the target projects. One just needs to change the
.tool-versions file in
elixir-ls folder before compiling and releasing again.
lsp-modeprovides support for
elixir-ls already. A recent PR to Spacemacs’ Elixir layer introduced support for
# In `dotspacemacs/layers`: (elixir :variables elixir-backend 'lsp elixir-ls-path "path-to-elixir-ls/release-1.9.0"
To switch between the different versions of
elixir-ls compiled for different Elixir versions, we can make
elixir-ls-path a directory local variable, by having a
.dir-locals.el file in the project root folder:
((elixir-mode (elixir-ls-path . "path-to-elixir-ls/release-1.8.1")))
To add auto formatting on save:
# In `dotspacemacs/user-config`: (add-hook 'elixir-mode-hook (lambda () (add-hook 'before-save-hook #'lsp-format-buffer nil t)))
You could also refer to the comprehensive FAQ on ElixirForum, should you have any questions regarding the setup.
Tweaks and Customizations
On MacOS, you might get an error about exceeding the maximum limit of file descriptors, since
lsp-mode tries to watch the folder for changes. Some workarounds are described in this post. If none of them works, you can also disable the file watching altogether:
(lsp :variables lsp-enable-file-watchers nil )
lsp-mode displays a floating window that displays documentation following your cursor movement, which I found a bit intrusive. You can turn it off by setting
(lsp :variables lsp-ui-doc-enable nil)
Then one can display the documentation with
, h h.
I don’t like the default behavior, where the documentation buffer pops up at the bottom of the editor. After some digging, it turns out that the
*Help* buffer is controlled by
popwin. By adding the following configuration, I was able to view the documentation buffer to the right of the screen:
(setcdr (assoc "*Help*" popwin:special-display-config) '(:dedicated t :position right :stick t :noselect t :width 0.3))