Skip to content

Commit 5ac30b9

Browse files
authored
feat(roslyn_ls): add initial config as vim.lsp.config #3753
1 parent 7d32353 commit 5ac30b9

1 file changed

Lines changed: 186 additions & 0 deletions

File tree

lsp/roslyn_ls.lua

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
---@brief
2+
---
3+
--- https://github.com/dotnet/roslyn
4+
--
5+
-- To install the server, compile from source or download as nuget package.
6+
-- Go to `https://dev.azure.com/azure-public/vside/_artifacts/feed/vs-impl/NuGet/Microsoft.CodeAnalysis.LanguageServer.<platform>/overview`
7+
-- 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).
8+
-- Download and extract it (nuget's are zip files).
9+
-- - if you chose `neutral` nuget version, then you have to change the `cmd` like so:
10+
-- cmd = {
11+
-- 'dotnet',
12+
-- '<my_folder>/Microsoft.CodeAnalysis.LanguageServer.dll',
13+
-- '--logLevel', -- this property is required by the server
14+
-- 'Information',
15+
-- '--extensionLogDirectory', -- this property is required by the server
16+
-- fs.joinpath(uv.os_tmpdir(), 'roslyn_ls/logs'),
17+
-- '--stdio',
18+
-- },
19+
-- where `<my_folder>` has to be the folder you extracted the nuget package to.
20+
-- - for all other platforms put the extracted folder to neovim's PATH (`vim.env.PATH`)
21+
22+
local uv = vim.uv
23+
local fs = vim.fs
24+
25+
---@param client vim.lsp.Client
26+
---@param target string
27+
local function on_init_sln(client, target)
28+
vim.notify('Initializing: ' .. target, vim.log.levels.INFO, { title = 'roslyn_ls' })
29+
---@diagnostic disable-next-line: param-type-mismatch
30+
client:notify('solution/open', {
31+
solution = vim.uri_from_fname(target),
32+
})
33+
end
34+
35+
---@param client vim.lsp.Client
36+
---@param project_files string[]
37+
local function on_init_project(client, project_files)
38+
vim.notify('Initializing: projects', vim.log.levels.INFO, { title = 'roslyn_ls' })
39+
---@diagnostic disable-next-line: param-type-mismatch
40+
client:notify('project/open', {
41+
projects = vim.tbl_map(function(file)
42+
return vim.uri_from_fname(file)
43+
end, project_files),
44+
})
45+
end
46+
47+
local function roslyn_handlers()
48+
return {
49+
['workspace/projectInitializationComplete'] = function(_, _, ctx)
50+
vim.notify('Roslyn project initialization complete', vim.log.levels.INFO, { title = 'roslyn_ls' })
51+
52+
local buffers = vim.lsp.get_buffers_by_client_id(ctx.client_id)
53+
for _, buf in ipairs(buffers) do
54+
vim.lsp.util._refresh('textDocument/diagnostic', { bufnr = buf })
55+
end
56+
end,
57+
['workspace/_roslyn_projectHasUnresolvedDependencies'] = function()
58+
vim.notify('Detected missing dependencies. Run `dotnet restore` command.', vim.log.levels.ERROR, {
59+
title = 'roslyn_ls',
60+
})
61+
return vim.NIL
62+
end,
63+
['workspace/_roslyn_projectNeedsRestore'] = function(_, result, ctx)
64+
local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
65+
66+
---@diagnostic disable-next-line: param-type-mismatch
67+
client:request('workspace/_roslyn_restore', result, function(err, response)
68+
if err then
69+
vim.notify(err.message, vim.log.levels.ERROR, { title = 'roslyn_ls' })
70+
end
71+
if response then
72+
for _, v in ipairs(response) do
73+
vim.notify(v.message, vim.log.levels.INFO, { title = 'roslyn_ls' })
74+
end
75+
end
76+
end)
77+
78+
return vim.NIL
79+
end,
80+
['razor/provideDynamicFileInfo'] = function(_, _, _)
81+
vim.notify(
82+
'Razor is not supported.\nPlease use https://github.com/tris203/rzls.nvim',
83+
vim.log.levels.WARN,
84+
{ title = 'roslyn_ls' }
85+
)
86+
return vim.NIL
87+
end,
88+
}
89+
end
90+
91+
---@type vim.lsp.ClientConfig
92+
return {
93+
name = 'roslyn_ls',
94+
offset_encoding = 'utf-8',
95+
cmd = {
96+
'Microsoft.CodeAnalysis.LanguageServer',
97+
'--logLevel',
98+
'Information',
99+
'--extensionLogDirectory',
100+
fs.joinpath(uv.os_tmpdir(), 'roslyn_ls/logs'),
101+
'--stdio',
102+
},
103+
filetypes = { 'cs' },
104+
handlers = roslyn_handlers(),
105+
root_dir = function(bufnr, cb)
106+
local bufname = vim.api.nvim_buf_get_name(bufnr)
107+
-- don't try to find sln or csproj for files from libraries
108+
-- outside of the project
109+
if not bufname:match('^' .. fs.joinpath('/tmp/MetadataAsSource/')) then
110+
-- try find solutions root first
111+
local root_dir = fs.root(bufnr, function(fname, _)
112+
return fname:match('%.sln$') ~= nil
113+
end)
114+
115+
if not root_dir then
116+
-- try find projects root
117+
root_dir = fs.root(bufnr, function(fname, _)
118+
return fname:match('%.csproj$') ~= nil
119+
end)
120+
end
121+
122+
if root_dir then
123+
cb(root_dir)
124+
end
125+
end
126+
end,
127+
on_init = {
128+
function(client)
129+
local root_dir = client.config.root_dir
130+
131+
-- try load first solution we find
132+
for entry, type in vim.fs.dir(root_dir) do
133+
if type == 'file' and vim.endswith(entry, '.sln') then
134+
on_init_sln(client, entry)
135+
return
136+
end
137+
end
138+
139+
-- if no solution is found load project
140+
for entry, type in vim.fs.dir(root_dir) do
141+
if type == 'file' and vim.endswith(entry, '.csproj') then
142+
on_init_project(client, { entry })
143+
end
144+
end
145+
end,
146+
},
147+
capabilities = {
148+
-- HACK: Doesn't show any diagnostics if we do not set this to true
149+
textDocument = {
150+
diagnostic = {
151+
dynamicRegistration = true,
152+
},
153+
},
154+
},
155+
settings = {
156+
['csharp|background_analysis'] = {
157+
dotnet_analyzer_diagnostics_scope = 'fullSolution',
158+
dotnet_compiler_diagnostics_scope = 'fullSolution',
159+
},
160+
['csharp|inlay_hints'] = {
161+
csharp_enable_inlay_hints_for_implicit_object_creation = true,
162+
csharp_enable_inlay_hints_for_implicit_variable_types = true,
163+
csharp_enable_inlay_hints_for_lambda_parameter_types = true,
164+
csharp_enable_inlay_hints_for_types = true,
165+
dotnet_enable_inlay_hints_for_indexer_parameters = true,
166+
dotnet_enable_inlay_hints_for_literal_parameters = true,
167+
dotnet_enable_inlay_hints_for_object_creation_parameters = true,
168+
dotnet_enable_inlay_hints_for_other_parameters = true,
169+
dotnet_enable_inlay_hints_for_parameters = true,
170+
dotnet_suppress_inlay_hints_for_parameters_that_differ_only_by_suffix = true,
171+
dotnet_suppress_inlay_hints_for_parameters_that_match_argument_name = true,
172+
dotnet_suppress_inlay_hints_for_parameters_that_match_method_intent = true,
173+
},
174+
['csharp|symbol_search'] = {
175+
dotnet_search_reference_assemblies = true,
176+
},
177+
['csharp|completion'] = {
178+
dotnet_show_name_completion_suggestions = true,
179+
dotnet_show_completion_items_from_unimported_namespaces = true,
180+
dotnet_provide_regex_completions = true,
181+
},
182+
['csharp|code_lens'] = {
183+
dotnet_enable_references_code_lens = true,
184+
},
185+
},
186+
}

0 commit comments

Comments
 (0)