Skip to content

Conversation

@xentropic-dev
Copy link

@xentropic-dev xentropic-dev commented May 26, 2025

Implements support for JetBrains resharper code inspection CLI tools.
Closes #798

@xentropic-dev xentropic-dev changed the title Feat/resharper feat:resharper May 26, 2025
@xentropic-dev xentropic-dev marked this pull request as draft November 19, 2025 22:20
@xentropic-dev
Copy link
Author

@mfussenegger , I have converted this PR to a draft. I addressed all of your points, I think:

  1. ReSharper upstream now provides --output=- to direct SARIF results to stdout. This requires the latest version of resharper command line tools
  2. Linter definition uses for_sarif parser

I'm keeping it as draft for now in case you want me to include anything in the documentation about which version of resharper is required. I am also looking into optimizing it so the linter runs faster; I'm not sure caching is working right now.

@xentropic-dev
Copy link
Author

Also just noticed I accidentally reformatted the readme; i'll get that fixed.

@xentropic-dev xentropic-dev marked this pull request as ready for review November 24, 2025 22:23
Comment on lines +1 to +35
local function find_upward(extension)
local dir = vim.fn.getcwd()
while dir and dir ~= "/" do
local files = vim.fn.globpath(dir, "*" .. extension, false, true)
if not vim.tbl_isempty(files) then
return files[1]
end
dir = vim.fn.fnamemodify(dir, ":h")
end
return nil
end

return function()
local root_file = find_upward(".sln")
if not root_file then
root_file = find_upward(".csproj")
end

if not root_file then
vim.notify("No solution file or csproj found in parent directories", vim.log.levels.WARN)
return {}
end

local current_buffer = vim.api.nvim_get_current_buf()
local filepath = vim.api.nvim_buf_get_name(current_buffer)

if filepath == "" then
vim.notify("Current buffer has no file associated", vim.log.levels.WARN)
return {}
end

local solution_directory = vim.fn.fnamemodify(root_file, ":h")

local relative_filepath = filepath:sub(#solution_directory + 2)
local cache_directory = vim.fn.stdpath("cache") .. "/nvim-lint-resharper"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be changed to only search .sln or .csproj relative to the current dir?
Adding root dir heuristics as part of the linter is out of scope for nvim-dap. cwd can be parameterized as part of the try_lint call for users who have cwd != project_dir.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the resharper cli cannot lint a single file. It has to run against an entire project or solution. So I guess it's fine as long the user always has csproj or sln in the cwd. For me, that rarely is the case because .NET projects are often nested in various folders. .NET has solution groups to organize files virtually that is irrespective of file tree structure on disk, which makes it even a little more confusing. I have a plugin I wrote for this problem, but basically .NET projects aren't always structured relative on disk; sometimes it's by the "logical" solution groups.
https://github.com/xentropic-dev/explorer.dotnet.nvim

I think for nvim-lint, I should just do whatever makes sense for the good of the rest of the plugin's ecosystem, but I'm really starting to think I need to just make a separate plugin for just the resharper cli. There's too many ways in which the tool is different than the standard linters in this project.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I guess it's fine as long the user always has csproj or sln in the cwd. For me, that rarely is the case because

You could still do something as described in #482 (comment)

And at some point in the future there might be a solution based on neovim/neovim#34622

So for now I'd restrict resharper to only search downward from cwd

local cache_directory = vim.fn.stdpath("cache") .. "/nvim-lint-resharper"

-- Ensure cache directory exists
vim.fn.mkdir(cache_directory, "p")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be specified?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I'm not sure. In my tests, it could take 7 or 8 seconds or more for the linter to run on an entire project and caching seemed to have minor effects to the point where I couldn't even be sure if it was working. This was an attempt by me to be as explicit as possible to try to ensure caching was working, and it also gave me a way to check to make sure the cache was actually being saved. I still didn't see any performance increase really by enabling caching and/or specifying the cache directory. I'm fine with removing the cache_directory completely tbh.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there wasn't any difference in your tests I'd be in favor of removing it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature]: Support JetBrains Resharper linting for C#

2 participants