From 4001943a7b1dd512032e2eaadbfdd622c91bff68 Mon Sep 17 00:00:00 2001 From: Ching Pei Yang Date: Wed, 3 Jan 2024 00:55:03 +0100 Subject: [PATCH] feat(nvimtree): add custom setup options --- modules/filetree/nvimtree/config.nix | 235 +-- modules/filetree/nvimtree/nvimtree.nix | 1904 ++++++++++++------------ 2 files changed, 951 insertions(+), 1188 deletions(-) diff --git a/modules/filetree/nvimtree/config.nix b/modules/filetree/nvimtree/config.nix index 0286c1af..c5606501 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 ecd74b58..216f0988 100644 --- a/modules/filetree/nvimtree/nvimtree.nix +++ b/modules/filetree/nvimtree/nvimtree.nix @@ -4,7 +4,8 @@ ... }: let inherit (lib.options) mkEnableOption mkOption literalExpression; - inherit (lib.types) nullOr str bool int listOf enum attrs oneOf addCheck submodule; + 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 +39,453 @@ 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; + autoreload_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_buf_enter = 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"; }; - symlink = mkOption { - type = str; - description = "Glyph for symlinks."; - default = ""; + max = mkOption { + description = "Maximum severity."; + type = enum ["HINT" "INFO" "WARNING" "ERROR"]; + default = "ERROR"; + }; + }; + }; + }; + }; + }; + }; + + 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. + ''; + }; + }; + }; + }; + + 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 = { + 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 +494,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 = ""; + arrowOpen = ""; + arrowClosed = ""; + empty = ""; + emptyOpen = ""; + symlink = ""; + symlinkOpen = ""; }; + }; - 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 +740,360 @@ 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"; + }; - 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; + }; }; }; };