Multi-target projects don't get language server capabilities
What
I've noticed that csharp-ls only supports projects with
<TargetFramework>whatever</TargetFramework>
And not
<TargetFrameworks>two; or more</TargetFrameworks>
The language server starts up, but I get no language server capabilities coming out.
Investigation
I've not looked too deeply into this, as I use neovim and rider so I just switch over to rider when in a multi-target project. If this is a core limitation of the Roslyn language server, then this can be closed. I didn't find any mentions in the issues when I looked, however.
Context
System
nvim:
NVIM v0.11.0-dev
Build type: RelWithDebInfo
LuaJIT 2.1.1703358377
csharp-ls:
csharp-ls version 0.15.0.0
OS: Ubuntu 24.04.1 LTS on Windows 10 x86_64 (actually windows 11)
Kernel: 5.15.153.1-microsoft-standard-WSL2
Logs
For completeness, here's the logs I receive:
[START][2024-11-13 12:21:22] LSP logging initiated
[ERROR][2024-11-13 12:21:22] .../vim/lsp/rpc.lua:772 "rpc" "/home/<REDACTED>/.local/share/nvim/mason/bin/csharp-ls" "stderr" "[12:21:22.121 INF] [Initialization] initializing, csharp-ls version 0.15.0.0\n"
[ERROR][2024-11-13 12:21:22] .../vim/lsp/rpc.lua:772 "rpc" "/home/<REDACTED>/.local/share/nvim/mason/bin/csharp-ls" "stderr" "[12:21:22.150 INF] [Initialization] csharp-ls is released under MIT license and is not affiliated with Microsoft Corp.; see https://github.com/razzmatazz/csharp-language-server\n"
[ERROR][2024-11-13 12:21:22] .../vim/lsp/rpc.lua:772 "rpc" "/home/<REDACTED>/.local/share/nvim/mason/bin/csharp-ls" "stderr" '[12:21:22.158 INF] [Initialization] MSBuildLocator: will register ".NET Core SDK", Version=8.0.303 as default instance\n'
[ERROR][2024-11-13 12:21:22] .../vim/lsp/rpc.lua:772 "rpc" "/home/<REDACTED>/.local/share/nvim/mason/bin/csharp-ls" "stderr" '[12:21:22.234 VRB] [Initialization] handleInitialized: "initialized" notification received from client\n'
[WARN][2024-11-13 12:21:22] ...lsp/handlers.lua:136 "The language server csharp_ls triggers a registerCapability handler for workspace/symbol despite dynamicRegistration set to false. Report upstream, this warning is harmless"
[ERROR][2024-11-13 12:21:22] .../vim/lsp/rpc.lua:772 "rpc" "/home/<REDACTED>/.local/share/nvim/mason/bin/csharp-ls" "stderr" "[12:21:22.261 VRB] [Initialization] handleInitialized: OK\n"
[ERROR][2024-11-13 12:21:32] .../vim/lsp/rpc.lua:772 "rpc" "/home/<REDACTED>/.local/share/nvim/mason/bin/csharp-ls" "stderr" "[12:21:32.740 VRB] [LSP Server] Shutdown received\n"
[ERROR][2024-11-13 12:21:32] .../vim/lsp/rpc.lua:772 "rpc" "/home/<REDACTED>/.local/share/nvim/mason/bin/csharp-ls" "stderr" "[12:21:32.745 VRB] [LSP Server] Exit received\n"
Config
Here's my watered down config to what's relevant:
lspconfig.lua
return {
"neovim/nvim-lspconfig",
event = { "BufReadPre", "BufNewFile" },
dependencies = {
"hrsh7th/cmp-nvim-lsp",
{ "antosha417/nvim-lsp-file-operations", config = true },
{ "folke/neodev.nvim", opts = {} },
},
config = function()
local lspconfig = require("lspconfig")
local mason_lspconfig = require("mason-lspconfig")
local cmp_nvim_lsp = require("cmp_nvim_lsp")
local capabilities = cmp_nvim_lsp.default_capabilities()
local on_attach = require("alsi.core.lsp_keymaps").on_attach
mason_lspconfig.setup_handlers({
function(server_name)
lspconfig[server_name].setup({
capabilities = capabilities,
on_attach = on_attach,
})
end,
})
end,
}
alsi.core.lsp_keymaps.lua
local lsp_keymaps = {}
lsp_keymaps.on_attach = function(client, bufnr)
local keymap = vim.keymap
local opts = { buffer = bufnr, silent = true }
opts.desc = "Show LSP references"
keymap.set("n", "gR", "<cmd>Telescope lsp_references<CR>", opts)
opts.desc = "Go to declaration"
keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
opts.desc = "Show LSP definitions"
keymap.set("n", "gd", "<cmd>Telescope lsp_definitions<CR>", opts)
opts.desc = "Show LSP implementations"
keymap.set("n", "gi", "<cmd>Telescope lsp_implementations<CR>", opts)
opts.desc = "Show LSP type definitions"
keymap.set("n", "gt", "<cmd>Telescope lsp_type_definitions<CR>", opts)
opts.desc = "See available code actions"
keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts)
opts.desc = "Smart rename"
keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
opts.desc = "Show buffer diagnostics"
keymap.set("n", "<leader>D", "<cmd>Telescope diagnostics bufnr=0<CR>", opts)
opts.desc = "Show line diagnostics"
keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts)
opts.desc = "Go to previous diagnostic"
keymap.set("n", "[d", function()
vim.diagnostic.jump({ count = -1 })
end, opts)
opts.desc = "Go to next diagnostic"
keymap.set("n", "]d", function()
vim.diagnostic.jump({ count = 1 })
end, opts)
opts.desc = "Show documentation for what is under cursor"
keymap.set("n", "K", vim.lsp.buf.hover, opts)
opts.desc = "Restart LSP"
keymap.set("n", "<leader>rs", ":LspRestart<CR>", opts)
end
return lsp_keymaps
mason.lua
return {
"williamboman/mason.nvim",
dependencies = {
"williamboman/mason-lspconfig.nvim",
"WhoIsSethDaniel/mason-tool-installer.nvim",
},
config = function()
local mason = require("mason")
local mason_lspconfig = require("mason-lspconfig")
local mason_tool_installer = require("mason-tool-installer")
mason_lspconfig.setup({
ensure_installed = {
"csharp_ls",
},
})
mason_tool_installer.setup({
ensure_installed = {
"csharpier",
})
end,
}
I have just merged https://github.com/razzmatazz/csharp-language-server/pull/205 which should add some/experimental support for loading multi-tfm projects
0.18.0 has been released with (experimental) support for loading these kind of solutions; it works for me but I am not sure it will work for your case -- please report!
https://github.com/razzmatazz/csharp-language-server/releases/tag/0.18.0