csharp.nvim
csharp.nvim copied to clipboard
feat: support roslyn lsp
I tried to integrate the new roslyn LSP but can't get it to work yet. The LSP seems to launch without issues; however, it never sends a workspace/projectInitializationComplete
server event, so it can't be attached to buffers. Any help would be appreciated!
To use the roslyn lsp instead of omnisharp set lsp.use_omnisharp = false
in the configurations and set cmd_path
to the LSP binary.
Perhaps this might seem like a naive question (as I'm new to configuring NeoVim), but why you don't use the csharp-language-server. It stands as Roslyn based.
I`ve tried to fix issue by using other plugin for that task but had no success. Anyway maybe my code would be a little bit usefful
local M = {}
local config_store = require("csharp.config")
local logger = require("csharp.log")
local on_attach = function(client, bufnr)
print("Attaching to Roslyn")
end
function M.start_roslyn(buffer, root)
local function get_capabilities()
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true
local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
if status_ok then
capabilities = cmp_nvim_lsp.default_capabilities(capabilities)
end
return capabilities
end
my_capabilities = get_capabilities()
require("roslyn").setup({
on_attach = on_attach,
capabilities = my_capabilities,
})
require("mason-lspconfig").setup()
require("mason-lspconfig").setup_handlers({
-- The first entry (without a key) will be the default handler
function(server_name)
require("lspconfig")[server_name].setup({
on_attach = on_attach,
capabilities = my_capabilities,
})
end,
})
print("Roslyn launched client")
end
return M
The script initiates the server and attempts to attach, but eventually, I encounter a "Client exit" message, and I'm unable to determine the cause due to the lack of logs.
Perhaps I will be able to help out.
Just to be sure: make sure you use neovim 0.10
add this
plugins/roslyn.lua
return {
"jmederosalvarado/roslyn.nvim",
}
and this
config/lazy.lua
_G.on_attach = function(server_name)
return function(_, bufnr)
-- Create a command `:Format` local to the LSP buffer
-- Set keymaps here so they only pertain to buffers that a lang server attaches too
-- buffer=0 means only set for current buffer
vim.api.nvim_buf_create_user_command(bufnr, "Format", function(_)
if vim.lsp.buf.format then
vim.lsp.buf.format()
elseif vim.lsp.buf.formatting then
vim.lsp.buf.formatting()
end
end, { desc = "Format current buffer with LSP" })
vim.keymap.set("n", "K", vim.lsp.buf.hover, { buffer = 0 })
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { buffer = 0, desc = "LSP Go To Definition" })
vim.keymap.set("n", "gt", vim.lsp.buf.type_definition, { buffer = 0, desc = "LSP Go to Type Definition" })
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, { buffer = 0, desc = "LSP Go to implementation" })
vim.keymap.set(
"n",
"<leader>dl",
"<cmd>Telescope diagnostics<cr>",
{ buffer = 0, desc = "LSP Telescope diagnostics" }
)
vim.keymap.set("n", "rn", ":lua vim.lsp.buf.rename()<cr>", { buffer = 0, desc = "LSP Rename Variable" })
vim.keymap.set("n", "gc", ":lua vim.lsp.buf.code_action()<cr>", { buffer = 0, desc = "LSP Code action" })
vim.keymap.set("n", "gD", ":lua vim.lsp.buf.declaration()<cr>", { buffer = 0, desc = "LSP Go To Declaration" })
vim.keymap.set(
"n",
"gr",
":lua require('telescope.builtin').lsp_references()<cr>",
{ buffer = 0, desc = "LSP Telescope Find References" }
)
vim.keymap.set("n", "gR", ":lua vim.lsp.buf.references()<cr>", { buffer = 0, desc = "LSP Find References" })
vim.keymap.set("n", "gs", ":lua vim.lsp.buf.signature_help()<cr>", { buffer = 0, desc = "LSP Signature" })
-- Lesser used LSP functionality
vim.keymap.set("n", "<leader>wl", ":lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<cr>")
vim.keymap.set("n", "<leader>wa", ":lua vim.lsp.buf.add_workspace_folder()<cr>")
vim.keymap.set("n", "<leader>wr", ":lua vim.lsp.buf.remove_workspace_folder()<cr>")
--Diagnostic keymaps
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, { buffer = 0, desc = "Go to prev diagnostic" })
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, { buffer = 0, desc = "Go to next diagnostic" })
vim.keymap.set("n", "<LocalLeader>do", vim.diagnostic.open_float, { buffer = 0, desc = "Diagnostics open float" })
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { buffer = 0, desc = "Set loc list" })
vim.keymap.set("n", "<LocalLeader>dh", ":lua vim.diagnostic.hide()<CR>", { buffer = 0, desc = "Hide diagnostics" })
vim.keymap.set("n", "<LocalLeader>ds", ":lua vim.diagnostic.show()<CR>", { buffer = 0, desc = "Show diagnostics" })
vim.keymap.set("n", "<leader>F", ":lua vim.lsp.buf.format()<cr>", { buffer = 0, desc = "LSP Format" })
vim.keymap.set(
"n",
"<leader>ls",
":lua require('telescope.builtin').lsp_document_symbols()<cr>",
{ buffer = 0, desc = "LSP document symbol" }
)
vim.keymap.set(
"n",
"<leader>ws",
":lua require('telescope.builtin').lsp_dynamic_workspace_symbols()<cr>",
{ buffer = 0, desc = "LSP workspace symbol" }
)
end
end
require("roslyn").setup({
dotnet_cmd = "dotnet",
roslyn_version = "4.11.0-2.24266.3",
on_attach = _G.on_attach(vim.lsp),
capabilities = nil,
})
after adding those files I believe you should re-start your neovim and call inside neovim
:CSInstallRoslyn
this might take few seconds, neovim will appear frozen
Once it's done installing roslyn, you should open a .cs file and it should start roslyn LSP
First you will see this message:
Roslyn client initialized for target YourSolutionFile.sln
and once it's done it will show:
Roslyn project initialization complete