Lexical - A Language Server for Elixir

No worries! These are good libraries to have in your toolbelt.

We know when we might have a use case for a space and time efficient membership test where storing things explicitly would too expensive.

I did see the Elixir water park presentation where they used a bloom filter to record health messages on a per patient basis where every patient was represented as an in memory Elixir process mirrored across many datacenters in 5 regions with no backend persistent storage, just memory only, and doing hot code upgrades over years. Using a bloom filter enabled memory efficient and fast testing for any combination of messages those patient processes had “witnessed” to quickly evaluate business rules and co-ordinate patient care. It’s a brilliant talk.

5 Likes

I’ve just installed lexical and gave it a very quick try, and I must say I like what I see so far. It seems to react a lot faster than elixir-ls.
So I’ll use this as my default lsp for now.

Nice work!

2 Likes

@scohen Is it safe to use Lexical with it at the tip of the main branch, or should we stick to using the latest release / tag?

Thank you!

We try to keep main safe for people to use. I’m using it now, and I don’t think it has any issues.

1 Like

Cool, thank you.

Well, now I have the solve the problem that my LunarVim is using both ElixirLS and Lexical at the same time (visible in the bottom status line) even though I disabled it from everywhere I can see and removed it from the list of servers that have to be ensured are installed…

Even doing :LspUninstall elixirls and then restarting NeoVim / LunarVim installs it again. Oh well, I’ll fight with that next apparently.

Looking to check this out but when I follow the instruction on github for installation, running git clone git@github.com:lexical-lsp/lexical.git returns

$ git clone git@github.com:lexical-lsp/lexical.git
Cloning into ‘lexical’…
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.

What am I doing wrong?

Doing the same thing works for me. If that still doesn’t work, maybe try the https url instead of the ssh one.

yeah that worked. thanks.

1 Like

git@… requires you have permissions to push IIRC. Just use the https schema, it’s for read-only access.

1 Like

Apologies for polluting the thread with NeoVim / LunarVim details, just thought it could be useful for people.

If not, we can ask moderators to move this comment.

So, here’s how I made lexical work for me without LunarVim working with ElixirLS at all (because it normally would reinstall it if you uninstall it, and it will still use it). This Lua code made it all work (:bangbang:though the absolute path to lexical must be changed if anyone copy-pastes this :bangbang:):

-- (1) add `elixirls` to `skipped_servers` list
-- (2) remove `lexical` from `skipped_servers` list
vim.list_extend(lvim.lsp.automatic_configuration.skipped_servers, { "elixirls" })
lvim.lsp.automatic_configuration.skipped_servers = vim.tbl_filter(function(server)
  return server ~= "lexical"
end, lvim.lsp.automatic_configuration.skipped_servers)

-- (3) configure `lexical`
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")

local lexical_config = {
  filetypes = { "elixir", "eelixir", "heex", "surface" },
  cmd = { "/Users/dimi/bin/lexical/_build/dev/package/lexical/bin/start_lexical.sh" },
  settings = {},
}

if not configs.lexical then
  configs.lexical = {
    default_config = {
      filetypes = lexical_config.filetypes,
      cmd = lexical_config.cmd,
      root_dir = function(fname)
        return lspconfig.util.root_pattern("mix.exs", ".git")(fname) or vim.loop.os_homedir()
      end,
      -- optional settings
      settings = lexical_config.settings,
    },
  }
end

lspconfig.lexical.setup({})

1 Like

Just did some brief work with Lexical running with ALE in Vim. Small project so not really pushing performance, but it does seem to be faster with code completion than elixir-ls. For some reason though I’m not seeing the error highlighting. I think that was being handled by credo in my previous setup. Should I need to use both credo and lexical?

If you didn’t see any highlighting, it’s likely that the lexical project node didn’t start properly. Please check the “.lexical/lexical.log” file.

One significant difference between lexical’s error highlighting and other language servers is that it provides real-time feedback while you’re editing. Similar to the video below, you can see some yellow and red highlights() without any saving action from me.

BTW, detailed information such as “undefined variable…” is set to be hidden by default on the client side, and I reveal them by using a shortcut.

I have switched to Lexical since the first announce. Everything I expect from it works really fine and rapidly with every project. I use Lexical from main git branch. My environment is GNU Emacs 29.1, eglot-1.15, erlang-26.1.2, elixir-1.15.7. Thank you very much, @scohen!

4 Likes

Has anyone gotten Lexical to work with Sublime Text or is a sanctioned installation method planned?

Why don’t you submit a documentation PR for lexical’s detailed instructions README? This could be helpful to others!

1 Like

I’d love for this to happen. Lexical is just a language server, and presently has no configuration, so it shouldn’t be particularly hard to get it working, at least in MacOS and Linux.

It looks like this guide along with Lexical’s own installation docs should get things up and running!

IGNORE. Had a problem with my ALE settings (it was being disabled on startup for some reason). All is good now. Lexical seems to have a warmup initially that is noticeable but after that error highlighting is nearly real time (at least for someone typing as slowly as I do).

=======================================
I actually think Lexical is not running in vim with ALE for me. I’ve got the file .vim/after/ftplugin/elixir.vim with the contents:

let b:ale_linters = ['lexical', 'mix']
let b:ale_elixir_lexical_release = '/my/home/projects/_build/dev/package/lexical/bin'

But no .lexical/lexical.log and no highlighting or auto-completion.