Skip to content

Commit b281999

Browse files
committed
modules/lsp/server: declare package defaults
Convert the `attrsOf (servers.nix)` option to a freeform submodule. Declare a `servers.nix` option for each lsp server listed in `lsp-packages.nix` that has a known nixpkgs package.
1 parent cd3cbb1 commit b281999

File tree

3 files changed

+94
-31
lines changed

3 files changed

+94
-31
lines changed

modules/lsp/default.nix

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,58 @@
22
lib,
33
config,
44
options,
5+
pkgs,
56
...
67
}:
78
let
89
inherit (lib) types;
910
inherit (lib.nixvim) toLuaObject;
1011

1112
cfg = config.lsp;
13+
14+
mkServerModule = args: lib.modules.importApply ./server.nix ({ inherit pkgs; } // args);
15+
16+
mkServerOption =
17+
name:
18+
{
19+
package ? null,
20+
# lsp-packages.nix tracks some custom commands, however this is currently not used by `server.nix`
21+
cmd ? null,
22+
}:
23+
let
24+
# Get the package so we can link to its homepage
25+
homepage = lib.pipe options.lsp.servers [
26+
# Get suboptions of `lsp.servers`
27+
(opt: opt.type.getSubOptions opt.loc)
28+
# Get suboptions of `lsp.servers.<name>`
29+
(opts: opts.${name}.type.getSubOptions opts.${name}.loc)
30+
# Get package option's homepage
31+
(opts: opts.package.default.meta.homepage or null)
32+
];
33+
34+
nameLink = if homepage == null then name else "[${name}](${homepage})";
35+
in
36+
lib.mkOption {
37+
type = types.submodule (mkServerModule {
38+
inherit name package;
39+
});
40+
description = ''
41+
The ${nameLink} language server.
42+
'';
43+
default = { };
44+
};
45+
46+
# Combine `packages` and `customCmd` sets from `lsp-packages.nix`
47+
# We use this set to generate the package-option defaults
48+
serverPackages =
49+
let
50+
inherit (import ../../plugins/lsp/lsp-packages.nix)
51+
packages
52+
customCmd
53+
;
54+
normalisedPackages = builtins.mapAttrs (_: package: { inherit package; }) packages;
55+
in
56+
normalisedPackages // customCmd;
1257
in
1358
{
1459
options.lsp = {
@@ -25,7 +70,11 @@ in
2570
};
2671

2772
servers = lib.mkOption {
28-
type = types.attrsOf (types.submodule ./server.nix);
73+
type = types.submodule {
74+
freeformType = types.attrsOf (types.submodule (mkServerModule { }));
75+
options = builtins.mapAttrs mkServerOption serverPackages;
76+
};
77+
2978
description = ''
3079
LSP servers to enable and/or configure.
3180
@@ -35,7 +84,7 @@ in
3584
This can be installed using [`${options.plugins.lspconfig.enable}`][`plugins.lspconfig`].
3685
3786
[nvim-lspconfig]: ${options.plugins.lspconfig.package.default.meta.homepage}
38-
[`plugins.lspconfig`]: ../plugins/lspconfig/index.md
87+
[`plugins.lspconfig`]: ../../plugins/lspconfig/index.md
3988
'';
4089
default = { };
4190
example = {

modules/lsp/server.nix

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,73 @@
1+
# Usage: lib.importApply ./server.nix { /*args*/ }
2+
{
3+
name ? "the language server",
4+
package ? null,
5+
config ? null,
6+
pkgs ? { },
7+
}:
8+
let
9+
# module arg `name` shadows `name`
10+
displayName = name;
11+
in
112
{ lib, name, ... }:
213
let
314
inherit (lib) types;
415
in
516
{
617
options = {
7-
enable = lib.mkEnableOption "the language server";
18+
enable = lib.mkEnableOption displayName;
819

920
name = lib.mkOption {
1021
type = types.maybeRaw types.str;
1122
description = ''
12-
The name of the language server, supplied to functions like `vim.lsp.enable()`.
23+
The name to use for ${displayName}.
24+
Supplied to functions like `vim.lsp.enable()`.
1325
'';
1426
default = name;
1527
defaultText = lib.literalMD "the attribute name";
1628
};
1729

30+
package = lib.mkPackageOption pkgs (package.name or (lib.strings.removePrefix "the " displayName)) {
31+
nullable = true;
32+
default = package.default or package;
33+
example = package.example or null;
34+
extraDescription = ''
35+
${package.extraDescription or ""}
36+
37+
Alternatively, ${displayName} should be installed on your `$PATH`.
38+
'';
39+
};
40+
1841
activate = lib.mkOption {
1942
type = types.bool;
2043
description = ''
21-
Whether to call `vim.lsp.enable()` for this server.
44+
Whether to call `vim.lsp.enable()` for ${displayName}.
2245
'';
2346
default = true;
2447
example = false;
2548
};
2649

27-
package = lib.mkOption {
28-
type = with types; nullOr package;
29-
default = null;
30-
description = ''
31-
Package to use for this language server.
32-
33-
Alternatively, the language server should be available on your `$PATH`.
34-
'';
35-
};
36-
3750
config = lib.mkOption {
3851
type = with types; attrsOf anything;
3952
description = ''
40-
Configurations for each language server.
53+
Configurations for ${displayName}. ${config.extraDescription or ""}
4154
'';
4255
default = { };
43-
example = {
44-
cmd = [
45-
"clangd"
46-
"--background-index"
47-
];
48-
root_markers = [
49-
"compile_commands.json"
50-
"compile_flags.txt"
51-
];
52-
filetypes = [
53-
"c"
54-
"cpp"
55-
];
56-
};
56+
example =
57+
config.example or {
58+
cmd = [
59+
"clangd"
60+
"--background-index"
61+
];
62+
root_markers = [
63+
"compile_commands.json"
64+
"compile_flags.txt"
65+
];
66+
filetypes = [
67+
"c"
68+
"cpp"
69+
];
70+
};
5771
};
5872
};
5973
}

plugins/by-name/lspconfig/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ lib.nixvim.plugins.mkNeovimPlugin {
3535
> setup that relate to neovim's builtin LSP and are now being moved to the
3636
> new [`lsp`] module.
3737
38-
[`lsp`]: ../../lsp/servers.md
38+
[`lsp`]: ../../lsp/servers/index.md
3939
[`plugins.lsp`]: ../lsp/index.md
4040
[nvim-lspconfig]: ${opts.package.default.meta.homepage}
4141
'';

0 commit comments

Comments
 (0)