I'm using rust-tool.vim and ChatGpt cooked up this solution for me based on telling RA that the root_dir can only be the current workspace. Should be portable as long as the lsp is rust-analyzer.
First define these helpers
local function ensure_uri_scheme(uri)
if not vim.startswith(uri, "file://") then
return "file://" .. uri
end
return uri
end
local function is_in_workspace(uri)
uri = ensure_uri_scheme(uri)
local path = vim.uri_to_fname(uri)
local workspace_dir = vim.fn.getcwd()
return vim.startswith(path, workspace_dir)
end
local function filter_diagnostics(diagnostics)
local filtered_diagnostics = {}
for _, diagnostic in ipairs(diagnostics) do
if is_in_workspace(diagnostic.source) then
table.insert(filtered_diagnostics, diagnostic)
end
end
return filtered_diagnostics
end
Then configure the root_dir
option in lspconfig or lsp zero. In my case I just used rust-tools config directly and it worked.
local lspconfig = require('lspconfig')
let rt = require('rust-tools')
rt.setup({
--....
--....
server = {
root_dir = function(startpath)
local startpath_uri = vim.uri_from_fname(startpath)
if not is_in_workspace(startpath) then
return nil
end
return lspconfig.util.root_pattern("Cargo.toml", "rust-project.json")(startpath)
end,
}
})
It also gave me another option I can set with a function that does diagnostic filtering based on if the file is from the workspace. But I'm satisfied with RA being disabled all together with the above solution. Here is the filtering snippet
local lspconfig = require('lspconfig')
let rt = require('rust-tools')
rt.setup({
--....
--....
server = {
handlers = {
["textDocument/publishDiagnostics"] = function(err, method, result, client_id, bufnr, config)
if not result or not result.uri then
return
end
local uri = result.uri
local bufnr = vim.uri_to_bufnr(uri)
if not bufnr then
return
end
if is_in_workspace(uri) then
local diagnostics = vim.lsp.diagnostic.to_severity(result.diagnostics)
diagnostics = filter_diagnostics(diagnostics)
vim.lsp.diagnostic.save(diagnostics, bufnr, client_id)
if vim.api.nvim_buf_is_loaded(bufnr) then
vim.lsp.diagnostic.set_signs(diagnostics, bufnr, client_id)
end
end
end;
},
}
})