๐ฝ 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:
1
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
- Implement textDocument/diagnostic
- Implement workspace/diagnostic
Initialize the LSP server
The LSP server must be initialized so that it can returns the list of available capabilities to clients.
Fetch diagnostic from Bacon
All the rest of the LSP server implementation is using this function to fetch them diagnostics from Bacon.
Implement textDocument/diagnostic
This method is what is being called by the LSP client when it wants to retrieve the current 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.
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.
Done ๐
I was not expecting this do be so easy and well integrated with Rust!




