Skip to content

Commit af0e162

Browse files
authored
feat(filesystem): add a fzf based fuzzy search algorithm, with sorting by score (#721)
1 parent 245cf1e commit af0e162

File tree

10 files changed

+544
-80
lines changed

10 files changed

+544
-80
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ use {
284284
["H"] = "toggle_hidden",
285285
["/"] = "fuzzy_finder",
286286
["D"] = "fuzzy_finder_directory",
287+
["#"] = "fuzzy_sorter", -- fuzzy sorting using the fzy algorithm
288+
-- ["D"] = "fuzzy_sorter_directory",
287289
["f"] = "filter_on_submit",
288290
["<c-x>"] = "clear_filter",
289291
["[g"] = "prev_git_modified",

doc/neo-tree.txt

+8
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,14 @@ D = fuzzy_finder_directory: Like fuzzy_finder above, but only shows directories.
325325
search and set the focus on that directory.
326326
Requires `fd` or `find` to be installed~
327327

328+
# = fuzzy_sorter: Sort the tree recursively based on fzy algorithm,
329+
showing top score files. Space separated keywords
330+
are treated as `and` which will be useful to narrow
331+
down as you type. The file list is taken from fd
332+
and other programs mentioned in `fuzzy_finder`.
333+
`fuzzy_sorter_directory` can be used to show list
334+
of directories instead.
335+
328336
f = filter_on_submit: Same as above, but does not search until you hit
329337
enter. Useful if filter_as_you_type is too slow.
330338
Also useful if you want to leave the tree

lua/neo-tree/defaults.lua

+2
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ local config = {
359359
["/"] = "fuzzy_finder",
360360
["D"] = "fuzzy_finder_directory",
361361
--["/"] = "filter_as_you_type", -- this was the default until v1.28
362+
["#"] = "fuzzy_sorter", -- fuzzy sorting using the fzy algorithm
363+
-- ["D"] = "fuzzy_sorter_directory",
362364
["f"] = "filter_on_submit",
363365
["<C-x>"] = "clear_filter",
364366
["<bs>"] = "navigate_up",

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

+10
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ M.fuzzy_finder_directory = function(state)
9494
filter.show_filter(state, true, "directory")
9595
end
9696

97+
---Shows the filter input in fuzzy sorter
98+
M.fuzzy_sorter = function(state)
99+
filter.show_filter(state, true, true, true)
100+
end
101+
102+
---Shows the filter input in fuzzy sorter with only directories
103+
M.fuzzy_sorter_directory = function(state)
104+
filter.show_filter(state, true, "directory", true)
105+
end
106+
97107
---Navigate up one level.
98108
M.navigate_up = function(state)
99109
local parent_path, _ = utils.split_path(state.path)

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

+4
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ end
185185
M.reset_search = function(state, refresh, open_current_node)
186186
log.trace("reset_search")
187187
state.fuzzy_finder_mode = nil
188+
state.use_fzy = nil
189+
state.fzy_sort_result_scores = nil
190+
state.fzy_sort_file_list_cache = nil
191+
state.sort_function_override = nil
188192
if refresh == nil then
189193
refresh = true
190194
end

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

+24-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ local renderer = require("neo-tree.ui.renderer")
1414

1515
local M = {}
1616

17-
M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode)
17+
M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode, use_fzy)
1818
local popup_options
1919
local winid = vim.api.nvim_get_current_win()
2020
local height = vim.api.nvim_win_get_height(winid)
@@ -55,6 +55,29 @@ M.show_filter = function(state, search_as_you_type, fuzzy_finder_mode)
5555
})
5656
end
5757

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
72+
end
73+
return a_score > b_score
74+
end
75+
end
76+
if use_fzy then
77+
set_sort_by_score()
78+
state.use_fzy = true
79+
end
80+
5881
local select_first_file = function()
5982
local is_file = function(node)
6083
return node.type == "file"

0 commit comments

Comments
 (0)