2424 in
2525 optionalString ( key != null ) "vim.keymap.set('n', '${ key } ', ${ action } , {buffer=bufnr, noremap=true, silent=true, desc='${ desc } '})" ;
2626
27- # Omnisharp doesn't have colors in popup docs for some reason, and I've also
28- # seen mentions of it being way slower, so until someone finds missing
29- # functionality, this will be the default.
30- defaultServers = [ "csharp_ls" ] ;
27+ # roslyn is the official language server and the most feature-rich
28+ defaultServers = [ "roslyn" ] ;
3129 servers = {
3230 omnisharp = {
3331 cmd = mkLuaInline ''
4341 }
4442 '' ;
4543 filetypes = [ "cs" "vb" ] ;
46- root_dir = mkLuaInline ''
47- function(bufnr, on_dir)
48- local function find_root_pattern(fname, lua_pattern)
49- return vim.fs.root(0, function(name, path)
50- return name:match(lua_pattern)
51- end)
52- end
53-
54- local fname = vim.api.nvim_buf_get_name(bufnr)
55- on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$"))
56- end
57- '' ;
58- init_options = { } ;
44+ root_marks = [ ".sln" ".csproj" ] ;
5945 capabilities = {
6046 workspace = {
6147 workspaceFolders = false ; # https://github.com/OmniSharp/omnisharp-roslyn/issues/909
120106 csharp_ls = {
121107 cmd = [ ( lib . getExe pkgs . csharp-ls ) ] ;
122108 filetypes = [ "cs" ] ;
123- root_dir = mkLuaInline ''
124- function(bufnr, on_dir)
125- local function find_root_pattern(fname, lua_pattern)
126- return vim.fs.root(0, function(name, path)
127- return name:match(lua_pattern)
128- end)
129- end
130-
131- local fname = vim.api.nvim_buf_get_name(bufnr)
132- on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$"))
133- end
134- '' ;
109+ root_marks = [ ".sln" ".csproj" ] ;
135110 init_options = {
136111 AutomaticWorkspaceInit = true ;
137112 } ;
138113 } ;
139114
140- roslyn_ls = {
141- cmd = mkLuaInline ''
142- {
143- ${ toLuaObject ( getExe pkgs . roslyn-ls ) } ,
144- '--logLevel=Warning',
145- '--extensionLogDirectory=' .. vim.fs.dirname(vim.lsp.get_log_path()),
146- '--stdio',
147- }
148- '' ;
149-
150- filetypes = [ "cs" ] ;
151- root_dir = mkLuaInline ''
152- function(bufnr, on_dir)
153- local function find_root_pattern(fname, lua_pattern)
154- return vim.fs.root(0, function(name, path)
155- return name:match(lua_pattern)
156- end)
157- end
158-
159- local fname = vim.api.nvim_buf_get_name(bufnr)
160- on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$"))
161- end
162- '' ;
163- init_options = { } ;
115+ roslyn = {
116+ # NOTE: cmd is set by roslyn-nvim!
117+ filetypes = [ "cs" "razor" "cshtml" ] ;
118+ root_marks = [ ".sln" ".csproj" ] ;
164119 } ;
165120 } ;
166121
167122 extraServerPlugins = {
168123 omnisharp = [ "omnisharp-extended-lsp-nvim" ] ;
169124 csharp_ls = [ "csharpls-extended-lsp-nvim" ] ;
170- roslyn_ls = [ ] ;
125+ roslyn = [ "roslyn-nvim" ] ;
126+ } ;
127+
128+ defaultRazorExtension = "vscode-csharp" ;
129+ razorExtensions = let
130+ packageExtension = pkg : path :
131+ pkgs . stdenv . mkDerivation {
132+ name = "${ pkg . pname } _razor-extension" ;
133+ inherit ( pkg ) version ;
134+ src = pkg ;
135+ installPhase = ''
136+ mkdir -p $out/packages/{roslyn,roslyn-unstable}/libexec
137+ cp -r $src/${ path } $out/packages/roslyn/libexec/.razorExtension
138+ cp -r $src/${ path } $out/packages/roslyn-unstable/libexec/.razorExtension
139+ '' ;
140+ } ;
141+ in {
142+ vscode-csharp =
143+ packageExtension pkgs . vscode-extensions . ms-dotnettools . csharp "share/vscode/extensions/ms-dotnettools.csharp/.razorExtension" ;
171144 } ;
172145
173146 cfg = config . vim . languages . csharp ;
174147in {
175148 options = {
176149 vim . languages . csharp = {
177- enable = mkEnableOption "C# language support" ;
150+ enable = mkEnableOption ''
151+ C# language support.
152+
153+ ::: {.note}
154+ It's worth noting that this support will not work if the .NET SDK is not installed.
155+ `roslyn` requires the .NET SDK 10 to work properly with Razor.
156+ `csharp_ls` and `omnisharp` require the .NET SDK 9. I strongly recommend using the most recent version available.
157+ :::
158+
159+ ::: {.warning}
160+ At the moment, only `roslyn` supports Razor.
161+ :::
162+ '' ;
178163
179164 treesitter = {
180- enable = mkEnableOption "C# treesitter" // { default = config . vim . languages . enableTreesitter ; } ;
181- package = mkGrammarOption pkgs "c-sharp" ;
165+ enable = mkEnableOption "C#/razor treesitter" // { default = config . vim . languages . enableTreesitter ; } ;
166+ csPackage = mkGrammarOption pkgs "c-sharp" ;
167+ razorPackage = mkGrammarOption pkgs "razor" ;
182168 } ;
183169
184170 lsp = {
@@ -188,18 +174,43 @@ in {
188174 type = deprecatedSingleOrListOf "vim.language.csharp.lsp.servers" ( enum ( attrNames servers ) ) ;
189175 default = defaultServers ;
190176 } ;
177+
178+ razorExtension = mkOption {
179+ description = ''
180+ razor extensions package to use
181+
182+ ::: {.warning}
183+ At the moment, only `roslyn` supports Razor;
184+ therefore, this option is effective only when `roslyn` is selected.
185+ :::
186+ '' ;
187+ type = enum ( attrNames razorExtensions ) ;
188+ default = defaultRazorExtension ;
189+ } ;
191190 } ;
192191 } ;
193192 } ;
194193
195194 config = mkIf cfg . enable ( mkMerge [
196195 ( mkIf cfg . treesitter . enable {
197196 vim . treesitter . enable = true ;
198- vim . treesitter . grammars = [ cfg . treesitter . package ] ;
197+ vim . treesitter . grammars = [ cfg . treesitter . csPackage cfg . treesitter . razorPackage ] ;
199198 } )
200199
200+ ( mkIf ( cfg . lsp . enable && lib . elem "roslyn" cfg . lsp . servers )
201+ {
202+ vim . extraPackages = [ pkgs . roslyn-ls pkgs . vscode-langservers-extracted ] ;
203+
204+ # NOTE: roslyn-nvim requires razorExtension dll's
205+ # See: https://github.com/seblyng/roslyn.nvim/blob/main/lua/roslyn/health.lua
206+ vim . luaConfigRC . razorExtension = ''
207+ vim.env.MASON = "${ razorExtensions . ${ cfg . lsp . razorExtension } } "
208+ '' ;
209+ } )
210+
201211 ( mkIf cfg . lsp . enable {
202212 vim . startPlugins = concatMap ( server : extraServerPlugins . ${ server } ) cfg . lsp . servers ;
213+
203214 vim . lsp . servers =
204215 mapListToAttrs ( name : {
205216 inherit name ;
0 commit comments