Skip to content

Commit cef57e6

Browse files
authored
fix: handle backspacing correctly in fzy search (#798)
fixes #794
1 parent b830452 commit cef57e6

File tree

3 files changed

+41
-75
lines changed

3 files changed

+41
-75
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,13 @@ end
184184

185185
M.reset_search = function(state, refresh, open_current_node)
186186
log.trace("reset_search")
187+
-- reset search state
187188
state.fuzzy_finder_mode = nil
188189
state.use_fzy = nil
189190
state.fzy_sort_result_scores = nil
190191
state.fzy_sort_file_list_cache = nil
191192
state.sort_function_override = nil
193+
192194
if refresh == nil then
193195
refresh = true
194196
end

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

+18-19
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode, use_fzy)
2020
local height = vim.api.nvim_win_get_height(winid)
2121
local scroll_padding = 3
2222
local popup_msg = "Search:"
23+
2324
if search_as_you_type then
2425
if fuzzy_finder_mode == "directory" then
2526
popup_msg = "Filter Directories:"
@@ -55,27 +56,21 @@ M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode, use_fzy)
5556
})
5657
end
5758

58-
local set_sort_by_score = function()
59-
state.sort_function_override = function(a, b)
60-
-- `state.fzy_sort_result_scores` should be defined in
61-
-- `sources.filesystem.lib.filter_external.fzy_sort_files`
62-
local result_scores = state.fzy_sort_result_scores or { foo = 0, baz = 0 }
63-
local a_score = result_scores[a.path]
64-
local b_score = result_scores[b.path]
65-
if a_score == nil or b_score == nil then
66-
log.debug(string.format([[Fzy: failed to compare %s: %s, %s: %s]], a.path, a_score, b.path, b_score))
67-
local config = require("neo-tree").config
68-
if config.sort_function ~= nil then
69-
return config.sort_function(a, b)
70-
end
71-
return nil
59+
local sort_by_score = function(a, b)
60+
-- `state.fzy_sort_result_scores` should be defined in
61+
-- `sources.filesystem.lib.filter_external.fzy_sort_files`
62+
local result_scores = state.fzy_sort_result_scores or { foo = 0, baz = 0 }
63+
local a_score = result_scores[a.path]
64+
local b_score = result_scores[b.path]
65+
if a_score == nil or b_score == nil then
66+
log.debug(string.format([[Fzy: failed to compare %s: %s, %s: %s]], a.path, a_score, b.path, b_score))
67+
local config = require("neo-tree").config
68+
if config.sort_function ~= nil then
69+
return config.sort_function(a, b)
7270
end
73-
return a_score > b_score
71+
return nil
7472
end
75-
end
76-
if use_fzy then
77-
set_sort_by_score()
78-
state.use_fzy = true
73+
return a_score > b_score
7974
end
8075

8176
local select_first_file = function()
@@ -151,6 +146,10 @@ M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode, use_fzy)
151146
log.trace("Setting search in on_change to: " .. value)
152147
state.search_pattern = value
153148
state.fuzzy_finder_mode = fuzzy_finder_mode
149+
if use_fzy then
150+
state.sort_function_override = sort_by_score
151+
state.use_fzy = true
152+
end
154153
local callback = select_first_file
155154
if fuzzy_finder_mode == "directory" then
156155
callback = nil

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

+21-56
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
196196
on_stderr = function(err, line)
197197
if item_count < limit and on_insert then
198198
on_insert(err or line, line)
199-
item_count = item_count + 1
199+
-- item_count = item_count + 1
200200
end
201201
end,
202202
on_exit = function(_, return_val)
@@ -249,70 +249,35 @@ M.fzy_sort_files = function(opts, state)
249249
end
250250
local result_counter = 0
251251

252-
if state.fzy_sort_file_list_cache ~= nil and #state.fzy_sort_file_list_cache > 0 then
253-
-- list of files are already cached
254-
for _, relative_path in ipairs(state.fzy_sort_file_list_cache) do
255-
-- if full_path_words, contents of state.fzy_sort_file_list_cache is absolute path
256-
local path = full_path_words and relative_path or pwd .. relative_path
252+
-- fetch file list for the first time and calculate scores along the way
253+
local index = 1
254+
state.fzy_sort_result_scores = { foo = 0, baz = 0 }
255+
local function on_insert(err, path)
256+
if not err then
257+
if result_counter >= limit then
258+
return
259+
end
260+
local relative_path = path
261+
if not full_path_words and #path > pwd_length and path:sub(1, pwd_length) == pwd then
262+
relative_path = "./" .. path:sub(pwd_length + 1)
263+
end
264+
index = index + 1
265+
state.fzy_sort_result_scores[path] = 0
257266
local score = fzy_sort_get_total_score(terms, relative_path)
258267
if score > 0 then
259268
state.fzy_sort_result_scores[path] = score
260269
result_counter = result_counter + 1
261270
modify_parent_scores(state.fzy_sort_result_scores, path, score)
262271
opts.on_insert(nil, path)
263-
if result_counter >= limit then
264-
break
265-
end
266-
end
267-
end
268-
269-
if opts.on_exit then
270-
opts.on_exit(0)
271-
end
272-
else
273-
-- fetch file list for the first time and calculate scores along the way
274-
state.fzy_sort_file_list_cache = {}
275-
local index = 1
276-
local cached_everything = true
277-
state.fzy_sort_result_scores = { foo = 0, baz = 0 }
278-
local function on_insert(err, path)
279-
if not err then
280-
if result_counter >= limit then
281-
cached_everything = false
282-
return
283-
end
284-
local relative_path = path
285-
if not full_path_words and #path > pwd_length and path:sub(1, pwd_length) == pwd then
286-
relative_path = "./" .. path:sub(pwd_length + 1)
287-
end
288-
state.fzy_sort_file_list_cache[index] = relative_path
289-
index = index + 1
290-
state.fzy_sort_result_scores[path] = 0
291-
local score = fzy_sort_get_total_score(terms, relative_path)
292-
if score > 0 then
293-
state.fzy_sort_result_scores[path] = score
294-
result_counter = result_counter + 1
295-
modify_parent_scores(state.fzy_sort_result_scores, path, score)
296-
opts.on_insert(nil, path)
297-
end
298272
end
299273
end
300-
301-
local function on_exit(_)
302-
log.debug(string.format([[fzy_sort_files: cached_everything: %s, len: %s]], cached_everything,
303-
#state.fzy_sort_file_list_cache))
304-
if not cached_everything then
305-
state.fzy_sort_file_list_cache = {}
306-
end
307-
opts.on_exit(0)
308-
end
309-
310-
M.filter_files_external(get_find_command(state), pwd, nil, nil, true,
311-
{ directory = fuzzy_finder_mode == "directory", file = fuzzy_finder_mode ~= "directory" },
312-
{ dotfiles = not filters.visible and filters.hide_dotfiles,
313-
gitignore = not filters.visible and filters.hide_gitignored },
314-
nil, opts.find_args, on_insert, on_exit)
315274
end
275+
276+
M.filter_files_external(get_find_command(state), pwd, nil, nil, true,
277+
{ directory = fuzzy_finder_mode == "directory", file = fuzzy_finder_mode ~= "directory" },
278+
{ dotfiles = not filters.visible and filters.hide_dotfiles,
279+
gitignore = not filters.visible and filters.hide_gitignored },
280+
nil, opts.find_args, on_insert, opts.on_exit)
316281
end
317282

318283
M.find_files = function(opts)

0 commit comments

Comments
 (0)