Skip to content

Latest commit

 

History

History
286 lines (212 loc) · 11.7 KB

README.md

File metadata and controls

286 lines (212 loc) · 11.7 KB

🐽 Bacon Language Server 🐽

Ci Release Crates.io Crates.io License Codecov

Are you tired of rust-analyzer diagnostics being slow?

LSP Server wrapper for the exceptional Bacon exposing textDocument/diagnostic and workspace/diagnostic capabilities.

bacon-ls 🐽 does not substitute rust-analyzer, it's a companion tool that can help with large codebases where rust-analyzer can become slow dealing with diagnostics.

bacon-ls 🐽 does not help with completion, analysis, refactor, etc... For these, rust-analyzer must be running.

Bacon screenshot

NOTE: bacon-ls 0.5+ has breaking changes and will work only with bacon 3.7+. The README for bacon-ls 0.4 can be found here.

See bacon-ls 🐽 blog post: https://lmno.lol/crisidev/bacon-language-server

bacon-ls 🐽 is meant to be easy to include in your IDE configuration.

Bacon gif

Features

  • Read diagnostics from produced by Bacon.
  • Push diagnostics to the LSP client on certain events like saving or files changes.
  • Precise diagnostics positions.
  • Ability to react to changes over document saves and changes that can be configured.
  • Replacement code actions as suggested by clippy.
  • Automatic validation of bacon preferences to ensure bacon-ls can work with them.
  • Start bacon in background based on user preferences (requires bacon 3.8.0).
  • Synchronize diagnostics for all open files.

Limitations

  • Windows support is not tested and probably broken - #10

Installation

VSCode

First, install Bacon.

The VSCode extension is available on both VSCE and OVSX:

Mason.nvim

Both Bacon and Bacon-ls are installable via mason.nvim:

:MasonInstall bacon bacon-ls

Manual

First, install Bacon and bacon-ls 🐽

❯❯❯ cargo install --locked bacon bacon-ls
❯❯❯ bacon --version
bacon 3.8.0  # make sure you have at least 3.8.0
❯❯❯ bacon-ls --version
0.12.0        # make sure you have at least 0.12.0

Nix

Both bacon and bacon-ls can be consumed from their Nix flakes.

Configuration

Configure Bacon export settings with bacon-ls 🐽 export format and proper span support in the bacon preference file. To find where the file should be saved, you can use the command bacon --prefs:

[jobs.bacon-ls]
command = [ "cargo", "clippy", "--tests", "--all-targets", "--all-features", "--message-format", "json-diagnostic-rendered-ansi" ]
analyzer = "cargo_json"
need_stdout = true

[exports.cargo-json-spans]
auto = true
exporter = "analyzer"
line_format = "{diagnostic.level}|:|{span.file_name}|:|{span.line_start}|:|{span.line_end}|:|{span.column_start}|:|{span.column_end}|:|{diagnostic.message}|:|{span.suggested_replacement}"
path = ".bacon-locations"

NOTE: bacon MUST be running to generate the export locations with the bacon-ls job: bacon -j bacon-ls. From bacon-ls 0.10.0, this is done automatically if the option runBaconInBackground is set to true.

The language server can be configured using the appropriate LSP protocol and supports the following values:

  • locationsFile Bacon export filename (default: .bacon-locations).
  • updateOnSave Try to update diagnostics every time the file is saved (default: true).
  • updateOnSaveWaitMillis How many milliseconds to wait before updating diagnostics after a save (default: 1000).
  • updateOnChange Try to update diagnostics every time the file changes (default: true).
  • validateBaconPreferences: Try to validate that bacon preferences are setup correctly to work with bacon-ls (default: true).
  • createBaconPreferencesFile: If no bacon preferences file is found, create a new preferences file with the bacon-ls job definition (default: true).
  • runBaconInBackground: Run bacon in background for the bacon-ls job (default: true)
  • runBaconInBackgroundCommandArguments: Command line arguments to pass to bacon running in background (default "--headless -j bacon-ls")
  • synchronizeAllOpenFilesWaitMillis: How many milliseconds to wait between background diagnostics check to synchronize all open files (default: 2000).

Neovim - LazyVim

vim.g.lazyvim_rust_diagnostics = "bacon-ls"

Neovim - Manual

NeoVim requires nvim-lspconfig to be configured and rust-analyzer diagnostics must be turned off for bacon-ls 🐽 to properly function.

bacon-ls is part of nvim-lspconfig from commit 6d2ae9f and it can be configured like any other LSP server works best when vim.diagnostics.opts.update_in_insert is set to true.

require("lspconfig").bacon_ls.setup({
    init_options = {
        updateOnSave = true 
        updateOnSaveWaitMillis = 1000
        updateOnChange = false
        ...
    }
})

For rust-analyzer, these 2 options must be turned off:

rust-analyzer.checkOnSave.enable = false
rust-analyzer.diagnostics.enable = false

VSCode

The extension can be configured using the VSCode settings interface.

It is very important that rust-analyzer Check On Save and Diagnostics are turned off for bacon-ls to work properly:

  • Untick Rust-analyzer -> general -> Check On Save
  • Untick Rust-analyzer -> diagnostics -> Enable

Coc.nvim

call coc#config('languageserver', {
      \ 'bacon-ls': {
      \   'command': '~/.cargo/bin/bacon-ls',
      \   'filetypes': ['rust'],
      \   'rootPatterns': ['.git/', 'Cargo.lock', 'Cargo.toml'],
      \   'initializationOptions': {
      \     'updateOnSave': v:true, 
      \     'updateOnSaveWaitMillis': 1000,
      \     'updateOnChange': v:false
      \   },
      \   'settings': {}
      \ }
\ })

Helix

Extend your languages.toml with the following:

[[language]]
name = "rust"
language-servers = ["rust-analyzer", "bacon-ls"]

[language-server.rust-analyzer.config]
checkOnSave = { enable = false }
diagnostics = { enable = false }

[language-server.bacon-ls]
command = "bacon-ls"

Troubleshooting

bacon-ls 🐽 can produce a log file in the folder where its running by exporting the RUST_LOG variable in the shell:

Bacon preferences

If the bacon preference are not correct, an error message will be published to the LSP client, advising the user to check the README.

Vim - Neovim

❯❯❯ export RUST_LOG=debug
❯❯❯ nvim src/some-file.rs                 # or vim src/some-file.rs
# the variable can also be exported for the current command and not for the whole shell
❯❯❯ RUST_LOG=debug nvim src/some-file.rs  # or RUST_LOG=debug vim src/some-file.rs
❯❯❯ tail -F ./bacon-ls.log

VSCode

Enable debug logging in the extension options.

❯❯❯ tail -F ./bacon-ls.log

How does it work?

bacon-ls 🐽 reads the diagnostics location list generated by Bacon's export-locations and exposes them on STDIO over the LSP protocol to be consumed by the client diagnostics.

It requires Bacon to be running alongside to ensure regular updates of the export locations.

The LSP client reads them as response to textDocument/diagnostic and workspace/diagnostic.

Thanks

bacon-ls 🐽 has been inspired by typos-lsp.

Roadmap to 1.0 - ✅ done 🕖 in progress 🌍 future

  • ✅ Implement LSP server interface for textDocument/diagnostic and workspace/diagnostic
  • ✅ Manual Neovim configuration
  • ✅ Manual LazyVim configuration
  • ✅ Automatic NeoVim configuration
  • ✅ Add compiler hints to Bacon export locations - Canop/bacon#187 Canop/bacon#188
  • ✅ Support correct span in Bacon export locations - working from bacon 3.7 and bacon-ls 0.6.0
  • ✅ VSCode extension and configuration - available on the release page from 0.6.0
  • ✅ VSCode extension published available on Marketplace
  • ✅ Add bacon-ls to bacon website - Canop/bacon#289
  • ✅ Smarter handling of parsing the Bacon locations file
  • ✅ Faster response after a save event
  • ✅ Replacement code actions
  • ✅ Validate bacon preferences and return an error to the LSP client if they are not compatible with bacon - working from bacon-ls 0.9.0
  • ✅ Create bacon preferences file if not found on disk - working from bacon-ls 0.10.0
  • ✅ Start bacon in background based on user preferences - working from bacon-ls 0.10.0
  • ✅ Synchronize diagnostics for all open files - working from bacon-ls 0.10.0
  • ✅ Support Helix editor - working from bacon-ls 0.12.0
  • ✅ Nix flake support
  • 🌍 Emacs configuration