|
| 1 | +{ |
| 2 | + lib, |
| 3 | + config, |
| 4 | + options, |
| 5 | + ... |
| 6 | +}: |
| 7 | +let |
| 8 | + cfg = config.plugins.cmp; |
| 9 | + opt = options.plugins.cmp; |
| 10 | + |
| 11 | + cleanSrc = lib.flip builtins.removeAttrs [ |
| 12 | + "name" |
| 13 | + ]; |
| 14 | + |
| 15 | + getSrcDefs = |
| 16 | + sourceName: list: |
| 17 | + lib.pipe list [ |
| 18 | + (builtins.filter (src: src.name == sourceName)) |
| 19 | + (builtins.map (lib.filterAttrs (_: v: v != null))) |
| 20 | + lib.mergeAttrsList |
| 21 | + ]; |
| 22 | + |
| 23 | + getNestedSrcDefs = |
| 24 | + sourceName: set: |
| 25 | + lib.pipe set [ |
| 26 | + (builtins.mapAttrs (_: settings: getSrcDefs sourceName settings.sources)) |
| 27 | + (lib.filterAttrs (_: v: v != { })) |
| 28 | + (builtins.mapAttrs (_: cleanSrc)) |
| 29 | + ]; |
| 30 | + |
| 31 | + # Check if the source is listed in `plugins.cmp.settings.sources` without the plugin being enabled |
| 32 | + # This is most likely to happen when a user was relying on the now removed `autoEnableSources` option |
| 33 | + # Produce a warning with detailed migration instructions. |
| 34 | + mkWarningDef = |
| 35 | + name: |
| 36 | + let |
| 37 | + pluginOpt = options.plugins.${name}; |
| 38 | + pluginCfg = config.plugins.${name}; |
| 39 | + pluginLoc = lib.dropEnd 1 pluginOpt.enable.loc; |
| 40 | + cmpLoc = lib.dropEnd 1 options.plugins.cmp.enable.loc; |
| 41 | + |
| 42 | + # Collect defined sources for this plugin |
| 43 | + defaultDef = getSrcDefs pluginCfg.cmp.name cfg.settings.sources; |
| 44 | + sourceDefs = |
| 45 | + lib.optionalAttrs (defaultDef != { }) { |
| 46 | + default = cleanSrc defaultDef; |
| 47 | + } |
| 48 | + // lib.filterAttrs (_: v: v != { }) { |
| 49 | + cmdline = getNestedSrcDefs pluginCfg.cmp.name cfg.cmdline; |
| 50 | + filetypes = getNestedSrcDefs pluginCfg.cmp.name cfg.filetype; |
| 51 | + }; |
| 52 | + |
| 53 | + indent = " "; |
| 54 | + |
| 55 | + showSrcDef = |
| 56 | + loc: new: def: |
| 57 | + let |
| 58 | + defLoc = lib.showOption (cmpLoc ++ loc ++ [ "sources" ]); |
| 59 | + join = if lib.hasInfix "\n" suggestion then "\n" + indent else " "; |
| 60 | + suggestion = "${lib.showOption (pluginLoc ++ [ "cmp" ] ++ new)} = ${ |
| 61 | + if def == { } then "true" else lib.generators.toPretty { inherit indent; } def |
| 62 | + };"; |
| 63 | + in |
| 64 | + '' |
| 65 | + remove ${builtins.toJSON pluginCfg.cmp.name} from: ${defLoc} |
| 66 | + Instead define:${join}${suggestion}''; |
| 67 | + |
| 68 | + lines = |
| 69 | + lib.singleton "manually enable `${pluginOpt.enable}`" |
| 70 | + ++ lib.optional (sourceDefs ? default) (showSrcDef [ "settings" ] [ "default" ] sourceDefs.default) |
| 71 | + ++ lib.mapAttrsToList (name: showSrcDef [ "cmdline" name ] [ "cmdline" name ]) ( |
| 72 | + sourceDefs.cmdline or { } |
| 73 | + ) |
| 74 | + ++ lib.mapAttrsToList (name: showSrcDef [ "filetype" name ] [ "filetypes" name ]) ( |
| 75 | + sourceDefs.filetype or { } |
| 76 | + ); |
| 77 | + |
| 78 | + lineCount = builtins.length lines; |
| 79 | + in |
| 80 | + lib.mkIf |
| 81 | + ( |
| 82 | + cfg.enable |
| 83 | + && !pluginCfg.enable |
| 84 | + && pluginOpt.enable.highestPrio == 1500 |
| 85 | + && pluginCfg.cmp.enable |
| 86 | + && sourceDefs != { } |
| 87 | + ) |
| 88 | + ( |
| 89 | + lib.nixvim.mkWarnings (lib.showOption pluginLoc) '' |
| 90 | + The ${builtins.toJSON pluginCfg.cmp.name} nvim-cmp source has been defined via `${lib.showOption cmpLoc}`, howevew `${pluginOpt.enable}` is not enabled. |
| 91 | + You should${ |
| 92 | + if lineCount == 1 then |
| 93 | + " " + builtins.head lines |
| 94 | + else |
| 95 | + ":" |
| 96 | + + lib.concatImapStrings ( |
| 97 | + i: line: "\n${builtins.toString i}. ${lib.nixvim.utils.upperFirstChar line}" |
| 98 | + ) lines |
| 99 | + } |
| 100 | + (You can suppress this warning by explicitly setting `${pluginOpt.enable} = true`) |
| 101 | + '' # TODO: link to PR/docs/guide/faq |
| 102 | + ); |
| 103 | +in |
| 104 | +{ |
| 105 | + imports = [ |
| 106 | + (lib.mkRemovedOptionModule [ |
| 107 | + "cmpSourcePlugins" |
| 108 | + ] "Use `lib.nixvim.modules.mkCmpPluginModule` instead.") |
| 109 | + (lib.mkRemovedOptionModule [ "plugins" "cmp" "autoEnableSources" ] '' |
| 110 | + Instead of defining `${ |
| 111 | + lib.showOption (opt.settings.loc ++ [ "sources" ]) |
| 112 | + }` and using `autoEnableSources` to enable the relevant plugins, |
| 113 | + you should now enable the plugins and they will automatically add themselves to `${ |
| 114 | + lib.showOption (opt.settings.loc ++ [ "sources" ]) |
| 115 | + }`. |
| 116 | + '') # TODO: add a link to PR/docs/faq/guide |
| 117 | + ]; |
| 118 | + |
| 119 | + warnings = lib.pipe options.plugins [ |
| 120 | + (lib.flip builtins.removeAttrs [ |
| 121 | + # lspkind has its own `cmp` options, but isn't a nvim-cmp source |
| 122 | + "lspkind" |
| 123 | + ]) |
| 124 | + # Actual options are probably aliases, not plugins |
| 125 | + (lib.filterAttrs (_: opt: !lib.isOption opt)) |
| 126 | + (lib.filterAttrs (_: opt: opt ? cmp)) |
| 127 | + builtins.attrNames |
| 128 | + (builtins.map mkWarningDef) |
| 129 | + lib.mkMerge |
| 130 | + ]; |
| 131 | +} |
0 commit comments