Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/manual/release-notes/rl-0.9.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,9 @@ https://github.com/gorbit99/codewindow.nvim
- Fix non-functional `vim.keymaps.*.noremap`. Now, setting it to false is
equivalent to `:lua vim.keymap.set(..., { remap = true })`

[CaueAnjos](https://github.com/caueanjos)

- Rename `roslyn_ls` to `roslyn` (required by roslyn-nvim).
- Add razor support for `roslyn` and `csharp_ls`

<!-- vim: set textwidth=80: -->
34 changes: 32 additions & 2 deletions modules/neovim/init/lsp.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,46 @@

cfg = config.vim.lsp;

# NOTE: Used to notify and redirect deprecated lsp servers
mkDeprecated = {
old,
new ? null,
message ? (
if new == null
then "${old} is deprecated."
else "${old} was renamed to ${new}. Please update it accordingly."
),
}: (
lib.warnIf
(cfg.servers.${old}
!= {})
message
{
${old}.enable = false;
}
// (mkIf (new != null) {
${new} = cfg.servers.${old};
})
);

servers =
cfg.servers
# Deprecated lsp servers
// (mkDeprecated {
old = "roslyn_ls";
new = "roslyn";
});

# TODO: lspConfigurations filter on enabledServers instead of cfg.servers?
lspConfigurations =
mapAttrsToList (
name: value: ''
vim.lsp.config["${name}"] = ${toLuaObject value}
''
)
cfg.servers;
servers;

enabledServers = filterAttrs (_: u: u.enable) cfg.servers;
enabledServers = filterAttrs (_: u: u.enable) servers;
in {
options = {
vim.lsp = {
Expand Down
108 changes: 84 additions & 24 deletions modules/plugins/languages/csharp.nix
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@
in
optionalString (key != null) "vim.keymap.set('n', '${key}', ${action}, {buffer=bufnr, noremap=true, silent=true, desc='${desc}'})";

# Omnisharp doesn't have colors in popup docs for some reason, and I've also
# seen mentions of it being way slower, so until someone finds missing
# functionality, this will be the default.
defaultServers = ["csharp_ls"];
# NOTE: roslyn is the most feature-rich option, and its Razor integration is better than csharp-ls (which only supports .cshtml).
defaultServers = ["roslyn"];
servers = {
omnisharp = {
cmd = mkLuaInline ''
Expand Down Expand Up @@ -118,8 +116,8 @@
};

csharp_ls = {
cmd = [(lib.getExe pkgs.csharp-ls)];
filetypes = ["cs"];
cmd = [(lib.getExe pkgs.csharp-ls) "--features" "razor-support"];
filetypes = ["cs" "razor"];
root_dir = mkLuaInline ''
function(bufnr, on_dir)
local function find_root_pattern(fname, lua_pattern)
Expand All @@ -137,17 +135,28 @@
};
};

roslyn_ls = {
roslyn = let
pkg = pkgs.vscode-extensions.ms-dotnettools.csharp;
pluginRoot = "${pkg}/share/vscode/extensions/ms-dotnettools.csharp";
exe = "${pluginRoot}/.roslyn/Microsoft.CodeAnalysis.LanguageServer";
razorSourceGenerator = "${pluginRoot}/.razorExtension/Microsoft.CodeAnalysis.LanguageServer";
razorDesignTimePath = "${pluginRoot}/.razorExtension/Targets/Microsoft.NET.Sdk.Razor.DesignTime.targets";
razorExtension = "${pluginRoot}/.razorExtension/Microsoft.VisualStudioCode.RazorExtension.dll";
in {
cmd = mkLuaInline ''
{
${toLuaObject (getExe pkgs.roslyn-ls)},
'--logLevel=Warning',
'--extensionLogDirectory=' .. vim.fs.dirname(vim.lsp.get_log_path()),
'--stdio',
"dotnet",
"${exe}.dll",
"--stdio",
"--logLevel=Information",
"--extensionLogDirectory=" .. vim.fs.dirname(vim.lsp.get_log_path()),
"--razorSourceGenerator=${razorSourceGenerator}",
"--razorDesignTimePath=${razorDesignTimePath}",
"--extension=${razorExtension}",
}
'';

filetypes = ["cs"];
filetypes = ["cs" "razor"];
root_dir = mkLuaInline ''
function(bufnr, on_dir)
local function find_root_pattern(fname, lua_pattern)
Expand All @@ -167,22 +176,58 @@
extraServerPlugins = {
omnisharp = ["omnisharp-extended-lsp-nvim"];
csharp_ls = ["csharpls-extended-lsp-nvim"];
roslyn_ls = [];
roslyn = ["roslyn-nvim"];
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is technically a breaking change, a warning about removal of "roslyn_ls" in lsp.servers would be nice

Copy link
Author

Choose a reason for hiding this comment

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

Now I warn it on lsp.servers. Just not sure if I did it the right way.

};

cfg = config.vim.languages.csharp;
in {
options = {
vim.languages.csharp = {
enable = mkEnableOption "C# language support";
enable = mkEnableOption ''
C# language support.

::: {.note}
This feature will not work if the .NET SDK is not installed.
Both `roslyn` and `csharp_ls` require the .NET SDK 10 to work properly with Razor.
Using the most recent SDK version is strongly recommended.
:::

:::{.tip}
There is a way to avoid always specifying _dotnet-sdk_10_ inside devshells, even when a project targets _dotnet-sdk_8_. You can achieve this by adding the following **Lua** configuration to your **NVF** setup (for example, via `luaConfigRC`):

```lua
vim.lsp.config('roslyn', {
cmd = vim.list_extend(
{ "$${pkgs.lib.getExe (with pkgs.dotnetCorePackages;
combinePackages [
sdk_10_0
sdk_9_0
sdk_8_0
])}" },
vim.list_slice(vim.lsp.config.roslyn.cmd, 2)
)
})
```
This configuration overrides only the first argument of the Roslyn LSP command (the `dotnet` executable), replacing it with a `dotnet` binary built from a combined package that includes SDK versions 10, 9, and 8. Additional SDK versions can be added if needed.

This approach is not a perfect solution. You may encounter issues if your project requires a specific patch version (for example, `8.0.433`) but the combined package only provides an earlier version (such as `8.0.300`). While this usually does not cause major problems, it is something to be aware of when using this setup.
:::

::: {.warning}
At the moment, only `roslyn` provides full Razor support.
`csharp_ls` is limited to `.cshtml` files.
:::
'';

treesitter = {
enable = mkEnableOption "C# treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "c_sharp";
csPackage = mkGrammarOption pkgs "c_sharp";
razorPackage = mkGrammarOption pkgs "razor";
};

lsp = {
enable = mkEnableOption "C# LSP support" // {default = config.vim.lsp.enable;};
enable =
mkEnableOption "C# language support" // {default = config.vim.lsp.enable;};
servers = mkOption {
description = "C# LSP server to use";
type = deprecatedSingleOrListOf "vim.language.csharp.lsp.servers" (enum (attrNames servers));
Expand All @@ -195,17 +240,32 @@ in {
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable {
vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package];
vim.treesitter.grammars = with cfg.treesitter; [csPackage razorPackage];
})

(mkIf cfg.lsp.enable {
vim.startPlugins = concatMap (server: extraServerPlugins.${server}) cfg.lsp.servers;
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
vim = {
startPlugins = concatMap (server: extraServerPlugins.${server}) cfg.lsp.servers;
luaConfigRC.razorFileTypes =
/*
lua
*/
''
-- Set unkown file types!
vim.filetype.add {
extension = {
razor = "razor",
cshtml = "razor",
},
}
'';
lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
};
})
]);
}
13 changes: 13 additions & 0 deletions npins/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,19 @@
"url": "https://github.com/rose-pine/neovim/archive/72a04c4065345b51b56aed4859ea1d884f734097.tar.gz",
"hash": "sha256-CAPZaKFR/WcLW/NW9FNG3jJDnNgzLuwJP+I43ppzkpA="
},
"roslyn-nvim": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "seblyng",
"repo": "roslyn.nvim"
},
"branch": "main",
"submodules": false,
"revision": "24f7c91ee5e09c63104deaab68f932620f25c24a",
"url": "https://github.com/seblyng/roslyn.nvim/archive/24f7c91ee5e09c63104deaab68f932620f25c24a.tar.gz",
"hash": "sha256-a/Slmkrz/4P/rfRhPa1W5kGV7joQNTN0Un7bbncCnk0="
},
"rtp-nvim": {
"type": "Git",
"repository": {
Expand Down