diff --git a/modules/ui/breadcrumbs/breadcrumbs.nix b/modules/ui/breadcrumbs/breadcrumbs.nix index f56223b..f3b1a28 100644 --- a/modules/ui/breadcrumbs/breadcrumbs.nix +++ b/modules/ui/breadcrumbs/breadcrumbs.nix @@ -5,7 +5,28 @@ }: let inherit (lib.options) mkOption mkEnableOption; inherit (lib.types) nullOr listOf enum bool str int; + inherit (lib.modules) mkRenamedOptionModule; + inherit (lib.nvim.types) mkPluginSetupOption; in { + imports = let + renameSetupOpt = oldPath: newPath: + mkRenamedOptionModule + (["vim" "ui" "breadcrumbs" "navbuddy"] ++ oldPath) + (["vim" "ui" "breadcrumbs" "navbuddy" "setupOpts"] ++ newPath); + in [ + (renameSetupOpt ["useDefaultMappings"] ["use_default_mappings"]) + (renameSetupOpt ["window"] ["window"]) + (renameSetupOpt ["nodeMarkers"] ["node_markers"]) + (renameSetupOpt ["lsp" "autoAttach"] ["lsp" "auto_attach"]) + (renameSetupOpt ["lsp" "preference"] ["lsp" "preference"]) + (renameSetupOpt ["sourceBuffer" "followNode"] ["source_buffer" "follow_node"]) + (renameSetupOpt ["sourceBuffer" "highlight"] ["source_buffer" "highlight"]) + (renameSetupOpt ["sourceBuffer" "reorient"] ["source_buffer" "reorient"]) + (renameSetupOpt ["sourceBuffer" "scrolloff"] ["source_buffer" "scrolloff"]) + # TODO: every option under icon is renamed to first letter capitalized + (renameSetupOpt ["icon"] ["icon"]) + ]; + options.vim.ui.breadcrumbs = { enable = mkEnableOption "breadcrumbs"; source = mkOption { @@ -27,13 +48,6 @@ in { navbuddy = { enable = mkEnableOption "navbuddy LSP helper UI. Enabling this option automatically loads and enables nvim-navic"; - # this option is interpreted as null if mkEnableOption is used, and therefore cannot be converted to a string in config.nix - useDefaultMappings = mkOption { - type = bool; - default = true; - description = "use default Navbuddy keybindings (disables user-specified keybinds)"; - }; - mappings = { close = mkOption { type = str; @@ -61,7 +75,7 @@ in { children = mkOption { type = str; - default = "h"; + default = "l"; description = "keybinding to navigate to the child node"; }; @@ -180,301 +194,310 @@ in { }; }; - window = { - # size = {} - # position = {} - - border = mkOption { - # TODO: let this type accept a custom string - type = enum ["single" "rounded" "double" "solid" "none"]; - default = config.vim.ui.borders.globalStyle; - description = "border style to use"; + setupOpts = mkPluginSetupOption "navbuddy" { + useDefaultMappings = mkOption { + type = bool; + default = true; + description = "use default Navbuddy keybindings (disables user-specified keybinds)"; }; - scrolloff = mkOption { - type = nullOr int; - default = null; - description = "Scrolloff value within navbuddy window"; - }; + window = { + # size = {} + # position = {} - sections = { - # left section - left = { - /* - size = { - type = with types; nullOr (intBetween 0 100); - default = null; - description = "size of the left section of Navbuddy UI in percentage (0-100)"; - }; - */ - - border = mkOption { - # TODO: let this type accept a custom string - type = nullOr (enum ["single" "rounded" "double" "solid" "none"]); - default = config.vim.ui.borders.globalStyle; - description = "border style to use for the left section of Navbuddy UI"; - }; + border = mkOption { + # TODO: let this type accept a custom string + type = enum ["single" "rounded" "double" "solid" "none"]; + default = config.vim.ui.borders.globalStyle; + description = "border style to use"; }; - # middle section - mid = { - /* - size = { - type = with types; nullOr (intBetween 0 100); - default = null; - description = "size of the left section of Navbuddy UI in percentage (0-100)"; - }; - */ - - border = mkOption { - # TODO: let this type accept a custom string - type = nullOr (enum ["single" "rounded" "double" "solid" "none"]); - default = config.vim.ui.borders.globalStyle; - description = "border style to use for the middle section of Navbuddy UI"; - }; + scrolloff = mkOption { + type = nullOr int; + default = null; + description = "Scrolloff value within navbuddy window"; }; - # right section - # there is no size option for the right section, it fills the remaining space - right = { - border = mkOption { - # TODO: let this type accept a custom string - type = nullOr (enum ["single" "rounded" "double" "solid" "none"]); - default = config.vim.ui.borders.globalStyle; - description = "border style to use for the right section of Navbuddy UI"; + sections = { + # left section + left = { + /* + size = mkOption { + type = nullOr (intBetween 0 100); + default = null; + description = "size of the left section of Navbuddy UI in percentage (0-100)"; + }; + */ + + border = mkOption { + # TODO: let this type accept a custom string + type = nullOr (enum ["single" "rounded" "double" "solid" "none"]); + default = config.vim.ui.borders.globalStyle; + description = "border style to use for the left section of Navbuddy UI"; + }; }; - preview = mkOption { - type = enum ["leaf" "always" "never"]; - default = "leaf"; - description = "display mode of the preview on the right section"; + # middle section + mid = { + /* + size = { + type = nullOr (intBetween 0 100); + default = null; + description = "size of the left section of Navbuddy UI in percentage (0-100)"; + }; + */ + + border = mkOption { + # TODO: let this type accept a custom string + type = nullOr (enum ["single" "rounded" "double" "solid" "none"]); + default = config.vim.ui.borders.globalStyle; + description = "border style to use for the middle section of Navbuddy UI"; + }; + }; + + # right section + # there is no size option for the right section, it fills the remaining space + right = { + border = mkOption { + # TODO: let this type accept a custom string + type = nullOr (enum ["single" "rounded" "double" "solid" "none"]); + default = config.vim.ui.borders.globalStyle; + description = "border style to use for the right section of Navbuddy UI"; + }; + + preview = mkOption { + type = enum ["leaf" "always" "never"]; + default = "leaf"; + description = "display mode of the preview on the right section"; + }; }; }; }; - }; - nodeMarkers = { - enable = mkEnableOption "node markers"; + node_markers = { + enable = mkEnableOption "node markers"; + icons = { + leaf = mkOption { + type = str; + default = " "; + description = ""; + }; + + leaf_selected = mkOption { + type = str; + default = " → "; + description = ""; + }; + + branch = mkOption { + type = str; + default = " "; + description = ""; + }; + }; + }; + + lsp = { + auto_attach = mkOption { + type = bool; + default = true; + description = "Whether to attach to LSP server manually"; + }; + + preference = mkOption { + type = nullOr (listOf str); + default = null; + description = "list of lsp server names in order of preference"; + }; + }; + + source_buffer = { + followNode = mkOption { + type = bool; + default = true; + description = "keep the current node in focus on the source buffer"; + }; + + highlight = mkOption { + type = bool; + default = true; + description = "highlight the currently focused node"; + }; + + reorient = mkOption { + type = enum ["smart" "top" "mid" "none"]; + default = "smart"; + description = "reorient buffer after changing nodes"; + }; + + scrolloff = mkOption { + type = nullOr int; + default = null; + description = "scrolloff value when navbuddy is open"; + }; + }; + icons = { - leaf = mkOption { + File = mkOption { type = str; - default = " "; + default = "󰈙 "; description = ""; }; - leafSelected = mkOption { + Module = mkOption { type = str; - default = " → "; + default = " "; description = ""; }; - branch = mkOption { + Namespace = mkOption { type = str; - default = " "; + default = "󰌗 "; description = ""; }; - }; - }; - lsp = { - autoAttach = mkOption { - type = bool; - default = true; - description = "Whether to attach to LSP server manually"; - }; + Package = mkOption { + type = str; + default = " "; + description = ""; + }; - preference = mkOption { - type = nullOr (listOf str); - default = null; - description = "list of lsp server names in order of preference"; - }; - }; + Class = mkOption { + type = str; + default = "󰌗 "; + description = ""; + }; - sourceBuffer = { - followNode = mkOption { - type = bool; - default = true; - description = "keep the current node in focus on the source buffer"; - }; + Property = mkOption { + type = str; + default = " "; + description = ""; + }; - highlight = mkOption { - type = bool; - default = true; - description = "highlight the currently focused node"; - }; + Field = mkOption { + type = str; + default = " "; + description = ""; + }; - reorient = mkOption { - type = enum ["smart" "top" "mid" "none"]; - default = "smart"; - description = "reorient buffer after changing nodes"; - }; + Constructor = mkOption { + type = str; + default = " "; + description = ""; + }; - scrolloff = mkOption { - type = nullOr int; - default = null; - description = "scrolloff value when navbuddy is open"; + Enum = mkOption { + type = str; + default = "󰕘"; + description = ""; + }; + + Interface = mkOption { + type = str; + default = "󰕘"; + description = ""; + }; + + Function = mkOption { + type = str; + default = "󰊕 "; + description = ""; + }; + + Variable = mkOption { + type = str; + default = "󰆧 "; + description = ""; + }; + + Constant = mkOption { + type = str; + default = "󰏿 "; + description = ""; + }; + + String = mkOption { + type = str; + default = " "; + description = ""; + }; + + Number = mkOption { + type = str; + default = "󰎠 "; + description = ""; + }; + + Boolean = mkOption { + type = str; + default = "◩ "; + description = ""; + }; + + Array = mkOption { + type = str; + default = "󰅪 "; + description = ""; + }; + + Object = mkOption { + type = str; + default = "󰅩 "; + description = ""; + }; + + Method = mkOption { + type = str; + default = "󰆧 "; + description = ""; + }; + + Key = mkOption { + type = str; + default = "󰌋 "; + description = ""; + }; + + Null = mkOption { + type = str; + default = "󰟢 "; + description = ""; + }; + + EnumMember = mkOption { + type = str; + default = "󰕘 "; + description = ""; + }; + + Struct = mkOption { + type = str; + default = "󰌗 "; + description = ""; + }; + + Event = mkOption { + type = str; + default = " "; + description = ""; + }; + + Operator = mkOption { + type = str; + default = "󰆕 "; + description = ""; + }; + + TypeParameter = mkOption { + type = str; + default = "󰊄 "; + description = ""; + }; }; }; # there probably is a better way to do this # alas, I am not a nix wizard - icons = { - file = mkOption { - type = str; - default = "󰈙 "; - description = "File icon"; - }; - - module = mkOption { - type = str; - default = " "; - description = "Module icon"; - }; - - namespace = mkOption { - type = str; - default = "󰌗 "; - description = "Namespace icon"; - }; - - package = mkOption { - type = str; - default = " "; - description = ""; - }; - - class = mkOption { - type = str; - default = "󰌗 "; - description = "Class icon"; - }; - - property = mkOption { - type = str; - default = " "; - description = ""; - }; - - field = mkOption { - type = str; - default = " "; - description = "Field icon"; - }; - - constructor = mkOption { - type = str; - default = " "; - description = "Constructor icon"; - }; - - enum = mkOption { - type = str; - default = "󰕘"; - description = "Enum icon"; - }; - - interface = mkOption { - type = str; - default = "󰕘"; - description = "Interface icon"; - }; - - function = mkOption { - type = str; - default = "󰊕 "; - description = "Function icon"; - }; - - variable = mkOption { - type = str; - default = "󰆧 "; - description = ""; - }; - - constant = mkOption { - type = str; - default = "󰏿 "; - description = "Constant icon"; - }; - - string = mkOption { - type = str; - default = " "; - description = ""; - }; - - number = mkOption { - type = str; - default = "󰎠 "; - description = "Number icon"; - }; - - boolean = mkOption { - type = str; - default = "◩ "; - description = ""; - }; - - array = mkOption { - type = str; - default = "󰅪 "; - description = "Array icon"; - }; - - object = mkOption { - type = str; - default = "󰅩 "; - description = "Object icon"; - }; - - method = mkOption { - type = str; - default = "󰆧 "; - description = "Method icon"; - }; - - key = mkOption { - type = str; - default = "󰌋 "; - description = "Key icon"; - }; - - null = mkOption { - type = str; - default = "󰟢 "; - description = "Null icon"; - }; - - enumMember = mkOption { - type = str; - default = "󰕘 "; - description = "Enum member icon"; - }; - - struct = mkOption { - type = str; - default = "󰌗 "; - description = "Struct icon"; - }; - - event = mkOption { - type = str; - default = " "; - description = "Event icon"; - }; - - operator = mkOption { - type = str; - default = "󰆕 "; - description = "Operator icon"; - }; - - typeParameter = mkOption { - type = str; - default = "󰊄 "; - description = "Type parameter icon"; - }; - }; }; }; } diff --git a/modules/ui/breadcrumbs/config.nix b/modules/ui/breadcrumbs/config.nix index 3dc3713..88ddddf 100644 --- a/modules/ui/breadcrumbs/config.nix +++ b/modules/ui/breadcrumbs/config.nix @@ -4,14 +4,13 @@ ... }: let inherit (lib.strings) optionalString; - inherit (lib.trivial) boolToString; inherit (lib.modules) mkIf; inherit (lib.lists) optionals; - inherit (lib.nvim.lua) nullString; inherit (lib.nvim.dag) entryAfter; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.ui.breadcrumbs; - nbcfg = cfg.navbuddy; + mkRawLua = code: {__raw = code;}; in { config = mkIf cfg.enable { vim.startPlugins = @@ -30,6 +29,55 @@ in { "nvim-navic" ]; + vim.ui.breadcrumbs.navbuddy.setupOpts = { + mappings = { + ${cfg.navbuddy.mappings.close} = mkRawLua "actions.close()"; + ${cfg.navbuddy.mappings.nextSibling} = mkRawLua "actions.next_sibling()"; + ${cfg.navbuddy.mappings.previousSibling} = mkRawLua "actions.previous_sibling()"; + ${cfg.navbuddy.mappings.parent} = mkRawLua "actions.parent()"; + ${cfg.navbuddy.mappings.children} = mkRawLua "actions.children()"; + ${cfg.navbuddy.mappings.root} = mkRawLua "actions.root()"; + + ${cfg.navbuddy.mappings.visualName} = mkRawLua "actions.visual_name()"; + ${cfg.navbuddy.mappings.visualScope} = mkRawLua "actions.visual_scope()"; + + ${cfg.navbuddy.mappings.yankName} = mkRawLua "actions.yank_name()"; + ${cfg.navbuddy.mappings.yankScope} = mkRawLua "actions.yank_scope()"; + + ${cfg.navbuddy.mappings.insertName} = mkRawLua "actions.insert_name()"; + ${cfg.navbuddy.mappings.insertScope} = mkRawLua "actions.insert_scope()"; + + ${cfg.navbuddy.mappings.appendName} = mkRawLua "actions.append_name()"; + ${cfg.navbuddy.mappings.appendScope} = mkRawLua "actions.append_scope()"; + + ${cfg.navbuddy.mappings.rename} = mkRawLua "actions.rename()"; + + ${cfg.navbuddy.mappings.delete} = mkRawLua "actions.delete()"; + + ${cfg.navbuddy.mappings.foldCreate} = mkRawLua "actions.fold_create()"; + ${cfg.navbuddy.mappings.foldDelete} = mkRawLua "actions.fold_delete()"; + + ${cfg.navbuddy.mappings.comment} = mkRawLua "actions.comment()"; + + ${cfg.navbuddy.mappings.select} = mkRawLua "actions.select()"; + + ${cfg.navbuddy.mappings.moveDown} = mkRawLua "actions.move_down()"; + ${cfg.navbuddy.mappings.moveUp} = mkRawLua "actions.move_up()"; + + ${cfg.navbuddy.mappings.telescope} = mkRawLua '' + actions.telescope({ + layout_strategy = "horizontal", + layout_config = { + height = 0.60, + width = 0.75, + prompt_position = "top", + preview_width = 0.50 + }, + })''; + ${cfg.navbuddy.mappings.help} = mkRawLua "actions.help()"; + }; + }; + vim.luaConfigRC.breadcrumbs = entryAfter ["lspconfig"] '' ${optionalString (cfg.source == "nvim-navic") '' @@ -42,128 +90,7 @@ in { ${optionalString cfg.navbuddy.enable '' local navbuddy = require("nvim-navbuddy") local actions = require("nvim-navbuddy.actions") - navbuddy.setup { - window = { - border = "${nbcfg.window.border}", -- "rounded", "double", "solid", "none" - size = "60%", - position = "50%", - scrolloff = ${(nullString nbcfg.window.scrolloff)}, - sections = { - left = { - size = "20%", - border = ${(nullString nbcfg.window.sections.left.border)}, - }, - - mid = { - size = "40%", - border = ${(nullString nbcfg.window.sections.mid.border)}, - }, - - right = { - border = ${(nullString nbcfg.window.sections.right.border)}, - preview = "leaf", - } - }, - }, - node_markers = { - enabled = ${boolToString nbcfg.nodeMarkers.enable}, - icons = { - leaf = "${nbcfg.nodeMarkers.icons.leaf}", - leaf_selected = "${nbcfg.nodeMarkers.icons.leafSelected}", - branch = "${nbcfg.nodeMarkers.icons.branch}", - }, - }, - - lsp = { - auto_attach = ${boolToString nbcfg.lsp.autoAttach}, - -- preference = nil, -- TODO: convert list to lua table if not null - }, - - source_buffer = { - follow_node = ${boolToString nbcfg.sourceBuffer.followNode}, - highlight = ${boolToString nbcfg.sourceBuffer.highlight}, - reorient = "${nbcfg.sourceBuffer.reorient}", - scrolloff = ${nullString nbcfg.sourceBuffer.scrolloff} - }, - - icons = { - File = "${cfg.navbuddy.icons.file}", - Module = "${cfg.navbuddy.icons.module}", - Namespace = "${cfg.navbuddy.icons.namespace}", - Package = "${cfg.navbuddy.icons.package}", - Class = "${cfg.navbuddy.icons.class}", - Method = "${cfg.navbuddy.icons.method}", - Property = "${cfg.navbuddy.icons.property}", - Field = "${cfg.navbuddy.icons.field}", - Constructor = "${cfg.navbuddy.icons.constructor}", - Enum = "${cfg.navbuddy.icons.enum}", - Interface = "${cfg.navbuddy.icons.interface}", - Function = "${cfg.navbuddy.icons.function}", - Variable = "${cfg.navbuddy.icons.variable}", - Constant = "${cfg.navbuddy.icons.constant}", - String = "${cfg.navbuddy.icons.string}", - Number = "${cfg.navbuddy.icons.number}", - Boolean = "${cfg.navbuddy.icons.boolean}", - Array = "${cfg.navbuddy.icons.array}", - Object = "${cfg.navbuddy.icons.object}", - Key = "${cfg.navbuddy.icons.key}", - Null = "${cfg.navbuddy.icons.null}", - EnumMember = "${cfg.navbuddy.icons.enumMember}", - Struct = "${cfg.navbuddy.icons.struct}", - Event = "${cfg.navbuddy.icons.event}", - Operator = "${cfg.navbuddy.icons.operator}", - TypeParameter = "${cfg.navbuddy.icons.typeParameter}" - }, - - -- make those configurable - use_default_mappings = ${boolToString cfg.navbuddy.useDefaultMappings}, - mappings = { - ["${cfg.navbuddy.mappings.close}"] = actions.close(), - ["${cfg.navbuddy.mappings.nextSibling}"] = actions.next_sibling(), - ["${cfg.navbuddy.mappings.previousSibling}"] = actions.previous_sibling(), - ["${cfg.navbuddy.mappings.close}"] = actions.parent(), - ["${cfg.navbuddy.mappings.children}"] = actions.children(), - ["${cfg.navbuddy.mappings.root}"] = actions.root(), - - ["${cfg.navbuddy.mappings.visualName}"] = actions.visual_name(), - ["${cfg.navbuddy.mappings.visualScope}"] = actions.visual_scope(), - - ["${cfg.navbuddy.mappings.yankName}"] = actions.yank_name(), - ["${cfg.navbuddy.mappings.yankScope}"] = actions.yank_scope(), - - ["${cfg.navbuddy.mappings.insertName}"] = actions.insert_name(), - ["${cfg.navbuddy.mappings.insertScope}"] = actions.insert_scope(), - - ["${cfg.navbuddy.mappings.appendName}"] = actions.append_name(), - ["${cfg.navbuddy.mappings.appendScope}"] = actions.append_scope(), - - ["${cfg.navbuddy.mappings.rename}"] = actions.rename(), - - ["${cfg.navbuddy.mappings.delete}"] = actions.delete(), - - ["${cfg.navbuddy.mappings.foldCreate}"] = actions.fold_create(), - ["${cfg.navbuddy.mappings.foldDelete}"] = actions.fold_delete(), - - ["${cfg.navbuddy.mappings.comment}"] = actions.comment(), - - ["${cfg.navbuddy.mappings.select}"] = actions.select(), - - ["${cfg.navbuddy.mappings.moveDown}"] = actions.move_down(), - ["${cfg.navbuddy.mappings.moveUp}"] = actions.move_up(), - - ["${cfg.navbuddy.mappings.telescope}"] = actions.telescope({ - layout_strategy = "horizontal", - layout_config = { - height = 0.60, - width = 0.75, - prompt_position = "top", - preview_width = 0.50 - }, - }), - - ["${cfg.navbuddy.mappings.help}"] = actions.help(), -- Open mappings help window - }, - } + navbuddy.setup ${toLuaObject cfg.navbuddy.setupOpts} ''} ''; };