Skip to content

Commit a9b720f

Browse files
committed
lib/modules: init mkCmpPluginModule
1 parent e354aeb commit a9b720f

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

lib/modules.nix

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,159 @@ in
190190
})
191191
];
192192
};
193+
194+
# Create a module configuring a plugin's integration with nvim-cmp and blink.cmp
195+
mkCmpPluginModule =
196+
{
197+
# The plugin's option location-path
198+
loc ? [
199+
"plugins"
200+
pluginName
201+
],
202+
# Name of the plugin, used in documentation
203+
pluginName,
204+
# The nvim-cmp source name
205+
# TODO: can we compute a sane default for sourceName?
206+
sourceName,
207+
# Defaults for the corresponding cmp options
208+
enableDefault ? true,
209+
enableCmdline ? { },
210+
enabledFiletypes ? { },
211+
# Whether to include a `blink` option at all
212+
offerBlinkCompatibility ? true,
213+
# Defaults for the blink compatibility option
214+
enableBlinkProvider ? false,
215+
enableBlinkDefault ? false,
216+
enableBlinkCmdline ? false,
217+
enabledBlinkFiletypes ? { },
218+
# Whether the plugin's settings should be used as the blink provider's `opts`
219+
usePluginSettingsForBlink ? false,
220+
# The key to use with blink,
221+
# i.e. the attr name for `sources.providers.<name>`
222+
# TODO: should this default to pluginName or sourceName?
223+
blinkProviderKey ? lib.strings.toLower pluginName,
224+
}:
225+
{ config, options, ... }:
226+
let
227+
pluginOpt = lib.getAttrFromPath loc options;
228+
pluginCfg = lib.getAttrFromPath loc config;
229+
blinkOpt = pluginOpt.blink;
230+
blinkCfg = pluginCfg.blink;
231+
cfg = pluginCfg.cmp;
232+
toSourceDef = v: lib.optionalAttrs (builtins.isAttrs v) v // { inherit (cfg) name; };
233+
toSources = v: { sources = [ (toSourceDef v) ]; };
234+
in
235+
{
236+
imports = lib.optionals offerBlinkCompatibility [
237+
(lib.nixvim.modules.mkBlinkPluginModule {
238+
inherit loc pluginName sourceName;
239+
key = blinkProviderKey;
240+
module = "blink.compat.source";
241+
enableProvider = enableBlinkProvider;
242+
enableDefault = enableBlinkDefault;
243+
enableCmdline = enableBlinkCmdline;
244+
enabledFiletypes = enabledBlinkFiletypes;
245+
usePluginSettings = usePluginSettingsForBlink;
246+
})
247+
{
248+
options = lib.setAttrByPath loc {
249+
blink.settings.name = internal;
250+
};
251+
config = lib.mkIf (pluginCfg.enable && blinkCfg.enable) {
252+
# Enable blink-compat if the plugin has `blink.enable = true`
253+
plugins.blink-compat.enable = true;
254+
# This warning will show if someone overrides `plugins.blink-compat.enable = mkForce false`
255+
warnings = lib.nixvim.mkWarnings (lib.showOption loc) {
256+
when = !config.plugins.blink-compat.enable;
257+
message = ''
258+
`${blinkOpt.enable}` is enabled, but `${options.plugins.blink-compat.enable}` is not.
259+
This plugin is a nvim-cmp source, so it requires blink.compat when used with blink.cmp.
260+
'';
261+
};
262+
};
263+
}
264+
];
265+
options = lib.setAttrByPath loc {
266+
cmp = {
267+
enable = lib.mkOption {
268+
type = lib.types.bool;
269+
# FIXME: this should default to true, but it is incompatible with autoEnableCmpSources
270+
default = false;
271+
example = true;
272+
description = ''
273+
Whether to integrate this plugin with nvim-cmp.
274+
'';
275+
};
276+
name = lib.mkOption {
277+
type = lib.types.str;
278+
default = sourceName;
279+
description = "${pluginName}'s nvim-cmp source name.";
280+
internal = true;
281+
};
282+
default = lib.mkOption {
283+
type = with lib.types; either bool (attrsOf anything);
284+
default = enableDefault;
285+
example = !enableDefault;
286+
description = ''
287+
Whether to include this plugin in the `default` completion source list.
288+
289+
Can be defined as attrs to pass additional config to the source.
290+
'';
291+
};
292+
cmdline = lib.mkOption {
293+
type = with lib.types; attrsOf (either bool (attrsOf anything));
294+
# Remove false attrs in the final value
295+
apply = lib.filterAttrs (_: v: v != false);
296+
default = enableCmdline;
297+
# TODO: example
298+
description = ''
299+
Whether to include this plugin in the specific `cmdline` completion source lists.
300+
301+
Elements can be defined as attrs to pass additional config to the source.
302+
'';
303+
};
304+
filetypes = lib.mkOption {
305+
type = with lib.types; attrsOf (either bool (attrsOf anything));
306+
# Remove false attrs in the final value
307+
apply = lib.filterAttrs (_: v: v != false);
308+
default = enabledFiletypes;
309+
# TODO: example
310+
description = ''
311+
Whether to include this plugin in the specific `per_filetype` completion source lists.
312+
313+
Elements can be defined as attrs to pass additional config to the source.
314+
'';
315+
};
316+
};
317+
};
318+
config = lib.mkMerge [
319+
{
320+
# Backwards compatibility with autoEnableCmpSources
321+
cmpSourcePlugins.${sourceName} =
322+
assert lib.assertMsg (builtins.length loc == 2 && builtins.head loc == "plugins")
323+
"autoEnableCmpSources assumes all cmp source plugins are in the `plugins` namespace. Unsupported plugin `${lib.showOption loc}`.";
324+
pluginName;
325+
}
326+
(lib.mkIf (pluginCfg.enable && cfg.enable) {
327+
# FIXME: even though we have the mkIf, we also need optionalAttrs
328+
# to avoid inf-recursion caused by `autoEnableSources`
329+
plugins.cmp = lib.optionalAttrs cfg.enable {
330+
# TODO: consider setting:
331+
# autoEnableSources = lib.mkDefault false;
332+
settings = lib.mkIf (cfg.default != false) (toSources cfg.default);
333+
cmdline = lib.mkIf (cfg.cmdline != { }) (builtins.mapAttrs (_: toSources) cfg.cmdline);
334+
filetype = lib.mkIf (cfg.filetypes != { }) (builtins.mapAttrs (_: toSources) cfg.filetypes);
335+
};
336+
warnings = lib.nixvim.mkWarnings (lib.showOption loc) {
337+
when = !config.plugins.cmp.enable && options.plugins.cmp.enable.highestPrio == 1500;
338+
message = ''
339+
You have enabled the nvim-cmp source, but `plugins.cmp` is not enabled.
340+
You can suppress this warning by explicitly setting `plugins.cmp.enable = false`.
341+
'';
342+
};
343+
})
344+
];
345+
};
193346
}
194347
// lib.mapAttrs (
195348
name: msg:

0 commit comments

Comments
 (0)