diff --git a/doc/nvim-tree-lua.txt b/doc/nvim-tree-lua.txt index 4952a5b8e3e..58ac68bd682 100644 --- a/doc/nvim-tree-lua.txt +++ b/doc/nvim-tree-lua.txt @@ -95,7 +95,9 @@ Setup the plugin in your `init.lua` > -- OR setup with some options require("nvim-tree").setup({ - sort_by = "case_sensitive", + sort = { + sorter = "case_sensitive", + }, view = { width = 30, }, @@ -312,7 +314,10 @@ applying configuration. hijack_cursor = false, hijack_netrw = true, hijack_unnamed_buffer_when_opening = false, - sort_by = "name", + sort = { + sorter = "name", + folders_first = true, + }, root_dirs = {}, prefer_startup_root = false, sync_root_with_cwd = false, @@ -566,31 +571,39 @@ Hijack netrw windows (overridden if |disable_netrw| is `true`) Reloads the explorer every time a buffer is written to. Type: `boolean`, Default: `true` -*nvim-tree.sort_by* -Changes how files within the same directory are sorted. -Can be one of `"name"`, `"case_sensitive"`, `"modification_time"`, `"extension"`, -`"suffix"`, `"filetype"` or a function. -`"extension"` uses all suffixes e.g. `foo.tar.gz` -> `.tar.gz` -`"suffix"` uses the last e.g. `.gz` - Type: `string` | `function(nodes)`, Default: `"name"` - - Function may perform a sort or return a string with one of the above - methods. It is passed a table of nodes to be sorted, each node containing: - - `absolute_path`: `string` - - `executable`: `boolean` - - `extension`: `string` - - `filetype`: `string` - - `link_to`: `string` - - `name`: `string` - - `type`: `"directory"` | `"file"` | `"link"` - - Example: sort by name length: > - local sort_by = function(nodes) - table.sort(nodes, function(a, b) - return #a.name < #b.name - end) - end +*nvim-tree.sort* +File and folder sorting options. + + *nvim-tree.sort.sorter* (previously `sort_by`) + Changes how files within the same directory are sorted. + Can be one of `"name"`, `"case_sensitive"`, `"modification_time"`, `"extension"`, + `"suffix"`, `"filetype"` or a function. + `"extension"` uses all suffixes e.g. `foo.tar.gz` -> `.tar.gz` + `"suffix"` uses the last e.g. `.gz` + Type: `string` | `function(nodes)`, Default: `"name"` + + Function may perform a sort or return a string with one of the above + methods. It is passed a table of nodes to be sorted, each node containing: + - `absolute_path`: `string` + - `executable`: `boolean` + - `extension`: `string` + - `filetype`: `string` + - `link_to`: `string` + - `name`: `string` + - `type`: `"directory"` | `"file"` | `"link"` + + Example: sort by name length: > + local sorter = function(nodes) + table.sort(nodes, function(a, b) + return #a.name < #b.name + end) + end < + *nvim-tree.sort.sort_folders_first* + Sort folders before files. Has no effect when |nvim-tree.sort.sorter| is a + function. + Type: `boolean`, Default: `true` + *nvim-tree.hijack_unnamed_buffer_when_opening* Opens in place of the unnamed buffer if it's empty. Type: `boolean`, Default: `false` diff --git a/lua/nvim-tree.lua b/lua/nvim-tree.lua index 74bc7f55caa..2228c2e4e97 100644 --- a/lua/nvim-tree.lua +++ b/lua/nvim-tree.lua @@ -366,7 +366,10 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS hijack_cursor = false, hijack_netrw = true, hijack_unnamed_buffer_when_opening = false, - sort_by = "name", + sort = { + sorter = "name", + folders_first = true, + }, root_dirs = {}, prefer_startup_root = false, sync_root_with_cwd = false, @@ -613,7 +616,7 @@ local FIELD_OVERRIDE_TYPECHECK = { min = { string = true, ["function"] = true, number = true }, remove_keymaps = { boolean = true, table = true }, on_attach = { ["function"] = true, string = true }, - sort_by = { ["function"] = true, string = true }, + sorter = { ["function"] = true, string = true }, root_folder_label = { ["function"] = true, string = true, boolean = true }, picker = { ["function"] = true, string = true }, } diff --git a/lua/nvim-tree/explorer/sorters.lua b/lua/nvim-tree/explorer/sorters.lua index a3a2af2add6..e685d6c0c72 100644 --- a/lua/nvim-tree/explorer/sorters.lua +++ b/lua/nvim-tree/explorer/sorters.lua @@ -3,10 +3,10 @@ local M = {} local C = {} --- Predefined comparator, defaulting to name ---- @param sort_by string as per options +--- @param sorter string as per options --- @return function -local function get_comparator(sort_by) - return C[sort_by] or C.name +local function get_comparator(sorter) + return C[sorter] or C.name end ---Create a shallow copy of a portion of a list. @@ -68,7 +68,7 @@ local function split_merge(t, first, last, comparator) merge(t, first, mid, last, comparator) end ----Perform a merge sort using sort_by option. +---Perform a merge sort using sorter option. ---@param t table nodes function M.sort(t) if C.user then @@ -115,7 +115,7 @@ function M.sort(t) split_merge(t, 1, #t, mini_comparator) -- sort by user order else - split_merge(t, 1, #t, get_comparator(M.config.sort_by)) + split_merge(t, 1, #t, get_comparator(M.config.sort.sorter)) end end @@ -123,10 +123,13 @@ local function node_comparator_name_ignorecase_or_not(a, b, ignorecase) if not (a and b) then return true end - if a.nodes and not b.nodes then - return true - elseif not a.nodes and b.nodes then - return false + + if M.config.sort.folders_first then + if a.nodes and not b.nodes then + return true + elseif not a.nodes and b.nodes then + return false + end end if ignorecase then @@ -148,10 +151,13 @@ function C.modification_time(a, b) if not (a and b) then return true end - if a.nodes and not b.nodes then - return true - elseif not a.nodes and b.nodes then - return false + + if M.config.sort.folders_first then + if a.nodes and not b.nodes then + return true + elseif not a.nodes and b.nodes then + return false + end end local last_modified_a = 0 @@ -174,12 +180,14 @@ function C.suffix(a, b) end -- directories go first - if a.nodes and not b.nodes then - return true - elseif not a.nodes and b.nodes then - return false - elseif a.nodes and b.nodes then - return C.name(a, b) + if M.config.sort.folders_first then + if a.nodes and not b.nodes then + return true + elseif not a.nodes and b.nodes then + return false + elseif a.nodes and b.nodes then + return C.name(a, b) + end end -- dotfiles go second @@ -223,10 +231,12 @@ function C.extension(a, b) return true end - if a.nodes and not b.nodes then - return true - elseif not a.nodes and b.nodes then - return false + if M.config.sort.folders_first then + if a.nodes and not b.nodes then + return true + elseif not a.nodes and b.nodes then + return false + end end if a.extension and not b.extension then @@ -249,10 +259,12 @@ function C.filetype(a, b) local b_ft = vim.filetype.match { filename = b.name } -- directories first - if a.nodes and not b.nodes then - return true - elseif not a.nodes and b.nodes then - return false + if M.config.sort.folders_first then + if a.nodes and not b.nodes then + return true + elseif not a.nodes and b.nodes then + return false + end end -- one is nil, the other wins @@ -272,10 +284,10 @@ end function M.setup(opts) M.config = {} - M.config.sort_by = opts.sort_by + M.config.sort = opts.sort - if type(opts.sort_by) == "function" then - C.user = opts.sort_by + if type(M.config.sort.sorter) == "function" then + C.user = M.config.sort.sorter end end diff --git a/lua/nvim-tree/legacy.lua b/lua/nvim-tree/legacy.lua index adf658badb1..53a1471a554 100644 --- a/lua/nvim-tree/legacy.lua +++ b/lua/nvim-tree/legacy.lua @@ -41,6 +41,9 @@ local function refactored(opts) end opts.view.adaptive_size = nil end + + -- 2023/07/15 + utils.move_missing_val(opts, "", "sort_by", opts, "sort", "sorter", true) end local function deprecated(opts)