New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal/Enhancement: Allow C#/F# to use "local" tools for LSP servers #3906
Comments
cc @razzmatazz |
Ha. I've also just discovered that |
Gastove
added a commit
to Gastove/lsp-mode
that referenced
this issue
Jan 13, 2024
This commit implements an approach proposed in emacs-lsp#3906. Specifically, it provides new control variables to make it possible to use C# and F# language servers _either_ as global _or_ local dotnet tools. So far, I've done this by providing boolean variables to control command construction, but I'm not attached to this approach. Closes emacs-lsp#3906.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
C# and F# both lean heavily on the
dotnet
CLI for all kinds of tasks -- including installing and managing language server binaries. This is referred to asdotnet
"tools".lsp-mode
currently makes use of both thedotnet
CLI and the "tools" functionality for installing C# and F# language servers.An important detail here is: a dotnet tool can be either local or global. Local tools are described in a "tool manifest" that is version controlled within a repo, allowing all contributors to share tool versions. Importantly: local tools can be installed one of two ways:
dotnet tool install
will install it and add it to the repo's tool manifest so it can be version controlled.dotnet tool restore
.Both
lsp-fsharp
andlsp-csharp
currently hard-code command line flags to force using only global tool installations. This works just fine in many cases, so this isn't a bug. However! Since dotnet can install language servers on a per-project basis, it would be an excellent -- and not especially complex --lsp-mode
enhancement to support running local tools if present.To my eye, this could happen loosely following one of two patterns:
defcustom
forlsp-<language>-use-local-tool
.defcustom
forlsp-<language>-prefer-local-tool
.I'm very happy to implement either approach; I personally prefer approach 1.
lsp-<language>-use-local-tool
/lsp-<language>-use-global-tool
In this implementation, a new boolean
defcustom
, safe as a local variable, would simply add or remove theglobal
flag fromdotnet tool
invocations. If the correct language server isn't installed locally,lsp-mode
would prompt for a server install. I like this approach because it's very explicit, and the semantics are fairly clear from a "global default / dir-locals overrides" perspective. To maintain the current behavior without disruption, I would default to addinglsp-<language>-use-local-tool
with default valuefalse/nil
; the semantics of adding a dir-local foruse-local-tool 't
seem very tidy to me. But, we'd get the same behavior (with inverted t/f semantics) fromuse-global-tool
.The downside here is that it introduces some complexity around tool installation. If a tool manifest already exists, it should be restored, then
lsp-mode
can check to see if the needed language server is available, and it can be installed/upgraded locally. If no tool manifest was present, then one must be created before installation can happen. This could all be totally do-able in code or a local tool install could revert to the user, prompting them to do their own restore/installation.lsp-<language>-prefer-local-tool
In this implementation, a new boolean
defcustom
would be added with default valuefalse/nil
. If set to true, the code that builds server run commands would check first for a locally installed tool, then fall back to a global tool if present, then prompt the user to do a tool install. This is a more "auto-magic" approach. To me, this approach opens up the possibility of some surprising behavior. For example: after cloning a dotnet project locally, adotnet tool
must be "restored" before it can be used. One could cheerfully wind up using a global version of a tool, encountering strange errors if versions miss-match expectations, without realizing that the wrong server is running.I see this option as overcoming the server installation complexity of
use-local-tool
by making it sensible for lsp-mode to only install servers globally. This is, strictly speaking, open to debate -- just my opening stance.I'm happy to help
There may, of course, be other great options! These are the two I can see straight out the gate. I'm likely to get cracking with Option 1,
lsp-<language>-use-local-tool
, to get myself unblocked and to see how I like it. I'll put up a PR when I have one, unless y'all feel very strongly about not doing this at all, or doing it yourselves, or not doing it either of the ways I've mentioned above. Just let me know.Thanks for the awesome project!
The text was updated successfully, but these errors were encountered: