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

๐Ÿฝ bacon-ls - LSP in Rust

What is the experience of building a Language Server in Rust ๐Ÿฆ€ you ask? Without any prior knowledge of the protocol?

Well, it not bad.. It requires basic familiarity with the tokio asynchronous ecosystem and with Rust async in general, but you can get something done in a couple of days of work.

bacon-ls depends on tower-lsp for the STDIN/STDOUT/HTTP communication and on tokio for the asynchronous runtime and the foundational LSP types are provided by lsp-types.

Bacon writes a file with a diagnostic per line and bacon-ls requires a specific format that can be parsed:

โฏ_bashโ€บ1 lines
  1line_format = "{kind}:{path}:{line}:{column}:{message}{context}"

Since Bacon supports (from #5d95852) the message {context}, any other line captured in relation to the current diagnostic, bacon-ls can emit the whole diagnostic, including hints from clippy and cargo.

Diagnostics and Language Servers

Language clients can request textDocument/diagnostic and workspace/diagnostic capabilities, expecting the list of diagnostics for the current file or for the whole workspace. The diagnostic carries metadata, such has the line:column of the diagnostic, URL, message and so on..

I think you see where this is going..

bacon-ls reads Bacon diagnostics and exposes them on the LSP interface to clients requesting it ๐Ÿš€!

Some some Rust please

tower-lsp is implemented more or less how you would expect it. It exports a LanguageServer trait the user can implement to expose the capabilities for their use-case.

For bacon-ls, we only need to implement 3 methods:

Initialize the LSP server

The LSP server must be initialized so that it can returns the list of available capabilities to clients.

initialize

Fetch diagnostic from Bacon

All the rest of the LSP server implementation is using this function to fetch them diagnostics from Bacon.

bacon-diagnostic

Implement textDocument/diagnostic

This method is what is being called by the LSP client when it wants to retrieve the current document diagnostic.

document-diagnostic

Implement workspace/diagnostic

This method is what is being called by the LSP client when it wants to retrieve the whole workspace diagnostic.

workspace-diagnostic

Tower service

The LSP server is implemented as a Tower service and only requires a structure implementing the LanguageServer. Tower will take care of the LSP server process lifecycle, clients handling and so on.

tower-service

Done ๐Ÿš€

I was not expecting this do be so easy and well integrated with Rust!

:discuss share / comment on Mastodon โ†’