diff options
| author | awy <awy@awy.one> | 2025-10-14 18:27:29 +0300 | 
|---|---|---|
| committer | awy <awy@awy.one> | 2025-10-14 18:27:29 +0300 | 
| commit | de009fd679e10d053fdcc10785f91ad5317449ea (patch) | |
| tree | 60918a488b579588596cf4d509fde298dccbf15d /.config/nvim/lsp/roslyn_ls.lua | |
| parent | 9ea6cf81adb5d6abc59843de1db45913210f9320 (diff) | |
| download | hyprdots-de009fd679e10d053fdcc10785f91ad5317449ea.tar.gz | |
nvim revamp
Diffstat (limited to '.config/nvim/lsp/roslyn_ls.lua')
| -rw-r--r-- | .config/nvim/lsp/roslyn_ls.lua | 237 | 
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, +    }, +  }, +}  |