Skip to content

Only getting diagnostics from currently open buffers #269

@HenrysHouses

Description

@HenrysHouses

Description

Quickfix list diagnostics not populating with all diagnostics correctly. I have checked old issues and solutions, especially #32, but with no success. i tried the configs listed there with the keymap for logging and its not giving me the present diagnostics for the entire workspace / solution. I am using a unity solution but afaik that shouldn't matter? the solution still is compiled with all the dlls and references.

Neovim version

v0.11.4-Release-LuaJIT-2.1.1741730670

Operating system and version

Windows 11

Expected behavior

the quickfix list should be populated with all the diagnostics thats in the solution when these settings are active

filewatching = "roslyn"
  ['csharp|background_analysis'] = {
            dotnet_analyzer_diagnostics_scope = 'fullSolution',
            dotnet_compiler_diagnostics_scope = 'fullSolution',
   },

Actual behavior

when you make a quickfix list with vim.diagnostic.setqflist() roslyn doesnt return all info / hints / warnings / errors from files that are in the solution. it still only returns diagnostics from open buffers

Minimal config

for name, url in pairs{
  roslyn = "https://github.com/seblyng/roslyn.nvim",
  -- Add other plugins to reproduce the issue
} do
  local install_path = vim.fn.fnamemodify("roslyn_issue/"..name, ":p")
  if vim.fn.isdirectory(install_path) == 0 then
    vim.fn.system({ "git", "clone", "--depth=1", url, install_path })
  end
  vim.opt.runtimepath:append(install_path)
end

-- Add additional config necessary to reproduce the issue
--
---@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)
  for buf, _ in pairs(vim.lsp.get_client_by_id(client.id).attached_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


require("roslyn").setup{
  -- Add config options necessary to reproduce the issue
  
	---@type vim.lsp.Config
	  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(),
	  filewatching = "roslyn",

	  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]

	      ---@diagnostic disable: undefined-field
	      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)
	      ---@diagnostic enable: undefined-field
	      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,
	    },
	  },
	}

Roslyn checkhealth

==============================================================================
roslyn:                                                                     ✅

roslyn.nvim: Requirements ~
- ✅ OK Neovim >= 0.11
- ✅ OK dotnet: found

roslyn.nvim: Roslyn Language Server ~
- ✅ OK C:/Users/Henri/AppData/Local/nvim-data/mason/bin/roslyn.cmd: found

roslyn.nvim: File Watching Configuration ~
- ✅ OK File watching: roslyn (using Roslyn's built-in file watcher)

roslyn.nvim: Solution Detection ~
- ✅ OK Selected solution: C:/Users/Henry/Documents/GitHub/Dare-Prototype/Dare-Prototype.sln

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions