Soft question: LanguageServerProtocol vs TreeSitter

Soft Question. Only relation to Rust is I'm looking at scripting languages written in Rust to embed in a Rust project, and am wondering about LSP / TreeSitter support.

Question: If you have a LSP for a language L, what additional benefits do you get from having a TreeSitter for L ?

My understanding is that LSP is for providing IDE features like auto completion, jump to ref, etc ...; whereas TreeSitter is for incremental parsing.

What I don't understand are things like:

  1. what happens if you feed LSP a source file that does not compile ?

  2. if you already have a LSP, does having a TreeSitter provide any benefits ?

if you already have a LSP, does having a TreeSitter provide any benefits ?
So, the single theoretical benefit I see here is ability to do fast synchronous syntax-dependent features.

LSP is a fundamentally asynchronous interface. it "races" with concurrent edits of user code. This woks surprisingly well for a wide variety of features, but some things, very close to editing proper, would benefit from access to a syntaxtree in process:

  • caret placement after Enter (autoindentation)
  • extend selection
  • line split/join
  • tab navigation through adjacent syntax nodes

They could work via async LSP interface as well, but doing them synchronously feels more natural, and should provide for better UX.

In today's practice, LSP proper actually lacks support for such "blocking caret" operations, except for extend selection, while various TreeSitter employing editors usually have that. So, the LSP way you'd have to also implment custom protocol extensions, while TreeSitter would work out of the box.

what happens if you feed LSP a source file that does not compile ?

Depends on the quality of LSP server. Good ones would not care at all whether the code is valid or not, bad ones would refuse to analyse file even with minor errors.

2 Likes

Thank you for sharing this. This is really insightful and I was completely unaware of it.

This is going way off topic now -- but for "TreeSitter employing editors" is the re-parse synchronous? I.e. is it something like:

loop {
  get user key press;
  modify_buffer();
  TreeSitter::reparse();
  re-adjust buffer based on reparsing();
}

or does the Editor also "race" with TreeSitter ?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.