Skip to content

fix: handle backspacing correctly in fzy search #798

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lua/neo-tree/sources/filesystem/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,13 @@ end

M.reset_search = function(state, refresh, open_current_node)
log.trace("reset_search")
-- reset search state
state.fuzzy_finder_mode = nil
state.use_fzy = nil
state.fzy_sort_result_scores = nil
state.fzy_sort_file_list_cache = nil
state.sort_function_override = nil

if refresh == nil then
refresh = true
end
Expand Down
37 changes: 18 additions & 19 deletions lua/neo-tree/sources/filesystem/lib/filter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode, use_fzy)
local height = vim.api.nvim_win_get_height(winid)
local scroll_padding = 3
local popup_msg = "Search:"

if search_as_you_type then
if fuzzy_finder_mode == "directory" then
popup_msg = "Filter Directories:"
Expand Down Expand Up @@ -55,27 +56,21 @@ M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode, use_fzy)
})
end

local set_sort_by_score = function()
state.sort_function_override = function(a, b)
-- `state.fzy_sort_result_scores` should be defined in
-- `sources.filesystem.lib.filter_external.fzy_sort_files`
local result_scores = state.fzy_sort_result_scores or { foo = 0, baz = 0 }
local a_score = result_scores[a.path]
local b_score = result_scores[b.path]
if a_score == nil or b_score == nil then
log.debug(string.format([[Fzy: failed to compare %s: %s, %s: %s]], a.path, a_score, b.path, b_score))
local config = require("neo-tree").config
if config.sort_function ~= nil then
return config.sort_function(a, b)
end
return nil
local sort_by_score = function(a, b)
-- `state.fzy_sort_result_scores` should be defined in
-- `sources.filesystem.lib.filter_external.fzy_sort_files`
local result_scores = state.fzy_sort_result_scores or { foo = 0, baz = 0 }
local a_score = result_scores[a.path]
local b_score = result_scores[b.path]
if a_score == nil or b_score == nil then
log.debug(string.format([[Fzy: failed to compare %s: %s, %s: %s]], a.path, a_score, b.path, b_score))
local config = require("neo-tree").config
if config.sort_function ~= nil then
return config.sort_function(a, b)
end
return a_score > b_score
return nil
end
end
if use_fzy then
set_sort_by_score()
state.use_fzy = true
return a_score > b_score
end

local select_first_file = function()
Expand Down Expand Up @@ -151,6 +146,10 @@ M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode, use_fzy)
log.trace("Setting search in on_change to: " .. value)
state.search_pattern = value
state.fuzzy_finder_mode = fuzzy_finder_mode
if use_fzy then
state.sort_function_override = sort_by_score
state.use_fzy = true
end
local callback = select_first_file
if fuzzy_finder_mode == "directory" then
callback = nil
Expand Down
77 changes: 21 additions & 56 deletions lua/neo-tree/sources/filesystem/lib/filter_external.lua
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
on_stderr = function(err, line)
if item_count < limit and on_insert then
on_insert(err or line, line)
item_count = item_count + 1
-- item_count = item_count + 1
end
end,
on_exit = function(_, return_val)
Expand Down Expand Up @@ -249,70 +249,35 @@ M.fzy_sort_files = function(opts, state)
end
local result_counter = 0

if state.fzy_sort_file_list_cache ~= nil and #state.fzy_sort_file_list_cache > 0 then
-- list of files are already cached
for _, relative_path in ipairs(state.fzy_sort_file_list_cache) do
-- if full_path_words, contents of state.fzy_sort_file_list_cache is absolute path
local path = full_path_words and relative_path or pwd .. relative_path
-- fetch file list for the first time and calculate scores along the way
local index = 1
state.fzy_sort_result_scores = { foo = 0, baz = 0 }
local function on_insert(err, path)
if not err then
if result_counter >= limit then
return
end
local relative_path = path
if not full_path_words and #path > pwd_length and path:sub(1, pwd_length) == pwd then
relative_path = "./" .. path:sub(pwd_length + 1)
end
index = index + 1
state.fzy_sort_result_scores[path] = 0
local score = fzy_sort_get_total_score(terms, relative_path)
if score > 0 then
state.fzy_sort_result_scores[path] = score
result_counter = result_counter + 1
modify_parent_scores(state.fzy_sort_result_scores, path, score)
opts.on_insert(nil, path)
if result_counter >= limit then
break
end
end
end

if opts.on_exit then
opts.on_exit(0)
end
else
-- fetch file list for the first time and calculate scores along the way
state.fzy_sort_file_list_cache = {}
local index = 1
local cached_everything = true
state.fzy_sort_result_scores = { foo = 0, baz = 0 }
local function on_insert(err, path)
if not err then
if result_counter >= limit then
cached_everything = false
return
end
local relative_path = path
if not full_path_words and #path > pwd_length and path:sub(1, pwd_length) == pwd then
relative_path = "./" .. path:sub(pwd_length + 1)
end
state.fzy_sort_file_list_cache[index] = relative_path
index = index + 1
state.fzy_sort_result_scores[path] = 0
local score = fzy_sort_get_total_score(terms, relative_path)
if score > 0 then
state.fzy_sort_result_scores[path] = score
result_counter = result_counter + 1
modify_parent_scores(state.fzy_sort_result_scores, path, score)
opts.on_insert(nil, path)
end
end
end

local function on_exit(_)
log.debug(string.format([[fzy_sort_files: cached_everything: %s, len: %s]], cached_everything,
#state.fzy_sort_file_list_cache))
if not cached_everything then
state.fzy_sort_file_list_cache = {}
end
opts.on_exit(0)
end

M.filter_files_external(get_find_command(state), pwd, nil, nil, true,
{ directory = fuzzy_finder_mode == "directory", file = fuzzy_finder_mode ~= "directory" },
{ dotfiles = not filters.visible and filters.hide_dotfiles,
gitignore = not filters.visible and filters.hide_gitignored },
nil, opts.find_args, on_insert, on_exit)
end

M.filter_files_external(get_find_command(state), pwd, nil, nil, true,
{ directory = fuzzy_finder_mode == "directory", file = fuzzy_finder_mode ~= "directory" },
{ dotfiles = not filters.visible and filters.hide_dotfiles,
gitignore = not filters.visible and filters.hide_gitignored },
nil, opts.find_args, on_insert, opts.on_exit)
end

M.find_files = function(opts)
Expand Down