|
190 | 190 | })
|
191 | 191 | ];
|
192 | 192 | };
|
| 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 | + }; |
193 | 346 | }
|
194 | 347 | // lib.mapAttrs (
|
195 | 348 | name: msg:
|
|
0 commit comments