1. 20
  1.  

  2. 18

    From the License Agreement:

    You may install and use any number of copies of the software only with Microsoft Visual Studio, Visual Studio for Mac, Visual Studio Code, Azure DevOps, Team Foundation Server, and successor Microsoft products and services (collectively, the “Visual Studio Products and Services”) to develop and test your applications

    Nice to see that Microsoft has gone full circle with LSP from proposing to solve the NM problem, to admitting that it is NM+M to now saying N = 1, and it’s VSCode. Guess that is just another way to approach the issue, just instead of the famous EEE this is Create, Extend, Extinguish.

    1. 5

      In what way is LSP NM+M? It still is N+M in my book…

      1. 3

        Not sure what zge meant, but a fun observation about M+N is that VS Code itself has a dedicated plugin for every language. There’s no universal LSP support in VS Code per se. To use Rust, you need one extension, to use Dart, you need another, etc. These extensions are not trivial.

        1. 4

          I wrote a language server for a niche language and wrote an extension for it for VS Code. The bare extension was very easy to write: I copy pasted their example code and changed the name of the executable.

          The cool thing was that I was able to then extend the VS Code extension and add many features to it over the Language Server.

          The code is here: https://github.com/rabix/benten/tree/master/vscode-client

          1. 3

            Yeah I agree it’s super weird that the flagship editor for LSP doesn’t have one-line config for it. I think it’s to make sure there are as many extensions as possible because it looks better, and it encourages people to add custom features to their extensions (“I already have an extension, why not add to it?”). Meanwhile in nvim it takes me one line to add a LSP server for a niche language.

            1. 3

              I don’t find this strange, I think that’s the right setup to get the best user experience. Languages are different, you can lowest-common-denominator 80% of the things, but the other 20% matter for people who are working with the tool extensively.

              What VS Code does is making this task embarrassingly parallel: folks who care about support for language X can implement perfect experience for this language with zero upstream coordination.

        2. 1

          What do NM, NM+M, and N=1 mean here?

          1. 5

            They have some unescaped asterisks turning part of the text italic. They refer to N*M meaning N code editors have to implement support for M languages, so there ends up being N*M implementations. Not sure about N*M+M.

            1. 2

              It’s funny how this still works even with markdown eating the asterisks because multiplication is often written as just two variables together without any punctuation :D

        3. 8

          I wonder what this bodes for the future of the VS Code ecosystem. First there was the Python Language Server (Apache 2 licensed), then there was Pyright (MIT) and now there is Pylance which is based on Pyright but closed source.

          1. 4

            To be fair, JetBrains effectively has their own, closed source, “code intelligence” implementations for basically every language. Even when a good language server exists, they don’t use it. Not that I blame them, I’ve personally found the LSP ecosystem to be pretty disappointing.

            1. 7

              To be fair, JetBrains effectively has their own, closed source, “code intelligence” implementations for basically every language.

              Python stuff is open source and Apache 2.0 licensed:

              https://github.com/JetBrains/intellij-community/blob/master/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeChecker.java

              1. 3

                I always found LSPs kinda flaky from a UX perspective. In my experience, editors with intelligence (i.e VS is what I’m familar with, but Eclipse and Emacs count) are more reliable with “knowing” your code.

                1. 4

                  this is a good article on the limitations of LSP with respect to IDEs https://perplexinglyemma.blogspot.com/2017/06/language-servers-and-ides.html

                  1. 3

                    This article makes little sense to me. The distinction between IDE and editor+LSP is arbitrary: LSP is just a mean of having the semantic part of the IDE be detached in a separate process, so that every language can have their own custom one that works for all compatible editors. The complaints about RLS are just that, complaints about a specific LSP implementation (rust-analyzer is much better). A lot of things have also been added to LSP in more recent versions.

                    The only thing IDEs have better than LSP on average is that they’re higher quality. But that’s not the protocol’s fault, it’s because the big IDEs are well funded (jetbrains, microsoft) and a lot of LSP servers are from niche communities and developed by people not experienced with the specifics of IDEs. Some good implementations do exist (thinking of ocamllsp here, which is also better than IDEs by virtue of existing at all for the language.)

                    1. 2

                      The complaint is that the LSP protocol is limited about how much it can express about the language; the IDE needs more information than the LSP is able to express to it. Hence serious IDEs end up implementing their own handling of the language rather than use LSP. I don’t think it is a matter of funding so much as a limitation of the LSP itself

                      1. 1

                        That’s exactly what I don’t understand. The LSP server is the IDE, and it communicates with an editor responsible for buffer management and actual edition and absolutely none of the semantics. Or do you mean that in the specific context where an existing IDE (like jetbrains’ suite or visual studio) would use an external LSP? In that case I agree that there’s a strong impedance mismatch.

                        1. 2

                          My understanding is that the LSP itself is limited in terms of what functionality it can implement - I have read that it cannot expose the AST. So Jetbrains can do some crazy refactoring and macros because it has direct access to the Java AST, which the Java language server will never be able to do unless they change how the LSP specification works.

                          1. 2

                            I think a LSP server typically will have trouble refactoring a whole project, because it tends to have access only to the files opened in the editor/client (that doesn’t have to be the case, but it’s what the protocol provides). Within a file, LSP can in theory do anything an IDE can, sending a new buffer back to the editor (typically that’d be a “code action”). Syntactic stuff like reindent, but also rename a variable, extract a method, add an import statement, etc. Again the LSP server is the one in charge of the AST; the editor only needs to know about text.

                            1. 4

                              (Replying to the whole thread)

                              LSP is just a particular RPC protocol. The buitin functionality is indeed pretty limited, but it’s easy enough to add extensions in practice. Even built in functionality is OK to do project-wide refactorings, there’s no “only opened files” limitation.

                              The actual limiting factor in practice is editor APIs. There’s a bunch of stuff I can just do in IntelliJ, which I can’t implement in VS Code (custom ui for ruining cargo commands and linkified backtraces are the two most annoying examples).

                              A good example of what is possible if you actually do powerful protocol and powerful front end is rider: https://www.codemag.com/Article/1811091/Building-a-.NET-IDE-with-JetBrains-Rider. They use a different flavor of the protocol, which is based on state synchronization, rather than request-response RPC, but you can (with a whole lot of pain) do something similar on top of an LSP.

                              What is interesting about IntelliJ architecture is that there’s a single engine for many languages, so cross-language features are much easier, and there’s a pinch (but not to much) of code re-use for code analysis for different languages.

                              1. 1

                                Thanks for clarifying this for me

                              2. 1

                                Hmm that makes sense, I need to read more about this. If every possible action an IDE could do can be implemented as a code action they seem equivalent.