diff --git a/configuration.nix b/configuration.nix index 8420bbf..de778d5 100644 --- a/configuration.nix +++ b/configuration.nix @@ -210,7 +210,7 @@ inputs: let }; smartcolumn = { enable = true; - columnAt.languages = { + setupOpts.custom_colorcolumn = { # this is a freeform module, it's `buftype = int;` for configuring column position nix = 110; ruby = 120; diff --git a/docs/manual/hacking/additional-plugins.md b/docs/manual/hacking/additional-plugins.md index c70727d..07a972f 100644 --- a/docs/manual/hacking/additional-plugins.md +++ b/docs/manual/hacking/additional-plugins.md @@ -31,3 +31,95 @@ You can now reference this plugin using its string name: ```nix config.vim.startPlugins = ["neodev-nvim"]; ``` + +## Modular setup options {#sec-modular-setup-options} + +Most plugins is initialized with a call to `require('plugin').setup({...})`. + +We use a special function that lets you easily add support for such setup options in a modular way: +`mkPluginSetupOption`. + +Once you have added the source of the plugin as shown above, you can define the setup options like +this: + +```nix +# in modules/.../your-plugin/your-plugin.nix + +{lib, ...}: +let + inherit (lib.types) bool int; + inherit (lib.nvim.types) mkPluginSetupOption; +in { + options.vim.your-plugin = { + setupOpts = mkPluginSetupOption "plugin name" { + enable_feature_a = mkOption { + type = bool; + default = false; + # ... + }; + + number_option = mkOption { + type = int; + default = 3; + # ... + }; + }; + }; +} +``` + +```nix +# in modules/.../your-plugin/config.nix +{lib, config, ...}: +let + cfg = config.vim.your-plugin; +in { + vim.luaConfigRC = lib.nvim.dag.entryAnywhere '' + require('plugin-name').setup(${lib.nvim.lua.toLuaObject cfg.setupOpts}) + ''; +} +``` + +This above config will result in this lua script: + +```lua +require('plugin-name').setup({ + enable_feature_a = false, + number_option = 3, +}) +``` + +Now users can set any of the pre-defined option field, and can also add their own fields! + +```nix +# in user's config +{ + vim.your-plugin.setupOpts = { + enable_feature_a = true; + number_option = 4; + another_field = "hello"; + size = { # nested fields work as well + top = 10; + }; + }; +} +``` + +## Details of toLuaObject {#sec-details-of-toluaobject} + +As you've seen above, `toLuaObject` is used to convert our nix attrSet `cfg.setupOpts`, into a lua +table. Here are some rules of the conversion: + +1. nix `null` converts to lua `nil` +2. number and strings convert to their lua counterparts +3. nix attrSet/list converts into lua tables +4. you can write raw lua code using `lib.generators.mkLuaInline`. This function is part of nixpkgs. + ```nix + vim.your-plugin.setupOpts = { + on_init = lib.generators.mkLuaInline '' + function() + print('we can write lua!') + end + ''; + } + ``` diff --git a/docs/release-notes/rl-0.6.md b/docs/release-notes/rl-0.6.md index 532f5d9..95d4e94 100644 --- a/docs/release-notes/rl-0.6.md +++ b/docs/release-notes/rl-0.6.md @@ -12,6 +12,10 @@ Release notes for release 0.6 - Fixed empty winbar when breadcrumbs are disabled +- Added custom setupOpts for various plugins + +- Removed support for deprecated plugin "nvim-compe" + [donnerinoern](https://github.com/donnerinoern): - Added Gruvbox theme diff --git a/flake.lock b/flake.lock index 4316578..387e831 100644 --- a/flake.lock +++ b/flake.lock @@ -1092,22 +1092,6 @@ "type": "github" } }, - "nvim-compe": { - "flake": false, - "locked": { - "lastModified": 1633188506, - "narHash": "sha256-Y2oqvsuAKM3qjmmtJVD9z34682eCRF25kPL+rxhhg7I=", - "owner": "hrsh7th", - "repo": "nvim-compe", - "rev": "d186d739c54823e0b010feb205c6f97792322c08", - "type": "github" - }, - "original": { - "owner": "hrsh7th", - "repo": "nvim-compe", - "type": "github" - } - }, "nvim-cursorline": { "flake": false, "locked": { @@ -1574,7 +1558,6 @@ "nvim-cmp": "nvim-cmp", "nvim-code-action-menu": "nvim-code-action-menu", "nvim-colorizer-lua": "nvim-colorizer-lua", - "nvim-compe": "nvim-compe", "nvim-cursorline": "nvim-cursorline", "nvim-dap": "nvim-dap", "nvim-dap-ui": "nvim-dap-ui", diff --git a/flake.nix b/flake.nix index 51c8861..b505b97 100644 --- a/flake.nix +++ b/flake.nix @@ -228,12 +228,6 @@ flake = false; }; - # Autocompletes - nvim-compe = { - url = "github:hrsh7th/nvim-compe"; - flake = false; - }; - nvim-cmp = { url = "github:hrsh7th/nvim-cmp"; flake = false; diff --git a/lib/lua.nix b/lib/lua.nix index d7dd982..eded8f3 100644 --- a/lib/lua.nix +++ b/lib/lua.nix @@ -48,11 +48,13 @@ in rec { # Convert a list of lua expressions to a lua table. The difference to listToLuaTable is that the elements here are expected to be lua expressions already, whereas listToLuaTable converts from nix types to lua first luaTable = items: ''{${concatStringsSep "," items}}''; + isLuaInline = {_type ? null, ...}: _type == "lua-inline"; + toLuaObject = args: if isAttrs args then - if hasAttr "__raw" args - then args.__raw + if isLuaInline args + then args.expr else if hasAttr "__empty" args then "{ }" else diff --git a/lib/types/default.nix b/lib/types/default.nix index 59a5181..89ce1ba 100644 --- a/lib/types/default.nix +++ b/lib/types/default.nix @@ -4,6 +4,6 @@ typesLanguage = import ./languages.nix {inherit lib;}; in { inherit (typesDag) dagOf; - inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption; + inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline; inherit (typesLanguage) diagnostics mkGrammarOption; } diff --git a/lib/types/plugins.nix b/lib/types/plugins.nix index da1d6ba..f6eceaa 100644 --- a/lib/types/plugins.nix +++ b/lib/types/plugins.nix @@ -15,7 +15,6 @@ with lib; let "nvim-tree-lua" "nvim-bufferline-lua" "lualine" - "nvim-compe" "nvim-autopairs" "nvim-ts-autotag" "nvim-web-devicons" @@ -145,6 +144,18 @@ in { type = pluginsType; }; + luaInline = lib.mkOptionType { + name = "luaInline"; + check = x: lib.nvim.lua.isLuaInline x || builtins.isString x; + merge = loc: defs: let + val = + if isString loc + then lib.generators.mkLuaInline loc + else loc; + in + lib.mergeOneOption val defs; + }; + # opts is a attrset of options, example: # ``` # mkPluginSetupOption "telescope" { diff --git a/modules/assistant/copilot/config.nix b/modules/assistant/copilot/config.nix index 5cfe955..0d3ee28 100644 --- a/modules/assistant/copilot/config.nix +++ b/modules/assistant/copilot/config.nix @@ -4,10 +4,10 @@ ... }: let inherit (builtins) toJSON; + inherit (lib.nvim.lua) toLuaObject; inherit (lib.modules) mkIf mkMerge; inherit (lib.nvim.dag) entryAnywhere; inherit (lib.lists) optionals; - inherit (lib.trivial) boolToString; inherit (lib.nvim.binds) mkLuaBinding; cfg = config.vim.assistant.copilot; @@ -28,55 +28,47 @@ in { vim.startPlugins = [ "copilot-lua" - cfg.copilotNodePackage + # cfg.copilotNodePackage ] ++ optionals (cfg.cmp.enable) [ "copilot-cmp" ]; vim.luaConfigRC.copilot = entryAnywhere '' - require("copilot").setup({ - -- available options: https://github.com/zbirenbaum/copilot.lua - copilot_node_command = "${cfg.copilotNodeCommand}", - panel = { - enabled = ${boolToString (!cfg.cmp.enable)}, - keymap = { - jump_prev = false, - jump_next = false, - accept = false, - refresh = false, - open = false, - }, - layout = { - position = "${cfg.panel.position}", - ratio = ${toString cfg.panel.ratio}, - }, - }, - suggestion = { - enabled = ${boolToString (!cfg.cmp.enable)}, - keymap = { - accept = false, - accept_word = false, - accept_line = false, - next = false, - prev = false, - dismiss = false, - }, - }, - }) + require("copilot").setup(${toLuaObject cfg.setupOpts}) ${lib.optionalString (cfg.cmp.enable) '' require("copilot_cmp").setup() ''} ''; + # Disable plugin handled keymaps. + # Setting it here so that it doesn't show up in user docs + vim.assistant.copilot.setupOpts = { + panel.keymap = { + jump_prev = lib.mkDefault false; + jump_next = lib.mkDefault false; + accept = lib.mkDefault false; + refresh = lib.mkDefault false; + open = lib.mkDefault false; + }; + suggestion.keymap = { + accept = lib.mkDefault false; + accept_word = lib.mkDefault false; + accept_line = lib.mkDefault false; + next = lib.mkDefault false; + prev = lib.mkDefault false; + dismiss = lib.mkDefault false; + }; + }; + vim.maps.normal = mkMerge [ (mkLuaBinding cfg.mappings.panel.jumpPrev (wrapPanelBinding "require(\"copilot.panel\").jump_prev" cfg.mappings.panel.jumpPrev) "[copilot] Accept suggestion") (mkLuaBinding cfg.mappings.panel.jumpNext (wrapPanelBinding "require(\"copilot.panel\").jump_next" cfg.mappings.panel.jumpNext) "[copilot] Accept suggestion") (mkLuaBinding cfg.mappings.panel.accept (wrapPanelBinding ''require("copilot.panel").accept'' cfg.mappings.panel.accept) "[copilot] Accept suggestion") (mkLuaBinding cfg.mappings.panel.refresh (wrapPanelBinding "require(\"copilot.panel\").refresh" cfg.mappings.panel.refresh) "[copilot] Accept suggestion") (mkLuaBinding cfg.mappings.panel.open (wrapPanelBinding '' - function() require("copilot.panel").open({ position = "${cfg.panel.position}", ratio = ${toString cfg.panel.ratio}, }) end + function() require("copilot.panel").open({ position = "${cfg.setupOpts.panel.layout.position}", ratio = ${toString cfg.setupOpts.panel.layout.ratio}, }) end '' cfg.mappings.panel.open) "[copilot] Accept suggestion") ]; diff --git a/modules/assistant/copilot/copilot.nix b/modules/assistant/copilot/copilot.nix index 283a0b6..c8aba32 100644 --- a/modules/assistant/copilot/copilot.nix +++ b/modules/assistant/copilot/copilot.nix @@ -4,31 +4,56 @@ lib, ... }: let + inherit (lib) mkRenamedOptionModule; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum float nullOr str package; - inherit (lib.meta) getExe; + inherit (lib.types) nullOr str enum float; + inherit (lib.nvim.types) mkPluginSetupOption; cfg = config.vim.assistant.copilot; in { + imports = [ + (mkRenamedOptionModule ["vim" "assistant" "copilot" "panel"] ["vim" "assistant" "copilot" "setupOpts" "panel"]) + (mkRenamedOptionModule ["vim" "assistant" "copilot" "copilotNodeCommand"] ["vim" "assistant" "copilot" "setupOpts" "copilot_node_command"]) + (mkRenamedOptionModule ["vim" "assistant" "copilot" "copilotNodePackage"] ["vim" "assistant" "copilot" "setupOpts" "copilot_node_command"]) + ]; + options.vim.assistant.copilot = { enable = mkEnableOption "GitHub Copilot AI assistant"; cmp.enable = mkEnableOption "nvim-cmp integration for GitHub Copilot"; - panel = { - position = mkOption { - type = enum [ - "bottom" - "top" - "left" - "right" - ]; - default = "bottom"; - description = "Panel position"; + setupOpts = mkPluginSetupOption "Copilot" { + copilot_node_command = mkOption { + type = str; + default = "${lib.getExe pkgs.nodejs-slim}"; + description = '' + The command that will be executed to initiate nodejs for GitHub Copilot. + Recommended to leave as default. + ''; }; - ratio = mkOption { - type = float; - default = 0.4; - description = "Panel size"; + panel = { + enabled = mkEnableOption "Completion Panel" // {default = !cfg.cmp.enable;}; + layout = { + position = mkOption { + type = enum [ + "bottom" + "top" + "left" + "right" + ]; + default = "bottom"; + description = "Panel position"; + }; + ratio = mkOption { + type = float; + default = 0.4; + description = "Panel size"; + }; + }; + }; + + suggestion = { + enabled = mkEnableOption "Suggestions" // {default = !cfg.cmp.enable;}; + # keymap = { }; }; }; @@ -102,23 +127,5 @@ in { }; }; }; - - copilotNodeCommand = mkOption { - type = str; - default = "${getExe cfg.copilotNodePackage}"; - description = '' - The command that will be executed to initiate nodejs for GitHub Copilot. - Recommended to leave as default. - ''; - }; - - copilotNodePackage = mkOption { - type = nullOr package; - default = pkgs.nodejs-slim; - description = '' - The nodeJS package that will be used for GitHub Copilot. If you are using a custom node command - you may want to set this option to null so that the package is not pulled from nixpkgs. - ''; - }; }; } diff --git a/modules/autopairs/nvim-autopairs/config.nix b/modules/autopairs/nvim-autopairs/config.nix index 1502db8..4058590 100644 --- a/modules/autopairs/nvim-autopairs/config.nix +++ b/modules/autopairs/nvim-autopairs/config.nix @@ -4,9 +4,9 @@ ... }: let inherit (lib.modules) mkIf; - inherit (lib.nvim.dag) entryAnywhere; inherit (lib.strings) optionalString; - inherit (lib.trivial) boolToString; + inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.autopairs; in { @@ -15,14 +15,6 @@ in { vim.luaConfigRC.autopairs = entryAnywhere '' require("nvim-autopairs").setup{} - ${optionalString (config.vim.autocomplete.type == "nvim-compe") '' - -- nvim-compe integration - require('nvim-autopairs.completion.compe').setup({ - map_cr = ${boolToString cfg.nvim-compe.map_cr}, - map_complete = ${boolToString cfg.nvim-compe.map_complete}, - auto_select = ${boolToString cfg.nvim-compe.auto_select}, - }) - ''} ''; }; } diff --git a/modules/autopairs/nvim-autopairs/nvim-autopairs.nix b/modules/autopairs/nvim-autopairs/nvim-autopairs.nix index 940a60c..7e45606 100644 --- a/modules/autopairs/nvim-autopairs/nvim-autopairs.nix +++ b/modules/autopairs/nvim-autopairs/nvim-autopairs.nix @@ -1,7 +1,12 @@ {lib, ...}: let + inherit (lib) mkRemovedOptionModule; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum bool; + inherit (lib.types) enum; in { + imports = [ + (mkRemovedOptionModule ["vim" "autopairs" "nvim-compe"] "nvim-compe is deprecated and no longer suported.") + ]; + options.vim = { autopairs = { enable = mkEnableOption "autopairs" // {default = false;}; @@ -11,26 +16,6 @@ in { default = "nvim-autopairs"; description = "Set the autopairs type. Options: nvim-autopairs [nvim-autopairs]"; }; - - nvim-compe = { - map_cr = mkOption { - type = bool; - default = true; - description = ''map on insert mode''; - }; - - map_complete = mkOption { - type = bool; - default = true; - description = "auto insert `(` after select function or method item"; - }; - - auto_select = mkOption { - type = bool; - default = false; - description = "auto select first item"; - }; - }; }; }; } diff --git a/modules/core/default.nix b/modules/core/default.nix index 682566c..954b9d9 100644 --- a/modules/core/default.nix +++ b/modules/core/default.nix @@ -12,6 +12,7 @@ inherit (lib.types) bool str listOf oneOf attrsOf nullOr attrs submodule unspecified lines; inherit (lib.nvim.types) dagOf pluginsOpt extraPluginType; inherit (lib.nvim.dag) entryAnywhere entryAfter topoSort; + inherit (lib.generators) mkLuaInline; inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.vim) valToVim; @@ -86,7 +87,7 @@ else config; action = if action.lua - then {"__raw" = action.action;} + then mkLuaInline action.action else action.action; }; in diff --git a/modules/filetree/nvimtree/config.nix b/modules/filetree/nvimtree/config.nix index 0286c1a..c560650 100644 --- a/modules/filetree/nvimtree/config.nix +++ b/modules/filetree/nvimtree/config.nix @@ -6,10 +6,9 @@ }: let inherit (lib.strings) optionalString; inherit (lib.modules) mkIf mkMerge; - inherit (lib.trivial) boolToString; inherit (lib.nvim.binds) mkBinding; inherit (lib.nvim.dag) entryAnywhere; - inherit (lib.nvim.lua) listToLuaTable expToLua; + inherit (lib.nvim.lua) toLuaObject; # TODO: move this to its own module inherit (lib) pushDownDefault; @@ -40,237 +39,7 @@ in { '' } - require'nvim-tree'.setup({ - disable_netrw = ${boolToString cfg.disableNetrw}, - hijack_netrw = ${boolToString cfg.hijackNetrw}, - auto_reload_on_write = ${boolToString cfg.autoreloadOnWrite}, - - sort = { - sorter = "${cfg.sort.sorter}", - folders_first = ${boolToString cfg.sort.foldersFirst}, - }, - - hijack_unnamed_buffer_when_opening = ${boolToString cfg.hijackUnnamedBufferWhenOpening}, - hijack_cursor = ${boolToString cfg.hijackCursor}, - root_dirs = ${listToLuaTable cfg.rootDirs}, - prefer_startup_root = ${boolToString cfg.preferStartupRoot}, - sync_root_with_cwd = ${boolToString cfg.syncRootWithCwd}, - reload_on_bufenter = ${boolToString cfg.reloadOnBufEnter}, - respect_buf_cwd = ${boolToString cfg.respectBufCwd}, - - hijack_directories = { - enable = ${boolToString cfg.hijackDirectories.enable}, - auto_open = ${boolToString cfg.hijackDirectories.autoOpen}, - }, - - update_focused_file = { - enable = ${boolToString cfg.updateFocusedFile.enable}, - update_root = ${boolToString cfg.updateFocusedFile.updateRoot}, - ignore_list = ${listToLuaTable cfg.updateFocusedFile.ignoreList}, - }, - - system_open = { - cmd = "${cfg.systemOpen.cmd}", - args = ${listToLuaTable cfg.systemOpen.args}, - }, - - diagnostics = { - enable = ${boolToString cfg.diagnostics.enable}, - icons = { - hint = "${cfg.diagnostics.icons.hint}", - info = "${cfg.diagnostics.icons.info}", - warning = "${cfg.diagnostics.icons.warning}", - error = "${cfg.diagnostics.icons.error}", - }, - - severity = { - min = vim.diagnostic.severity.${cfg.diagnostics.severity.min}, - max = vim.diagnostic.severity.${cfg.diagnostics.severity.max}, - }, - }, - - git = { - enable = ${boolToString cfg.git.enable}, - show_on_dirs = ${boolToString cfg.git.showOnDirs}, - show_on_open_dirs = ${boolToString cfg.git.showOnOpenDirs}, - disable_for_dirs = ${listToLuaTable cfg.git.disableForDirs}, - timeout = ${toString cfg.git.timeout}, - }, - - modified = { - enable = ${boolToString cfg.modified.enable}, - show_on_dirs = ${boolToString cfg.modified.showOnDirs}, - show_on_open_dirs = ${boolToString cfg.modified.showOnOpenDirs}, - }, - - filesystem_watchers = { - enable = ${boolToString cfg.filesystemWatchers.enable}, - debounce_delay = ${toString cfg.filesystemWatchers.debounceDelay}, - ignore_dirs = ${listToLuaTable cfg.filesystemWatchers.ignoreDirs}, - }, - - select_prompts = ${boolToString cfg.selectPrompts}, - - view = { - centralize_selection = ${boolToString cfg.view.centralizeSelection}, - cursorline = ${boolToString cfg.view.cursorline}, - debounce_delay = ${toString cfg.view.debounceDelay}, - width = ${expToLua cfg.view.width}, - side = "${cfg.view.side}", - preserve_window_proportions = ${boolToString cfg.view.preserveWindowProportions}, - number = ${boolToString cfg.view.number}, - relativenumber = ${boolToString cfg.view.relativenumber}, - signcolumn = "${cfg.view.signcolumn}", - float = { - enable = ${boolToString cfg.view.float.enable}, - quit_on_focus_loss = ${boolToString cfg.view.float.quitOnFocusLoss}, - open_win_config = { - relative = "${cfg.view.float.openWinConfig.relative}", - border = "${cfg.view.float.openWinConfig.border}", - width = ${toString cfg.view.float.openWinConfig.width}, - height = ${toString cfg.view.float.openWinConfig.height}, - row = ${toString cfg.view.float.openWinConfig.row}, - col = ${toString cfg.view.float.openWinConfig.col}, - }, - }, - }, - - renderer = { - add_trailing = ${boolToString cfg.renderer.addTrailing}, - group_empty = ${boolToString cfg.renderer.groupEmpty}, - full_name = ${boolToString cfg.renderer.fullName}, - highlight_git = ${boolToString cfg.renderer.highlightGit}, - highlight_opened_files = ${cfg.renderer.highlightOpenedFiles}, - highlight_modified = ${cfg.renderer.highlightModified}, - root_folder_label = ${expToLua cfg.renderer.rootFolderLabel}, - indent_width = ${toString cfg.renderer.indentWidth}, - indent_markers = { - enable = ${boolToString cfg.renderer.indentMarkers.enable}, - inline_arrows = ${boolToString cfg.renderer.indentMarkers.inlineArrows}, - icons = ${expToLua cfg.renderer.indentMarkers.icons}, - }, - - special_files = ${listToLuaTable cfg.renderer.specialFiles}, - symlink_destination = ${boolToString cfg.renderer.symlinkDestination}, - - icons = { - webdev_colors = ${boolToString cfg.renderer.icons.webdevColors}, - git_placement = "${cfg.renderer.icons.gitPlacement}", - modified_placement = "${cfg.renderer.icons.modifiedPlacement}", - padding = "${cfg.renderer.icons.padding}", - symlink_arrow = "${cfg.renderer.icons.symlinkArrow}", - - show = { - git = ${boolToString cfg.renderer.icons.show.git}, - folder = ${boolToString cfg.renderer.icons.show.folder}, - folder_arrow = ${boolToString cfg.renderer.icons.show.folderArrow}, - file = ${boolToString cfg.renderer.icons.show.file}, - modified = ${boolToString cfg.renderer.icons.show.modified}, - }, - - glyphs = { - default = "${cfg.renderer.icons.glyphs.default}", - symlink = "${cfg.renderer.icons.glyphs.symlink}", - modified = "${cfg.renderer.icons.glyphs.modified}", - - folder = { - default = "${cfg.renderer.icons.glyphs.folder.default}", - open = "${cfg.renderer.icons.glyphs.folder.open}", - arrow_open = "${cfg.renderer.icons.glyphs.folder.arrowOpen}", - arrow_closed = "${cfg.renderer.icons.glyphs.folder.arrowClosed}", - empty = "${cfg.renderer.icons.glyphs.folder.empty}", - empty_open = "${cfg.renderer.icons.glyphs.folder.emptyOpen}", - symlink = "${cfg.renderer.icons.glyphs.folder.symlink}", - symlink_open = "${cfg.renderer.icons.glyphs.folder.symlinkOpen}", - }, - - git = { - unstaged = "${cfg.renderer.icons.glyphs.git.unstaged}", - staged = "${cfg.renderer.icons.glyphs.git.staged}", - unmerged = "${cfg.renderer.icons.glyphs.git.unmerged}", - renamed = "${cfg.renderer.icons.glyphs.git.renamed}", - untracked = "${cfg.renderer.icons.glyphs.git.untracked}", - deleted = "${cfg.renderer.icons.glyphs.git.deleted}", - ignored = "${cfg.renderer.icons.glyphs.git.ignored}", - }, - }, - }, - }, - - filters = { - git_ignored = ${boolToString cfg.filters.gitIgnored}, - dotfiles = ${boolToString cfg.filters.dotfiles}, - git_clean = ${boolToString cfg.filters.gitClean}, - no_buffer = ${boolToString cfg.filters.noBuffer}, - exclude = ${listToLuaTable cfg.filters.exclude}, - }, - - trash = { - cmd = "${cfg.trash.cmd}", - }, - - actions = { - use_system_clipboard = ${boolToString cfg.actions.useSystemClipboard}, - change_dir = { - enable = ${boolToString cfg.actions.changeDir.enable}, - global = ${boolToString cfg.actions.changeDir.global}, - restrict_above_cwd = ${boolToString cfg.actions.changeDir.restrictAboveCwd}, - }, - - expand_all = { - max_folder_discovery = ${toString cfg.actions.expandAll.maxFolderDiscovery}, - exclude = ${listToLuaTable cfg.actions.expandAll.exclude}, - }, - - file_popup = { - open_win_config = ${expToLua cfg.actions.filePopup.openWinConfig}, - }, - - open_file = { - quit_on_open = ${boolToString cfg.actions.openFile.quitOnOpen}, - eject = ${boolToString cfg.actions.openFile.eject}, - resize_window = ${boolToString cfg.actions.openFile.resizeWindow}, - window_picker = { - enable = ${boolToString cfg.actions.openFile.windowPicker.enable}, - picker = "${cfg.actions.openFile.windowPicker.picker}", - chars = "${cfg.actions.openFile.windowPicker.chars}", - exclude = { - filetype = ${listToLuaTable cfg.actions.openFile.windowPicker.exclude.filetype}, - buftype = ${listToLuaTable cfg.actions.openFile.windowPicker.exclude.buftype}, - }, - }, - }, - - remove_file = { - close_window = ${boolToString cfg.actions.removeFile.closeWindow}, - }, - }, - - live_filter = { - prefix = "${cfg.liveFilter.prefix}", - always_show_folders = ${boolToString cfg.liveFilter.alwaysShowFolders}, - }, - - tab = { - sync = { - open = ${boolToString cfg.tab.sync.open}, - close = ${boolToString cfg.tab.sync.close}, - ignore = ${listToLuaTable cfg.tab.sync.ignore}, - }, - }, - - notify = { - threshold = vim.log.levels.${cfg.notify.threshold}, - absolute_path = ${boolToString cfg.notify.absolutePath}, - }, - - ui = { - confirm = { - remove = ${boolToString cfg.ui.confirm.remove}, - trash = ${boolToString cfg.ui.confirm.trash}, - }, - }, - }) + require'nvim-tree'.setup(${toLuaObject cfg.setupOpts}) ${ optionalString cfg.openOnSetup '' diff --git a/modules/filetree/nvimtree/nvimtree.nix b/modules/filetree/nvimtree/nvimtree.nix index ecd74b5..fb9a9d0 100644 --- a/modules/filetree/nvimtree/nvimtree.nix +++ b/modules/filetree/nvimtree/nvimtree.nix @@ -4,7 +4,9 @@ ... }: let inherit (lib.options) mkEnableOption mkOption literalExpression; - inherit (lib.types) nullOr str bool int listOf enum attrs oneOf addCheck submodule; + inherit (lib.generators) mkLuaInline; + inherit (lib.types) nullOr str bool int submodule listOf enum oneOf attrs addCheck; + inherit (lib.nvim.types) mkPluginSetupOption; in { options.vim.filetree.nvimTree = { enable = mkEnableOption "filetree via nvim-tree.lua"; @@ -38,708 +40,455 @@ in { type = bool; }; - hijackNetrw = mkOption { - default = true; - description = "Prevents netrw from automatically opening when opening directories"; - type = bool; - }; - - autoreloadOnWrite = mkOption { - default = true; - description = "Auto reload tree on write"; - type = bool; - }; - - updateFocusedFile = mkOption { - description = '' - Update the focused file on `BufEnter`, un-collapses the folders recursively - until it finds the file. - ''; - default = {}; - type = submodule { - options = { - enable = mkOption { - type = bool; - default = false; - description = "update focused file"; - }; - - updateRoot = mkOption { - type = bool; - default = false; - description = '' - Update the root directory of the tree if the file is not under current - root directory. It prefers vim's cwd and `root_dirs`. - Otherwise it falls back to the folder containing the file. - Only relevant when `update_focused_file.enable` is `true` - ''; - }; - - ignoreList = mkOption { - type = listOf str; - default = []; - description = '' - List of buffer names and filetypes that will not update the root dir - of the tree if the file isn't found under the current root directory. - Only relevant when `update_focused_file.update_root` and - `update_focused_file.enable` are `true`. - ''; - }; - }; - }; - }; - - sort = { - # TODO: function as a possible type - sorter = mkOption { - default = "name"; - description = "How files within the same directory are sorted."; - type = enum ["name" "extension" "modification_time" "case_sensitive" "suffix" "filetype"]; - }; - - foldersFirst = mkOption { + setupOpts = mkPluginSetupOption "Nvim Tree" { + hijack_netrw = mkOption { default = true; - description = "Sort folders before files. Has no effect when `sort.sorter` is a function."; + description = "Prevents netrw from automatically opening when opening directories"; type = bool; }; - }; - hijackCursor = mkOption { - default = false; - description = "Hijack the cursor in the tree to put it at the start of the filename"; - type = bool; - }; - - hijackUnnamedBufferWhenOpening = mkOption { - default = false; - description = "Open nvimtree in place of the unnamed buffer if it's empty."; - type = bool; - }; - - rootDirs = mkOption { - default = []; - description = '' - Preferred root directories. Only relevant when `updateFocusedFile.updateRoot` is `true` - ''; - type = listOf str; - }; - - preferStartupRoot = mkOption { - default = false; - description = '' - Prefer startup root directory when updating root directory of the tree. - Only relevant when `update_focused_file.update_root` is `true` - ''; - type = bool; - }; - - syncRootWithCwd = mkOption { - type = bool; - default = false; - description = '' - Changes the tree root directory on `DirChanged` and refreshes the tree. - Only relevant when `updateFocusedFile.updateRoot` is `true` - - (previously `update_cwd`) - ''; - }; - - reloadOnBufEnter = mkOption { - default = false; - type = bool; - description = "Automatically reloads the tree on `BufEnter` nvim-tree."; - }; - - respectBufCwd = mkOption { - default = false; - type = bool; - description = "Will change cwd of nvim-tree to that of new buffer's when opening nvim-tree."; - }; - - hijackDirectories = mkOption { - description = "hijack new directory buffers when they are opened (`:e dir`)."; - - default = { - enable = true; - autoOpen = false; - }; - - type = submodule { - options = { - enable = mkOption { - type = bool; - description = '' - Enable the `hijack_directories` feature. Disable this option if you use vim-dirvish or dirbuf.nvim. - If `hijack_netrw` and `disable_netrw` are `false`, this feature will be disabled. - ''; - }; - - autoOpen = mkOption { - type = bool; - description = '' - Opens the tree if the tree was previously closed. - ''; - }; - }; - }; - }; - - systemOpen = { - args = mkOption { - default = []; - description = "Optional argument list."; - type = listOf str; - }; - - cmd = mkOption { - default = - if pkgs.stdenv.isDarwin - then "open" - else if pkgs.stdenv.isLinux - then "${pkgs.xdg-utils}/bin/xdg-open" - else throw "NvimTree: No default system open command for this platform, please set `vim.filetree.nvimTree.systemOpen.cmd`"; - description = "The open command itself"; - type = str; - }; - }; - - diagnostics = mkOption { - description = '' - Show LSP and COC diagnostics in the signcolumn - Note that the modified sign will take precedence over the diagnostics signs. - ''; - - default = {}; - - type = submodule { - options = { - enable = mkEnableOption "diagnostics view in the signcolumn."; - - debounceDelay = mkOption { - description = "Idle milliseconds between diagnostic event and update."; - type = int; - default = 50; - }; - - showOnDirs = mkOption { - description = "Show diagnostic icons on parent directories."; - default = false; - }; - - showOnOpenDirs = mkOption { - type = bool; - default = true; - description = '' - Show diagnostics icons on directories that are open. - Only relevant when `diagnostics.show_on_dirs` is `true`. - ''; - }; - - icons = mkOption { - description = "Icons for diagnostic severity."; - default = {}; - type = submodule { - options = { - hint = mkOption { - description = "Icon used for `hint` diagnostic."; - type = str; - default = ""; - }; - info = mkOption { - description = "Icon used for `info` diagnostic."; - type = str; - default = ""; - }; - warning = mkOption { - description = "Icon used for `warning` diagnostic."; - type = str; - default = ""; - }; - error = mkOption { - description = "Icon used for `error` diagnostic."; - type = str; - default = ""; - }; - }; - }; - }; - - severity = mkOption { - description = "Severity for which the diagnostics will be displayed. See `:help diagnostic-severity`"; - default = {}; - type = submodule { - options = { - min = mkOption { - description = "Minimum severity."; - type = enum ["HINT" "INFO" "WARNING" "ERROR"]; - default = "HINT"; - }; - - max = mkOption { - description = "Maximum severity."; - type = enum ["HINT" "INFO" "WARNING" "ERROR"]; - default = "ERROR"; - }; - }; - }; - }; - }; - }; - }; - - git = { - enable = mkEnableOption "Git integration with icons and colors."; - - showOnDirs = mkOption { - type = bool; + auto_reload_on_write = mkOption { default = true; - description = "Show git icons on parent directories."; - }; - - showOnOpenDirs = mkOption { - type = bool; - default = true; - description = "Show git icons on directories that are open."; - }; - - disableForDirs = mkOption { - type = listOf str; - default = []; - description = '' - Disable git integration when git top-level matches these paths. - May be relative, evaluated via `":p"` - ''; - }; - - timeout = mkOption { - type = int; - default = 400; - description = '' - Kills the git process after some time if it takes too long. - Git integration will be disabled after 10 git jobs exceed this timeout. - ''; - }; - }; - - modified = mkOption { - description = "Indicate which file have unsaved modification."; - default = {}; - type = submodule { - options = { - enable = mkEnableOption "Modified files with icons and color highlight."; - - showOnDirs = mkOption { - type = bool; - description = "Show modified icons on parent directories."; - default = true; - }; - - showOnOpenDirs = mkOption { - type = bool; - description = "Show modified icons on directories that are open."; - default = true; - }; - }; - }; - }; - - filesystemWatchers = mkOption { - description = '' - Will use file system watcher (libuv fs_event) to watch the filesystem for changes. - Using this will disable BufEnter / BufWritePost events in nvim-tree which - were used to update the whole tree. With this feature, the tree will be - updated only for the appropriate folder change, resulting in better - performance. - ''; - default = {}; - type = submodule { - options = { - enable = mkOption { - description = "Enable filesystem watchers."; - type = bool; - default = true; - }; - - debounceDelay = mkOption { - description = "Idle milliseconds between filesystem change and action."; - type = int; - default = 50; - }; - - ignoreDirs = mkOption { - type = listOf str; - default = []; - description = '' - List of vim regex for absolute directory paths that will not be watched. - Backslashes must be escaped e.g. `"my-project/\\.build$"`. - Useful when path is not in `.gitignore` or git integration is disabled. - ''; - }; - }; - }; - }; - - selectPrompts = mkEnableOption '' - Use `vim.ui.select` style prompts. Necessary when using a UI prompt decorator such as dressing.nvim or telescope-ui-select.nvim - ''; - - view = mkOption { - description = "Window / buffer setup."; - default = {}; - type = submodule { - options = { - centralizeSelection = mkOption { - description = "If true, reposition the view so that the current node is initially centralized when entering nvim-tree."; - type = bool; - default = false; - }; - - cursorline = mkOption { - description = "Enable cursorline in nvim-tree window."; - type = bool; - default = true; - }; - - debounceDelay = mkOption { - type = int; - default = 15; - description = '' - Idle milliseconds before some reload / refresh operations. - Increase if you experience performance issues around screen refresh. - ''; - }; - - width = mkOption { - description = '' - Width of the window: can be a `%` string, a number representing columns, a - function or a table. - - A table (an attribute set in our case, see example) indicates that the view should be dynamically sized based on the - longest line. - ''; - type = oneOf [int attrs]; - default = 30; - example = literalExpression '' - { - min = 30; - max = -1; - padding = 1; - } - ''; - }; - - side = mkOption { - description = "Side of the tree."; - type = enum ["left" "right"]; - default = "left"; - }; - - preserveWindowProportions = mkOption { - description = '' - Preserves window proportions when opening a file. - If `false`, the height and width of windows other than nvim-tree will be equalized. - ''; - type = bool; - default = false; - }; - - number = mkOption { - description = "Print the line number in front of each line."; - type = bool; - default = false; - }; - - relativenumber = mkOption { - description = '' - Show the line number relative to the line with the cursor in front of each line. - If the option `view.number` is also `true`, the number on the cursor line - will be the line number instead of `0`. - ''; - type = bool; - default = false; - }; - - signcolumn = mkOption { - description = ''Show diagnostic sign column. Value can be `"yes"`, `"auto"` or`"no"`.''; - type = enum ["yes" "auto" "no"]; - default = "yes"; - }; - - float = mkOption { - description = "Configuration options for floating window."; - - default = {}; - type = submodule { - options = { - enable = mkOption { - description = "If true, tree window will be floating."; - type = bool; - default = false; - }; - - quitOnFocusLoss = mkOption { - description = "Close the floating tree window when it loses focus."; - type = bool; - default = true; - }; - - openWinConfig = mkOption { - description = "Floating window config. See `:h nvim_open_win()` for more details."; - type = attrs; - default = { - relative = "editor"; - border = "rounded"; - width = 30; - height = 30; - row = 1; - col = 1; - }; - }; - }; - }; - }; - }; - }; - }; - - renderer = { - addTrailing = mkOption { - default = false; - description = "Appends a trailing slash to folder names."; + description = "Auto reload tree on write"; type = bool; }; - groupEmpty = mkOption { - default = false; - description = "Compact folders that only contain a single folder into one node in the file tree."; - type = bool; - }; - - fullName = mkOption { - default = false; - description = "Display node whose name length is wider than the width of nvim-tree window in floating window."; - type = bool; - }; - - highlightGit = mkOption { - type = bool; - default = false; + update_focused_file = mkOption { description = '' - Enable file highlight for git attributes using `NvimTreeGit` highlight groups. - Requires `nvimTree.git.enable` - This can be used with or without the icons. + Update the focused file on `BufEnter`, un-collapses the folders recursively + until it finds the file. ''; - }; - - highlightOpenedFiles = mkOption { - type = enum ["none" "icon" "name" "all"]; - default = "none"; - description = '' - Highlight icons and/or names for bufloaded() files using the - `NvimTreeOpenedFile` highlight group. - ''; - }; - - highlightModified = mkOption { - type = enum ["none" "icon" "name" "all"]; - default = "none"; - description = '' - Highlight modified files in the tree using `NvimTreeNormal` highlight group. - Requires `nvimTree.view.highlightOpenedFiles` - ''; - }; - - rootFolderLabel = mkOption { - type = oneOf [str bool]; - default = false; - example = ''"":~:s?$?/..?"''; - description = '' - In what format to show root folder. See `:help filename-modifiers` for - available `string` options. - Set to `false` to hide the root folder. - - Function is passed the absolute path of the root folder and should - return a string. e.g. - my_root_folder_label = function(path) - return ".../" .. vim.fn.fnamemodify(path, ":t") - end - ''; - }; - - indentWidth = mkOption { - type = addCheck int (x: x >= 1); - default = 2; - description = "Number of spaces for an each tree nesting level. Minimum 1."; - }; - - indentMarkers = mkOption { - description = "Configuration options for tree indent markers."; default = {}; type = submodule { options = { - enable = mkEnableOption "Display indent markers when folders are open."; - inlineArrows = mkOption { + enable = mkOption { + type = bool; + default = false; + description = "update focused file"; + }; + + update_root = mkOption { + type = bool; + default = false; + description = '' + Update the root directory of the tree if the file is not under current + root directory. It prefers vim's cwd and `root_dirs`. + Otherwise it falls back to the folder containing the file. + Only relevant when `update_focused_file.enable` is `true` + ''; + }; + + ignore_list = mkOption { + type = listOf str; + default = []; + description = '' + List of buffer names and filetypes that will not update the root dir + of the tree if the file isn't found under the current root directory. + Only relevant when `update_focused_file.update_root` and + `update_focused_file.enable` are `true`. + ''; + }; + }; + }; + }; + + sort = { + # TODO: function as a possible type + sorter = mkOption { + default = "name"; + description = "How files within the same directory are sorted."; + type = enum ["name" "extension" "modification_time" "case_sensitive" "suffix" "filetype"]; + }; + + folders_first = mkOption { + default = true; + description = "Sort folders before files. Has no effect when `sort.sorter` is a function."; + type = bool; + }; + }; + + hijack_cursor = mkOption { + default = false; + description = "Hijack the cursor in the tree to put it at the start of the filename"; + type = bool; + }; + + hijack_unnamed_buffer_when_opening = mkOption { + default = false; + description = "Open nvimtree in place of the unnamed buffer if it's empty."; + type = bool; + }; + + root_dirs = mkOption { + default = []; + description = '' + Preferred root directories. Only relevant when `updateFocusedFile.updateRoot` is `true` + ''; + type = listOf str; + }; + + prefer_startup_root = mkOption { + default = false; + description = '' + Prefer startup root directory when updating root directory of the tree. + Only relevant when `update_focused_file.update_root` is `true` + ''; + type = bool; + }; + + sync_root_with_cwd = mkOption { + type = bool; + default = false; + description = '' + Changes the tree root directory on `DirChanged` and refreshes the tree. + Only relevant when `updateFocusedFile.updateRoot` is `true` + + (previously `update_cwd`) + ''; + }; + + reload_on_bufenter = mkOption { + default = false; + type = bool; + description = "Automatically reloads the tree on `BufEnter` nvim-tree."; + }; + + respect_buf_cwd = mkOption { + default = false; + type = bool; + description = "Will change cwd of nvim-tree to that of new buffer's when opening nvim-tree."; + }; + + hijack_directories = { + enable = mkOption { + type = bool; + description = '' + Enable the `hijack_directories` feature. Disable this option if you use vim-dirvish or dirbuf.nvim. + If `hijack_netrw` and `disable_netrw` are `false`, this feature will be disabled. + ''; + default = true; + }; + + auto_open = mkOption { + type = bool; + description = '' + Opens the tree if the tree was previously closed. + ''; + default = false; + }; + }; + + system_open = { + args = mkOption { + default = []; + description = "Optional argument list."; + type = listOf str; + }; + + cmd = mkOption { + default = + if pkgs.stdenv.isDarwin + then "open" + else if pkgs.stdenv.isLinux + then "${pkgs.xdg-utils}/bin/xdg-open" + else throw "NvimTree: No default system open command for this platform, please set `vim.filetree.nvimTree.systemOpen.cmd`"; + description = "The open command itself"; + type = str; + }; + }; + + diagnostics = mkOption { + description = '' + Show LSP and COC diagnostics in the signcolumn + Note that the modified sign will take precedence over the diagnostics signs. + ''; + + default = {}; + + type = submodule { + options = { + enable = mkEnableOption "diagnostics view in the signcolumn."; + + debounce_delay = mkOption { + description = "Idle milliseconds between diagnostic event and update."; + type = int; + default = 50; + }; + + show_on_dirs = mkOption { + description = "Show diagnostic icons on parent directories."; + default = false; + }; + + show_on_open_dirs = mkOption { type = bool; default = true; - description = "Display folder arrows in the same column as indent marker when using `renderer.icons.show.folder_arrow`"; + description = '' + Show diagnostics icons on directories that are open. + Only relevant when `diagnostics.show_on_dirs` is `true`. + ''; }; icons = mkOption { - type = attrs; - description = "Individual elements of the indent markers"; - default = { - corner = "└"; - edge = "│"; - item = "│"; - bottom = "─"; - none = ""; - }; - }; - }; - }; - }; - - specialFiles = mkOption { - type = listOf str; - default = ["Cargo.toml" "README.md" "readme.md" "Makefile" "MAKEFILE" "flake.nix"]; # ;) - description = "A list of filenames that gets highlighted with `NvimTreeSpecialFile"; - }; - - symlinkDestination = mkOption { - type = bool; - default = true; - description = "Whether to show the destination of the symlink."; - }; - - icons = mkOption { - description = "Configuration options for icons."; - default = {}; - type = submodule { - options = { - webdevColors = mkOption { - type = bool; - description = " Use the webdev icon colors, otherwise `NvimTreeFileIcon`"; - default = true; - }; - - gitPlacement = mkOption { - type = enum ["before" "after" "signcolumn"]; - description = "Place where the git icons will be rendered. `signcolumn` requires `view.signcolumn` to be enabled."; - default = "before"; - }; - - modifiedPlacement = mkOption { - type = enum ["before" "after" "signcolumn"]; - description = "Place where the modified icons will be rendered. `signcolumn` requires `view.signcolumn` to be enabled."; - default = "after"; - }; - - padding = mkOption { - type = str; - description = "Inserted between icon and filename"; - default = " "; - }; - - symlinkArrow = mkOption { - type = str; - description = "Used as a separator between symlinks' source and target."; - default = " ➛ "; - }; - - show = { - file = mkOption { - type = bool; - description = "Show an icon before the file name. `nvim-web-devicons` will be used if available."; - default = true; - }; - - folder = mkOption { - type = bool; - description = "Show an icon before the folder name."; - default = true; - }; - - folderArrow = mkOption { - type = bool; - default = true; - description = '' - Show a small arrow before the folder node. Arrow will be a part of the - node when using `renderer.indent_markers`. - ''; - }; - - git = mkOption { - type = bool; - default = false; - description = '' - Show a git status icon, see `renderer.icons.gitPlacement` - Requires `git.enable` to be true. - ''; - }; - - modified = mkOption { - type = bool; - default = true; - description = '' - Show a modified icon, see `renderer.icons.modifiedPlacement` - Requires `modified.enable` to be true. - ''; - }; - }; - glyphs = mkOption { - description = '' - Configuration options for icon glyphs. - NOTE: Do not set any glyphs to more than two characters if it's going - to appear in the signcolumn. - ''; + description = "Icons for diagnostic severity."; default = {}; type = submodule { options = { - default = mkOption { + hint = mkOption { + description = "Icon used for `hint` diagnostic."; type = str; - description = "Glyph for files. Will be overridden by `nvim-web-devicons` if available."; - default = ""; + default = ""; + }; + info = mkOption { + description = "Icon used for `info` diagnostic."; + type = str; + default = ""; + }; + warning = mkOption { + description = "Icon used for `warning` diagnostic."; + type = str; + default = ""; + }; + error = mkOption { + description = "Icon used for `error` diagnostic."; + type = str; + default = ""; + }; + }; + }; + }; + + severity = mkOption { + description = "Severity for which the diagnostics will be displayed. See `:help diagnostic-severity`"; + default = {}; + type = submodule { + options = { + min = mkOption { + description = "Minimum severity."; + type = enum ["HINT" "INFO" "WARNING" "ERROR"]; + default = "HINT"; + apply = x: mkLuaInline "vim.diagnostic.severity.${x}"; }; - symlink = mkOption { - type = str; - description = "Glyph for symlinks."; - default = ""; + max = mkOption { + description = "Maximum severity."; + type = enum ["HINT" "INFO" "WARNING" "ERROR"]; + default = "ERROR"; + apply = x: mkLuaInline "vim.diagnostic.severity.${x}"; + }; + }; + }; + }; + }; + }; + }; + + git = { + enable = mkEnableOption "Git integration with icons and colors."; + + show_on_dirs = mkOption { + type = bool; + default = true; + description = "Show git icons on parent directories."; + }; + + show_on_open_dirs = mkOption { + type = bool; + default = true; + description = "Show git icons on directories that are open."; + }; + + disable_for_dirs = mkOption { + type = listOf str; + default = []; + description = '' + Disable git integration when git top-level matches these paths. + May be relative, evaluated via `":p"` + ''; + }; + + timeout = mkOption { + type = int; + default = 400; + description = '' + Kills the git process after some time if it takes too long. + Git integration will be disabled after 10 git jobs exceed this timeout. + ''; + }; + }; + + modified = mkOption { + description = "Indicate which file have unsaved modification."; + default = {}; + type = submodule { + options = { + enable = mkEnableOption "Modified files with icons and color highlight."; + + show_on_dirs = mkOption { + type = bool; + description = "Show modified icons on parent directories."; + default = true; + }; + + show_on_open_dirs = mkOption { + type = bool; + description = "Show modified icons on directories that are open."; + default = true; + }; + }; + }; + }; + + filesystem_watchers = mkOption { + description = '' + Will use file system watcher (libuv fs_event) to watch the filesystem for changes. + Using this will disable BufEnter / BufWritePost events in nvim-tree which + were used to update the whole tree. With this feature, the tree will be + updated only for the appropriate folder change, resulting in better + performance. + ''; + default = {}; + type = submodule { + options = { + enable = mkOption { + description = "Enable filesystem watchers."; + type = bool; + default = true; + }; + + debounce_delay = mkOption { + description = "Idle milliseconds between filesystem change and action."; + type = int; + default = 50; + }; + + ignore_dirs = mkOption { + type = listOf str; + default = []; + description = '' + List of vim regex for absolute directory paths that will not be watched. + Backslashes must be escaped e.g. `"my-project/\\.build$"`. + Useful when path is not in `.gitignore` or git integration is disabled. + ''; + }; + }; + }; + }; + + select_prompts = mkEnableOption '' + Use `vim.ui.select` style prompts. Necessary when using a UI prompt decorator such as dressing.nvim or telescope-ui-select.nvim + ''; + + view = mkOption { + description = "Window / buffer setup."; + default = {}; + type = submodule { + options = { + centralize_selection = mkOption { + description = "If true, reposition the view so that the current node is initially centralized when entering nvim-tree."; + type = bool; + default = false; + }; + + cursorline = mkOption { + description = "Enable cursorline in nvim-tree window."; + type = bool; + default = true; + }; + + debounce_delay = mkOption { + type = int; + default = 15; + description = '' + Idle milliseconds before some reload / refresh operations. + Increase if you experience performance issues around screen refresh. + ''; + }; + + width = mkOption { + description = '' + Width of the window: can be a `%` string, a number representing columns, a + function or a table. + + A table (an attribute set in our case, see example) indicates that the view should be dynamically sized based on the + longest line. + ''; + type = oneOf [int attrs]; + default = 30; + example = literalExpression '' + { + min = 30; + max = -1; + padding = 1; + } + ''; + }; + + side = mkOption { + description = "Side of the tree."; + type = enum ["left" "right"]; + default = "left"; + }; + + preserve_window_proportions = mkOption { + description = '' + Preserves window proportions when opening a file. + If `false`, the height and width of windows other than nvim-tree will be equalized. + ''; + type = bool; + default = false; + }; + + number = mkOption { + description = "Print the line number in front of each line."; + type = bool; + default = false; + }; + + relativenumber = mkOption { + description = '' + Show the line number relative to the line with the cursor in front of each line. + If the option `view.number` is also `true`, the number on the cursor line + will be the line number instead of `0`. + ''; + type = bool; + default = false; + }; + + signcolumn = mkOption { + description = ''Show diagnostic sign column. Value can be `"yes"`, `"auto"` or`"no"`.''; + type = enum ["yes" "auto" "no"]; + default = "yes"; + }; + + float = mkOption { + description = "Configuration options for floating window."; + + default = {}; + type = submodule { + options = { + enable = mkOption { + description = "If true, tree window will be floating."; + type = bool; + default = false; }; - modified = mkOption { - type = str; - description = "Icon to display for modified files."; - default = ""; + quit_on_focus_loss = mkOption { + description = "Close the floating tree window when it loses focus."; + type = bool; + default = true; }; - # TODO: hardcode each attribute - folder = mkOption { + open_win_config = mkOption { + description = "Floating window config. See `:h nvim_open_win()` for more details."; type = attrs; - description = "Glyphs for directories. Recommended to use the defaults unless you know what you are doing."; default = { - default = ""; - open = ""; - arrowOpen = ""; - arrowClosed = ""; - empty = ""; - emptyOpen = ""; - symlink = ""; - symlinkOpen = ""; - }; - }; - - git = mkOption { - type = attrs; - description = "Glyphs for git status."; - default = { - unstaged = "✗"; - staged = "✓"; - unmerged = ""; - renamed = "➜"; - untracked = "★"; - deleted = ""; - ignored = "◌"; + relative = "editor"; + border = "rounded"; + width = 30; + height = 30; + row = 1; + col = 1; }; }; }; @@ -748,235 +497,245 @@ in { }; }; }; - }; - filters = mkOption { - description = "Filtering options."; + renderer = { + add_trailing = mkOption { + default = false; + description = "Appends a trailing slash to folder names."; + type = bool; + }; - default = { - gitIgnored = false; - dotfiles = false; - gitClean = false; - noBuffer = false; - exclude = []; - }; - type = submodule { - options = { - gitIgnored = mkOption { - type = bool; - description = "Ignore files based on `.gitignore`. Requires git.enable` to be `true`"; - default = false; - }; + group_empty = mkOption { + default = false; + description = "Compact folders that only contain a single folder into one node in the file tree."; + type = bool; + }; - dotfiles = mkOption { - type = bool; - description = "Do not show dotfiles: files starting with a `.`"; - default = false; - }; + full_name = mkOption { + default = false; + description = "Display node whose name length is wider than the width of nvim-tree window in floating window."; + type = bool; + }; - gitClean = mkOption { - type = bool; - default = false; + highlight_git = mkOption { + type = bool; + default = false; + description = '' + Enable file highlight for git attributes using `NvimTreeGit` highlight groups. + Requires `nvimTree.git.enable` + This can be used with or without the icons. + ''; + }; - description = '' - Do not show files with no git status. This will show ignored files when - `nvimTree.filters.gitIgnored` is set, as they are effectively dirty. - ''; - }; + highlight_opened_files = mkOption { + type = enum ["none" "icon" "name" "all"]; + default = "none"; + description = '' + Highlight icons and/or names for bufloaded() files using the + `NvimTreeOpenedFile` highlight group. + ''; + }; - noBuffer = mkOption { - type = bool; - default = false; - description = "Do not show files that have no `buflisted()` buffer."; - }; + highlight_modified = mkOption { + type = enum ["none" "icon" "name" "all"]; + default = "none"; + description = '' + Highlight modified files in the tree using `NvimTreeNormal` highlight group. + Requires `nvimTree.view.highlightOpenedFiles` + ''; + }; - exclude = mkOption { - type = listOf str; - default = []; - description = "List of directories or files to exclude from filtering: always show them."; + root_folder_label = mkOption { + type = oneOf [str bool]; + default = false; + example = ''"":~:s?$?/..?"''; + description = '' + In what format to show root folder. See `:help filename-modifiers` for + available `string` options. + Set to `false` to hide the root folder. + + Function is passed the absolute path of the root folder and should + return a string. e.g. + my_root_folder_label = function(path) + return ".../" .. vim.fn.fnamemodify(path, ":t") + end + ''; + }; + + indent_width = mkOption { + type = addCheck int (x: x >= 1); + default = 2; + description = "Number of spaces for an each tree nesting level. Minimum 1."; + }; + + indent_markers = mkOption { + description = "Configuration options for tree indent markers."; + default = {}; + type = submodule { + options = { + enable = mkEnableOption "Display indent markers when folders are open."; + inline_arrows = mkOption { + type = bool; + default = true; + description = "Display folder arrows in the same column as indent marker when using `renderer.icons.show.folder_arrow`"; + }; + + icons = mkOption { + type = attrs; + description = "Individual elements of the indent markers"; + default = { + corner = "└"; + edge = "│"; + item = "│"; + bottom = "─"; + none = ""; + }; + }; + }; }; }; - }; - }; - trash = mkOption { - description = "Configuration options for trashing."; - default = { - cmd = "${pkgs.glib}/bin/gio trash"; - }; - - type = submodule { - options = { - cmd = mkOption { - type = str; - description = "The command used to trash items"; - }; + special_files = mkOption { + type = listOf str; + default = ["Cargo.toml" "README.md" "readme.md" "Makefile" "MAKEFILE" "flake.nix"]; # ;) + description = "A list of filenames that gets highlighted with `NvimTreeSpecialFile"; }; - }; - }; - actions = mkOption { - description = "Configuration for various actions."; - default = {}; - type = submodule { - options = { - useSystemClipboard = mkOption { - type = bool; - default = true; - description = '' - A boolean value that toggle the use of system clipboard when copy/paste - function are invoked. When enabled, copied text will be stored in registers - '+' (system), otherwise, it will be stored in '1' and '"'. - ''; - }; + symlink_destination = mkOption { + type = bool; + default = true; + description = "Whether to show the destination of the symlink."; + }; - # change_dir actions - changeDir = mkOption { - description = "vim `change-directory` behaviour"; - default = {}; - type = submodule { - options = { - enable = mkOption { + icons = mkOption { + description = "Configuration options for icons."; + default = {}; + type = submodule { + options = { + webdev_colors = mkOption { + type = bool; + description = " Use the webdev icon colors, otherwise `NvimTreeFileIcon`"; + default = true; + }; + + git_placement = mkOption { + type = enum ["before" "after" "signcolumn"]; + description = "Place where the git icons will be rendered. `signcolumn` requires `view.signcolumn` to be enabled."; + default = "before"; + }; + + modified_placement = mkOption { + type = enum ["before" "after" "signcolumn"]; + description = "Place where the modified icons will be rendered. `signcolumn` requires `view.signcolumn` to be enabled."; + default = "after"; + }; + + padding = mkOption { + type = str; + description = "Inserted between icon and filename"; + default = " "; + }; + + symlink_arrow = mkOption { + type = str; + description = "Used as a separator between symlinks' source and target."; + default = " ➛ "; + }; + + show = { + file = mkOption { + type = bool; + description = "Show an icon before the file name. `nvim-web-devicons` will be used if available."; + default = true; + }; + + folder = mkOption { + type = bool; + description = "Show an icon before the folder name."; + default = true; + }; + + folder_arrow = mkOption { type = bool; default = true; - description = "Change the working directory when changing directories in the tree."; - }; - - global = mkOption { - type = bool; - default = false; description = '' - Use `:cd` instead of `:lcd` when changing directories. - Consider that this might cause issues with the `nvimTree.syncRootWithCwd` option. + Show a small arrow before the folder node. Arrow will be a part of the + node when using `renderer.indent_markers`. ''; }; - restrictAboveCwd = mkOption { + git = mkOption { type = bool; default = false; description = '' - Restrict changing to a directory above the global current working directory. + Show a git status icon, see `renderer.icons.gitPlacement` + Requires `git.enable` to be true. ''; }; - }; - }; - }; - # expand_all actions - expandAll = mkOption { - description = "Configuration for expand_all behaviour."; - default = {}; - type = submodule { - options = { - maxFolderDiscovery = mkOption { - type = int; - default = 300; + modified = mkOption { + type = bool; + default = true; description = '' - Limit the number of folders being explored when expanding every folders. - Avoids hanging neovim when running this action on very large folders. + Show a modified icon, see `renderer.icons.modifiedPlacement` + Requires `modified.enable` to be true. ''; }; - exclude = mkOption { - type = listOf str; - description = "A list of directories that should not be expanded automatically."; - default = [".git" "target" "build" "result"]; - }; }; - }; - }; + glyphs = mkOption { + description = '' + Configuration options for icon glyphs. + NOTE: Do not set any glyphs to more than two characters if it's going + to appear in the signcolumn. + ''; + default = {}; + type = submodule { + options = { + default = mkOption { + type = str; + description = "Glyph for files. Will be overridden by `nvim-web-devicons` if available."; + default = ""; + }; - # file_popup actions - filePopup = mkOption { - description = "Configuration for file_popup behaviour."; - default = {}; - type = submodule { - options = { - openWinConfig = mkOption { - type = attrs; - default = { - col = 1; - row = 1; - relative = "cursor"; - border = "rounded"; - style = "minimal"; - }; - description = "Floating window config for file_popup. See |nvim_open_win| for more details."; - }; - }; - }; - }; + symlink = mkOption { + type = str; + description = "Glyph for symlinks."; + default = ""; + }; - # open_file actions - openFile = mkOption { - description = "Configuration options for opening a file from nvim-tree."; - default = {}; - type = submodule { - options = { - quitOnOpen = mkOption { - type = bool; - description = "Closes the explorer when opening a file."; - default = false; - }; + modified = mkOption { + type = str; + description = "Icon to display for modified files."; + default = ""; + }; - eject = mkOption { - type = bool; - description = "Prevent new opened file from opening in the same window as the tree."; - default = false; - }; - - resizeWindow = mkOption { - type = bool; - default = false; - - description = "Resizes the tree when opening a file. Previously `view.auto_resize`"; - }; - - windowPicker = mkOption { - description = "window_picker"; - default = {}; - type = submodule { - options = { - enable = mkOption { - type = bool; - description = "Enable the window picker. If this feature is not enabled, files will open in window from which you last opened the tree."; - default = false; + # TODO: hardcode each attribute + folder = mkOption { + type = attrs; + description = "Glyphs for directories. Recommended to use the defaults unless you know what you are doing."; + default = { + default = ""; + open = ""; + arrow_open = ""; + arrow_closed = ""; + empty = ""; + empty_open = ""; + symlink = ""; + symlink_open = ""; }; + }; - picker = mkOption { - type = str; - default = "default"; - description = '' - Change the default window picker, can be a string `"default"` or a function. - The function should return the window id that will open the node, - or `nil` if an invalid window is picked or user cancelled the action. - - The picker may create a new window. - ''; - - example = literalExpression '' - -- with s1n7ax/nvim-window-picker plugin - require('window-picker').pick_window, - ''; - }; - - chars = mkOption { - type = str; - description = "A string of chars used as identifiers by the window picker."; - default = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - }; - - exclude = { - filetype = mkOption { - type = listOf str; - description = "A list of filetypes to exclude from the window picker."; - default = ["notify" "packer" "qf" "diff" "fugitive" "fugitiveblame"]; - }; - - buftype = mkOption { - type = listOf str; - description = "A list of buftypes to exclude from the window picker."; - default = ["nofile" "terminal" "help"]; - }; + git = mkOption { + type = attrs; + description = "Glyphs for git status."; + default = { + unstaged = "✗"; + staged = "✓"; + unmerged = ""; + renamed = "➜"; + untracked = "★"; + deleted = ""; + ignored = "◌"; }; }; }; @@ -984,122 +743,361 @@ in { }; }; }; + }; + }; - removeFile = { - closeWindow = mkOption { + filters = mkOption { + description = "Filtering options."; + + default = { + git_ignored = false; + dotfiles = false; + git_clean = false; + no_buffer = false; + exclude = []; + }; + type = submodule { + options = { + git_ignored = mkOption { type = bool; - default = true; - description = "Close any window displaying a file when removing the file from the tree"; + description = "Ignore files based on `.gitignore`. Requires git.enable` to be `true`"; + default = false; + }; + + dotfiles = mkOption { + type = bool; + description = "Do not show dotfiles: files starting with a `.`"; + default = false; + }; + + git_clean = mkOption { + type = bool; + default = false; + + description = '' + Do not show files with no git status. This will show ignored files when + `nvimTree.filters.gitIgnored` is set, as they are effectively dirty. + ''; + }; + + no_buffer = mkOption { + type = bool; + default = false; + description = "Do not show files that have no `buflisted()` buffer."; + }; + + exclude = mkOption { + type = listOf str; + default = []; + description = "List of directories or files to exclude from filtering: always show them."; }; }; }; }; - }; - liveFilter = mkOption { - description = '' - Configurations for the live_filtering feature. - The live filter allows you to filter the tree nodes dynamically, based on - regex matching (see `vim.regex`). - This feature is bound to the `f` key by default. - The filter can be cleared with the `F` key by default. - ''; - default = {}; - type = submodule { - options = { - prefix = mkOption { - type = str; - description = "Prefix of the filter displayed in the buffer."; - default = "[FILTER]: "; - }; + trash = mkOption { + description = "Configuration options for trashing."; + default = { + cmd = "${pkgs.glib}/bin/gio trash"; + }; - alwaysShowFolders = mkOption { - type = bool; - description = "Whether to filter folders or not."; - default = true; + type = submodule { + options = { + cmd = mkOption { + type = str; + description = "The command used to trash items"; + }; }; }; }; - }; - tab = mkOption { - description = "Configuration for tab behaviour."; - default = {}; - type = submodule { - options = { - sync = mkOption { - description = "Configuration for syncing nvim-tree across tabs."; - default = {}; - type = submodule { - options = { - open = mkOption { - type = bool; - default = false; - description = '' - Opens the tree automatically when switching tabpage or opening a new - tabpage if the tree was previously open. - ''; + actions = mkOption { + description = "Configuration for various actions."; + default = {}; + type = submodule { + options = { + use_system_clipboard = mkOption { + type = bool; + default = true; + description = '' + A boolean value that toggle the use of system clipboard when copy/paste + function are invoked. When enabled, copied text will be stored in registers + '+' (system), otherwise, it will be stored in '1' and '"'. + ''; + }; + + # change_dir actions + change_dir = mkOption { + description = "vim `change-directory` behaviour"; + default = {}; + type = submodule { + options = { + enable = mkOption { + type = bool; + default = true; + description = "Change the working directory when changing directories in the tree."; + }; + + global = mkOption { + type = bool; + default = false; + description = '' + Use `:cd` instead of `:lcd` when changing directories. + Consider that this might cause issues with the `nvimTree.syncRootWithCwd` option. + ''; + }; + + restrict_above_cwd = mkOption { + type = bool; + default = false; + description = '' + Restrict changing to a directory above the global current working directory. + ''; + }; }; + }; + }; - close = mkOption { - type = bool; - default = false; - description = '' - Closes the tree across all tabpages when the tree is closed. - ''; + # expand_all actions + expand_all = mkOption { + description = "Configuration for expand_all behaviour."; + default = {}; + type = submodule { + options = { + max_folder_discovery = mkOption { + type = int; + default = 300; + description = '' + Limit the number of folders being explored when expanding every folders. + Avoids hanging neovim when running this action on very large folders. + ''; + }; + exclude = mkOption { + type = listOf str; + description = "A list of directories that should not be expanded automatically."; + default = [".git" "target" "build" "result"]; + }; }; + }; + }; - ignore = mkOption { - type = listOf str; - default = []; - description = '' - List of filetypes or buffer names on new tab that will prevent - `nvimTree.tab.sync.open` and `nvimTree.tab.sync.close` - ''; + # file_popup actions + file_popup = mkOption { + description = "Configuration for file_popup behaviour."; + default = {}; + type = submodule { + options = { + open_win_config = mkOption { + type = attrs; + default = { + col = 1; + row = 1; + relative = "cursor"; + border = "rounded"; + style = "minimal"; + }; + description = "Floating window config for file_popup. See |nvim_open_win| for more details."; + }; + }; + }; + }; + + # open_file actions + open_file = mkOption { + description = "Configuration options for opening a file from nvim-tree."; + default = {}; + type = submodule { + options = { + quit_on_open = mkOption { + type = bool; + description = "Closes the explorer when opening a file."; + default = false; + }; + + eject = mkOption { + type = bool; + description = "Prevent new opened file from opening in the same window as the tree."; + default = false; + }; + + resize_window = mkOption { + type = bool; + default = false; + + description = "Resizes the tree when opening a file. Previously `view.auto_resize`"; + }; + + window_picker = mkOption { + description = "window_picker"; + default = {}; + type = submodule { + options = { + enable = mkOption { + type = bool; + description = "Enable the window picker. If this feature is not enabled, files will open in window from which you last opened the tree."; + default = false; + }; + + picker = mkOption { + type = str; + default = "default"; + description = '' + Change the default window picker, can be a string `"default"` or a function. + The function should return the window id that will open the node, + or `nil` if an invalid window is picked or user cancelled the action. + + The picker may create a new window. + ''; + + example = literalExpression '' + -- with s1n7ax/nvim-window-picker plugin + require('window-picker').pick_window, + ''; + }; + + chars = mkOption { + type = str; + description = "A string of chars used as identifiers by the window picker."; + default = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + }; + + exclude = { + filetype = mkOption { + type = listOf str; + description = "A list of filetypes to exclude from the window picker."; + default = ["notify" "packer" "qf" "diff" "fugitive" "fugitiveblame"]; + }; + + buftype = mkOption { + type = listOf str; + description = "A list of buftypes to exclude from the window picker."; + default = ["nofile" "terminal" "help"]; + }; + }; + }; + }; + }; + }; + }; + }; + + remove_file = { + close_window = mkOption { + type = bool; + default = true; + description = "Close any window displaying a file when removing the file from the tree"; + }; + }; + }; + }; + }; + + live_filter = mkOption { + description = '' + Configurations for the live_filtering feature. + The live filter allows you to filter the tree nodes dynamically, based on + regex matching (see `vim.regex`). + This feature is bound to the `f` key by default. + The filter can be cleared with the `F` key by default. + ''; + default = {}; + type = submodule { + options = { + prefix = mkOption { + type = str; + description = "Prefix of the filter displayed in the buffer."; + default = "[FILTER]: "; + }; + + always_show_folders = mkOption { + type = bool; + description = "Whether to filter folders or not."; + default = true; + }; + }; + }; + }; + + tab = mkOption { + description = "Configuration for tab behaviour."; + default = {}; + type = submodule { + options = { + sync = mkOption { + description = "Configuration for syncing nvim-tree across tabs."; + default = {}; + type = submodule { + options = { + open = mkOption { + type = bool; + default = false; + description = '' + Opens the tree automatically when switching tabpage or opening a new + tabpage if the tree was previously open. + ''; + }; + + close = mkOption { + type = bool; + default = false; + description = '' + Closes the tree across all tabpages when the tree is closed. + ''; + }; + + ignore = mkOption { + type = listOf str; + default = []; + description = '' + List of filetypes or buffer names on new tab that will prevent + `nvimTree.tab.sync.open` and `nvimTree.tab.sync.close` + ''; + }; }; }; }; }; }; }; - }; - notify = mkOption { - description = "Configuration for notifications."; - default = {}; - type = submodule { - options = { - threshold = mkOption { - type = enum ["ERROR" "WARNING" "INFO" "DEBUG"]; - description = "Specify minimum notification level, uses the values from `vim.log.levels`"; - default = "INFO"; - }; + notify = mkOption { + description = "Configuration for notifications."; + default = {}; + type = submodule { + options = { + threshold = mkOption { + type = enum ["ERROR" "WARNING" "INFO" "DEBUG"]; + description = "Specify minimum notification level, uses the values from `vim.log.levels`"; + default = "INFO"; + apply = x: mkLuaInline "vim.log.levels.${x}"; + }; - absolutePath = mkOption { - type = bool; - description = "Whether to use absolute paths or item names in fs action notifications."; - default = true; + absolute_path = mkOption { + type = bool; + description = "Whether to use absolute paths or item names in fs action notifications."; + default = true; + }; }; }; }; - }; - ui = mkOption { - description = "General UI configuration."; - default = {}; - type = submodule { - options = { - confirm = { - remove = mkOption { - type = bool; - description = "Prompt before removing."; - default = true; - }; + ui = mkOption { + description = "General UI configuration."; + default = {}; + type = submodule { + options = { + confirm = { + remove = mkOption { + type = bool; + description = "Prompt before removing."; + default = true; + }; - trash = mkOption { - type = bool; - description = "Prompt before trash."; - default = true; + trash = mkOption { + type = bool; + description = "Prompt before trash."; + default = true; + }; }; }; }; diff --git a/modules/lsp/lsp-signature/config.nix b/modules/lsp/lsp-signature/config.nix index 5b231bd..c194912 100644 --- a/modules/lsp/lsp-signature/config.nix +++ b/modules/lsp/lsp-signature/config.nix @@ -5,7 +5,7 @@ }: let inherit (lib.modules) mkIf; inherit (lib.nvim.dag) entryAnywhere; - inherit (lib.strings) optionalString; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.lsp; in { @@ -15,16 +15,14 @@ in { "lsp-signature" ]; + lsp.lspSignature.setupOpts = { + bind = config.vim.ui.borders.plugins.lsp-signature.enable; + handler_opts.border = config.vim.ui.borders.plugins.lsp-signature.style; + }; + luaConfigRC.lsp-signature = entryAnywhere '' -- Enable lsp signature viewer - require("lsp_signature").setup({ - ${optionalString config.vim.ui.borders.plugins.lsp-signature.enable '' - bind = true, -- This is mandatory, otherwise border config won't get registered. - handler_opts = { - border = "${config.vim.ui.borders.plugins.lsp-signature.style}" - } - ''} - }) + require("lsp_signature").setup(${toLuaObject cfg.lspSignature.setupOpts}) ''; }; }; diff --git a/modules/lsp/lsp-signature/lsp-signature.nix b/modules/lsp/lsp-signature/lsp-signature.nix index 981526b..be7b6cd 100644 --- a/modules/lsp/lsp-signature/lsp-signature.nix +++ b/modules/lsp/lsp-signature/lsp-signature.nix @@ -3,7 +3,8 @@ in { options.vim.lsp = { lspSignature = { - enable = mkEnableOption "lsp signature viewer [lsp-signature]"; + enable = mkEnableOption "lsp signature viewer"; + setupOpts = lib.nvim.types.mkPluginSetupOption "lsp-signature" {}; }; }; } diff --git a/modules/lsp/nvim-docs-view/config.nix b/modules/lsp/nvim-docs-view/config.nix index 008eee8..45de200 100644 --- a/modules/lsp/nvim-docs-view/config.nix +++ b/modules/lsp/nvim-docs-view/config.nix @@ -3,10 +3,10 @@ lib, ... }: let - inherit (builtins) toString; inherit (lib.modules) mkIf mkMerge; - inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.binds) addDescriptionsToMappings mkSetBinding; + inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.lsp.nvim-docs-view; self = import ./nvim-docs-view.nix {inherit lib;}; @@ -20,12 +20,7 @@ in { startPlugins = ["nvim-docs-view"]; luaConfigRC.nvim-docs-view = entryAnywhere '' - require("docs-view").setup { - position = "${cfg.position}", - width = ${toString cfg.width}, - height = ${toString cfg.height}, - update_mode = "${cfg.updateMode}", - } + require("docs-view").setup ${toLuaObject cfg.setupOpts} ''; maps.normal = mkMerge [ diff --git a/modules/lsp/nvim-docs-view/nvim-docs-view.nix b/modules/lsp/nvim-docs-view/nvim-docs-view.nix index 6b59a27..e75c385 100644 --- a/modules/lsp/nvim-docs-view/nvim-docs-view.nix +++ b/modules/lsp/nvim-docs-view/nvim-docs-view.nix @@ -1,45 +1,57 @@ {lib, ...}: let inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum int; inherit (lib.nvim.binds) mkMappingOption; + inherit (lib) types mkRenamedOptionModule; in { + imports = let + renamedSetupOption = oldPath: newPath: + mkRenamedOptionModule + (["vim" "lsp" "nvim-docs-view"] ++ oldPath) + (["vim" "lsp" "nvim-docs-view" "setupOpts"] ++ newPath); + in [ + (renamedSetupOption ["position"] ["position"]) + (renamedSetupOption ["width"] ["width"]) + (renamedSetupOption ["height"] ["height"]) + (renamedSetupOption ["updateMode"] ["update_mode"]) + ]; + options.vim.lsp.nvim-docs-view = { enable = mkEnableOption "nvim-docs-view, for displaying lsp hover documentation in a side panel."; - position = mkOption { - type = enum ["left" "right" "top" "bottom"]; - default = "right"; - description = '' - Where to open the docs view panel - ''; - }; + setupOpts = lib.nvim.types.mkPluginSetupOption "nvim-docs-view" { + position = mkOption { + type = types.enum ["left" "right" "top" "bottom"]; + default = "right"; + description = '' + Where to open the docs view panel + ''; + }; - height = mkOption { - type = int; - default = 10; - description = '' - Height of the docs view panel if the position is set to either top or bottom - ''; - }; + height = mkOption { + type = types.int; + default = 10; + description = '' + Height of the docs view panel if the position is set to either top or bottom + ''; + }; - width = mkOption { - type = int; - default = 60; - description = '' - Width of the docs view panel if the position is set to either left or right - ''; - }; + width = mkOption { + type = types.int; + default = 60; + description = '' + Width of the docs view panel if the position is set to either left or right + ''; + }; - updateMode = mkOption { - type = enum ["auto" "manual"]; - default = "auto"; - description = '' - Determines the mechanism used to update the docs view panel content - - Possible values: - - auto: the content will update upon cursor move. - - manual: the content will only update once :DocsViewUpdate is called - ''; + update_mode = mkOption { + type = types.enum ["auto" "manual"]; + default = "auto"; + description = '' + Determines the mechanism used to update the docs view panel content. + - If auto, the content will update upon cursor move. + - If manual, the content will only update once :DocsViewUpdate is called + ''; + }; }; mappings = { diff --git a/modules/notes/obsidian/config.nix b/modules/notes/obsidian/config.nix index 818d447..5ba005e 100644 --- a/modules/notes/obsidian/config.nix +++ b/modules/notes/obsidian/config.nix @@ -6,9 +6,9 @@ inherit (lib.modules) mkIf; inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.binds) pushDownDefault; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.notes.obsidian; - auto = config.vim.autocomplete; in { config = mkIf cfg.enable { vim = { @@ -23,28 +23,7 @@ in { }; luaConfigRC.obsidian = entryAnywhere '' - require("obsidian").setup({ - dir = "${cfg.dir}", - completion = { - nvim_cmp = ${ - if (auto.type == "nvim-cmp") - then "true" - else "false" - } - }, - daily_notes = { - folder = ${ - if (cfg.daily-notes.folder == "") - then "nil," - else "'${cfg.daily-notes.folder}'," - } - date_format = ${ - if (cfg.daily-notes.date-format == "") - then "nil," - else "'${cfg.daily-notes.date-format}'," - } - } - }) + require("obsidian").setup(${toLuaObject cfg.setupOpts}) ''; }; }; diff --git a/modules/notes/obsidian/obsidian.nix b/modules/notes/obsidian/obsidian.nix index 1b7bae6..c7152fb 100644 --- a/modules/notes/obsidian/obsidian.nix +++ b/modules/notes/obsidian/obsidian.nix @@ -1,33 +1,52 @@ -{lib, ...}: let - inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) str bool; +{ + config, + lib, + ... +}: let + inherit (lib) mkEnableOption mkOption types mkRenamedOptionModule; in { + imports = let + renamedSetupOption = oldPath: newPath: + mkRenamedOptionModule + (["vim" "notes" "obsidian"] ++ oldPath) + (["vim" "notes" "obsidian" "setupOpts"] ++ newPath); + in [ + (renamedSetupOption ["dir"] ["dir"]) + (renamedSetupOption ["daily-notes" "folder"] ["daily_notes" "folder"]) + (renamedSetupOption ["daily-notes" "date-format"] ["daily_notes" "date_format"]) + (renamedSetupOption ["completion"] ["completion"]) + ]; options.vim.notes = { obsidian = { enable = mkEnableOption "complementary neovim plugins for Obsidian editor"; - dir = mkOption { - type = str; - default = "~/my-vault"; - description = "Obsidian vault directory"; - }; - daily-notes = { - folder = mkOption { - type = str; - default = ""; - description = "Directory in which daily notes should be created"; + setupOpts = lib.nvim.types.mkPluginSetupOption "Obsidian.nvim" { + dir = mkOption { + type = types.str; + default = "~/my-vault"; + description = "Obsidian vault directory"; }; - date-format = mkOption { - type = str; - default = ""; - description = "Date format used for creating daily notes"; - }; - }; - completion = { - nvim_cmp = mkOption { - type = bool; - description = "If using nvim-cmp, otherwise set to false"; + daily_notes = { + folder = mkOption { + type = types.nullOr types.str; + default = null; + description = "Directory in which daily notes should be created"; + }; + date_format = mkOption { + type = types.nullOr types.str; + default = null; + description = "Date format used for creating daily notes"; + }; + }; + + completion = { + nvim_cmp = mkOption { + # if using nvim-cmp, otherwise set to false + type = types.bool; + description = "If using nvim-cmp, otherwise set to false"; + default = config.vim.autocomplete.type == "nvim-cmp"; + }; }; }; }; diff --git a/modules/notes/orgmode/config.nix b/modules/notes/orgmode/config.nix index 635f0f1..19be11d 100644 --- a/modules/notes/orgmode/config.nix +++ b/modules/notes/orgmode/config.nix @@ -6,6 +6,7 @@ inherit (lib.modules) mkIf mkMerge; inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.binds) pushDownDefault; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.notes.orgmode; in { @@ -37,10 +38,7 @@ in { }, } - require('orgmode').setup({ - org_agenda_files = ${cfg.orgAgendaFiles}, - org_default_notes_file = '${cfg.orgDefaultNotesFile}', - }) + require('orgmode').setup(${toLuaObject cfg.setupOpts}) ''; }; } diff --git a/modules/notes/orgmode/orgmode.nix b/modules/notes/orgmode/orgmode.nix index 2a06605..1dad458 100644 --- a/modules/notes/orgmode/orgmode.nix +++ b/modules/notes/orgmode/orgmode.nix @@ -4,23 +4,31 @@ pkgs, ... }: let - inherit (lib.options) mkOption mkEnableOption; - inherit (lib.types) str; - inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.modules) mkRenamedOptionModule; + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.types) str listOf; + inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption; in { + imports = [ + (mkRenamedOptionModule ["vim" "notes" "orgmode" "orgAgendaFiles"] ["vim" "notes" "orgmode" "setupOpts" "org_agenda_files"]) + (mkRenamedOptionModule ["vim" "notes" "orgmode" "orgDefaultNotesFile"] ["vim" "notes" "orgmode" "setupOpts" "org_default_notes_file"]) + ]; + options.vim.notes.orgmode = { enable = mkEnableOption "nvim-orgmode: Neovim plugin for Emac Orgmode. Get the best of both worlds"; - orgAgendaFiles = mkOption { - type = str; - default = "{'~/Documents/org/*', '~/my-orgs/**/*'}"; - description = "List of org files to be used as agenda files."; - }; + setupOpts = mkPluginSetupOption "Orgmode" { + org_agenda_files = mkOption { + type = listOf str; + default = ["~/Documents/org/*" "~/my-orgs/**/*"]; + description = "List of org files to be used as agenda files."; + }; - orgDefaultNotesFile = mkOption { - type = str; - default = "~/Documents/org/refile.org"; - description = "Default org file to be used for notes."; + org_default_notes_file = mkOption { + type = str; + default = "~/Documents/org/refile.org"; + description = "Default org file to be used for notes."; + }; }; treesitter = { diff --git a/modules/notes/todo-comments/config.nix b/modules/notes/todo-comments/config.nix index 8db653f..1fa5dde 100644 --- a/modules/notes/todo-comments/config.nix +++ b/modules/notes/todo-comments/config.nix @@ -4,11 +4,11 @@ lib, ... }: let - inherit (lib.modules) mkIf mkMerge; - inherit (lib.nvim.binds) mkBinding; + inherit (lib) mkMerge mkBinding mkIf; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.notes.todo-comments; - self = import ./todo-comments.nix {inherit lib;}; + self = import ./todo-comments.nix {inherit pkgs lib;}; inherit (self.options.vim.notes.todo-comments) mappings; in { config = mkIf cfg.enable { @@ -24,28 +24,7 @@ in { ]; luaConfigRC.todo-comments = '' - require('todo-comments').setup { - highlight = { - before = "", -- "fg" or "bg" or empty - keyword = "bg", -- "fg", "bg", "wide" or empty - after = "fg", -- "fg" or "bg" or empty - pattern = ${cfg.patterns.highlight}, - comments_only = true, -- uses treesitter to match keywords in comments only - max_line_len = 400, -- ignore lines longer than this - exclude = {}, -- list of file types to exclude highlighting - }, - search = { - command = "${pkgs.ripgrep}/bin/rg", - args = { - "--color=never", - "--no-heading", - "--with-filename", - "--line-number", - "--column", - }, - pattern = ${cfg.patterns.search}, - }, - } + require('todo-comments').setup(${toLuaObject cfg.setupOpts}) ''; }; }; diff --git a/modules/notes/todo-comments/todo-comments.nix b/modules/notes/todo-comments/todo-comments.nix index ca4e4be..f92af7a 100644 --- a/modules/notes/todo-comments/todo-comments.nix +++ b/modules/notes/todo-comments/todo-comments.nix @@ -1,22 +1,50 @@ -{lib, ...}: let - inherit (lib.options) mkOption mkEnableOption; - inherit (lib.types) str; - inherit (lib.nvim.binds) mkMappingOption; +{ + pkgs, + lib, + ... +}: let + inherit (lib) mkEnableOption mkOption types mkMappingOption mkRenamedOptionModule; in { + imports = let + renamedSetupOption = oldPath: newPath: + mkRenamedOptionModule + (["vim" "notes" "todo-comments"] ++ oldPath) + (["vim" "notes" "todo-comments" "setupOpts"] ++ newPath); + in [ + (renamedSetupOption ["patterns" "highlight"] ["highlight" "pattern"]) + (renamedSetupOption ["patterns" "search"] ["search" "pattern"]) + ]; + options.vim.notes.todo-comments = { enable = mkEnableOption "todo-comments: highlight and search for todo comments like TODO, HACK, BUG in your code base"; - patterns = { - highlight = mkOption { - type = str; - default = ''[[.*<(KEYWORDS)(\([^\)]*\))?:]]''; - description = "vim regex pattern used for highlighting comments"; + setupOpts = lib.nvim.types.mkPluginSetupOption "todo-comments.nvim" { + highlight = { + pattern = mkOption { + type = types.str; + default = ''.*<(KEYWORDS)(\([^\)]*\))?:''; + description = "vim regex pattern used for highlighting comments"; + }; }; - search = mkOption { - type = str; - default = ''[[\b(KEYWORDS)(\([^\)]*\))?:]]''; - description = "ripgrep regex pattern used for searching comments"; + search = { + pattern = mkOption { + type = types.str; + default = ''\b(KEYWORDS)(\([^\)]*\))?:''; + description = "ripgrep regex pattern used for searching comments"; + }; + + command = mkOption { + type = types.str; + default = "${pkgs.ripgrep}/bin/rg"; + description = "search command"; + }; + + args = mkOption { + type = types.listOf types.str; + default = ["--color=never" "--no-heading" "--with-filename" "--line-number" "--column"]; + description = "arguments to pass to the search command"; + }; }; }; diff --git a/modules/projects/project-nvim/config.nix b/modules/projects/project-nvim/config.nix index 5c036ef..435476d 100644 --- a/modules/projects/project-nvim/config.nix +++ b/modules/projects/project-nvim/config.nix @@ -3,10 +3,7 @@ lib, ... }: let - inherit (lib.modules) mkIf; - inherit (lib.trivial) boolToString; - inherit (lib.strings) concatStringsSep; - inherit (lib.nvim.dag) entryAnywhere; + inherit (lib) mkIf nvim; cfg = config.vim.projects.project-nvim; in { @@ -15,40 +12,8 @@ in { "project-nvim" ]; - vim.luaConfigRC.project-nvim = entryAnywhere '' - require('project_nvim').setup({ - manual_mode = ${boolToString cfg.manualMode}, - detection_methods = { ${concatStringsSep ", " (map (x: "\"" + x + "\"") cfg.detectionMethods)} }, - - -- All the patterns used to detect root dir, when **"pattern"** is in - -- detection_methods - patterns = { ${concatStringsSep ", " (map (x: "\"" + x + "\"") cfg.patterns)} }, - - -- Table of lsp clients to ignore by name - -- eg: { "efm", ... } - ignore_lsp = { ${concatStringsSep ", " (map (x: "\"" + x + "\"") cfg.lspIgnored)} }, - - -- Don't calculate root dir on specific directories - -- Ex: { "~/.cargo/*", ... } - exclude_dirs = { ${concatStringsSep ", " (map (x: "\"" + x + "\"") cfg.excludeDirs)} }, - - -- Show hidden files in telescope - show_hidden = ${boolToString cfg.showHidden}, - - -- When set to false, you will get a message when project.nvim changes your - -- directory. - silent_chdir = ${boolToString cfg.silentChdir}, - - -- What scope to change the directory, valid options are - -- * global (default) - -- * tab - -- * win - scope_chdir = '${toString cfg.scopeChdir}', - - -- Path where project.nvim will store the project history for use in - -- telescope - datapath = vim.fn.stdpath("data"), - }) + vim.luaConfigRC.project-nvim = nvim.dag.entryAnywhere '' + require('project_nvim').setup(${nvim.lua.toLuaObject cfg.setupOpts}) ''; }; } diff --git a/modules/projects/project-nvim/project-nvim.nix b/modules/projects/project-nvim/project-nvim.nix index 9331f37..234e4f0 100644 --- a/modules/projects/project-nvim/project-nvim.nix +++ b/modules/projects/project-nvim/project-nvim.nix @@ -1,59 +1,80 @@ -{lib, ...}: let - inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum bool listOf str; +{ + config, + lib, + ... +}: let + inherit (lib) mkEnableOption mkOption types mkRenamedOptionModule; in { + imports = let + renamedSetupOption = oldPath: newPath: + mkRenamedOptionModule + (["vim" "projects" "project-nvim"] ++ oldPath) + (["vim" "projects" "project-nvim" "setupOpts"] ++ newPath); + in [ + (renamedSetupOption ["manualMode"] ["manual_mode"]) + (renamedSetupOption ["detectionMethods"] ["detection_methods"]) + (renamedSetupOption ["patterns"] ["patterns"]) + (renamedSetupOption ["lspIgnored"] ["lsp_ignored"]) + (renamedSetupOption ["excludeDirs"] ["exclude_dirs"]) + (renamedSetupOption ["showHidden"] ["show_hidden"]) + (renamedSetupOption ["silentChdir"] ["silent_chdir"]) + (renamedSetupOption ["scopeChdir"] ["scope_chdir"]) + ]; + options.vim.projects.project-nvim = { enable = mkEnableOption "project-nvim for project management"; - manualMode = mkOption { - type = bool; - default = true; - description = "don't automatically change the root directory so the user has the option to manually do so using `:ProjectRoot` command"; - }; + setupOpts = lib.nvim.types.mkPluginSetupOption "Project.nvim" { + manual_mode = mkOption { + type = types.bool; + default = true; + description = "don't automatically change the root directory so the user has the option to manually do so using `:ProjectRoot` command"; + }; - # detection methods should accept one or more strings from a list - detectionMethods = mkOption { - type = listOf str; - default = ["lsp" "pattern"]; - description = "Detection methods to use"; - }; + # detection methods should accept one or more strings from a list + detection_methods = mkOption { + type = types.listOf types.str; + default = ["lsp" "pattern"]; + description = "Detection methods to use"; + }; - # patterns - patterns = mkOption { - type = listOf str; - default = [".git" "_darcs" ".hg" ".bzr" ".svn" "Makefile" "package.json" "flake.nix" "cargo.toml"]; - description = "Patterns to use for pattern detection method"; - }; + # patterns + patterns = mkOption { + type = types.listOf types.str; + default = [".git" "_darcs" ".hg" ".bzr" ".svn" "Makefile" "package.json" "flake.nix" "cargo.toml"]; + description = "Patterns to use for pattern detection method"; + }; - # table of lsp servers to ignore by name - lspIgnored = mkOption { - type = listOf str; - default = []; - description = "LSP servers no ignore by name"; - }; + # table of lsp servers to ignore by name + lsp_ignored = mkOption { + type = types.listOf types.str; + default = []; + description = "LSP servers no ignore by name"; + }; - excludeDirs = mkOption { - type = listOf str; - default = []; - description = "Directories to exclude from project root search"; - }; + exclude_dirs = mkOption { + type = types.listOf types.str; + default = []; + description = "Directories to exclude from project root search"; + }; - showHidden = mkOption { - type = bool; - default = false; - description = "Show hidden files in telescope picker"; - }; + show_hidden = mkOption { + type = types.bool; + default = false; + description = "Show hidden files in telescope picker"; + }; - silentChdir = mkOption { - type = bool; - default = true; - description = "Silently change directory when changing project"; - }; + silent_chdir = mkOption { + type = types.bool; + default = true; + description = "Silently change directory when changing project"; + }; - scopeChdir = mkOption { - type = enum ["global" "tab" "win"]; - default = "global"; - description = "What scope to change the directory"; + scope_chdir = mkOption { + type = types.enum ["global" "tab" "win"]; + default = "global"; + description = "What scope to change the directory"; + }; }; }; } diff --git a/modules/rich-presence/neocord/config.nix b/modules/rich-presence/neocord/config.nix index 3856db1..a6dcbb5 100644 --- a/modules/rich-presence/neocord/config.nix +++ b/modules/rich-presence/neocord/config.nix @@ -3,12 +3,9 @@ lib, ... }: let - inherit (builtins) toString; inherit (lib.modules) mkIf; - inherit (lib.trivial) boolToString; - inherit (lib.strings) escapeNixString; - inherit (lib.nvim.lua) listToLuaTable; inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.presence.neocord; in { @@ -17,31 +14,7 @@ in { vim.luaConfigRC.neocord = entryAnywhere '' -- Description of each option can be found in https://github.com/IogaMaster/neocord#lua - require("neocord").setup({ - -- General options - logo = "${cfg.logo}", - logo_tooltip = "${cfg.logo_tooltip}", - main_image = "${cfg.main_image}", - client_id = "${cfg.client_id}", - log_level = ${ - if cfg.log_level == null - then "nil" - else "${escapeNixString cfg.log_level}" - }, - debounce_timeout = ${toString cfg.debounce_timeout}, - blacklist = ${listToLuaTable cfg.blacklist}, - show_time = "${boolToString cfg.show_time}", - - -- Rich Presence text options - editing_text = "${cfg.rich_presence.editing_text}", - file_explorer_text = "${cfg.rich_presence.file_explorer_text}", - git_commit_text = "${cfg.rich_presence.git_commit_text}", - plugin_manager_text = "${cfg.rich_presence.plugin_manager_text}", - reading_text = "${cfg.rich_presence.reading_text}", - workspace_text = "${cfg.rich_presence.workspace_text}", - line_number_text = "${cfg.rich_presence.line_number_text}", - terminal_text = "${cfg.rich_presence.terminal_text}", - }) + require("neocord").setup(${toLuaObject cfg.setupOpts}) ''; }; } diff --git a/modules/rich-presence/neocord/neocord.nix b/modules/rich-presence/neocord/neocord.nix index c962d2d..1d6e625 100644 --- a/modules/rich-presence/neocord/neocord.nix +++ b/modules/rich-presence/neocord/neocord.nix @@ -1,86 +1,94 @@ {lib, ...}: let - inherit (lib.modules) mkRemovedOptionModule; + inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule; inherit (lib.options) mkEnableOption mkOption literalExpression; inherit (lib.types) bool int str enum nullOr listOf; + inherit (lib.nvim.types) mkPluginSetupOption; in { - imports = [ - (mkRemovedOptionModule ["vim" "presence" "presence-nvim"] '' - The option vim.presence.presence-nvim has been deprecated in favor of the new neocord module. - Options provided by the plugin remain mostly the same, but manual migration is required. + imports = + [ + (mkRemovedOptionModule ["vim" "presence" "presence-nvim"] '' + The option vim.presence.presence-nvim has been deprecated in favor of the new neocord module. + Options provided by the plugin remain mostly the same, but manual migration is required. - Please see neocord documentation and the neovim-flake options for more info - '') - ]; + Please see neocord documentation and the neovim-flake options for more info + '') + ] + ++ (map + (optName: mkRenamedOptionModule ["vim" "presence" "neocord" "rich_presence" optName] ["vim" "presence" "neocord" "setupOpts" optName]) + ["debounce_timeout" "blacklist" "show_time" "editing_text" "file_explorer_text" "git_commit_text" "plugin_manager_text" "reading_text" "workspace_text" "line_number_text" "terminal_text"]) + ++ (map + (optName: mkRenamedOptionModule ["vim" "presence" "neocord" optName] ["vim" "presence" "neocord" "setupOpts" optName]) + ["logo" "logo_tooltip" "main_image" "client_id" "log_level" "debounce_timeout" "blacklist" "show_time"]); options.vim.presence.neocord = { enable = mkEnableOption "neocord plugin for discord rich presence"; - logo = mkOption { - type = str; # TODO: can the default be documented better, maybe with an enum? - default = "auto"; - description = '' - Logo to be displayed on the RPC item + setupOpts = mkPluginSetupOption "neocord" { + logo = mkOption { + type = str; # TODO: can the default be documented better, maybe with an enum? + default = "auto"; + description = '' + Logo to be displayed on the RPC item - This must be either "auto" or an URL to your image of choice - ''; - }; + This must be either "auto" or an URL to your image of choice + ''; + }; - logo_tooltip = mkOption { - type = str; - default = "The One True Text Editor"; - description = "Text displayed when hovering over the Neovim image"; - }; + logo_tooltip = mkOption { + type = str; + default = "The One True Text Editor"; + description = "Text displayed when hovering over the Neovim image"; + }; - main_image = mkOption { - type = enum ["language" "logo"]; - default = "language"; - description = "Main image to be displayed"; - }; + main_image = mkOption { + type = enum ["language" "logo"]; + default = "language"; + description = "Main image to be displayed"; + }; - client_id = mkOption { - type = str; - default = "1157438221865717891"; - description = "Client ID of the application"; - }; + client_id = mkOption { + type = str; + default = "1157438221865717891"; + description = "Client ID of the application"; + }; - log_level = mkOption { - type = nullOr (enum ["debug" "info" "warn" "error"]); - default = null; - description = "Log level to be used by the plugin"; - }; + log_level = mkOption { + type = nullOr (enum ["debug" "info" "warn" "error"]); + default = null; + description = "Log level to be used by the plugin"; + }; - debounce_timeout = mkOption { - type = int; - default = 10; - description = "Number of seconds to debounce events"; - }; + debounce_timeout = mkOption { + type = int; + default = 10; + description = "Number of seconds to debounce events"; + }; - auto_update = mkOption { - type = bool; - default = true; - description = "Automatically update the presence"; - }; + auto_update = mkOption { + type = bool; + default = true; + description = "Automatically update the presence"; + }; - enable_line_number = mkOption { - type = bool; - default = false; - description = "Show line number on the RPC item"; - }; + enable_line_number = mkOption { + type = bool; + default = false; + description = "Show line number on the RPC item"; + }; - show_time = mkOption { - type = bool; - default = true; - description = "Show time on the RPC item"; - }; + show_time = mkOption { + type = bool; + default = true; + description = "Show time on the RPC item"; + }; - blacklist = mkOption { - type = listOf str; - default = []; - example = literalExpression ''["Alpha"]''; - description = "List of filetypes to ignore"; - }; + blacklist = mkOption { + type = listOf str; + default = []; + example = literalExpression ''["Alpha"]''; + description = "List of filetypes to ignore"; + }; - rich_presence = { editing_text = mkOption { type = str; default = "Editing %s"; diff --git a/modules/session/nvim-session-manager/config.nix b/modules/session/nvim-session-manager/config.nix index 91072f1..729270e 100644 --- a/modules/session/nvim-session-manager/config.nix +++ b/modules/session/nvim-session-manager/config.nix @@ -3,12 +3,8 @@ lib, ... }: let - inherit (lib.modules) mkIf mkMerge; - inherit (lib.lists) optionals; - inherit (lib.strings) concatStringsSep; - inherit (lib.trivial) boolToString; - inherit (lib.nvim.binds) mkBinding; - inherit (lib.nvim.dag) entryAnywhere; + inherit (lib) mkIf optionals mkMerge mkBinding nvim; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.session.nvim-session-manager; in { @@ -19,7 +15,7 @@ in { "nvim-session-manager" "plenary-nvim" ] - ++ optionals (cfg.usePicker) ["dressing-nvim"]; + ++ optionals cfg.usePicker ["dressing-nvim"]; maps.normal = mkMerge [ (mkBinding cfg.mappings.loadSession ":SessionManager load_session" "Load session") @@ -29,31 +25,10 @@ in { # TODO: load_current_dir_session ]; - luaConfigRC.nvim-session-manager = entryAnywhere '' + luaConfigRC.nvim-session-manager = nvim.dag.entryAnywhere '' local Path = require('plenary.path') local sm = require('session_manager.config') - require('session_manager').setup({ - sessions_dir = Path:new(vim.fn.stdpath('data'), 'sessions'), - - path_replacer = '${toString cfg.pathReplacer}', - - colon_replacer = '${toString cfg.colonReplacer}', - - autoload_mode = sm.AutoloadMode.${toString cfg.autoloadMode}, - - autosave_last_session = ${boolToString cfg.autoSave.lastSession}, - - autosave_ignore_not_normal = ${boolToString cfg.autoSave.ignoreNotNormal}, - - autosave_ignore_dirs = {${concatStringsSep ", " (map (x: "\'" + x + "\'") cfg.autoSave.ignoreDirs)}}, - - autosave_ignore_filetypes = {${concatStringsSep ", " (map (x: "\'" + x + "\'") cfg.autoSave.ignoreFiletypes)}}, - - autosave_ignore_buftypes = {${concatStringsSep ", " (map (x: "\'" + x + "\'") cfg.autoSave.ignoreBufTypes)}}, - - autosave_only_in_session = ${boolToString cfg.autoSave.onlyInSession}, - max_path_length = ${toString cfg.maxPathLength}, - }) + require('session_manager').setup(${toLuaObject cfg.setupOpts}) ''; }; }; diff --git a/modules/session/nvim-session-manager/nvim-session-manager.nix b/modules/session/nvim-session-manager/nvim-session-manager.nix index 2182db3..8dce6ce 100644 --- a/modules/session/nvim-session-manager/nvim-session-manager.nix +++ b/modules/session/nvim-session-manager/nvim-session-manager.nix @@ -1,7 +1,23 @@ {lib, ...}: let - inherit (lib.options) mkOption mkEnableOption; - inherit (lib.types) nullOr str bool int listOf enum; + inherit (lib.types) nullOr str bool; + inherit (lib) mkEnableOption mkOption types mkRenamedOptionModule; in { + imports = let + renameSetupOpt = oldPath: newPath: + mkRenamedOptionModule (["vim" "session" "nvim-session-manager"] ++ oldPath) (["vim" "session" "nvim-session-manager" "setupOpts"] ++ newPath); + in [ + (renameSetupOpt ["pathReplacer"] ["path_replacer"]) + (renameSetupOpt ["colonReplacer"] ["colon_replacer"]) + (renameSetupOpt ["autoloadMode"] ["autoload_mode"]) + (renameSetupOpt ["maxPathLength"] ["max_path_length"]) + (renameSetupOpt ["autoSave" "lastSession"] ["autosave_last_session"]) + (renameSetupOpt ["autoSave" "ignoreNotNormal"] ["autosave_ignore_not_normal"]) + (renameSetupOpt ["autoSave" "ignoreDirs"] ["autosave_ignore_dirs"]) + (renameSetupOpt ["autoSave" "ignoreFiletypes"] ["autosave_ignore_filetypes"]) + (renameSetupOpt ["autoSave" "ignoreBufTypes"] ["autosave_ignore_buftypes"]) + (renameSetupOpt ["autoSave" "onlyInSession"] ["autosave_only_in_session"]) + ]; + options.vim.session.nvim-session-manager = { enable = mkEnableOption "nvim-session-manager: manage sessions like folders in VSCode"; @@ -37,63 +53,63 @@ in { description = "Whether or not we should use dressing.nvim to build a session picker UI"; }; - pathReplacer = mkOption { - type = str; - default = "__"; - description = "The character to which the path separator will be replaced for session files"; - }; + setupOpts = { + path_replacer = mkOption { + type = types.str; + default = "__"; + description = "The character to which the path separator will be replaced for session files"; + }; - colonReplacer = mkOption { - type = str; - default = "++"; - description = "The character to which the colon symbol will be replaced for session files"; - }; + colon_replacer = mkOption { + type = types.str; + default = "++"; + description = "The character to which the colon symbol will be replaced for session files"; + }; - autoloadMode = mkOption { - type = enum ["Disabled" "CurrentDir" "LastSession"]; - default = "LastSession"; - description = "Define what to do when Neovim is started without arguments. Possible values: Disabled, CurrentDir, LastSession"; - }; + autoload_mode = mkOption { + type = types.enum ["Disabled" "CurrentDir" "LastSession"]; + default = "LastSession"; + description = "Define what to do when Neovim is started without arguments. Possible values: Disabled, CurrentDir, LastSession"; + }; - maxPathLength = mkOption { - type = nullOr int; - default = 80; - description = "Shorten the display path if length exceeds this threshold. Use 0 if don't want to shorten the path at all"; - }; + max_path_length = mkOption { + type = types.nullOr types.int; + default = 80; + description = "Shorten the display path if length exceeds this threshold. Use 0 if don't want to shorten the path at all"; + }; - autoSave = { - lastSession = mkOption { - type = bool; + autosave_last_session = mkOption { + type = types.bool; default = true; description = "Automatically save last session on exit and on session switch"; }; - ignoreNotNormal = mkOption { - type = bool; + autosave_ignore_not_normal = mkOption { + type = types.bool; default = true; description = "Plugin will not save a session when no buffers are opened, or all of them aren't writable or listed"; }; - ignoreDirs = mkOption { - type = listOf str; + autosave_ignore_dirs = mkOption { + type = types.listOf types.str; default = []; description = "A list of directories where the session will not be autosaved"; }; - ignoreFiletypes = mkOption { - type = listOf str; + autosave_ignore_filetypes = mkOption { + type = types.listOf types.str; default = ["gitcommit"]; description = "All buffers of these file types will be closed before the session is saved"; }; - ignoreBufTypes = mkOption { - type = listOf str; + autosave_ignore_buftypes = mkOption { + type = types.listOf types.str; default = []; description = "All buffers of these bufer types will be closed before the session is saved"; }; - onlyInSession = mkOption { - type = bool; + autosave_only_in_session = mkOption { + type = types.bool; default = false; description = "Always autosaves session. If true, only autosaves after a session is active"; }; diff --git a/modules/statusline/lualine/config.nix b/modules/statusline/lualine/config.nix index 04f123d..9578842 100644 --- a/modules/statusline/lualine/config.nix +++ b/modules/statusline/lualine/config.nix @@ -3,75 +3,73 @@ lib, ... }: let - inherit (lib.modules) mkIf; + inherit (lib.modules) mkIf mkMerge; inherit (lib.trivial) boolToString; - inherit (lib.strings) optionalString; - inherit (lib.nvim.lua) luaTable listToLuaTable; inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; + inherit (lib.generators) mkLuaInline; cfg = config.vim.statusline.lualine; breadcrumbsCfg = config.vim.ui.breadcrumbs; in { - config = (mkIf cfg.enable) { - vim.startPlugins = [ - "lualine" - ]; + config = mkMerge [ + # TODO: move into nvim-tree file + (mkIf (config.vim.filetree.nvimTree.enable) { + vim.statusline.lualine.setupOpts = { + extensions = ["nvim-tree"]; + }; + }) + (mkIf (breadcrumbsCfg.enable && breadcrumbsCfg.source == "nvim-navic") { + vim.statusline.lualine.setupOpts = { + # TODO: rewrite in new syntax + winbar.lualine_c = [ + [ + "navic" + (mkLuaInline "draw_empty = ${boolToString config.vim.ui.breadcrumbs.alwaysRender}") + ] + ]; + }; + }) + (mkIf cfg.enable { + vim.startPlugins = [ + "lualine" + ]; - vim.luaConfigRC.lualine = entryAnywhere '' - local lualine = require('lualine') - lualine.setup { + vim.luaConfigRC.lualine = entryAnywhere '' + local lualine = require('lualine') + lualine.setup ${toLuaObject cfg.setupOpts} + ''; + + # this is for backwards-compatibility + vim.statusline.lualine.setupOpts = { options = { - icons_enabled = ${boolToString cfg.icons.enable}, - theme = "${cfg.theme}", - component_separators = {"${cfg.componentSeparator.left}","${cfg.componentSeparator.right}"}, - section_separators = {"${cfg.sectionSeparator.left}","${cfg.sectionSeparator.right}"}, - disabled_filetypes = ${listToLuaTable cfg.disabledFiletypes}, - always_divide_middle = ${boolToString cfg.alwaysDivideMiddle}, - globalstatus = ${boolToString cfg.globalStatus}, - ignore_focus = ${listToLuaTable cfg.ignoreFocus}, - extensions = {${optionalString config.vim.filetree.nvimTree.enable "'nvim-tree'"}}, - refresh = { - statusline = ${toString cfg.refresh.statusline}, - tabline = ${toString cfg.refresh.tabline}, - winbar = ${toString cfg.refresh.winbar}, - }, - }, + icons_enabled = cfg.icons.enable; + theme = cfg.theme; + component_separators = [cfg.componentSeparator.left cfg.componentSeparator.right]; + section_separators = [cfg.sectionSeparator.left cfg.sectionSeparator.right]; + globalstatus = cfg.globalStatus; + refresh = cfg.refresh; + }; - -- active sections sections = { - lualine_a = ${luaTable (cfg.activeSection.a ++ cfg.extraActiveSection.a)}, - lualine_b = ${luaTable (cfg.activeSection.b ++ cfg.extraActiveSection.b)}, - lualine_c = ${luaTable (cfg.activeSection.c ++ cfg.extraActiveSection.c)}, - lualine_x = ${luaTable (cfg.activeSection.x ++ cfg.extraActiveSection.x)}, - lualine_y = ${luaTable (cfg.activeSection.y ++ cfg.extraActiveSection.y)}, - lualine_z = ${luaTable (cfg.activeSection.z ++ cfg.extraActiveSection.z)}, - }, - - -- inactive sections + lualine_a = builtins.map mkLuaInline (cfg.activeSection.a ++ cfg.extraActiveSection.a); + lualine_b = builtins.map mkLuaInline (cfg.activeSection.b ++ cfg.extraActiveSection.b); + lualine_c = builtins.map mkLuaInline (cfg.activeSection.c ++ cfg.extraActiveSection.c); + lualine_x = builtins.map mkLuaInline (cfg.activeSection.x ++ cfg.extraActiveSection.x); + lualine_y = builtins.map mkLuaInline (cfg.activeSection.y ++ cfg.extraActiveSection.y); + lualine_z = builtins.map mkLuaInline (cfg.activeSection.z ++ cfg.extraActiveSection.z); + }; inactive_sections = { - lualine_a = ${luaTable (cfg.inactiveSection.a ++ cfg.extraInactiveSection.a)}, - lualine_b = ${luaTable (cfg.inactiveSection.b ++ cfg.extraInactiveSection.b)}, - lualine_c = ${luaTable (cfg.inactiveSection.c ++ cfg.extraInactiveSection.c)}, - lualine_x = ${luaTable (cfg.inactiveSection.x ++ cfg.extraInactiveSection.x)}, - lualine_y = ${luaTable (cfg.inactiveSection.y ++ cfg.extraInactiveSection.y)}, - lualine_z = ${luaTable (cfg.inactiveSection.z ++ cfg.extraInactiveSection.z)}, - }, - - -- tabline (currently unsupported) - tabline = {}, - - ${optionalString (breadcrumbsCfg.enable && breadcrumbsCfg.source == "nvim-navic") '' - -- enable winbar if nvim-navic is enabled - winbar = { - lualine_c = { - { - "navic", - draw_empty = ${boolToString config.vim.ui.breadcrumbs.alwaysRender} - } - } - }, - ''} - } - ''; - }; + lualine_a = builtins.map mkLuaInline (cfg.inactiveSection.a ++ cfg.extraInactiveSection.a); + lualine_b = builtins.map mkLuaInline (cfg.inactiveSection.b ++ cfg.extraInactiveSection.b); + lualine_c = builtins.map mkLuaInline (cfg.inactiveSection.c ++ cfg.extraInactiveSection.c); + lualine_x = builtins.map mkLuaInline (cfg.inactiveSection.x ++ cfg.extraInactiveSection.x); + lualine_y = builtins.map mkLuaInline (cfg.inactiveSection.y ++ cfg.extraInactiveSection.y); + lualine_z = builtins.map mkLuaInline (cfg.inactiveSection.z ++ cfg.extraInactiveSection.z); + }; + # probably don't need this? + tabline = []; + }; + }) + ]; } diff --git a/modules/statusline/lualine/lualine.nix b/modules/statusline/lualine/lualine.nix index 9f5b583..7d1020f 100644 --- a/modules/statusline/lualine/lualine.nix +++ b/modules/statusline/lualine/lualine.nix @@ -7,6 +7,7 @@ inherit (lib.options) mkOption mkEnableOption; inherit (lib.types) int bool str listOf enum; inherit (lib.lists) optional; + inherit (lib.nvim.types) mkPluginSetupOption; supported_themes = import ./supported_themes.nix; colorPuccin = @@ -15,6 +16,8 @@ else "none"; in { options.vim.statusline.lualine = { + setupOpts = mkPluginSetupOption "Lualine" {}; + enable = mkEnableOption "lualine statusline plugin"; icons = { diff --git a/modules/terminal/toggleterm/config.nix b/modules/terminal/toggleterm/config.nix index 1ffec58..7f57358 100644 --- a/modules/terminal/toggleterm/config.nix +++ b/modules/terminal/toggleterm/config.nix @@ -9,6 +9,7 @@ inherit (lib.meta) getExe; inherit (lib.nvim.binds) mkBinding; inherit (lib.nvim.dag) entryAnywhere entryAfter; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.terminal.toggleterm; in { @@ -23,24 +24,7 @@ in { maps.normal = mkBinding cfg.mappings.open "execute v:count . \"ToggleTerm\"" "Toggle terminal"; luaConfigRC.toggleterm = entryAnywhere '' - require("toggleterm").setup({ - open_mapping = null, - direction = '${toString cfg.direction}', - -- TODO: this should probably be turned into a module that uses the lua function if and only if the user has not set it - size = function(term) - if term.direction == "horizontal" then - return 15 - elseif term.direction == "vertical" then - return vim.o.columns * 0.4 - end - end, - winbar = { - enabled = '${toString cfg.enable_winbar}', - name_formatter = function(term) -- term: Terminal - return term.name - end - }, - }) + require("toggleterm").setup(${toLuaObject cfg.setupOpts}) ''; }; } diff --git a/modules/terminal/toggleterm/toggleterm.nix b/modules/terminal/toggleterm/toggleterm.nix index dbc8e54..865e66f 100644 --- a/modules/terminal/toggleterm/toggleterm.nix +++ b/modules/terminal/toggleterm/toggleterm.nix @@ -5,8 +5,16 @@ }: let inherit (lib.options) mkOption mkEnableOption; inherit (lib.nvim.binds) mkMappingOption; - inherit (lib.types) nullOr str enum bool package; + inherit (lib.types) nullOr str enum bool package either int; + inherit (lib) mkRenamedOptionModule; + inherit (lib.nvim.types) mkPluginSetupOption luaInline; + inherit (lib.generators) mkLuaInline; in { + imports = [ + (mkRenamedOptionModule ["vim" "terminal" "toggleterm" "direction"] ["vim" "terminal" "toggleterm" "setupOpts" "direction"]) + (mkRenamedOptionModule ["vim" "terminal" "toggleterm" "enable_winbar"] ["vim" "terminal" "toggleterm" "setupOpts" "enable_winbar"]) + ]; + options.vim.terminal.toggleterm = { enable = mkEnableOption "toggleterm as a replacement to built-in terminal command"; mappings = { @@ -17,16 +25,44 @@ in { }; }; - direction = mkOption { - type = enum ["horizontal" "vertical" "tab" "float"]; - default = "horizontal"; - description = "Direction of the terminal"; - }; + setupOpts = mkPluginSetupOption "ToggleTerm" { + direction = mkOption { + type = enum ["horizontal" "vertical" "tab" "float"]; + default = "horizontal"; + description = "Direction of the terminal"; + }; - enable_winbar = mkOption { - type = bool; - default = false; - description = "Enable winbar"; + enable_winbar = mkOption { + type = bool; + default = false; + description = "Enable winbar"; + }; + + size = mkOption { + type = either luaInline int; + description = "Number or lua function which is passed to the current terminal"; + default = mkLuaInline '' + function(term) + if term.direction == "horizontal" then + return 15 + elseif term.direction == "vertical" then + return vim.o.columns * 0.4 + end + end + ''; + }; + winbar = { + enabled = mkEnableOption "winbar in terminal" // {default = true;}; + name_formatter = mkOption { + type = luaInline; + description = "Winbar formatter function."; + default = mkLuaInline '' + function(term) + return term.name + end + ''; + }; + }; }; lazygit = { diff --git a/modules/ui/borders/borders.nix b/modules/ui/borders/borders.nix index 4d4952b..37589dc 100644 --- a/modules/ui/borders/borders.nix +++ b/modules/ui/borders/borders.nix @@ -18,7 +18,7 @@ in { type = enum defaultStyles; default = "rounded"; description = '' - The global border style to use + The global border style to use. ''; }; diff --git a/modules/ui/breadcrumbs/breadcrumbs.nix b/modules/ui/breadcrumbs/breadcrumbs.nix index 68c2a9f..18df8c0 100644 --- a/modules/ui/breadcrumbs/breadcrumbs.nix +++ b/modules/ui/breadcrumbs/breadcrumbs.nix @@ -5,7 +5,34 @@ }: let inherit (lib.options) mkOption mkEnableOption; inherit (lib.types) nullOr listOf enum bool str int; + inherit (lib.modules) mkRenamedOptionModule; + inherit (lib.nvim.types) mkPluginSetupOption; + mkSimpleIconOption = default: + mkOption { + inherit default; + type = str; + description = ""; + }; 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 +54,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 +81,7 @@ in { children = mkOption { type = str; - default = "h"; + default = "l"; description = "keybinding to navigate to the child node"; }; @@ -180,299 +200,162 @@ 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 = mkSimpleIconOption " "; + leaf_selected = mkSimpleIconOption " → "; + branch = mkSimpleIconOption " "; + }; + }; + + 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 { - type = str; - default = " "; - description = ""; - }; - - leafSelected = mkOption { - type = str; - default = " → "; - description = ""; - }; - - branch = mkOption { - type = str; - default = " "; - description = ""; - }; - }; - }; - - lsp = { - autoAttach = 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"; - }; - }; - - sourceBuffer = { - 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"; - }; - }; - - # 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 = "Package icon"; - }; - - class = mkOption { - type = str; - default = "󰌗 "; - description = "Class icon"; - }; - - property = mkOption { - type = str; - default = " "; - description = "Property icon"; - }; - - 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 = "Variable icon"; - }; - - constant = mkOption { - type = str; - default = "󰏿 "; - description = "Constant icon"; - }; - - string = mkOption { - type = str; - default = " "; - description = "String icon"; - }; - - number = mkOption { - type = str; - default = "󰎠 "; - description = "Number icon"; - }; - - boolean = mkOption { - type = str; - default = " "; - description = "Boolean icon"; - }; - - 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"; + File = mkSimpleIconOption "󰈙 "; + Module = mkSimpleIconOption " "; + Namespace = mkSimpleIconOption "󰌗 "; + Package = mkSimpleIconOption " "; + Class = mkSimpleIconOption "󰌗 "; + Property = mkSimpleIconOption " "; + Field = mkSimpleIconOption " "; + Constructor = mkSimpleIconOption " "; + Enum = mkSimpleIconOption "󰕘"; + Interface = mkSimpleIconOption "󰕘"; + Function = mkSimpleIconOption "󰊕 "; + Variable = mkSimpleIconOption "󰆧 "; + Constant = mkSimpleIconOption "󰏿 "; + String = mkSimpleIconOption " "; + Number = mkSimpleIconOption "󰎠 "; + Boolean = mkSimpleIconOption "◩ "; + Array = mkSimpleIconOption "󰅪 "; + Object = mkSimpleIconOption "󰅩 "; + Method = mkSimpleIconOption "󰆧 "; + Key = mkSimpleIconOption "󰌋 "; + Null = mkSimpleIconOption "󰟢 "; + EnumMember = mkSimpleIconOption "󰕘 "; + Struct = mkSimpleIconOption "󰌗 "; + Event = mkSimpleIconOption " "; + Operator = mkSimpleIconOption "󰆕 "; + TypeParameter = mkSimpleIconOption "󰊄 "; }; }; }; diff --git a/modules/ui/breadcrumbs/config.nix b/modules/ui/breadcrumbs/config.nix index 5afda30..35c08ec 100644 --- a/modules/ui/breadcrumbs/config.nix +++ b/modules/ui/breadcrumbs/config.nix @@ -3,15 +3,14 @@ lib, ... }: let - inherit (lib.modules) mkIf; 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; + inherit (lib.generators) mkLuaInline; cfg = config.vim.ui.breadcrumbs; - nbcfg = cfg.navbuddy; in { config = mkIf cfg.enable { vim.startPlugins = @@ -30,6 +29,55 @@ in { "nvim-navic" ]; + vim.ui.breadcrumbs.navbuddy.setupOpts = { + mappings = { + ${cfg.navbuddy.mappings.close} = mkLuaInline "actions.close()"; + ${cfg.navbuddy.mappings.nextSibling} = mkLuaInline "actions.next_sibling()"; + ${cfg.navbuddy.mappings.previousSibling} = mkLuaInline "actions.previous_sibling()"; + ${cfg.navbuddy.mappings.parent} = mkLuaInline "actions.parent()"; + ${cfg.navbuddy.mappings.children} = mkLuaInline "actions.children()"; + ${cfg.navbuddy.mappings.root} = mkLuaInline "actions.root()"; + + ${cfg.navbuddy.mappings.visualName} = mkLuaInline "actions.visual_name()"; + ${cfg.navbuddy.mappings.visualScope} = mkLuaInline "actions.visual_scope()"; + + ${cfg.navbuddy.mappings.yankName} = mkLuaInline "actions.yank_name()"; + ${cfg.navbuddy.mappings.yankScope} = mkLuaInline "actions.yank_scope()"; + + ${cfg.navbuddy.mappings.insertName} = mkLuaInline "actions.insert_name()"; + ${cfg.navbuddy.mappings.insertScope} = mkLuaInline "actions.insert_scope()"; + + ${cfg.navbuddy.mappings.appendName} = mkLuaInline "actions.append_name()"; + ${cfg.navbuddy.mappings.appendScope} = mkLuaInline "actions.append_scope()"; + + ${cfg.navbuddy.mappings.rename} = mkLuaInline "actions.rename()"; + + ${cfg.navbuddy.mappings.delete} = mkLuaInline "actions.delete()"; + + ${cfg.navbuddy.mappings.foldCreate} = mkLuaInline "actions.fold_create()"; + ${cfg.navbuddy.mappings.foldDelete} = mkLuaInline "actions.fold_delete()"; + + ${cfg.navbuddy.mappings.comment} = mkLuaInline "actions.comment()"; + + ${cfg.navbuddy.mappings.select} = mkLuaInline "actions.select()"; + + ${cfg.navbuddy.mappings.moveDown} = mkLuaInline "actions.move_down()"; + ${cfg.navbuddy.mappings.moveUp} = mkLuaInline "actions.move_up()"; + + ${cfg.navbuddy.mappings.telescope} = mkLuaInline '' + actions.telescope({ + layout_strategy = "horizontal", + layout_config = { + height = 0.60, + width = 0.75, + prompt_position = "top", + preview_width = 0.50 + }, + })''; + ${cfg.navbuddy.mappings.help} = mkLuaInline "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} ''} ''; }; diff --git a/modules/ui/colorizer/colorizer.nix b/modules/ui/colorizer/colorizer.nix index de3281c..364abb9 100644 --- a/modules/ui/colorizer/colorizer.nix +++ b/modules/ui/colorizer/colorizer.nix @@ -1,68 +1,104 @@ -{lib, ...}: let +{ + config, + lib, + ... +}: let inherit (lib.options) mkOption mkEnableOption; inherit (lib.types) attrsOf attrs bool enum; + inherit (lib.modules) mkRenamedOptionModule; + inherit (lib.nvim.types) mkPluginSetupOption; in { + imports = [ + (mkRenamedOptionModule ["vim" "ui" "colorizer" "options"] ["vim" "ui" "colorizer" "setupOpts" "user_default_options"]) + (mkRenamedOptionModule ["vim" "ui" "colorizer" "filetypes"] ["vim" "ui" "colorizer" "setupOpts" "filetypes"]) + ]; + options.vim.ui.colorizer = { enable = mkEnableOption "color highlighting [nvim-colorizer.lua]"; - filetypes = mkOption { - type = attrsOf attrs; - default = { - css = {}; - scss = {}; - }; - description = "Filetypes to highlight on"; - }; - - options = { - alwaysUpdate = mkEnableOption "updating color values even if buffer is not focused, like when using cmp_menu, cmp_docs"; - - rgb = mkOption { - type = bool; - default = true; - description = "#RGB hex codes"; + setupOpts = mkPluginSetupOption "nvim-colorizer" { + filetypes = mkOption { + type = attrsOf attrs; + default = { + css = {}; + scss = {}; + }; + description = "Filetypes to highlight on"; }; - rrggbb = mkOption { - type = bool; - default = true; - description = "#RRGGBB hex codes"; - }; + user_default_options = { + rgb = mkOption { + type = bool; + default = true; + description = "#RGB hex codes"; + }; - names = mkOption { - type = bool; - default = true; - description = ''"Name" codes such as "Blue"''; - }; + rrggbb = mkOption { + type = bool; + default = true; + description = "#RRGGBB hex codes"; + }; - rgb_fn = mkOption { - type = bool; - default = false; - description = "CSS rgb() and rgba() functions"; - }; + names = mkOption { + type = bool; + default = true; + description = ''"Name" codes such as "Blue"''; + }; - rrggbbaa = mkOption { - type = bool; - default = false; - description = "#RRGGBBAA hex codes"; - }; + rgb_fn = mkOption { + type = bool; + default = false; + description = "CSS rgb() and rgba() functions"; + }; - hsl_fn = mkOption { - type = bool; - default = false; - description = "CSS hsl() and hsla() functions"; - }; + rrggbbaa = mkOption { + type = bool; + default = false; + description = "#RRGGBBAA hex codes"; + }; - mode = mkOption { - type = enum ["foreground" "background"]; - default = "background"; - description = "Set the display mode"; - }; + hsl_fn = mkOption { + type = bool; + default = false; + description = "CSS hsl() and hsla() functions"; + }; - tailwind = mkEnableOption "tailwind colors"; - sass = mkEnableOption "sass colors"; - css = mkEnableOption "all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB"; - css_fn = mkEnableOption "all CSS *functions*: rgb_fn, hsl_fn"; + css = mkOption { + type = bool; + default = false; + description = "Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB"; + }; + + css_fn = mkOption { + type = bool; + default = false; + description = "Enable all CSS *functions*: rgb_fn, hsl_fn"; + }; + + mode = mkOption { + type = enum ["foreground" "background"]; + default = "background"; + description = "Set the display mode"; + }; + + tailwind = mkOption { + type = bool; + default = false; + description = "Enable tailwind colors"; + }; + + sass = mkOption { + type = bool; + default = false; + description = "Enable sass colors"; + }; + + alwaysUpdate = mkOption { + type = bool; + default = false; + description = "Update color values even if buffer is not focused, like when using cmp_menu, cmp_docs"; + }; + }; }; }; } diff --git a/modules/ui/colorizer/config.nix b/modules/ui/colorizer/config.nix index a21644f..1ff45f6 100644 --- a/modules/ui/colorizer/config.nix +++ b/modules/ui/colorizer/config.nix @@ -4,9 +4,8 @@ ... }: let inherit (lib.modules) mkIf; - inherit (lib.trivial) boolToString; - inherit (lib.nvim.lua) attrsetToLuaTable; inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.ui.colorizer; in { @@ -16,23 +15,7 @@ in { ]; vim.luaConfigRC.colorizer = entryAnywhere '' - require('colorizer').setup({ - filetypes = ${attrsetToLuaTable cfg.filetypes}, - user_default_options = { - RGB = ${boolToString cfg.options.rgb}; - RRGGBB = ${boolToString cfg.options.rrggbb}; - RRGGBBAA = ${boolToString cfg.options.rrggbbaa}; - names = ${boolToString cfg.options.names}; - rgb_fn = ${boolToString cfg.options.rgb_fn}; - hsl_fn = ${boolToString cfg.options.hsl_fn}; - css = ${boolToString cfg.options.css}; - css_fn = ${boolToString cfg.options.css_fn}; - mode = '${toString cfg.options.mode}'; - tailwind = ${boolToString cfg.options.tailwind}; - sass = ${boolToString cfg.options.tailwind}; - always_update = ${boolToString cfg.options.alwaysUpdate}; - } - }) + require('colorizer').setup(${toLuaObject cfg.setupOpts}) ''; }; } diff --git a/modules/ui/modes/config.nix b/modules/ui/modes/config.nix index 25ee337..9f49dc4 100644 --- a/modules/ui/modes/config.nix +++ b/modules/ui/modes/config.nix @@ -4,8 +4,8 @@ ... }: let inherit (lib.modules) mkIf; - inherit (lib.trivial) boolToString; inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.ui.modes-nvim; in { @@ -15,18 +15,7 @@ in { ]; vim.luaConfigRC.modes-nvim = entryAnywhere '' - require('modes').setup({ - set_cursorline = ${boolToString cfg.setCursorline}, - line_opacity = { - visual = 0, - }, - colors = { - copy = "${toString cfg.colors.copy}", - delete = "${toString cfg.colors.delete}", - insert = "${toString cfg.colors.insert}", - visual = "${toString cfg.colors.visual}", - }, - }) + require('modes').setup(${toLuaObject cfg.setupOpts}) ''; }; } diff --git a/modules/ui/modes/modes.nix b/modules/ui/modes/modes.nix index e49251a..f73a298 100644 --- a/modules/ui/modes/modes.nix +++ b/modules/ui/modes/modes.nix @@ -1,33 +1,47 @@ {lib, ...}: let inherit (lib.options) mkOption mkEnableOption; - inherit (lib.types) str; + inherit (lib.types) bool str float; + inherit (lib.nvim.types) mkPluginSetupOption; in { options.vim.ui.modes-nvim = { - enable = mkEnableOption "prismatic line decorations [modes.nvim]"; - setCursorline = mkEnableOption "colored cursorline on current line"; - colors = { - copy = mkOption { - type = str; - description = "The #RRGGBB color code for the visual mode highlights"; - default = "#f5c359"; + enable = mkEnableOption "modes.nvim's prismatic line decorations"; + + setupOpts = { + setCursorline = mkOption { + type = bool; + description = "Set a colored cursorline on current line"; + default = false; # looks ugly, disabled by default }; - delete = mkOption { - type = str; - description = "The #RRGGBB color code for the visual mode highlights"; - default = "#c75c6a"; + line_opacity = { + visual = mkOption { + type = float; + description = "Set opacity for cursorline and number background"; + default = 0.0; + }; }; - insert = mkOption { - type = str; - description = "The #RRGGBB color code for the visual mode highlights"; - default = "#78ccc5"; - }; - - visual = mkOption { - type = str; - description = "The #RRGGBB color code for the visual mode highlights"; - default = "#9745be"; + colors = mkPluginSetupOption "modes.nvim" { + copy = mkOption { + type = str; + description = "The #RRGGBB color code for the visual mode highlights"; + default = "#f5c359"; + }; + delete = mkOption { + type = str; + description = "The #RRGGBB color code for the visual mode highlights"; + default = "#c75c6a"; + }; + insert = mkOption { + type = str; + description = "The #RRGGBB color code for the visual mode highlights"; + default = "#78ccc5"; + }; + visual = mkOption { + type = str; + description = "The #RRGGBB color code for the visual mode highlights"; + default = "#9745be"; + }; }; }; }; diff --git a/modules/ui/noice/noice.nix b/modules/ui/noice/noice.nix index 3997987..b361d45 100644 --- a/modules/ui/noice/noice.nix +++ b/modules/ui/noice/noice.nix @@ -2,6 +2,6 @@ inherit (lib.options) mkEnableOption; in { options.vim.ui.noice = { - enable = mkEnableOption "UI modification library [noice.nvim]"; + enable = mkEnableOption "noice.nvim UI modification library"; }; } diff --git a/modules/ui/notifications/nvim-notify/config.nix b/modules/ui/notifications/nvim-notify/config.nix index c2c4991..7a11b6b 100644 --- a/modules/ui/notifications/nvim-notify/config.nix +++ b/modules/ui/notifications/nvim-notify/config.nix @@ -5,6 +5,7 @@ }: let inherit (lib.modules) mkIf; inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.notify.nvim-notify; in { @@ -13,19 +14,7 @@ in { startPlugins = ["nvim-notify"]; luaConfigRC.nvim-notify = entryAnywhere '' - require('notify').setup { - stages = "${cfg.stages}", - timeout = ${toString cfg.timeout}, - background_colour = "${cfg.background_colour}", - position = "${cfg.position}", - icons = { - ERROR = "${cfg.icons.ERROR}", - WARN = "${cfg.icons.WARN}", - INFO = "${cfg.icons.INFO}", - DEBUG = "${cfg.icons.DEBUG}", - TRACE = "${cfg.icons.TRACE}", - }, - } + require('notify').setup(${toLuaObject cfg.setupOpts}) -- required to fix offset_encoding errors local notify = vim.notify diff --git a/modules/ui/notifications/nvim-notify/nvim-notify.nix b/modules/ui/notifications/nvim-notify/nvim-notify.nix index ab78d45..86d15cd 100644 --- a/modules/ui/notifications/nvim-notify/nvim-notify.nix +++ b/modules/ui/notifications/nvim-notify/nvim-notify.nix @@ -1,42 +1,64 @@ -{lib, ...}: let - inherit (lib.options) mkOption mkEnableOption; - inherit (lib.types) enum int str attrsOf; +{ + config, + lib, + ... +}: let + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.modules) mkRenamedOptionModule; + inherit (lib.types) int str enum attrsOf; + inherit (lib.nvim.types) mkPluginSetupOption; in { + imports = let + renamedSetupOpt = name: + mkRenamedOptionModule + ["vim" "notify" "nvim-notify" name] + ["vim" "notify" "nvim-notify" "setupOpts" name]; + in [ + (renamedSetupOpt "stages") + (renamedSetupOpt "timeout") + (renamedSetupOpt "background_colour") + (renamedSetupOpt "position") + (renamedSetupOpt "icons") + ]; + options.vim.notify.nvim-notify = { enable = mkEnableOption "nvim-notify notifications"; - stages = mkOption { - type = enum ["fade_in_slide_out" "fade_in" "slide_out" "none"]; - default = "fade_in_slide_out"; - description = "The stages of the notification"; - }; - timeout = mkOption { - type = int; - default = 1000; - description = "The timeout of the notification"; - }; + setupOpts = mkPluginSetupOption "nvim-notify" { + stages = mkOption { + type = enum ["fade_in_slide_out" "fade_in" "slide_out" "none"]; + default = "fade_in_slide_out"; + description = "The stages of the notification"; + }; - background_colour = mkOption { - type = str; - default = "#000000"; - description = "The background colour of the notification"; - }; + timeout = mkOption { + type = int; + default = 1000; + description = "The timeout of the notification"; + }; - position = mkOption { - type = enum ["top_left" "top_right" "bottom_left" "bottom_right"]; - default = "top_right"; - description = "The position of the notification"; - }; + background_colour = mkOption { + type = str; + default = "#000000"; + description = "The background colour of the notification"; + }; - icons = mkOption { - type = attrsOf str; - description = "The icons of the notification"; - default = { - ERROR = ""; - WARN = ""; - INFO = ""; - DEBUG = ""; - TRACE = ""; + position = mkOption { + type = enum ["top_left" "top_right" "bottom_left" "bottom_right"]; + default = "top_right"; + description = "The position of the notification"; + }; + + icons = mkOption { + type = attrsOf str; + description = "The icons of the notification"; + default = { + ERROR = ""; + WARN = ""; + INFO = ""; + DEBUG = ""; + TRACE = ""; + }; }; }; }; diff --git a/modules/ui/smartcolumn/config.nix b/modules/ui/smartcolumn/config.nix index 3f4ae05..9edbdbb 100644 --- a/modules/ui/smartcolumn/config.nix +++ b/modules/ui/smartcolumn/config.nix @@ -4,9 +4,9 @@ ... }: let inherit (lib.modules) mkIf; - inherit (lib.strings) concatStringsSep; - inherit (lib.nvim.lua) attrsetToLuaTable; inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.lua) toLuaObject; + cfg = config.vim.ui.smartcolumn; in { config = mkIf cfg.enable { @@ -14,13 +14,7 @@ in { startPlugins = ["smartcolumn"]; luaConfigRC.smartcolumn = entryAnywhere '' - require("smartcolumn").setup({ - colorcolumn = "${toString cfg.showColumnAt}", - -- { "help", "text", "markdown", "NvimTree", "alpha"}, - disabled_filetypes = { ${concatStringsSep ", " (map (x: "\"" + x + "\"") cfg.disabledFiletypes)} }, - custom_colorcolumn = ${attrsetToLuaTable cfg.columnAt.languages}, - scope = "file", - }) + require("smartcolumn").setup(${toLuaObject cfg.setupOpts}) ''; }; }; diff --git a/modules/ui/smartcolumn/smartcolumn.nix b/modules/ui/smartcolumn/smartcolumn.nix index fe578be..37d7a94 100644 --- a/modules/ui/smartcolumn/smartcolumn.nix +++ b/modules/ui/smartcolumn/smartcolumn.nix @@ -1,31 +1,41 @@ {lib, ...}: let inherit (lib.options) mkOption mkEnableOption literalExpression; - inherit (lib.types) attrsOf either nullOr listOf int str submodule; + inherit (lib.types) nullOr int str attrsOf either listOf; + inherit (lib.modules) mkRenamedOptionModule; + inherit (lib.nvim.types) mkPluginSetupOption; in { + imports = let + renamedSetupOpt = oldPath: newPath: + mkRenamedOptionModule (["vim" "ui" "smartcolumn"] ++ oldPath) (["vim" "ui" "smartcolumn" "setupOpts"] ++ newPath); + in [ + (renamedSetupOpt ["disabledFiletypes"] ["disabled_filetypes"]) + (renamedSetupOpt ["showColumnAt"] ["colorcolumn"]) + (renamedSetupOpt ["columnAt" "languages"] ["custom_colorcolumn"]) + ]; + options.vim.ui.smartcolumn = { enable = mkEnableOption "line length indicator"; - showColumnAt = mkOption { - type = nullOr int; - default = 120; - description = "The position at which the column will be displayed. Set to null to disable"; - }; + setupOpts = mkPluginSetupOption "smartcolumn.nvim" { + colorcolumn = mkOption { + type = nullOr (either str (listOf str)); + default = "120"; + description = "The position at which the column will be displayed. Set to null to disable"; + }; - disabledFiletypes = mkOption { - type = listOf str; - default = ["help" "text" "markdown" "NvimTree" "alpha"]; - description = "The filetypes smartcolumn will be disabled for."; - }; + disabled_filetypes = mkOption { + type = listOf str; + default = ["help" "text" "markdown" "NvimTree" "alpha"]; + description = "The filetypes smartcolumn will be disabled for."; + }; - columnAt = { - languages = mkOption { + custom_colorcolumn = mkOption { description = "The position at which smart column should be displayed for each individual buffer type"; - type = submodule { - freeformType = attrsOf (either int (listOf int)); - }; + type = attrsOf (either int (listOf int)); + default = {}; example = literalExpression '' - vim.ui.smartcolumn.columnAt.languages = { + vim.ui.smartcolumn.setupOpts.custom_colorcolumn = { nix = 110; ruby = 120; java = 130; diff --git a/modules/utility/telescope/config.nix b/modules/utility/telescope/config.nix index d9a156f..f178158 100644 --- a/modules/utility/telescope/config.nix +++ b/modules/utility/telescope/config.nix @@ -9,9 +9,10 @@ inherit (lib.nvim.dag) entryAnywhere; # TODO: move this to its own module inherit (lib) pushDownDefault; + inherit (lib.nvim.lua) toLuaObject; cfg = config.vim.telescope; - self = import ./telescope.nix {inherit lib;}; + self = import ./telescope.nix {inherit pkgs lib;}; mappingDefinitions = self.options.vim.telescope.mappings; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; @@ -66,52 +67,7 @@ in { vim.luaConfigRC.telescope = entryAnywhere '' local telescope = require('telescope') - telescope.setup { - defaults = { - vimgrep_arguments = { - "${pkgs.ripgrep}/bin/rg", - "--color=never", - "--no-heading", - "--with-filename", - "--line-number", - "--column", - "--smart-case", - "--hidden", - "--no-ignore", - }, - pickers = { - find_command = { - "${pkgs.fd}/bin/fd", - }, - }, - }, - prompt_prefix = "  ", - selection_caret = " ", - entry_prefix = " ", - initial_mode = "insert", - selection_strategy = "reset", - sorting_strategy = "ascending", - layout_strategy = "horizontal", - layout_config = { - horizontal = { - prompt_position = "top", - preview_width = 0.55, - results_width = 0.8, - }, - vertical = { - mirror = false, - }, - width = 0.8, - height = 0.8, - preview_cutoff = 120, - }, - file_ignore_patterns = { "node_modules", ".git/", "dist/", "build/", "target/", "result/" }, -- TODO: make this configurable - color_devicons = true, - path_display = { "absolute" }, - set_env = { ["COLORTERM"] = "truecolor" }, - winblend = 0, - border = {}, - } + telescope.setup(${toLuaObject cfg.setupOpts}) ${ if config.vim.ui.noice.enable diff --git a/modules/utility/telescope/telescope.nix b/modules/utility/telescope/telescope.nix index fd8d2f3..bebe6c8 100644 --- a/modules/utility/telescope/telescope.nix +++ b/modules/utility/telescope/telescope.nix @@ -1,6 +1,152 @@ -{lib, ...}: let - inherit (lib.options) mkEnableOption; +{ + pkgs, + lib, + ... +}: let + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.types) int str listOf float bool either enum submodule attrsOf; inherit (lib.nvim.binds) mkMappingOption; + inherit (lib.nvim.types) mkPluginSetupOption luaInline; + setupOptions = { + defaults = { + vimgrep_arguments = mkOption { + description = '' + Defines the command that will be used for `live_grep` and `grep_string` pickers. + Make sure that color is set to `never` because telescope does not yet interpret color codes. + ''; + type = listOf str; + default = [ + "${pkgs.ripgrep}/bin/rg" + "--color=never" + "--no-heading" + "--with-filename" + "--line-number" + "--column" + "--smart-case" + "--hidden" + "--no-ignore" + ]; + }; + pickers.find_command = mkOption { + description = "cmd to use for finding files"; + type = either (listOf str) luaInline; + default = ["${pkgs.fd}/bin/fd"]; + }; + prompt_prefix = mkOption { + description = "Shown in front of Telescope's prompt"; + type = str; + default = "  "; + }; + selection_caret = mkOption { + description = "Character(s) to show in front of the current selection"; + type = str; + default = " "; + }; + entry_prefix = mkOption { + description = "Prefix in front of each result entry. Current selection not included."; + type = str; + default = " "; + }; + initial_mode = mkOption { + description = "Determines in which mode telescope starts."; + type = enum ["insert" "normal"]; + default = "insert"; + }; + selection_strategy = mkOption { + description = "Determines how the cursor acts after each sort iteration."; + type = enum ["reset" "follow" "row" "closest" "none"]; + default = "reset"; + }; + sorting_strategy = mkOption { + description = ''Determines the direction "better" results are sorted towards.''; + type = enum ["descending" "ascending"]; + default = "ascending"; + }; + layout_strategy = mkOption { + description = "Determines the default layout of Telescope pickers. See `:help telescope.layout`."; + type = str; + default = "horizontal"; + }; + layout_config = mkOption { + description = '' + Determines the default configuration values for layout strategies. + See telescope.layout for details of the configurations options for + each strategy. + ''; + default = {}; + type = submodule { + options = { + horizontal = { + prompt_position = mkOption { + description = ""; + type = str; + default = "top"; + }; + preview_width = mkOption { + description = ""; + type = float; + default = 0.55; + }; + results_width = mkOption { + description = ""; + type = float; + default = 0.8; + }; + }; + vertical = { + mirror = mkOption { + description = ""; + type = bool; + default = false; + }; + }; + width = mkOption { + description = ""; + type = float; + default = 0.8; + }; + height = mkOption { + description = ""; + type = float; + default = 0.8; + }; + preview_cutoff = mkOption { + description = ""; + type = int; + default = 120; + }; + }; + }; + }; + file_ignore_patterns = mkOption { + description = "A table of lua regex that define the files that should be ignored."; + type = listOf str; + default = ["node_modules" ".git/" "dist/" "build/" "target/" "result/"]; + }; + color_devicons = mkOption { + description = "Boolean if devicons should be enabled or not."; + type = bool; + default = true; + }; + path_display = mkOption { + description = "Determines how file paths are displayed."; + type = listOf (enum ["hidden" "tail" "absolute" "smart" "shorten" "truncate"]); + default = ["absolute"]; + }; + set_env = mkOption { + description = "Set an envrionment for term_previewer"; + type = attrsOf str; + default = { + COLORTERM = "truecolor"; + }; + }; + winblend = mkOption { + description = "pseudo-transparency of keymap hints floating window"; + type = int; + default = 0; + }; + }; + }; in { options.vim.telescope = { mappings = { @@ -30,5 +176,7 @@ in { }; enable = mkEnableOption "telescope.nvim: multi-purpose search and picker utility"; + + setupOpts = mkPluginSetupOption "Telescope" setupOptions; }; } diff --git a/modules/visuals/fidget/fidget.nix b/modules/visuals/fidget/fidget.nix index 482391a..6897800 100644 --- a/modules/visuals/fidget/fidget.nix +++ b/modules/visuals/fidget/fidget.nix @@ -9,8 +9,7 @@ inherit (lib.strings) toUpper; inherit (lib.types) int float bool str enum listOf attrsOf; inherit (lib.nvim.types) mkPluginSetupOption; - - rawLua = lua: {__raw = lua;}; + inherit (lib.generators) mkLuaInline; in { imports = [ (mkRenamedOptionModule ["vim" "visuals" "fidget-nvim" "align" "bottom"] ["vim" "visuals" "fidget-nvim" "setupOpts" "notification" "window" "align"]) @@ -50,7 +49,7 @@ in { apply = clear: if clear then - rawLua '' + mkLuaInline '' function(client_id) local client = vim.lsp.get_client_by_id(client_id) return client and client.name or nil @@ -66,7 +65,7 @@ in { return msg.lsp_client.name end ''; - apply = rawLua; + apply = mkLuaInline; }; ignore = mkOption { description = "Ignore LSP servers by name"; @@ -177,7 +176,7 @@ in { default = '' require("fidget.progress.display").default_format_message ''; - apply = rawLua; + apply = mkLuaInline; }; format_annote = mkOption { description = "How to format a progress annotation"; @@ -185,7 +184,7 @@ in { default = '' function(msg) return msg.title end ''; - apply = rawLua; + apply = mkLuaInline; }; format_group_name = mkOption { description = "How to format a progress notification group's name"; @@ -193,13 +192,13 @@ in { default = '' function(group) return tostring(group) end ''; - apply = rawLua; + apply = mkLuaInline; }; overrides = mkOption { description = "Override options from the default notification config"; type = attrsOf str; default = {rust_analyzer = "{ name = 'rust-analyzer' }";}; - apply = mapAttrs (key: lua: rawLua lua); + apply = mapAttrs (key: lua: mkLuaInline lua); }; }; @@ -227,7 +226,7 @@ in { description = "Minimum notifications level"; type = enum ["debug" "info" "warn" "error"]; default = "info"; - apply = filter: rawLua "vim.log.levels.${toUpper filter}"; + apply = filter: mkLuaInline "vim.log.levels.${toUpper filter}"; }; history_size = mkOption { description = "Number of removed messages to retain in history"; @@ -243,7 +242,7 @@ in { description = "How to configure notification groups when instantiated"; type = attrsOf str; default = {default = "require('fidget.notification').default_config";}; - apply = mapAttrs (key: lua: rawLua lua); + apply = mapAttrs (key: lua: mkLuaInline lua); }; redirect = mkOption { description = "Conditionally redirect notifications to another backend"; @@ -255,7 +254,7 @@ in { end end ''; - apply = rawLua; + apply = mkLuaInline; }; view = { @@ -287,7 +286,7 @@ in { return cnt == 1 and msg or string.format("(%dx) %s", cnt, msg) end ''; - apply = rawLua; + apply = mkLuaInline; }; }; @@ -373,7 +372,7 @@ in { description = "Minimum logging level"; type = enum ["debug" "error" "info" "trace" "warn" "off"]; default = "warn"; - apply = logLevel: rawLua "vim.log.levels.${toUpper logLevel}"; + apply = logLevel: mkLuaInline "vim.log.levels.${toUpper logLevel}"; }; max_size = mkOption { description = "Maximum log file size, in KB"; @@ -391,7 +390,7 @@ in { default = '' string.format("%s/fidget.nvim.log", vim.fn.stdpath("cache")) ''; - apply = rawLua; + apply = mkLuaInline; }; }; };