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 "C# language support. It requires .NET sdk 10 " ;
178151
179152 treesitter = {
180- enable = mkEnableOption "C# treesitter" // { default = config . vim . languages . enableTreesitter ; } ;
181- package = mkGrammarOption pkgs "c-sharp" ;
153+ enable = mkEnableOption "C#/razor treesitter" // { default = config . vim . languages . enableTreesitter ; } ;
154+ csPackage = mkGrammarOption pkgs "c-sharp" ;
155+ razorPackage = mkGrammarOption pkgs "razor" ;
182156 } ;
183157
184158 lsp = {
@@ -188,18 +162,36 @@ in {
188162 type = deprecatedSingleOrListOf "vim.language.csharp.lsp.servers" ( enum ( attrNames servers ) ) ;
189163 default = defaultServers ;
190164 } ;
165+
166+ razorExtension = mkOption {
167+ description = "razor extensions package to use" ;
168+ type = enum ( attrNames razorExtensions ) ;
169+ default = defaultRazorExtension ;
170+ } ;
191171 } ;
192172 } ;
193173 } ;
194174
195175 config = mkIf cfg . enable ( mkMerge [
196176 ( mkIf cfg . treesitter . enable {
197177 vim . treesitter . enable = true ;
198- vim . treesitter . grammars = [ cfg . treesitter . package ] ;
178+ vim . treesitter . grammars = [ cfg . treesitter . csPackage cfg . treesitter . razorPackage ] ;
199179 } )
200180
181+ ( mkIf ( cfg . lsp . enable && lib . elem "roslyn" cfg . lsp . servers )
182+ {
183+ vim . extraPackages = [ pkgs . roslyn-ls pkgs . vscode-langservers-extracted ] ;
184+
185+ # NOTE: roslyn-nvim requires razorExtension dll's
186+ # See: https://github.com/seblyng/roslyn.nvim/blob/main/lua/roslyn/health.lua
187+ vim . luaConfigRC . razorExtension = ''
188+ vim.env.MASON = "${ razorExtensions . ${ cfg . lsp . razorExtension } } "
189+ '' ;
190+ } )
191+
201192 ( mkIf cfg . lsp . enable {
202193 vim . startPlugins = concatMap ( server : extraServerPlugins . ${ server } ) cfg . lsp . servers ;
194+
203195 vim . lsp . servers =
204196 mapListToAttrs ( name : {
205197 inherit name ;
0 commit comments