aboutsummaryrefslogtreecommitdiff
path: root/.config/nvim/lsp/roslyn_ls.lua
diff options
context:
space:
mode:
authorawy <awy@awy.one>2025-10-20 20:55:26 +0300
committerawy <awy@awy.one>2025-10-20 20:55:26 +0300
commit662dafc52b2c8a9426bb2197ab9246a8cda318e4 (patch)
treef9d1f20e3864360bf941fd6bc02848ed77b037a8 /.config/nvim/lsp/roslyn_ls.lua
parent8131d9f2898b991a2d2c7a2ac601ce9e07cc9c9f (diff)
downloadhyprdots-662dafc52b2c8a9426bb2197ab9246a8cda318e4.tar.gz
nvqw
Diffstat (limited to '.config/nvim/lsp/roslyn_ls.lua')
-rw-r--r--.config/nvim/lsp/roslyn_ls.lua237
1 files changed, 237 insertions, 0 deletions
diff --git a/.config/nvim/lsp/roslyn_ls.lua b/.config/nvim/lsp/roslyn_ls.lua
new file mode 100644
index 0000000..e332443
--- /dev/null
+++ b/.config/nvim/lsp/roslyn_ls.lua
@@ -0,0 +1,237 @@
+---@brief
+---
+--- https://github.com/dotnet/roslyn
+--
+-- To install the server, compile from source or download as nuget package.
+-- Go to `https://dev.azure.com/azure-public/vside/_artifacts/feed/vs-impl/NuGet/Microsoft.CodeAnalysis.LanguageServer.<platform>/overview`
+-- replace `<platform>` with one of the following `linux-x64`, `osx-x64`, `win-x64`, `neutral` (for more info on the download location see https://github.com/dotnet/roslyn/issues/71474#issuecomment-2177303207).
+-- Download and extract it (nuget's are zip files).
+-- - if you chose `neutral` nuget version, then you have to change the `cmd` like so:
+-- cmd = {
+-- 'dotnet',
+-- '<my_folder>/Microsoft.CodeAnalysis.LanguageServer.dll',
+-- '--logLevel', -- this property is required by the server
+-- 'Information',
+-- '--extensionLogDirectory', -- this property is required by the server
+-- fs.joinpath(uv.os_tmpdir(), 'roslyn_ls/logs'),
+-- '--stdio',
+-- },
+-- where `<my_folder>` has to be the folder you extracted the nuget package to.
+-- - for all other platforms put the extracted folder to neovim's PATH (`vim.env.PATH`)
+
+local uv = vim.uv
+local fs = vim.fs
+
+local group = vim.api.nvim_create_augroup('lspconfig.roslyn_ls', { clear = true })
+
+---@param client vim.lsp.Client
+---@param target string
+local function on_init_sln(client, target)
+ vim.notify('Initializing: ' .. target, vim.log.levels.TRACE, { title = 'roslyn_ls' })
+ ---@diagnostic disable-next-line: param-type-mismatch
+ client:notify('solution/open', {
+ solution = vim.uri_from_fname(target),
+ })
+end
+
+---@param client vim.lsp.Client
+---@param project_files string[]
+local function on_init_project(client, project_files)
+ vim.notify('Initializing: projects', vim.log.levels.TRACE, { title = 'roslyn_ls' })
+ ---@diagnostic disable-next-line: param-type-mismatch
+ client:notify('project/open', {
+ projects = vim.tbl_map(function(file)
+ return vim.uri_from_fname(file)
+ end, project_files),
+ })
+end
+
+---@param client vim.lsp.Client
+local function refresh_diagnostics(client)
+ local buffers = vim.lsp.get_buffers_by_client_id(client.id)
+ for _, buf in ipairs(buffers) do
+ if vim.api.nvim_buf_is_loaded(buf) then
+ client:request(
+ vim.lsp.protocol.Methods.textDocument_diagnostic,
+ { textDocument = vim.lsp.util.make_text_document_params(buf) },
+ nil,
+ buf
+ )
+ end
+ end
+end
+
+local function roslyn_handlers()
+ return {
+ ['workspace/projectInitializationComplete'] = function(_, _, ctx)
+ vim.notify('Roslyn project initialization complete', vim.log.levels.INFO, { title = 'roslyn_ls' })
+ local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
+ refresh_diagnostics(client)
+ return vim.NIL
+ end,
+ ['workspace/_roslyn_projectNeedsRestore'] = function(_, result, ctx)
+ local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
+
+ ---@diagnostic disable-next-line: param-type-mismatch
+ client:request('workspace/_roslyn_restore', result, function(err, response)
+ if err then
+ vim.notify(err.message, vim.log.levels.ERROR, { title = 'roslyn_ls' })
+ end
+ if response then
+ for _, v in ipairs(response) do
+ vim.notify(v.message, vim.log.levels.INFO, { title = 'roslyn_ls' })
+ end
+ end
+ end)
+
+ return vim.NIL
+ end,
+ ['razor/provideDynamicFileInfo'] = function(_, _, _)
+ vim.notify(
+ 'Razor is not supported.\nPlease use https://github.com/tris203/rzls.nvim',
+ vim.log.levels.WARN,
+ { title = 'roslyn_ls' }
+ )
+ return vim.NIL
+ end,
+ }
+end
+
+---@type vim.lsp.Config
+return {
+ name = 'roslyn_ls',
+ offset_encoding = 'utf-8',
+ cmd = {
+ 'Microsoft.CodeAnalysis.LanguageServer',
+ '--logLevel',
+ 'Information',
+ '--extensionLogDirectory',
+ fs.joinpath(uv.os_tmpdir(), 'roslyn_ls/logs'),
+ '--stdio',
+ },
+ filetypes = { 'cs' },
+ handlers = roslyn_handlers(),
+
+ commands = {
+ ['roslyn.client.completionComplexEdit'] = function(command, ctx)
+ local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
+ local args = command.arguments or {}
+ local uri, edit = args[1], args[2]
+
+ if uri and edit and edit.newText and edit.range then
+ local workspace_edit = {
+ changes = {
+ [uri.uri] = {
+ {
+ range = edit.range,
+ newText = edit.newText,
+ },
+ },
+ },
+ }
+ vim.lsp.util.apply_workspace_edit(workspace_edit, client.offset_encoding)
+ else
+ vim.notify('roslyn_ls: completionComplexEdit args not understood: ' .. vim.inspect(args), vim.log.levels.WARN)
+ end
+ end,
+ },
+
+ root_dir = function(bufnr, cb)
+ local bufname = vim.api.nvim_buf_get_name(bufnr)
+ -- don't try to find sln or csproj for files from libraries
+ -- outside of the project
+ if not bufname:match('^' .. fs.joinpath('/tmp/MetadataAsSource/')) then
+ -- try find solutions root first
+ local root_dir = fs.root(bufnr, function(fname, _)
+ return fname:match('%.sln[x]?$') ~= nil
+ end)
+
+ if not root_dir then
+ -- try find projects root
+ root_dir = fs.root(bufnr, function(fname, _)
+ return fname:match('%.csproj$') ~= nil
+ end)
+ end
+
+ if root_dir then
+ cb(root_dir)
+ end
+ end
+ end,
+ on_init = {
+ function(client)
+ local root_dir = client.config.root_dir
+
+ -- try load first solution we find
+ for entry, type in fs.dir(root_dir) do
+ if type == 'file' and (vim.endswith(entry, '.sln') or vim.endswith(entry, '.slnx')) then
+ on_init_sln(client, fs.joinpath(root_dir, entry))
+ return
+ end
+ end
+
+ -- if no solution is found load project
+ for entry, type in fs.dir(root_dir) do
+ if type == 'file' and vim.endswith(entry, '.csproj') then
+ on_init_project(client, { fs.joinpath(root_dir, entry) })
+ end
+ end
+ end,
+ },
+
+ on_attach = function(client, bufnr)
+ -- avoid duplicate autocmds for same buffer
+ if vim.api.nvim_get_autocmds({ buffer = bufnr, group = group })[1] then
+ return
+ end
+
+ vim.api.nvim_create_autocmd({ 'BufWritePost', 'InsertLeave' }, {
+ group = group,
+ buffer = bufnr,
+ callback = function()
+ refresh_diagnostics(client)
+ end,
+ desc = 'roslyn_ls: refresh diagnostics',
+ })
+ end,
+
+ capabilities = {
+ -- HACK: Doesn't show any diagnostics if we do not set this to true
+ textDocument = {
+ diagnostic = {
+ dynamicRegistration = true,
+ },
+ },
+ },
+ settings = {
+ ['csharp|background_analysis'] = {
+ dotnet_analyzer_diagnostics_scope = 'fullSolution',
+ dotnet_compiler_diagnostics_scope = 'fullSolution',
+ },
+ ['csharp|inlay_hints'] = {
+ csharp_enable_inlay_hints_for_implicit_object_creation = true,
+ csharp_enable_inlay_hints_for_implicit_variable_types = true,
+ csharp_enable_inlay_hints_for_lambda_parameter_types = true,
+ csharp_enable_inlay_hints_for_types = true,
+ dotnet_enable_inlay_hints_for_indexer_parameters = true,
+ dotnet_enable_inlay_hints_for_literal_parameters = true,
+ dotnet_enable_inlay_hints_for_object_creation_parameters = true,
+ dotnet_enable_inlay_hints_for_other_parameters = true,
+ dotnet_enable_inlay_hints_for_parameters = true,
+ dotnet_suppress_inlay_hints_for_parameters_that_differ_only_by_suffix = true,
+ dotnet_suppress_inlay_hints_for_parameters_that_match_argument_name = true,
+ dotnet_suppress_inlay_hints_for_parameters_that_match_method_intent = true,
+ },
+ ['csharp|symbol_search'] = {
+ dotnet_search_reference_assemblies = true,
+ },
+ ['csharp|completion'] = {
+ dotnet_show_name_completion_suggestions = true,
+ dotnet_show_completion_items_from_unimported_namespaces = true,
+ dotnet_provide_regex_completions = true,
+ },
+ ['csharp|code_lens'] = {
+ dotnet_enable_references_code_lens = true,
+ },
+ },
+}