Skip to content

Commit 027e523

Browse files
authored
feat: Sort nodes sensibly (#334)
1 parent 96d8e20 commit 027e523

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

lua/nvim-tree/populate.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ local function should_group(cwd, dirs, files, links)
106106
return false
107107
end
108108

109+
local function node_comparator(a, b)
110+
if a.entries and not b.entries then
111+
return true
112+
elseif not a.entries and b.entries then
113+
return false
114+
end
115+
116+
return a.name:lower() <= b.name:lower()
117+
end
118+
109119
local function gen_ignore_check(cwd)
110120
if not cwd then cwd = luv.cwd() end
111121
local ignore_list = {}
@@ -231,12 +241,14 @@ function M.refresh_entries(entries, cwd, parent_node)
231241

232242
local prev = nil
233243
local change_prev
244+
local new_nodes_added = false
234245
for _, e in ipairs(all) do
235246
for _, name in ipairs(e.entries) do
236247
change_prev = true
237248
if not named_entries[name] then
238249
local n = e.fn(cwd, name)
239250
if e.check(n.link_to, n.absolute_path) then
251+
new_nodes_added = true
240252
git.invalidate_gitignore_map(n.absolute_path)
241253
idx = 1
242254
if prev then
@@ -258,6 +270,10 @@ function M.refresh_entries(entries, cwd, parent_node)
258270
if next_node then
259271
table.insert(entries, 1, next_node)
260272
end
273+
274+
if new_nodes_added then
275+
utils.merge_sort(entries, node_comparator)
276+
end
261277
end
262278

263279
function M.populate(entries, cwd, parent_node)
@@ -326,6 +342,8 @@ function M.populate(entries, cwd, parent_node)
326342
return
327343
end
328344

345+
utils.merge_sort(entries, node_comparator)
346+
329347
git.update_status(entries, cwd, parent_node)
330348
end
331349

lua/nvim-tree/utils.lua

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
local M = {}
2-
local uv = vim.loop -- or require("luv") ? i dont understand
2+
local uv = vim.loop
33
local api = vim.api
44

55
function M.path_to_matching_str(path)
@@ -83,4 +83,74 @@ function M.find_node(nodes, fn)
8383
return nil, i
8484
end
8585

86+
---Create a shallow copy of a portion of a list.
87+
---@param t table
88+
---@param first integer First index, inclusive
89+
---@param last integer Last index, inclusive
90+
---@return table
91+
function M.tbl_slice(t, first, last)
92+
local slice = {}
93+
for i = first, last or #t, 1 do
94+
table.insert(slice, t[i])
95+
end
96+
97+
return slice
98+
end
99+
100+
local function merge(t, first, mid, last, comparator)
101+
local n1 = mid - first + 1
102+
local n2 = last - mid
103+
local ls = M.tbl_slice(t, first, mid)
104+
local rs = M.tbl_slice(t, mid + 1, last)
105+
local i = 1
106+
local j = 1
107+
local k = first
108+
109+
while (i <= n1 and j <= n2) do
110+
if comparator(ls[i], rs[j]) then
111+
t[k] = ls[i]
112+
i = i + 1
113+
else
114+
t[k] = rs[j]
115+
j = j + 1
116+
end
117+
k = k + 1
118+
end
119+
120+
while i <= n1 do
121+
t[k] = ls[i]
122+
i = i + 1
123+
k = k + 1
124+
end
125+
126+
while j <= n2 do
127+
t[k] = rs[j]
128+
j = j + 1
129+
k = k + 1
130+
end
131+
end
132+
133+
local function split_merge(t, first, last, comparator)
134+
if (last - first) < 1 then return end
135+
136+
local mid = math.floor((first + last) / 2)
137+
138+
split_merge(t, first, mid, comparator)
139+
split_merge(t, mid + 1, last, comparator)
140+
merge(t, first, mid, last, comparator)
141+
end
142+
143+
---Perform a merge sort on a given list.
144+
---@param t any[]
145+
---@param comparator function|nil
146+
function M.merge_sort(t, comparator)
147+
if not comparator then
148+
comparator = function (a, b)
149+
return a < b
150+
end
151+
end
152+
153+
split_merge(t, 1, #t, comparator)
154+
end
155+
86156
return M

0 commit comments

Comments
 (0)