โ—index ๐Ÿฝbacon-ls.md ๐Ÿท๏ธtags ๐Ÿ‘คabout

๐Ÿฝ Bacon Language Server

If you, like, me, spend a lot of my development time doing Rust ๐Ÿฆ€ inside Neovim and is not satisfied by rust-analyzer performance with medium to large sized repositories, you are in the right place ๐Ÿคฉ.

Disabling rust-analyzer.diagnostic and rust-analyzer.checkOnSave, the experience becomes much more snappy, but we loose LSP diagnostics. Here comes Bacon to the rescue.. Bacon is a wrapper around cargo that watches the crate we are developing, runs the target command (build, test, clippy, etc..) when there are changes and reports the diagnostics in a structured view in the bacon TUI. This little tool is also able to keep the cargo diagnostics up to date in a file and in a format we can parse.

๐Ÿฝ bacon-ls

bacon-ls is the companion to Bacon, reading the diagnostics from the Bacon export file and exposing them via the Language Server Protocol over standard input.

So how does developing with bacon-ls looks like?

First of all, bacon and bacon-ls must be installed on the system:

โฏ_bashโ€บ1 lines
  1โฏโฏโฏ cargo install --locked bacon bacon-ls

We need to disable a couple of rules in rust-analyzer configuration. Depending on your editor, the instructions could differ, but for Neovim LSP, it is roughly like this:

๐ŸŒ™luaโ€บ6 lines
  1default_settings = {
  2    ["rust-analyzer"] = { 
  3        diagnostics = { enable = false },
  4        checkOnSave = { enable = false },
  5    }
  6}

bacon-ls needs to be added to the available servers for nvim-lspconfig. Unfortunately this is still manual, but I am slowly adding the support upstream:

  • โœ… #3160 Add bacon-ls to nvim-lspconfig
  • ๐Ÿ•– #5774 Add bacon-ls to mason-nvim
  • ๐Ÿ•– #186 Include compiler hints in Bacon locations
  • ๐Ÿ•– #3132 Add bacon-ls to LazyVim Rust extras
๐ŸŒ™luaโ€บ11 lines
  1local configs = require("lspconfig.configs")
  2if not configs.bacon_ls then
  3    configs.bacon_ls = {
  4        default_config = {
  5            cmd = { "bacon-ls" },
  6            root_dir = require("lspconfig").util.root_pattern(".git"),
  7            filetypes = { "rust" },
  8        },
  9    }
 10end
 11lspconfig.bacon_ls.setup({ autostart = true })

And now you are ready to go!

Neovim should look like this:

neovim bacon img

If you like the look and feel, you can check my Neovim configurations and this blog post ๐Ÿ˜€.

Live diagnostics

With a properly configured client, the experience is pretty snappy. I keep nvim-lspconfig setting update_in_insert = true for very smooth diagnostic icons transitions.

neovim bacon gif

If you are interested in how the LSP server is designed and implemented, I'll shortly release a new post about it!

bacon-ls is open source and can be found on Github.

:discuss share / comment on Mastodon โ†’