diff --git a/plugins/by-name/navbuddy/default.nix b/plugins/by-name/navbuddy/default.nix index befaf70e..d098be42 100644 --- a/plugins/by-name/navbuddy/default.nix +++ b/plugins/by-name/navbuddy/default.nix @@ -1,273 +1,32 @@ -{ - lib, - helpers, - config, - pkgs, - ... -}: -with lib; +{ lib, ... }: let - cfg = config.plugins.navbuddy; - - percentageType = types.ints.between 0 100; - mkPercentageOpt = default: helpers.defaultNullOpts.mkNullable percentageType (toString default); + inherit (lib.nixvim) nestedLiteralLua; in -{ - options.plugins.navbuddy = lib.nixvim.plugins.neovim.extraOptionsOptions // { - enable = mkEnableOption "nvim-navbuddy"; +lib.nixvim.plugins.mkNeovimPlugin { + name = "navbuddy"; + package = "nvim-navbuddy"; + moduleName = "nvim-navbuddy"; + description = "A simple popup display that provides a breadcrumbs feature using an LSP server."; + maintainers = [ ]; - package = lib.mkPackageOption pkgs "nvim-navbuddy" { - default = [ - "vimPlugins" - "nvim-navbuddy" - ]; + # TODO: introduced 2025-10-10: remove after 26.05 + inherit (import ./deprecations.nix lib) deprecateExtraOptions optionsRenamedToSettings imports; + + settingsExample = { + lsp.auto_attach = true; + use_default_mapping = true; + mappings = { + "" = nestedLiteralLua "require('nvim-navbuddy.actions').close()"; + "q" = nestedLiteralLua "require('nvim-navbuddy.actions').close()"; + "j" = nestedLiteralLua "require('nvim-navbuddy.actions').next_sibling()"; + "k" = nestedLiteralLua "require('nvim-navbuddy.actions').previous_sibling()"; + "" = nestedLiteralLua "require('nvim-navbuddy.actions').vsplit()"; + "" = nestedLiteralLua "require('nvim-navbuddy.actions').hsplit()"; }; - - window = { - border = helpers.defaultNullOpts.mkBorder "rounded" "window border" '' - "rounded", "double", "solid", "none" or an array with eight chars building up the border in a clockwise fashion - starting with the top-left corner. eg: { "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" }. - ''; - - size = helpers.defaultNullOpts.mkNullable ( - with types; - either percentageType (submodule { - options = { - height = mkPercentageOpt 40 "The height size (in %)."; - - width = mkPercentageOpt 100 "The width size (in %)."; - }; - }) - ) 60 "The size of the window."; - - position = helpers.defaultNullOpts.mkNullable ( - with types; - either percentageType (submodule { - options = { - height = mkPercentageOpt 40 "The height size (in %)."; - - width = mkPercentageOpt 100 "The width size (in %)."; - }; - }) - ) 50 "The position of the window."; - - scrolloff = helpers.mkNullOrOption types.int '' - scrolloff value within navbuddy window - ''; - - sections = { - left = { - size = mkPercentageOpt 20 "The height size (in %)."; - - border = helpers.defaultNullOpts.mkBorder "rounded" "left section border" '' - "rounded", "double", "solid", "none" or an array with eight chars building up the border in a clockwise fashion - starting with the top-left corner. eg: { "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" }. - ''; - }; - - mid = { - size = mkPercentageOpt 40 "The height size (in %)."; - - border = helpers.defaultNullOpts.mkBorder "rounded" "mid section border" '' - "rounded", "double", "solid", "none" or an array with eight chars building up the border in a clockwise fashion - starting with the top-left corner. eg: { "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" }. - ''; - }; - - right = { - border = helpers.defaultNullOpts.mkBorder "rounded" "right section border" '' - "rounded", "double", "solid", "none" or an array with eight chars building up the border in a clockwise fashion - starting with the top-left corner. eg: { "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" }. - ''; - - preview = - helpers.defaultNullOpts.mkEnumFirstDefault - [ - "leaf" - "always" - "never" - ] - '' - Right section can show previews too. - Options: "leaf", "always" or "never" - ''; - }; - }; - }; - - nodeMarkers = { - enabled = helpers.defaultNullOpts.mkBool true "Enable node markers."; - - icons = { - leaf = helpers.defaultNullOpts.mkStr " " '' - The icon to use for leaf nodes. - ''; - - leafSelected = helpers.defaultNullOpts.mkStr " → " '' - The icon to use for selected leaf node. - ''; - - branch = helpers.defaultNullOpts.mkStr "  " '' - The icon to use for branch nodes. - ''; - }; - }; - - icons = mapAttrs (name: default: helpers.defaultNullOpts.mkStr default "icon for ${name}.") { - File = "󰈙 "; - Module = " "; - Namespace = "󰌗 "; - Package = " "; - Class = "󰌗 "; - Method = "󰆧 "; - Property = " "; - Field = " "; - Constructor = " "; - Enum = "󰕘"; - Interface = "󰕘"; - Function = "󰊕 "; - Variable = "󰆧 "; - Constant = "󰏿 "; - String = "󰀬 "; - Number = "󰎠 "; - Boolean = "◩ "; - Array = "󰅪 "; - Object = "󰅩 "; - Key = "󰌋 "; - Null = "󰟢 "; - EnumMember = " "; - Struct = "󰌗 "; - Event = " "; - Operator = "󰆕 "; - TypeParameter = "󰊄 "; - }; - - useDefaultMapping = helpers.defaultNullOpts.mkBool true '' - If set to false, only mappings set by user are set. Else default mappings are used for keys that are not set by user - ''; - - keymapsSilent = mkOption { - type = types.bool; - description = "Whether navbuddy keymaps should be silent"; - default = false; - }; - - mappings = - helpers.defaultNullOpts.mkAttrsOf types.str - { - "" = "close"; - "q" = "close"; - "j" = "next_sibling"; - "k" = "previous_sibling"; - - "h" = "parent"; - "l" = "children"; - "0" = "root"; - - "v" = "visual_name"; - "V" = "visual_scope"; - - "y" = "yank_name"; - "Y" = "yank_scope"; - - "i" = "insert_name"; - "I" = "insert_scope"; - - "a" = "append_name"; - "A" = "append_scope"; - - "r" = "rename"; - - "d" = "delete"; - - "f" = "fold_create"; - "F" = "fold_delete"; - - "c" = "comment"; - - "" = "select"; - "o" = "select"; - "J" = "move_down"; - "K" = "move_up"; - - "s" = "toggle_preview"; - - "" = "vsplit"; - "" = "hsplit"; - } - '' - Actions to be triggered for specified keybindings. It can take either action name i.e `toggle_preview` - Or it can a `rawLua`. - ''; - - lsp = { - autoAttach = helpers.defaultNullOpts.mkBool false '' - If set to true, you don't need to manually use attach function - ''; - - preference = helpers.mkNullOrOption (with types; listOf str) '' - list of lsp server names in order of preference - ''; - }; - - sourceBuffer = { - followNode = helpers.defaultNullOpts.mkBool true "Keep the current node in focus on the source buffer"; - - highlight = helpers.defaultNullOpts.mkBool true "Highlight the currently focused node"; - - reorient = - helpers.defaultNullOpts.mkEnumFirstDefault - [ - "smart" - "top" - "mid" - "none" - ] - '' - Right section can show previews too. - Options: "leaf", "always" or "never" - ''; - - scrolloff = helpers.defaultNullOpts.mkInt null '' - scrolloff value when navbuddy is open. - ''; + icons = { + Array = "> "; + Boolean = "> "; + Class = "> "; }; }; - - config = - let - setupOptions = - with cfg; - { - inherit window; - node_markers = with nodeMarkers; { - inherit enabled; - icons = with icons; { - inherit leaf branch; - leaf_selected = leafSelected; - }; - }; - inherit icons; - use_default_mapping = useDefaultMapping; - lsp = with lsp; { - auto_attach = autoAttach; - inherit preference; - }; - source_buffer = sourceBuffer; - mappings = helpers.ifNonNull' cfg.mappings ( - mapAttrs ( - key: action: if isString action then helpers.mkRaw "actions.${action}()" else action - ) mappings - ); - } - // cfg.extraOptions; - in - mkIf cfg.enable { - extraPlugins = [ cfg.package ]; - - extraConfigLua = '' - local actions = require("nvim-navbuddy.actions") - require('nvim-navbuddy').setup(${lib.nixvim.toLuaObject setupOptions}) - ''; - }; } diff --git a/plugins/by-name/navbuddy/deprecations.nix b/plugins/by-name/navbuddy/deprecations.nix new file mode 100644 index 00000000..1af86428 --- /dev/null +++ b/plugins/by-name/navbuddy/deprecations.nix @@ -0,0 +1,114 @@ +lib: +let + inherit (lib) + const + genAttrs + mapAttrs + ; + inherit (lib.nixvim) ifNonNull' mkRaw; +in +{ + deprecateExtraOptions = true; + + optionsRenamedToSettings = + map (lib.splitString ".") [ + "window.border" + "window.size" + "window.position" + "window.scrolloff" + "window.sections.left.size" + "window.sections.left.border" + "window.sections.mid.size" + "window.sections.mid.border" + "window.sections.right.border" + "window.sections.right.preview" + + "nodeMarkers.enabled" + "nodeMarkers.icons.leaf" + "nodeMarkers.icons.leafSelected" + "nodeMarkers.icons.branch" + "useDefaultMapping" + + "lsp.autoAttach" + "lsp.preference" + + "sourceBuffer.followNode" + "sourceBuffer.highlight" + "sourceBuffer.reorient" + "sourceBuffer.scrolloff" + ] + # Move icons to settings without changing case as icons are PascalCase in the plugin config + ++ + map + ( + x: + genAttrs [ "old" "new" ] (const [ + "icons" + x + ]) + ) + [ + "File" + "Module" + "Namespace" + "Package" + "Class" + "Method" + "Property" + "Field" + "Constructor" + "Enum" + "Interface" + "Function" + "Variable" + "Constant" + "String" + "Number" + "Boolean" + "Array" + "Object" + "Key" + "Null" + "EnumMember" + "Struct" + "Event" + "Operator" + "TypeParameter" + ]; + + imports = + let + basePathAnd = lib.concat [ + "plugins" + "navbuddy" + ]; + in + [ + (lib.mkRemovedOptionModule (basePathAnd [ "keymapsSilent" ]) '' + This option has never had any effect. + Please remove it. + '') + ( + let + oldOptPath = basePathAnd [ "mappings" ]; + in + lib.mkChangedOptionModule oldOptPath + (basePathAnd [ + "settings" + "mappings" + ]) + ( + config: + let + old = lib.getAttrFromPath oldOptPath config; + in + ifNonNull' old ( + mapAttrs ( + _: action: + if builtins.isString action then mkRaw "require('nvim-navbuddy.actions').${action}()" else action + ) old + ) + ) + ) + ]; +} diff --git a/tests/test-sources/plugins/by-name/navbuddy/default.nix b/tests/test-sources/plugins/by-name/navbuddy/default.nix index f59a11ac..8b631954 100644 --- a/tests/test-sources/plugins/by-name/navbuddy/default.nix +++ b/tests/test-sources/plugins/by-name/navbuddy/default.nix @@ -3,114 +3,153 @@ plugins.navbuddy.enable = true; }; + example = { + plugins.navbuddy = { + settings = { + lsp.auto_attach = true; + use_default_mapping = true; + mappings = { + "".__raw = "require('nvim-navbuddy.actions').close()"; + "q".__raw = "require('nvim-navbuddy.actions').close()"; + "j".__raw = "require('nvim-navbuddy.actions').next_sibling()"; + "k".__raw = "require('nvim-navbuddy.actions').previous_sibling()"; + "".__raw = "require('nvim-navbuddy.actions').vsplit()"; + "".__raw = "require('nvim-navbuddy.actions').hsplit()"; + }; + icons = { + Array = "> "; + Boolean = "> "; + Class = "> "; + }; + }; + }; + }; + defaults = { plugins.navbuddy = { enable = true; - - window = { - border = "rounded"; - size = { - height = 50; - width = 50; - }; - position = { - height = 50; - width = 50; - }; - scrolloff = 8; - sections = { - left = { - size = 50; - border = "rounded"; - }; - mid = { - size = 50; - border = "rounded"; - }; - right = { - preview = "always"; - border = "rounded"; + settings = { + window = { + border = "single"; + size = "60%"; + position = "50%"; + scrolloff.__raw = "nil"; + sections = { + left = { + border.__raw = "nil"; + size = "20%"; + win_options.__raw = "nil"; + }; + mid = { + border.__raw = "nil"; + size = "40%"; + win_options.__empty = { }; + }; + right = { + border.__raw = "nil"; + preview = "leaf"; + win_options.__raw = "nil"; + }; }; }; - }; - nodeMarkers = { - enabled = true; icons = { - leaf = " ... "; - leafSelected = "  "; - branch = " 󰆧 "; + "1" = "󰈙 "; + "2" = " "; + "3" = "󰌗 "; + "4" = " "; + "5" = "󰌗 "; + "6" = "󰆧 "; + "7" = " "; + "8" = " "; + "9" = " "; + "10" = "󰕘"; + "11" = "󰕘"; + "12" = "󰊕 "; + "13" = "󰆧 "; + "14" = "󰏿 "; + "15" = " "; + "16" = "󰎠 "; + "17" = "◩ "; + "18" = "󰅪 "; + "19" = "󰅩 "; + "20" = "󰌋 "; + "21" = "󰟢 "; + "22" = " "; + "23" = "󰌗 "; + "24" = " "; + "25" = "󰆕 "; + "26" = "󰊄 "; + "255" = "󰉨 "; }; - }; - icons = { - File = "󰆧 "; - Module = " "; - Namespace = "󰌗 "; - Package = " "; - Class = "󰌗 "; - Method = "󰆧 "; - Property = " "; - Field = " "; - Constructor = " "; - Enum = "󰕘"; - Interface = "󰕘"; - Function = "󰊕 "; - Variable = "󰆧 "; - Constant = "󰏿 "; - String = "󰀬 "; - Number = "󰎠 "; - Boolean = "◩ "; - Array = "󰅪 "; - Object = "󰅩 "; - Key = "󰌋 "; - Null = "󰟢 "; - EnumMember = " "; - Struct = "󰌗 "; - Event = " "; - Operator = "󰆕 "; - TypeParameter = "󰊄 "; - }; - useDefaultMapping = false; - mappings = { - "" = "close"; - "q" = "close"; - "j" = "next_sibling"; - "k" = "previous_sibling"; - "h" = "parent"; - "l" = "children"; - "0" = "root"; - "v" = "visual_name"; - "V" = "visual_scope"; - "y" = "yank_name"; - "Y" = "yank_scope"; - "i" = "insert_name"; - "I" = "insert_scope"; - "a" = "append_name"; - "A" = "append_scope"; - "r" = "rename"; - "d" = "delete"; - "f" = "fold_create"; - "F" = "fold_delete"; - "c" = "comment"; - "" = "select"; - "o" = "select"; - "J" = "move_down"; - "K" = "move_up"; - "s" = "toggle_preview"; - "" = "vsplit"; - "" = "hsplit"; - }; - lsp = { - autoAttach = true; - preference = [ - "clang" - "pyright" - ]; - }; - sourceBuffer = { - followNode = true; - highlight = true; - reorient = "top"; - scrolloff = 8; + use_default_mappings = true; + integrations = { + telescope.__raw = "nil"; + snacks.__raw = "nil"; + }; + mappings = { + "".__raw = "require('nvim-navbuddy.actions').close()"; + q.__raw = "require('nvim-navbuddy.actions').close()"; + + j.__raw = "require('nvim-navbuddy.actions').next_sibling()"; + k.__raw = "require('nvim-navbuddy.actions').previous_sibling()"; + + h.__raw = "require('nvim-navbuddy.actions').parent()"; + l.__raw = "require('nvim-navbuddy.actions').children()"; + "0".__raw = "require('nvim-navbuddy.actions').root()"; + + v.__raw = "require('nvim-navbuddy.actions').visual_name()"; + V.__raw = "require('nvim-navbuddy.actions').visual_scope()"; + + y.__raw = "require('nvim-navbuddy.actions').yank_name()"; + Y.__raw = "require('nvim-navbuddy.actions').yank_scope()"; + + i.__raw = "require('nvim-navbuddy.actions').insert_name()"; + I.__raw = "require('nvim-navbuddy.actions').insert_scope()"; + + a.__raw = "require('nvim-navbuddy.actions').append_name()"; + A.__raw = "require('nvim-navbuddy.actions').append_scope()"; + + r.__raw = "require('nvim-navbuddy.actions').rename()"; + + d.__raw = "require('nvim-navbuddy.actions').delete()"; + + f.__raw = "require('nvim-navbuddy.actions').fold_create()"; + F.__raw = "require('nvim-navbuddy.actions').fold_delete()"; + + c.__raw = "require('nvim-navbuddy.actions').comment()"; + + "".__raw = "require('nvim-navbuddy.actions').select()"; + o.__raw = "require('nvim-navbuddy.actions').select()"; + + J.__raw = "require('nvim-navbuddy.actions').move_down()"; + K.__raw = "require('nvim-navbuddy.actions').move_up()"; + + s.__raw = "require('nvim-navbuddy.actions').toggle_preview()"; + + "".__raw = "require('nvim-navbuddy.actions').vsplit()"; + "".__raw = "require('nvim-navbuddy.actions').hsplit()"; + + "g?".__raw = "require('nvim-navbuddy.actions').help()"; + }; + lsp = { + auto_attach = false; + preference.__raw = "nil"; + }; + source_buffer = { + follow_node = true; + highlight = true; + reorient = "smart"; + scrolloff.__raw = "nil"; + }; + node_markers = { + enabled = true; + icons = { + leaf = " "; + leaf_selected = " → "; + branch = " "; + }; + }; + custom_hl_group.__raw = "nil"; }; }; };