The following instructions document how to install Lexical after building from source. Some editors, like Visual Studio Code, have the ability to automatically install the latest version of Lexical for you.
Lexical supports the following versions of Elixir and Erlang:
Erlang | Version range | Notes |
---|---|---|
24 | >= 24.3.4.12 |
Might run on older versions; this was the lowest that would compile on arm |
25 | >= 25.0 |
|
26 | >= 26.0.2 |
|
27 | >= 27.0 |
Will use dramatically more memory due to a bug in Erlang's ETS table compression |
Elixir | Version Range | Notes |
---|---|---|
1.13 | >= 1.13.4 |
|
1.14 | all |
|
1.15 | >= 1.15.3 |
1.15.0 - 1.15.2 had compiler bugs that prevented lexical from working |
1.16 | >= 1.16.0 |
|
1.17 | >= 1.17.0 |
Lexical can run projects in any version of Elixir and Erlang that it supports, but it's important to understand that Lexical needs to be compiled under the lowest version of elixir and erlang that you intend to use it with. That means if you have the following projects:
first
: elixir1.14.4
erlang24.3.2
second
: elixir1.14.3
erlang25.0
third
: elixir:1.13.3
erlang25.2.3
Lexical would need to be compiled with Erlang 24.3.2
and Elixir 1.13.3
.
Lexical's prepackaged builds use Erlang 24.3.4.12
and Elixir 1.13.4
First, Install git LFS by following these instructions.
Then, clone the git repository. Do this with
git clone git@github.com:lexical-lsp/lexical.git
Then change to the lexical directory
cd lexical
Then fetch lexical's dependencies
mix deps.get
...and build the project
mix package
If things complete successfully, you will then have a release in your
_build/dev/package/lexical
directory. If you see errors, please file a
bug.
For the following examples, assume the absolute path to your Lexical
source code is /my/home/projects/lexical
.
- Vanilla Emacs with lsp-mode
- Vanilla Emacs with eglot
- Visual Studio Code
- neovim
- LunarVim
- Vim + ALE
- Vim + Vim-LSP
- Helix
- Sublime Text
The emacs instructions assume you're using use-package
, which you
really should be. In your .emacs.d/init.el
(or wherever you put your
emacs configuration), insert the following code:
(use-package lsp-mode
:ensure t
:config
(setq lsp-modeline-code-actions-segments '(count icon name))
:init
'(lsp-mode))
(use-package elixir-mode
:ensure t
:custom
(lsp-elixir-server-command '("/my/home/projects/_build/dev/package/lexical/bin/start_lexical.sh")))
Restart emacs, and Lexical should start when you open a file with a
.ex
extension.
Eglot in Emacs 30 already has built-in support for Lexical after commit 9e0524a8820fbb8fdb155b1ca58919dcfcaffd63.
If you're using Emacs 30 and before that commit, it's recommended to update Emacs, but you can add lexical support in the following way:
(with-eval-after-load 'eglot
(setf (alist-get '(elixir-mode elixir-ts-mode heex-ts-mode)
eglot-server-programs
nil nil #'equal)
(if (and (fboundp 'w32-shell-dos-semantics)
(w32-shell-dos-semantics))
'("language_server.bat")
(eglot-alternatives
'("language_server.sh" "start_lexical.sh")))))
For versions before 30, you can add Eglot support for Lexical in the following way:
(with-eval-after-load 'eglot
(setf (alist-get 'elixir-mode eglot-server-programs)
(if (and (fboundp 'w32-shell-dos-semantics)
(w32-shell-dos-semantics))
'("language_server.bat")
(eglot-alternatives
'("language_server.sh" "start_lexical.sh")))))
If you're using elixir-ts-mode
on Emacs 29, you can add a new entry
for Eglot:
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
`((elixir-ts-mode heex-ts-mode) .
,(if (and (fboundp 'w32-shell-dos-semantics)
(w32-shell-dos-semantics))
'("language_server.bat")
(eglot-alternatives
'("language_server.sh" "start_lexical.sh"))))))
Click on the extensions button on the sidebar, then search for
lexical
, then click install
. By default, the extension will automatically
download the latest version of Lexical.
To change to a local executable, go to Settings -> Extensions -> Lexical
and
type /my/home/projects/lexical/_build/dev/package/lexical/bin
into the text box in
the Server: Release path override
section.
Lexical requires neovim >= 0.9.0
.
In version >= 0.9.0
, the key is to append the custom LS
configuration to
lspconfig, so regardless
of whether you are using mason or others, you can use this
configuration below as a reference:
require('lspconfig').lexical.setup {
cmd = { "my/home/projects/_build/dev/package/lexical/bin/start_lexical.sh" },
root_dir = function(fname)
return util.root_pattern("mix.exs", ".git")(fname) or vim.loop.cwd()
end,
filetypes = { "elixir", "eelixir", "heex" },
-- optional settings
settings = {}
}
If the configuration above doesn't work for you, please try this minimal neovim configuration, It can eliminate other plugin factors.
LunarVim is a neovim configuration package with a lot of goodies built-in, while remaining very configurable.
First, add this to your configuration:
-- Add `elixirls` to `skipped_servers` list
vim.list_extend(lvim.lsp.automatic_configuration.skipped_servers, { "elixirls" })
-- Remove `lexical` from `skipped_servers` list
lvim.lsp.automatic_configuration.skipped_servers = vim.tbl_filter(function(server)
return server ~= "lexical"
end, lvim.lsp.automatic_configuration.skipped_servers)
This is necessary because LunarVim defaults to elixirls
so we must ignore it first. Otherwise you'll have both lexical
and elixirls
running when you open Elixir files.
Remove elixirls
from the lvim.lsp.installer.setup.ensure_installed = { ... }
list so it does not get automatically reinstalled.
Optionally run :LspUninstall elixirls
from within neovim if you don't want to keep elixirls
around.
Then use the same configuration as the one in the neovim section.
ALE includes built-in LSP support for Lexical.
To enable it, you'll need to tell ALE where your Lexical release is located (including
the bin
directory) and add lexical
to the list of enabled Elixir linters.
A good way to do this is to add the following to a ~/.vim/after/ftplugin/elixir.vim
file:
let b:ale_linters = ['lexical', 'mix']
let b:ale_elixir_lexical_release = '/my/home/projects/_build/dev/package/lexical/bin'
That will automatically enable the lexical
and mix
linters for all buffers with
the elixir
file type.
An example of configuring Lexical as the Elixir language server for
Vim-LSP. Uses the newer vim9script syntax but
can be converted to Vim 8 etc (:h vim9script
).
# Loading vim-lsp with minpac:
call minpac#add("prabirshrestha/vim-lsp")
# ...or use your package manager of choice/Vim native packages
# Useful for debugging vim-lsp:
# g:lsp_log_verbose = 1
# g:lsp_log_file = expand('~/vim-lsp.log')
# Configure as the elixir language server
if executable("elixir")
augroup lsp_lexical
autocmd!
autocmd User lsp_setup call lsp#register_server({ name: "lexical", cmd: (server_info) => "{{path_to_lexical}}/lexical-lsp/lexical/_build/dev/package/lexical/bin/start_lexical.sh", allowlist: ["elixir", "eelixir"] })
autocmd FileType elixir setlocal omnifunc=lsp#complete
autocmd FileType eelixir setlocal omnifunc=lsp#complete
augroup end
endif
If you use Vim-LSP-Settings for installing and configuring language servers, you can use the following flag to disable prompts to install elixir-ls:
g:lsp_settings_filetype_elixir = ["lexical"]
For more config, debugging help, or getting vim-lsp to work with ALE, see this example vimrc.
Note: This configuration is applicable for Helix version 23.09 and above.
Add the language server to your ~/.config/helix/languages.toml
config.
In the case that the file doesn't exist yet, you can create a new file at this location.
[language-server.lexical]
command = "/my/home/projects/_build/dev/package/lexical/bin/start_lexical.sh"
[[language]]
name = "elixir"
language-servers = ["lexical"]
[[language]]
name = "heex"
language-servers = ["lexical"]
Lexical can be used with Sublime Text via the LSP-Sublime package, which integrates Language Servers with Sublime Text. If you don't have the LSP-Sublime package installed already, install it with Package Control.
There is currently no language server package specifically for Lexical that works with LSP-Sublime so we'll need to create a custom client configuration.
First, ensure that you have Lexical installed from source correctly and note the full path of the directory with Lexical's executables:
Print the full path of the directory holding the Lexical executables:
cd {directory_you_cloned_lexical_to}/_build/dev/package/lexical/bin/ && pwd
Then, install LSP-Sublime with Package Control if you haven't already.
Next, open up the LSP settings in Sublime. You can do this by invoking the command palette (ctrl/cmd + shift + p
) and selecting Preferences: LSP Settings
.
You'll need to add a key called "clients"
in the top-level LSP.sublime-settings
JSON dictionary that is as follows:
"clients": {
"elixir-lexical": {
"enabled": true,
"command": ["{output_from_pwd_cmd_above}/start_lexical.sh", ""],
"selector": "source.elixir"
}
}
note: you can name elixir-lexical whatever you like, it's just for your own identification
Upon saving the configuration, LSP-Sublime should enable the new elixir-lexical
LSP server. Go into an Elixir file and you should now see elixir-lexical
in the lower left of the status bar. If not, invoke the command palette and select LSP: Enable Language Server Globally/In Project
and it should run.