Skip to content

Commit 0fde78e

Browse files
committed
feat(filesystem): use fd/find as first level filter in fzy, cancel jobs as needed
1 parent c5036c5 commit 0fde78e

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

lua/neo-tree/sources/filesystem/init.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ end
184184

185185
M.reset_search = function(state, refresh, open_current_node)
186186
log.trace("reset_search")
187+
-- Cancel any pending search
188+
require("neo-tree.sources.filesystem.lib.filter_external").cancel()
187189
-- reset search state
188190
state.fuzzy_finder_mode = nil
189191
state.use_fzy = nil

lua/neo-tree/sources/filesystem/lib/filter_external.lua

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ local get_find_command = function(state)
4343
return state.find_command
4444
end
4545

46+
local running_jobs = {}
47+
M.cancel = function()
48+
while #running_jobs > 0 do
49+
local job = table.remove(running_jobs, 1)
50+
print("cancelling job", job)
51+
local pid = job.pid
52+
job:shutdown()
53+
if pid ~= nil then
54+
print("killing pid", pid)
55+
if utils.is_windows then
56+
vim.fn.system("taskkill /F /T /PID " .. pid)
57+
else
58+
vim.fn.system("kill -9 " .. pid)
59+
end
60+
end
61+
end
62+
end
63+
4664
---@class FileTypes
4765
---@field file boolean
4866
---@field directory boolean
@@ -68,9 +86,12 @@ end
6886
---@param on_insert? fun(err: string, line: string): any Executed for each line of stdout and stderr.
6987
---@param on_exit? fun(return_val: table): any Executed at the end.
7088
M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ignore, limit, find_args, on_insert, on_exit)
89+
-- First cancel the last job if it is still running
90+
M.cancel()
91+
7192
if glob ~= nil and regex ~= nil then
7293
local log_msg = string.format([[glob: %s, regex: %s]], glob, regex)
73-
log.warning("both glob and regex are set. glob will take precedence. " .. log_msg)
94+
log.warn("both glob and regex are set. glob will take precedence. " .. log_msg)
7495
end
7596
ignore = ignore or {}
7697
types = types or {}
@@ -182,7 +203,7 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
182203
limit = math.huge -- `fd` manages limit on its own
183204
end
184205
local item_count = 0
185-
Job:new({
206+
local job = Job:new({
186207
command = cmd,
187208
cwd = path,
188209
args = args,
@@ -204,7 +225,10 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
204225
on_exit(return_val)
205226
end
206227
end,
207-
}):start()
228+
})
229+
M.cancel()
230+
job:start()
231+
table.insert(running_jobs, job)
208232
end
209233

210234
local function fzy_sort_get_total_score(terms, path)
@@ -247,11 +271,24 @@ M.fzy_sort_files = function(opts, state)
247271
for term in string.gmatch(opts.term, "[^%s]+") do -- space split opts.term
248272
terms[#terms + 1] = term
249273
end
274+
275+
-- The base search is anything that contains the characters in the term
276+
-- The fzy score is then used to sort the results
277+
local chars = {}
278+
local regex = ".*"
279+
for _, term in ipairs(terms) do
280+
for c in term:gmatch(".") do
281+
if not chars[c] then
282+
regex = regex .. c .. "+.*"
283+
end
284+
chars[c] = true
285+
end
286+
end
287+
250288
local result_counter = 0
251289

252-
-- fetch file list for the first time and calculate scores along the way
253290
local index = 1
254-
state.fzy_sort_result_scores = { foo = 0, baz = 0 }
291+
state.fzy_sort_result_scores = {}
255292
local function on_insert(err, path)
256293
if not err then
257294
if result_counter >= limit then
@@ -262,6 +299,9 @@ M.fzy_sort_files = function(opts, state)
262299
relative_path = "./" .. path:sub(pwd_length + 1)
263300
end
264301
index = index + 1
302+
if state.fzy_sort_result_scores == nil then
303+
state.fzy_sort_result_scores = {}
304+
end
265305
state.fzy_sort_result_scores[path] = 0
266306
local score = fzy_sort_get_total_score(terms, relative_path)
267307
if score > 0 then
@@ -273,11 +313,11 @@ M.fzy_sort_files = function(opts, state)
273313
end
274314
end
275315

276-
M.filter_files_external(get_find_command(state), pwd, nil, nil, true,
316+
M.filter_files_external(get_find_command(state), pwd, nil, regex, true,
277317
{ directory = fuzzy_finder_mode == "directory", file = fuzzy_finder_mode ~= "directory" },
278318
{ dotfiles = not filters.visible and filters.hide_dotfiles,
279319
gitignore = not filters.visible and filters.hide_gitignored },
280-
nil, opts.find_args, on_insert, opts.on_exit)
320+
limit * 10, opts.find_args, on_insert, opts.on_exit)
281321
end
282322

283323
M.find_files = function(opts)

0 commit comments

Comments
 (0)