Skip to content

Commit 3a8d4fe

Browse files
committed
plugins/cmp: refactor source->plugin association
Introduce the internal option `cmpSourcePlugins` where plugins can register their nvim-cmp source name association.
1 parent bd422db commit 3a8d4fe

File tree

6 files changed

+136
-99
lines changed

6 files changed

+136
-99
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{
2+
lib,
3+
helpers,
4+
config,
5+
...
6+
}:
7+
with lib;
8+
let
9+
cfg = config.plugins.cmp;
10+
11+
extractSources = { sources, ... }: if isList sources then sources else [ ];
12+
13+
# Collect the names of the sources provided by the user
14+
# ["foo" "bar"]
15+
enabledSources =
16+
pipe
17+
[
18+
# cfg.setup.sources
19+
(extractSources cfg.settings)
20+
# cfg.filetype.<name>.sources
21+
(mapAttrsToList (_: extractSources) cfg.filetype)
22+
# cfg.cmdline.<name>.sources
23+
(mapAttrsToList (_: extractSources) cfg.cmdline)
24+
]
25+
[
26+
flatten
27+
(map (getAttr "name"))
28+
unique
29+
];
30+
in
31+
{
32+
options = {
33+
# Note: this option must be outside of `plugins` to avoid infinite recursion
34+
cmpSourcePlugins = mkOption {
35+
type = with types; attrsOf str;
36+
default = { };
37+
description = ''
38+
Internal option used to associate nvim-cmp source names with nixvim plugin module names.
39+
40+
Maps `<source-name> = <plugin-name>` where _plugin-name_ is the module name: `plugins.<plugin-name>.enable`.
41+
'';
42+
example = {
43+
foo = "cmp-foo";
44+
bar = "cmp-bar";
45+
};
46+
internal = true;
47+
visible = false;
48+
};
49+
50+
plugins.cmp.autoEnableSources = mkOption {
51+
type = types.bool;
52+
default = true;
53+
example = false;
54+
description = ''
55+
Scans the sources array and enable the corresponding plugins if they are known to nixvim.
56+
'';
57+
};
58+
};
59+
60+
config = mkIf (cfg.enable && cfg.autoEnableSources) (mkMerge [
61+
{
62+
warnings =
63+
# TODO: expand this warning to ft & cmd sources lists and `showDefs` the offending definitions
64+
optional (helpers.nixvimTypes.isRawType cfg.settings.sources) ''
65+
Nixvim (plugins.cmp): You have enabled `autoEnableSources` that tells Nixvim to automatically
66+
enable the source plugins with respect to the list of sources provided in `settings.sources`.
67+
However, the latter is proveded as a raw lua string which is not parseable by Nixvim.
68+
69+
If you want to keep using raw lua for defining your sources:
70+
- Ensure you enable the relevant plugins manually in your configuration;
71+
- Dismiss this warning by explicitly setting `autoEnableSources` to `false`;
72+
'';
73+
74+
# If the user has enabled the `foo` and `bar` sources, then `plugins` will look like:
75+
# {
76+
# cmp-foo.enable = true;
77+
# cmp-bar.enable = true;
78+
# }
79+
plugins = mapAttrs' (source: name: {
80+
inherit name;
81+
value.enable = mkIf (elem source enabledSources) true;
82+
}) config.cmpSourcePlugins;
83+
}
84+
{
85+
plugins.lsp.capabilities = mkIf (elem "nvim_lsp" enabledSources) ''
86+
capabilities = vim.tbl_deep_extend("force", capabilities, require('cmp_nvim_lsp').default_capabilities())
87+
'';
88+
}
89+
]);
90+
}

plugins/completion/cmp/cmp-helpers.nix

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
}:
88
with helpers.vim-plugin;
99
with lib;
10-
rec {
10+
{
1111
mkCmpSourcePlugin =
1212
{
1313
name,
14+
sourceName,
1415
extraPlugins ? [ ],
1516
useDefaultPackage ? true,
1617
...
@@ -20,49 +21,8 @@ rec {
2021
extraPlugins = extraPlugins ++ (lists.optional useDefaultPackage pkgs.vimPlugins.${name});
2122

2223
maintainers = [ maintainers.GaetanLepage ];
23-
};
24-
25-
extractSourcesFromOptionValue = sources: if isList sources then sources else [ ];
26-
27-
autoInstallSourcePluginsModule =
28-
cfg:
29-
let
30-
# cfg.setup.sources
31-
setupSources = extractSourcesFromOptionValue cfg.settings.sources;
32-
# cfg.filetype.<name>.sources
33-
filetypeSources = mapAttrsToList (
34-
_: filetypeConfig: extractSourcesFromOptionValue filetypeConfig.sources
35-
) cfg.filetype;
36-
# cfg.cmdline.<name>.sources
37-
cmdlineSources = mapAttrsToList (
38-
_: cmdlineConfig: extractSourcesFromOptionValue cmdlineConfig.sources
39-
) cfg.cmdline;
4024

41-
# [{name = "foo";} {name = "bar"; x = 42;} ...]
42-
allSources = flatten (setupSources ++ filetypeSources ++ cmdlineSources);
43-
44-
# Take only the names from the sources provided by the user
45-
# ["foo" "bar"]
46-
foundSources = lists.unique (map (source: source.name) allSources);
47-
48-
# If the user has enabled the `foo` and `bar` sources, this attrs will look like:
49-
# {
50-
# cmp-foo.enable = true;
51-
# cmp-bar.enable = true;
52-
# }
53-
attrsEnabled = mapAttrs' (sourceName: pluginName: {
54-
name = pluginName;
55-
value.enable = mkIf (elem sourceName foundSources) true;
56-
}) (import ./sources.nix);
57-
58-
lspCapabilities = mkIf (elem "nvim_lsp" foundSources) {
59-
lsp.capabilities = ''
60-
capabilities = vim.tbl_deep_extend("force", capabilities, require('cmp_nvim_lsp').default_capabilities())
61-
'';
62-
};
63-
in
64-
mkMerge [
65-
(mkIf cfg.autoEnableSources attrsEnabled)
66-
lspCapabilities
67-
];
25+
# Register the source -> plugin name association
26+
imports = [ { cmpSourcePlugins.${sourceName} = name; } ];
27+
};
6828
}

plugins/completion/cmp/default.nix

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,22 @@ helpers.neovim-plugin.mkNeovimPlugin config {
1616

1717
maintainers = [ maintainers.GaetanLepage ];
1818

19-
# Introduced on 2024 February 21
20-
# TODO: remove ~June 2024
2119
imports = [
20+
# Introduced on 2024 February 21
21+
# TODO: remove ~June 2024
2222
./deprecations.nix
23+
./auto-enable.nix
2324
./sources
2425
];
2526
deprecateExtraOptions = true;
2627

28+
inherit (cmpOptions) settingsOptions settingsExample;
2729
extraOptions = {
28-
autoEnableSources = mkOption {
29-
type = types.bool;
30-
default = true;
31-
description = ''
32-
Scans the sources array and installs the plugins if they are known to nixvim.
33-
'';
34-
};
35-
3630
inherit (cmpOptions) filetype cmdline;
3731
};
3832

39-
inherit (cmpOptions) settingsOptions settingsExample;
40-
4133
callSetup = false;
4234
extraConfig = cfg: {
43-
warnings =
44-
optional (cfg.autoEnableSources && (helpers.nixvimTypes.isRawType cfg.settings.sources))
45-
''
46-
Nixvim (plugins.cmp): You have enabled `autoEnableSources` that tells Nixvim to automatically
47-
enable the source plugins with respect to the list of sources provided in `settings.sources`.
48-
However, the latter is proveded as a raw lua string which is not parseable by Nixvim.
49-
50-
If you want to keep using raw lua for defining your sources:
51-
- Ensure you enable the relevant plugins manually in your configuration;
52-
- Dismiss this warning by explicitly setting `autoEnableSources` to `false`;
53-
'';
54-
5535
extraConfigLua =
5636
''
5737
local cmp = require('cmp')
@@ -68,9 +48,5 @@ helpers.neovim-plugin.mkNeovimPlugin config {
6848
cmdtype: settings: "cmp.setup.cmdline('${cmdtype}', ${helpers.toLuaObject settings})\n"
6949
) cfg.cmdline
7050
));
71-
72-
# If autoEnableSources is set to true, figure out which are provided by the user
73-
# and enable the corresponding plugins.
74-
plugins = (import ./cmp-helpers.nix args).autoInstallSourcePluginsModule cfg;
7551
};
7652
}

plugins/completion/cmp/sources/default.nix

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ let
1515
pkgs
1616
;
1717
};
18-
cmpSourcesPluginNames = attrValues (import ../sources.nix);
19-
pluginModules = map (name: cmpLib.mkCmpSourcePlugin { inherit name; }) cmpSourcesPluginNames;
18+
19+
cmpSourcesPluginNames = import ../sources.nix;
20+
pluginModules = mapAttrsToList (
21+
sourceName: name: cmpLib.mkCmpSourcePlugin { inherit sourceName name; }
22+
) cmpSourcesPluginNames;
2023
in
2124
{
2225
# For extra cmp plugins

tests/fetch-tests.nix

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ let
5757
inherit pkgs lib helpers;
5858
config = { };
5959
};
60-
cmp-sources = import ../plugins/completion/cmp/sources.nix;
6160
};
6261
inherit namespace;
6362
}
Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,39 @@
1-
{ pkgs, cmp-sources, ... }:
1+
{ pkgs, ... }:
22
{
33
all-sources = {
4-
plugins = {
5-
copilot-lua = {
6-
enable = true;
4+
module =
5+
{ config, ... }:
6+
{
7+
plugins = {
8+
copilot-lua = {
9+
enable = true;
710

8-
panel.enabled = false;
9-
suggestion.enabled = false;
10-
};
11-
12-
cmp = {
13-
enable = true;
14-
settings.sources =
15-
with pkgs.lib;
16-
let
17-
disabledSources = [
18-
# We do not provide the required HF_API_KEY environment variable.
19-
"cmp_ai"
20-
] ++ optional (pkgs.stdenv.hostPlatform.system == "aarch64-linux") "cmp_tabnine";
21-
22-
filterFunc = sourceName: !(elem sourceName disabledSources);
11+
panel.enabled = false;
12+
suggestion.enabled = false;
13+
};
2314

24-
sourceNames = filter filterFunc (attrNames cmp-sources);
25-
in
26-
map (sourceName: { name = sourceName; }) sourceNames;
15+
cmp = {
16+
enable = true;
17+
settings.sources =
18+
with pkgs.lib;
19+
let
20+
disabledSources = [
21+
# We do not provide the required HF_API_KEY environment variable.
22+
"cmp_ai"
23+
] ++ optional (pkgs.stdenv.hostPlatform.system == "aarch64-linux") "cmp_tabnine";
24+
in
25+
pipe config.cmpSourcePlugins [
26+
# All known source names
27+
attrNames
28+
# Filter out disabled sources
29+
(filter (name: !(elem name disabledSources)))
30+
# Convert names to source attributes
31+
(map (name: {
32+
inherit name;
33+
}))
34+
];
35+
};
36+
};
2737
};
28-
};
2938
};
3039
}

0 commit comments

Comments
 (0)