Stream: t-compiler/wg-rls-2.0

Topic: lsp-server framework


Maxim Kurnikov (Apr 27 2020 at 11:17, on Zulip):

Hi. I'm working on a language server for Move language for libra
https://github.com/libra/libra/tree/master/language/move-lang
https://github.com/dfinance/move-language-server

I'm using the rust-analyzer code as a reference on how to structure the project and obviously using lsp-server for connections and handshake. I borrowed multithreading architecture / ra_vfs / WorldState concepts too.
I'm wondering, wouldn't it be great to extract more code into lsp-server, make it smth like an lsp-framework? Most of the code in the main_loop could be reused, on_request could be converted into a trait with all those on_completion, on_status_check methods.

matklad (Apr 27 2020 at 11:18, on Zulip):

I'll reply later today (well, if the amoutn of work I absolutely need to to today is less than today), but you might want to talke a look at tower-lsp-server library as well

matklad (Apr 28 2020 at 09:05, on Zulip):

So, I thought about extracting lsp-framework a while back, and decided against it, for two reasons, one stupid technical, and one real one.

The technical one is that the framework would have to use lsp_types library, and proper semver versioning of it is complicated (what is semver compatible in TS is breaking in Rust).

The real one is that I think there's a great benefit in running the main event loop yourself. It's a very complicated bit with respect to runtime behavior, so being able to see / dbg! everything yourself is hugely beneficial

matklad (Apr 28 2020 at 09:05, on Zulip):

that's why lsp-server is designed as a library, and doesn't really do much

matklad (Apr 28 2020 at 09:07, on Zulip):

The vfs bit could conievably be extracted into a separate library, but unforutantely it's been in a "design is broken, badly needs rewrite" state for about a year now :D

matklad (Apr 28 2020 at 09:08, on Zulip):

the tower-lsp thing is a framework, so it's a good way to check if my gut feeling about framework vs library here is wrong

Coenen Benjamin (Apr 28 2020 at 09:13, on Zulip):

The technical one is that the framework would have to use lsp_types library, and proper semver versioning of it is complicated (what is semver compatible in TS is breaking in Rust). Why not generate either Rust or Ts part to be sure to be sync ? I don't know the context so it could be a dumb question :p

matklad (Apr 28 2020 at 09:15, on Zulip):

There's no source to generate from :-(

The spec is literally a markdown document. There's a publish a JSON schema request sitting for ages

Coenen Benjamin (Apr 28 2020 at 09:17, on Zulip):

Oh god :(

Maxim Kurnikov (Apr 28 2020 at 11:59, on Zulip):

The real one is that I think there's a great benefit in running the main event loop yourself. It's a very complicated bit with respect to runtime behavior, so being able to see / dbg! everything yourself is hugely beneficial

I don't quite understand this one. While I've been working on move-language-server, I had to reimplement (copy-paste with modifications) lots of code from the rust-analyzer crate in the RA project.

I trust your expertise, so I believe that the current design of lsp server in RA is optimal. It would be great not to reimplement all this stuff for every language server, and just to focus on the relevant parts from the beginning. But if one would like to improve on top of it in any way, it's just the same copy-paste as in the no-framework case.

Framework lowers barrier to entry, in my opinion.

Maxim Kurnikov (Apr 28 2020 at 12:03, on Zulip):

I've looked at tower-lsp. It's an example of the framework, yes, but it's

  1. async-based (which doesn't make much sense in case of lsp, as there's won't be a lot of threads anyway)
  2. it's not tied to rust-analyzer in any way. If the hypothetical lsp-framework could exist, it would be awesome for it to share codebase with rust-analyzer.
Maxim Kurnikov (Apr 28 2020 at 12:05, on Zulip):

Thanks for the answers!
And thank you very much for rust-analyzer, it's an amazing tool, I've learn't lots and lots of stuff from the implementation! And thanks for the https://www.youtube.com/watch?v=Oy_VYovfWyo too=)

peter (Apr 28 2020 at 23:31, on Zulip):

if i can ask a silly question, i am looking at setting up a language server and was also looking at lsp-server — when i run this example https://github.com/rust-analyzer/lsp-server/blob/master/examples/goto_def.rs, which sets up a connection over stdio, how do i send a request to the server?

do i just paste e.g. the initialize request listed in the comments in that file, into stdin and hit enter? (when i do that i get a crossbeam::channel::RecvError).

matklad (May 01 2020 at 09:58, on Zulip):

Driving the server directly from the command line is super painful, as you need correct ContentLenght headers

matklad (May 01 2020 at 09:59, on Zulip):

The best way is to either drive programmatically via channels, or drive vie some existing client, like VS Code

matklad (May 01 2020 at 10:01, on Zulip):

I don't quite understand this one. While I've been working on move-language-server, I had to reimplement (copy-paste with modifications) lots of code from the rust-analyzer crate in the RA project.

@Maxim Kurnikov for example here we do some introspection for the single turn of the event loop, which would be awkward to do if the loop was hidden inside the framework

matklad (May 01 2020 at 10:02, on Zulip):

In general, being able to insert printf into arbitrary state of request processing is something I've found useful

Last update: Sep 30 2020 at 17:00UTC