The reason it’s done like that, I think, is because Microsoft’s flagship editor focuses on LSP heavily, and because LSP is their own child, I feel that they simply want to use it, instead of other, often more appropriate solutions.
Well kinda, the point is that if you have LSPs which can provide all that then all the relevant smarts are in the LSP which (you might hope or assume) is best-of-class and has all the community focus. That means the editor gets all of that for free without needing to implement anything other than the LSP protocol (obviously “anything other than” does a lot of lifting here).
It should also be noted that treesitter was created after LSP.
I did try switching to eglot but I just failed to configure it for a monorepo I am working on. We use npm workspaces and eglot just didn’t want to work with them. I did try several solutions online including configuring project.el to no avail. For one project eglot did work well though. Emacs felt way smoother with it.
It is worth mentioning that I am Emacs configuration noob so if changes don’t work I just fallback to Doom’s defaults.
That will be a good way to convince your boss: “Hey, I know we have a monorepo, but I’ve been trying to switch from lsp-mode to eglot, and eglot doesn’t work well on monorepos, so maybe can we change the architecture?”
My understanding was that the language major mode was ideally supposed to configure eglot for optimal use for that language, just as it is supposed to configure tree sitter. It feels like cider could do quite a bit with its knowledge of the language and which other features are being used (nrepl) to smooth things over for its users here.
If the major mode has to resort to hacks, then it is a deficiency with eglot that needs to be addressed.
I know that this case is probably not as common with other languages, and Clojure is kinda special because it has two separate sources of truth that don’t often line up.
I remember reading an article about Erlang that said “Erlang programmers are worrying about the concurrency problems you wish you had” and this gives me the same vibes; you can’t even have a problem like this in most languages because the idea of connecting to a remote server and having all the same tooling there is nearly inconceivable for most.
My employer disabled remote repls a few years ago, so I haven’t encountered any of the problems described in this article; I use eglot extensively for Clojure and Fennel. Similar to the article, for me by far the most appealing are the live-linting and the ability to find all references. (Finding the definition is already very easy to implement using REPL-based tooling; I’ve probably written it five different times, but finding usages is much, much harder.) Using it for Clojure can be pretty janky compared to Fennel because it doesn’t even perform macroexpansion; I’m surprised the article doesn’t mention that.
Same as with lsp-mode I disable most things I don’t need LS to do, like syntax highlighting, formatting, hovering, and folding. I, personally, don’t agree with the decision to put syntax highlighting, formatting and folding into the language server to begin with - requiring to send data to the server in order to do these things is bananas.
Is syntax highlighting actually being handled by the LSP spec? IIUC, documentHighlightProvider is used to highlight all references of the token under the cursor, rather than for syntax highlighting. Or did I misunderstand?
I was gonna ask what this buys over e.g. tree-sittter (or the traditional regexp-based highlighters), then I read this, so bascically anything that requires dynamically available information can only be done via LSP. Could be quite useful in some cases, but also overlap a lot with tree-sitter in most other ones.
Well kinda, the point is that if you have LSPs which can provide all that then all the relevant smarts are in the LSP which (you might hope or assume) is best-of-class and has all the community focus. That means the editor gets all of that for free without needing to implement anything other than the LSP protocol (obviously “anything other than” does a lot of lifting here).
It should also be noted that treesitter was created after LSP.
I did try switching to eglot but I just failed to configure it for a monorepo I am working on. We use npm workspaces and eglot just didn’t want to work with them. I did try several solutions online including configuring project.el to no avail. For one project eglot did work well though. Emacs felt way smoother with it.
It is worth mentioning that I am Emacs configuration noob so if changes don’t work I just fallback to Doom’s defaults.
Honestly, life is easier that way. Doom’s defaults are great.
Monorepos have their disadvantages. This is a good chance to split them.
That will be a good way to convince your boss: “Hey, I know we have a monorepo, but I’ve been trying to switch from lsp-mode to eglot, and eglot doesn’t work well on monorepos, so maybe can we change the architecture?”
Well, you could try!
Thanks but I actually prefer the monorepo setup we have.
My understanding was that the language major mode was ideally supposed to configure eglot for optimal use for that language, just as it is supposed to configure tree sitter. It feels like cider could do quite a bit with its knowledge of the language and which other features are being used (nrepl) to smooth things over for its users here.
If the major mode has to resort to hacks, then it is a deficiency with eglot that needs to be addressed.
I remember reading an article about Erlang that said “Erlang programmers are worrying about the concurrency problems you wish you had” and this gives me the same vibes; you can’t even have a problem like this in most languages because the idea of connecting to a remote server and having all the same tooling there is nearly inconceivable for most.
My employer disabled remote repls a few years ago, so I haven’t encountered any of the problems described in this article; I use eglot extensively for Clojure and Fennel. Similar to the article, for me by far the most appealing are the live-linting and the ability to find all references. (Finding the definition is already very easy to implement using REPL-based tooling; I’ve probably written it five different times, but finding usages is much, much harder.) Using it for Clojure can be pretty janky compared to Fennel because it doesn’t even perform macroexpansion; I’m surprised the article doesn’t mention that.
Is syntax highlighting actually being handled by the LSP spec? IIUC,
documentHighlightProvideris used to highlight all references of the token under the cursor, rather than for syntax highlighting. Or did I misunderstand?It is: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_semanticTokens
Good to know, thanks!
I was gonna ask what this buys over e.g. tree-sittter (or the traditional regexp-based highlighters), then I read this, so bascically anything that requires dynamically available information can only be done via LSP. Could be quite useful in some cases, but also overlap a lot with tree-sitter in most other ones.
Is there a way to tweak which is used when?