diff --git a/lib/helpers.nix b/lib/helpers.nix index ab0658fe..a7467bb8 100644 --- a/lib/helpers.nix +++ b/lib/helpers.nix @@ -141,7 +141,7 @@ with lib; rec { else "false" ); mkStr = default: mkNullable lib.types.str ''${builtins.toString default}''; - mkAttributeSet = default: mkNullable lib.types.attrs ''"${default}"''; + mkAttributeSet = default: mkNullable lib.types.attrs ''${default}''; mkEnum = enum: default: mkNullable (lib.types.enum enum) ''"${default}"''; mkEnumFirstDefault = enum: mkEnum enum (head enum); mkBorder = default: name: desc: diff --git a/plugins/default.nix b/plugins/default.nix index 4c9adbd7..90912b21 100644 --- a/plugins/default.nix +++ b/plugins/default.nix @@ -23,6 +23,7 @@ ./completion/nvim-cmp/sources ./completion/lspkind.nix + ./filetrees/chadtree.nix ./filetrees/neo-tree.nix ./filetrees/nvim-tree.nix diff --git a/plugins/filetrees/chadtree.nix b/plugins/filetrees/chadtree.nix new file mode 100644 index 00000000..a46854f1 --- /dev/null +++ b/plugins/filetrees/chadtree.nix @@ -0,0 +1,432 @@ +{ + pkgs, + config, + lib, + ... +}: +with lib; let + cfg = config.plugins.chadtree; + helpers = import ../helpers.nix {inherit lib;}; + mkListStr = helpers.defaultNullOpts.mkNullable (types.listOf types.str); +in { + options.plugins.chadtree = + helpers.extraOptionsOptions + // { + enable = mkEnableOption "chadtree"; + + package = helpers.mkPackageOption "chadtree" pkgs.vimPlugins.chadtree; + + options = { + follow = helpers.defaultNullOpts.mkBool true '' + CHADTree will highlight currently open file, and open all its parents. + ''; + + lang = helpers.mkNullOrOption types.str '' + CHADTree will guess your locale from unix environmental variables. + Set to `c` to disable emojis. + ''; + + mimetypes = { + warn = mkListStr ''["audio" "font" "image" "video"]'' '' + Show a warning before opening these datatypes. + ''; + + allowExts = mkListStr ''[".ts"]'' '' + Skip warning for these extensions. + ''; + }; + + pageIncrement = helpers.defaultNullOpts.mkInt 5 '' + Change how many lines `{` and `}` scroll. + ''; + + pollingRate = helpers.defaultNullOpts.mkNum 2.0 '' + CHADTree's background refresh rate. + ''; + + session = helpers.defaultNullOpts.mkBool true '' + Save & restore currently open folders. + ''; + + showHidden = helpers.defaultNullOpts.mkBool false '' + Hide some files and folders by default. By default this can be toggled using the `.` key. + see `chadtree_settings.ignore` for more details. + ''; + + versionControl = helpers.defaultNullOpts.mkBool true '' + Enable version control. This can also be toggled. But unlike `show_hidden`, does not have a default keybind. + ''; + + ignore = { + nameExact = mkListStr ''[".DS_Store" ".directory" "thumbs.db" ".git"]'' '' + Files whose name match these exactly will be ignored. + ''; + + nameGlob = mkListStr "[]" '' + Files whose name match these glob patterns will be ignored. + ie. `*.py` will match all python files + ''; + + pathGlob = mkListStr "[]" '' + Files whose full path match these glob patterns will be ignored. + ''; + }; + }; + + view = { + openDirection = helpers.defaultNullOpts.mkEnum ["left" "right"] "left" '' + Which way does CHADTree open? + ''; + + sortBy = mkListStr ''["is_folder" "ext" "file_name"]'' '' + CHADTree can sort by the following criterion. + Reorder them if you want a different sorting order. + legal keys: some of + `["is_folder" "ext" "file_name"]` + ''; + + width = helpers.defaultNullOpts.mkInt 40 '' + How big is CHADTree when initially opened? + ''; + + windowOptions = + helpers.defaultNullOpts.mkAttributeSet '' + { + cursorline = true; + number = false; + relativenumber = false; + signcolumn = "no"; + winfixwidth = true; + wrap = false; + } + '' + '' + Set of window local options to for CHADTree windows. + ''; + }; + + theme = { + highlights = { + ignored = helpers.defaultNullOpts.mkStr "Comment" '' + These are used for files that are ignored by user supplied pattern + in `chadtree.ignore` and by version control. + ''; + + bookmarks = helpers.defaultNullOpts.mkStr "Title" '' + These are used to show bookmarks. + ''; + + quickfix = helpers.defaultNullOpts.mkStr "Label" '' + These are used to notify the number of times a file / folder appears in the `quickfix` list. + ''; + + versionControl = helpers.defaultNullOpts.mkStr "Comment" '' + These are used to put a version control status beside each file. + ''; + }; + + iconGlyphSet = helpers.defaultNullOpts.mkEnum ["devicons" "emoji" "ascii" "ascii_hollow"] "devicons" '' + Icon glyph set to use. + ''; + + textColourSet = + helpers.defaultNullOpts.mkEnum [ + "env" + "solarized_dark_256" + "solarized_dark" + "solarized_light" + "solarized_universal" + "nord" + "trapdoor" + "nerdtree_syntax_light" + "nerdtree_syntax_dark" + ] "env" '' + On `unix`, the command `ls` can produce coloured results based on the `LS_COLORS` environmental variable. + + CHADTree can pretend it's `ls` by setting `chadtree.theme.textColourSet` to `env`. + + If you are not happy with that, you can choose one of the many others. + ''; + + iconColourSet = helpers.defaultNullOpts.mkEnum ["github" "none"] "github" '' + Right now you all the file icons are coloured according to Github colours. + + You may also disable colouring if you wish. + ''; + }; + + keymap = { + windowManagement = { + quit = mkListStr ''["q"]'' '' + Close CHADTree window, quit if it is the last window. + ''; + + bigger = mkListStr ''["+" "="]'' '' + Resize CHADTree window bigger. + ''; + + smaller = mkListStr ''["-" "_"]'' '' + Resize CHADTree window smaller. + ''; + + refresh = mkListStr ''[""]'' '' + Refresh CHADTree. + ''; + }; + + rerooting = { + changeDir = mkListStr ''["b"]'' '' + Change vim's working directory. + ''; + + changeFocus = mkListStr ''["c"]'' '' + Set CHADTree's root to folder at cursor. Does not change working directory. + ''; + + changeFocusUp = mkListStr ''["C"]'' '' + Set CHADTree's root one level up. + ''; + }; + + openFileFolder = { + primary = mkListStr ''[""]'' '' + Open file at cursor. + ''; + + secondary = mkListStr ''[" <2-leftmouse>"]'' '' + Open file at cursor, keep cursor in CHADTree's window. + ''; + + tertiary = mkListStr ''["" ]'' '' + Open file at cursor in a new tab. + ''; + + vSplit = mkListStr ''["w"]'' '' + Open file at cursor in vertical split. + ''; + + hSplit = mkListStr ''["W"]'' '' + Open file at cursor in horizontal split. + ''; + + openSys = mkListStr ''["o"]'' '' + Open file with GUI tools using `open` or `xdg open`. + This will open third party tools such as Finder or KDE Dolphin or GNOME nautilus, etc. + Depends on platform and user setup. + ''; + + collapse = mkListStr ''["o"]'' '' + Collapse all subdirectories for directory at cursor. + ''; + }; + + cursor = { + refocus = mkListStr ''["~"]'' '' + Put cursor at the root of CHADTree. + ''; + + jumpToCurrent = mkListStr ''["J"]'' '' + Position cursor in CHADTree at currently open buffer, if the buffer points to a location visible under CHADTree. + ''; + + stat = mkListStr ''["K"]'' '' + Print `ls --long` stat for file under cursor. + ''; + + copyName = mkListStr ''["y"]'' '' + Copy paths of files under cursor or visual block. + ''; + + copyBasename = mkListStr ''["Y"]'' '' + Copy names of files under cursor or visual block. + ''; + + copyRelname = mkListStr ''[""]'' '' + Copy relative paths of files under cursor or visual block. + ''; + }; + + filtering = { + filter = mkListStr ''["f"]'' '' + Set a glob pattern to narrow down visible files. + ''; + + clearFilter = mkListStr ''["F"]'' '' + Clear filter. + ''; + }; + + bookmarks = { + bookmarkGoto = mkListStr ''["m"]'' '' + Goto bookmark `A-Z`. + ''; + }; + + selecting = { + select = mkListStr ''["s"]'' '' + Select files under cursor or visual block. + ''; + + clearSelection = mkListStr ''["S"]'' '' + Clear selection. + ''; + }; + + fileOperations = { + new = mkListStr ''["a"]'' '' + Create new file at location under cursor. Files ending with platform specific path separator will be folders. + + Intermediary folders are created automatically. + + ie. `uwu/owo/` under unix will create `uwu/` then `owo/` under it. Both are folders. + ''; + + link = mkListStr ''["A"]'' '' + Create links at location under cursor from selection. + + Links are always relative. + + Intermediary folders are created automatically. + ''; + + rename = mkListStr ''["r"]'' '' + Rename file under cursor. + ''; + + toggleExec = mkListStr ''["X"]'' '' + Toggle all the `+x` bits of the selected / highlighted files. + + Except for directories, where `-x` will prevent reading. + ''; + + copy = mkListStr ''["p"]'' '' + Copy the selected files to location under cursor. + ''; + + cut = mkListStr ''["x"]'' '' + Move the selected files to location under cursor. + ''; + + delete = mkListStr ''["d"]'' '' + Delete the selected files. Items deleted cannot be recovered. + ''; + + trash = mkListStr ''[t]'' '' + Trash the selected files using platform specific `trash` command, if they are available. + Items trashed may be recovered. + ''; + }; + + toggles = { + toggleHidden = mkListStr ''["."]'' '' + Toggle show_hidden on and off. See `chadtree.showHidden` for details. + ''; + + toggleFollow = mkListStr ''["u"]'' '' + Toggle `follow` on and off. See `chadtree.follow` for details. + ''; + + toggleVersionControl = mkListStr ''["i"]'' '' + Toggle version control integration on and off. + ''; + }; + }; + }; + + config = let + setupOptions = with cfg; { + xdg = true; + options = with options; { + inherit follow; + inherit lang; + mimetypes = with mimetypes; { + inherit warn; + allow_exts = allowExts; + }; + page_increment = pageIncrement; + polling_rate = pollingRate; + inherit session; + show_hidden = showHidden; + version_control = versionControl; + ignore = with ignore; { + name_exact = nameExact; + name_glob = nameGlob; + path_glob = pathGlob; + }; + }; + view = with view; { + open_direction = openDirection; + sort_by = sortBy; + inherit width; + window_options = windowOptions; + }; + theme = with theme; { + highlights = with highlights; { + inherit ignored; + inherit bookmarks; + inherit quickfix; + version_control = versionControl; + }; + icon_glyph_set = iconGlyphSet; + text_colour_set = textColourSet; + icon_colour_set = iconColourSet; + }; + keymap = with keymap; + with windowManagement; + with rerooting; + with openFileFolder; + with cursor; + with filtering; + with bookmarks; + with selecting; + with fileOperations; + with toggles; { + inherit quit; + inherit bigger; + inherit smaller; + inherit refresh; + change_dir = changeDir; + change_focus = changeFocus; + change_focus_up = changeFocusUp; + inherit primary; + inherit secondary; + inherit tertiary; + v_split = vSplit; + h_split = hSplit; + open_sys = openSys; + inherit collapse; + inherit refocus; + jump_to_current = jumpToCurrent; + inherit stat; + copy_name = copyName; + copy_basename = copyBasename; + copy_relname = copyRelname; + inherit filter; + clear_filter = clearFilter; + bookmark_goto = bookmarkGoto; + inherit select; + clear_selection = clearSelection; + inherit new; + inherit link; + inherit rename; + toggle_exec = toggleExec; + inherit copy; + inherit cut; + inherit delete; + inherit trash; + toggle_hidden = toggleHidden; + toggle_follow = toggleFollow; + toggle_version_control = toggleVersionControl; + }; + }; + in + mkIf cfg.enable { + extraPlugins = + [cfg.package] + ++ (optional (cfg.theme == null || cfg.theme.iconGlyphSet == "devicons") pkgs.vimPlugins.nvim-web-devicons); + + extraConfigLua = '' + vim.api.nvim_set_var("chadtree_settings", ${helpers.toLuaObject setupOptions}) + ''; + }; +} diff --git a/tests/test-sources/plugins/filetrees/chadtree.nix b/tests/test-sources/plugins/filetrees/chadtree.nix new file mode 100644 index 00000000..f01716f9 --- /dev/null +++ b/tests/test-sources/plugins/filetrees/chadtree.nix @@ -0,0 +1,109 @@ +{ + empty = { + plugins.chadtree.enable = true; + }; + + example = { + plugins.chadtree = { + enable = true; + + options = { + follow = true; + mimetypes = { + warn = ["audio" "font" "image" "video"]; + allowExts = [".ts"]; + }; + pageIncrement = 5; + pollingRate = 2.0; + session = true; + showHidden = false; + versionControl = true; + ignore = { + nameExact = [".DS_Store" ".directory" "thumbs.db" ".git"]; + nameGlob = []; + pathGlob = []; + }; + }; + view = { + openDirection = "left"; + sortBy = ["is_folder" "ext" "file_name"]; + width = 40; + windowOptions = { + cursorline = true; + number = false; + relativenumber = false; + signcolumn = "no"; + winfixwidth = true; + wrap = false; + }; + }; + theme = { + highlights = { + ignored = "Comment"; + bookmarks = "Title"; + quickfix = "Label"; + versionControl = "Comment"; + }; + iconGlyphSet = "devicons"; + textColourSet = "env"; + iconColourSet = "github"; + }; + keymap = { + windowManagement = { + quit = ["q"]; + bigger = ["+" "="]; + smaller = ["-" "_"]; + refresh = [""]; + }; + rerooting = { + changeDir = ["b"]; + changeFocus = ["c"]; + changeFocusUp = ["C"]; + }; + openFileFolder = { + primary = [""]; + secondary = ["" "<2-leftmouse>"]; + tertiary = ["" ""]; + vSplit = ["w"]; + hSplit = ["W"]; + openSys = ["o"]; + collapse = ["o"]; + }; + cursor = { + refocus = ["~"]; + jumpToCurrent = ["J"]; + stat = ["K"]; + copyName = ["y"]; + copyBasename = ["Y"]; + copyRelname = [""]; + }; + filtering = { + filter = ["f"]; + clearFilter = ["F"]; + }; + bookmarks = { + bookmarkGoto = ["m"]; + }; + selecting = { + select = ["s"]; + clearSelection = ["S"]; + }; + fileOperations = { + new = ["a"]; + link = ["A"]; + rename = ["r"]; + toggleExec = ["X"]; + copy = ["p"]; + cut = ["x"]; + delete = ["d"]; + trash = ["t"]; + }; + toggles = { + toggleHidden = ["."]; + toggleFollow = ["u"]; + toggleVersionControl = ["i"]; + }; + }; + }; + }; +}