diff --git a/plugins/by-name/wilder/default.nix b/plugins/by-name/wilder/default.nix index 76e3749b..2518430b 100644 --- a/plugins/by-name/wilder/default.nix +++ b/plugins/by-name/wilder/default.nix @@ -1,258 +1,56 @@ -{ - lib, - helpers, - config, - pkgs, - ... -}: -with lib; -let - cfg = config.plugins.wilder; +{ lib, ... }: +lib.nixvim.plugins.mkNeovimPlugin { + name = "wilder"; + package = "wilder-nvim"; + maintainers = [ lib.maintainers.GaetanLepage ]; - mkKeyOption = - default: desc: - helpers.defaultNullOpts.mkNullable - ( - with types; - either str (submodule { - options = { - key = mkOption { - type = str; - description = desc; - }; + # TODO: introduced 2025-10-13: remove after 26.05 + inherit (import ./deprecations.nix lib) deprecateExtraOptions optionsRenamedToSettings imports; - fallback = mkOption { - type = either str (enum [ false ]); - description = '' - For a no-op, set to "". - - The fallback mappings can be disabled by setting `fallback` to 0. - - Disabling the fallback mapping allows a `||` mapping to be used which improves - rendering performance slightly as the mappings to be called outside the sandbox - (see `|:map-expression|`). - ''; - }; - }; - }) - ) - default - '' - ${desc} - - NOTE: - A string or an attrs (with keys `key` and `fallback`) representing the mapping to bind to - `|wilder#next()|`. - If a string is provided, it is automatically converted to `{key = ; fallback = ;}`. - - - `mapping` is the `|cmap|` used to bind to `|wilder#next()|`. - - `fallback` is the mapping used if `|wilder#in_context()|` is false. - ''; -in -{ - options.plugins.wilder = lib.nixvim.plugins.neovim.extraOptionsOptions // { - enable = mkEnableOption "wilder-nvim"; - - package = lib.mkPackageOption pkgs "wilder-nvim" { - default = [ - "vimPlugins" - "wilder-nvim" - ]; - }; - - ### Setup options ### - enableCmdlineEnter = helpers.defaultNullOpts.mkBool true '' - If true calls `wilder#enable_cmdline_enter()`. - Creates a new `|CmdlineEnter|` autocmd to which will start wilder when the cmdline is - entered. - ''; - - modes = - helpers.defaultNullOpts.mkListOf - (types.enum [ - "/" - "?" - ":" - ]) - [ - "/" - "?" - ] - "List of modes that wilder will be active in."; - - wildcharm = - helpers.defaultNullOpts.mkNullable (with types; either str (enum [ false ])) "&wildchar" - '' - Key to set the 'wildcharm' option to. - Can be set to v:false to skip the setting. - ''; - - nextKey = mkKeyOption "" '' - A key to map to `wilder#next()` providing next suggestion. - ''; - - prevKey = mkKeyOption "" '' - A key to map to `wilder#prev()` providing previous suggestion. - ''; - - acceptKey = mkKeyOption "" '' - Mapping to bind to `wilder#accept_completion()`. - ''; - - rejectKey = mkKeyOption "" '' - Mapping to bind to `wilder#reject_completion()`. - ''; - - acceptCompletionAutoSelect = helpers.defaultNullOpts.mkBool true '' - The `auto_select` option passed to `wilder#accept_completion()`, if mapped. - ''; - - ### Other options ### - useCmdlinechanged = helpers.mkNullOrOption types.bool '' - If true, wilder will refresh queries when the `|CmdlineChanged|` autocommand is triggered. - Otherwise it will use a `|timer|` to check whether the cmdline has changed. - Using a timer will be more resource intensive. - - Default: `exists('##CmdlineChanged')` - ''; - - interval = helpers.defaultNullOpts.mkUnsignedInt 100 '' - Interval of the `|timer|` used to check whether the cmdline has changed, in milliseconds. - Only applicable if `useCmdlinechanged` is false. - ''; - - beforeCursor = helpers.defaultNullOpts.mkBool false '' - If true, wilder will look only at the part of the cmdline before the cursor, and when - selecting a completion, the entire cmdline will be replaced. - Only applicable if `useCmdlinechanged` is false. - ''; - - usePythonRemotePlugin = helpers.mkNullOrOption types.bool '' - If true, uses the Python remote plugin. - This option can be set to false to disable the Python remote plugin. - - This option has to be set before setting the `pipeline` option and before wilder is first - run. - - Default: `has('python3') && (has('nvim') || exists('*yarp#py3'))` - ''; - - numWorkers = helpers.defaultNullOpts.mkUnsignedInt 2 '' - Number of workers for the Python 3 `|remote-plugin|`. - Has to be set at startup, before wilder is first run. - Setting the option after the first run has no effect. - ''; - - pipeline = helpers.mkNullOrOption (with lib.types; listOf strLua) '' - Sets the pipeline to use to get completions. - See `|wilder-pipeline|`. - - Example: - ```lua - [ - \'\' - wilder.branch( - wilder.cmdline_pipeline({ - language = 'python', - fuzzy = 1, - }), - wilder.python_search_pipeline({ - pattern = wilder.python_fuzzy_pattern(), - sorter = wilder.python_difflib_sorter(), - engine = 're', - }) - ) - \'\' - ] - ``` - ''; - - renderer = helpers.defaultNullOpts.mkLuaFn "nil" '' - Sets the renderer to used to display the completions. - See `|wilder-renderer|`. - - Example: - ```lua - \'\' - wilder.wildmenu_renderer({ - -- highlighter applies highlighting to the candidates - highlighter = wilder.basic_highlighter(), - }) - \'\' - ``` - ''; - - preHook = helpers.defaultNullOpts.mkLuaFn "nil" '' - A function which takes a `ctx`. - This function is called when wilder starts, or when wilder becomes unhidden. - See `|wilder-hidden|`. - - `ctx` contains no keys. - ''; - - postHook = helpers.defaultNullOpts.mkLuaFn "nil" '' - A function which takes a `ctx`. - This function is called when wilder stops, or when wilder becomes hidden. - See `|wilder-hidden|`. - - `ctx` contains no keys. - ''; + settingsExample = { + modes = [ + ":" + "/" + "?" + ]; + next_key = ""; + previous_key = ""; }; - config = - let - setupOptions = - with cfg; - let - processKeyOpt = - key: - helpers.ifNonNull' key ( - if isString key then - key - else - [ - key.key - key.fallback - ] - ); - in - { - enable_cmdline_enter = enableCmdlineEnter; - inherit modes; - inherit wildcharm; - next_key = processKeyOpt nextKey; - previous_key = processKeyOpt prevKey; - accept_key = processKeyOpt acceptKey; - reject_key = processKeyOpt rejectKey; - accept_completion_auto_select = acceptCompletionAutoSelect; - }; + extraOptions = { + options = lib.mkOption { + type = with lib.types; attrsOf anything; + default = { }; + example = { + use_python_remote_plugin = 0; + renderer = lib.nixvim.nestedLiteralLua '' + wilder.popupmenu_renderer( + wilder.popupmenu_border_theme({ + highlights = { border = 'Normal' }, + border = 'rounded', + pumblend = 20, + }) + ) + ''; + }; + description = '' + Attrs of options to forward to `require('wilder').set_option`. - options = - with cfg; - { - use_cmdlinechanged = useCmdlinechanged; - inherit interval; - before_cursor = beforeCursor; - use_python_remote_plugin = usePythonRemotePlugin; - num_workers = numWorkers; - pipeline = helpers.ifNonNull' pipeline (map helpers.mkRaw pipeline); - inherit renderer; - pre_hook = preHook; - post_hook = postHook; - } - // cfg.extraOptions; - in - mkIf cfg.enable { - extraPlugins = [ cfg.package ]; - - extraConfigLua = '' - wilder = require("wilder") - wilder.setup(${lib.nixvim.toLuaObject setupOptions}) - - local __wilderOptions = ${lib.nixvim.toLuaObject options} - for key, value in pairs(__wilderOptions) do - wilder.set_option(key, value) - end + For your convenience, the `wilder` variable is available in the scope. ''; }; + }; + + callSetup = false; + extraConfig = cfg: { + plugins.wilder.luaConfig.content = '' + local wilder = require("wilder") + wilder.setup(${lib.nixvim.toLuaObject cfg.settings}) + + local __wilderOptions = ${lib.nixvim.toLuaObject cfg.options} + for key, value in pairs(__wilderOptions) do + wilder.set_option(key, value) + end + ''; + }; } diff --git a/plugins/by-name/wilder/deprecations.nix b/plugins/by-name/wilder/deprecations.nix new file mode 100644 index 00000000..13f9af75 --- /dev/null +++ b/plugins/by-name/wilder/deprecations.nix @@ -0,0 +1,114 @@ +lib: { + # NOTE: extraOptions was not used along with `require('wilder').setup` but with the `set_option` logic + # It is replaced by the `plugins.wilder.options` option. + deprecateExtraOptions = false; + + imports = + let + basePluginPath = [ + "plugins" + "wilder" + ]; + settingsPath = basePluginPath ++ [ "settings" ]; + optionsPath = basePluginPath ++ [ "options" ]; + + mkKeymapRename = + oldOptName: newOptName: + let + oldPath = basePluginPath ++ [ oldOptName ]; + newPath = settingsPath ++ [ newOptName ]; + convert = + v: + if lib.isAttrs v then + let + newValue = [ + v.key + v.fallback + ]; + in + lib.warn '' + WARNING: the `${lib.showOption newPath}` will not automatically process the provided input. + You will need to provide the value as a list `${ + lib.generators.toPretty { multiline = false; } newValue + }`. + '' newValue + else + v; + in + lib.mkChangedOptionModule oldPath newPath (config: (convert (lib.getAttrFromPath oldPath config))); + + keymapRenames = lib.mapAttrsToList mkKeymapRename { + nextKey = "next_key"; + prevKey = "previous_key"; + acceptKey = "accept_key"; + rejectKey = "reject_key"; + }; + + mkLuaOptionRename = + oldOptName: newOptName: + let + oldPath = basePluginPath ++ [ oldOptName ]; + newPath = optionsPath ++ [ newOptName ]; + in + lib.mkChangedOptionModule oldPath newPath ( + config: + let + oldValue = lib.getAttrFromPath oldPath config; + in + ( + if lib.isString oldValue then + lib.warn '' + WARNING: `${lib.showOption newPath}` will not convert the value to a raw lua string. + '' lib.nixvim.mkRaw + else + lib.id + ) + oldValue + ); + optionRenames = + (lib.mapAttrsToList mkLuaOptionRename { + renderer = "renderer"; + preHook = "pre_hook"; + postHook = "post_hook"; + }) + ++ [ + ( + let + oldPath = basePluginPath ++ [ "pipeline" ]; + newPath = optionsPath ++ [ "pipeline" ]; + in + lib.mkChangedOptionModule oldPath newPath ( + config: + let + oldValue = lib.getAttrFromPath oldPath config; + in + if lib.isList oldValue then + lib.warn '' + WARNING: `${lib.showOption newPath}` will not convert list elements to raw lua strings. + '' map lib.nixvim.mkRaw oldValue + else + oldValue + ) + ) + ] + ++ (lib.nixvim.mkSettingsRenamedOptionModules basePluginPath optionsPath [ + "useCmdlinechanged" + "interval" + "beforeCursor" + "usePythonRemotePlugin" + "numWorkers" + ]); + in + keymapRenames + ++ optionRenames + ++ [ + (lib.mkRenamedOptionModule (basePluginPath ++ [ "extraOptions" ]) (basePluginPath ++ [ "options" ])) + ]; + + optionsRenamedToSettings = [ + "enableCmdlineEnter" + "modes" + "wildcharm" + "acceptCompletionAutoSelect" + ]; +} diff --git a/tests/test-sources/plugins/by-name/wilder/default.nix b/tests/test-sources/plugins/by-name/wilder/default.nix index c3ba53c8..85839478 100644 --- a/tests/test-sources/plugins/by-name/wilder/default.nix +++ b/tests/test-sources/plugins/by-name/wilder/default.nix @@ -1,3 +1,4 @@ +{ lib, ... }: { empty = { plugins.wilder.enable = true; @@ -7,46 +8,50 @@ plugins.wilder = { enable = true; - enableCmdlineEnter = true; - modes = [ - "/" - "?" - ]; - wildcharm = "&wildchar"; - nextKey = ""; - prevKey = ""; - acceptKey = ""; - rejectKey = ""; - acceptCompletionAutoSelect = true; + settings = { + enable_cmdline_enter = true; + modes = [ + "/" + "?" + ]; + wildcharm = "&wildchar"; + next_key = ""; + previous_key = ""; + accept_key = ""; + reject_key = ""; + accept_completion_auto_select = true; + }; - useCmdlinechanged = false; - interval = 100; - beforeCursor = false; - usePythonRemotePlugin = true; - numWorkers = 2; - pipeline = [ - '' - wilder.branch( - wilder.cmdline_pipeline({ - language = 'python', - fuzzy = 1, - }), - wilder.python_search_pipeline({ - pattern = wilder.python_fuzzy_pattern(), - sorter = wilder.python_difflib_sorter(), - engine = 're', - }) - ) - '' - ]; - renderer = '' - wilder.wildmenu_renderer({ - -- highlighter applies highlighting to the candidates - highlighter = wilder.basic_highlighter(), - }) - ''; - preHook = null; - postHook = null; + options = { + use_cmdlinechanged = false; + interval = 100; + before_cursor = false; + use_python_remote_plugin = true; + num_workers = 2; + pipeline = [ + (lib.nixvim.mkRaw '' + wilder.branch( + wilder.cmdline_pipeline({ + language = 'python', + fuzzy = 1, + }), + wilder.python_search_pipeline({ + pattern = wilder.python_fuzzy_pattern(), + sorter = wilder.python_difflib_sorter(), + engine = 're', + }) + ) + '') + ]; + renderer = lib.nixvim.mkRaw '' + wilder.wildmenu_renderer({ + -- highlighter applies highlighting to the candidates + highlighter = wilder.basic_highlighter(), + }) + ''; + pre_hook = null; + post_hook = null; + }; }; }; }