Skip to content

Commit 7e34112

Browse files
committed
update
1 parent cd9da7a commit 7e34112

File tree

1 file changed

+113
-45
lines changed

1 file changed

+113
-45
lines changed

lua/dired/init.lua

Lines changed: 113 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ int os_get_uname(uv_uid_t uid, char *s, size_t len);
2727
---@field shortcuts string
2828
---@field show_hidden boolean
2929
---@field normal_when_fits boolean
30-
---@filed use_trash boolean
30+
---@field use_trash boolean
3131
---@field file_dir_based boolean
3232
---@field keymaps KeyMapConfig
3333

@@ -230,7 +230,7 @@ local Browser = {}
230230
local Actions = {}
231231

232232
UI.Entry = {
233-
render = function(state, row, entry, file_idx)
233+
render = function(state, row, entry)
234234
local formatted = {
235235
perms = Format.permissions(entry.stat.mode),
236236
user = Format.username(entry.stat.uid),
@@ -659,10 +659,8 @@ end
659659

660660
local function create_shortcut_manager()
661661
local pool = vim.split(Config.shortcuts, '')
662-
local idx = 1
663662
-- {shortcut -> line_num}
664663
local assigned = {} -- type table<string, int>
665-
local existing_keymaps = {}
666664

667665
return {
668666
get = function()
@@ -728,6 +726,106 @@ local function create_shortcut_manager()
728726
}
729727
end
730728

729+
local function create_debounced_search()
730+
local timer = nil
731+
local last_search = ''
732+
local last_results = {}
733+
local is_searching = false
734+
local pending_search = nil
735+
736+
-- 清理函数
737+
local function cleanup()
738+
if timer then
739+
if timer:is_active() then
740+
timer:stop()
741+
end
742+
timer:close()
743+
timer = nil
744+
end
745+
end
746+
747+
local function execute_search(state, search_text, callback)
748+
if search_text == last_search and #last_results > 0 then
749+
return vim.schedule(function()
750+
callback(last_results)
751+
end)
752+
end
753+
754+
is_searching = true
755+
last_search = search_text
756+
757+
vim.schedule(function()
758+
local filtered_entries = {}
759+
760+
for _, entry in ipairs(state.entries) do
761+
local match = vim.fn.matchfuzzypos({ entry.name }, search_text)
762+
if #match[3] > 0 and match[3][1] > 0 then
763+
entry.match_pos = match[2][1]
764+
entry.score = match[3][1]
765+
table.insert(filtered_entries, entry)
766+
end
767+
end
768+
769+
table.sort(filtered_entries, function(a, b)
770+
return a.score > b.score
771+
end)
772+
last_results = filtered_entries
773+
is_searching = false
774+
775+
if pending_search then
776+
local pending = pending_search
777+
pending_search = nil
778+
execute_search(state, pending.text, pending.callback)
779+
return
780+
end
781+
782+
vim.schedule(function()
783+
callback(filtered_entries)
784+
end)
785+
end)
786+
end
787+
788+
return {
789+
search = function(state, search_text, callback, delay)
790+
delay = delay or 100
791+
if is_searching then
792+
pending_search = { text = search_text, callback = callback }
793+
return
794+
end
795+
if not timer then
796+
timer = assert(vim.uv.new_timer())
797+
end
798+
799+
if timer:is_active() then
800+
timer:stop()
801+
end
802+
803+
if #search_text == 0 then
804+
last_search = ''
805+
last_results = {}
806+
return vim.schedule(function()
807+
callback(state.entries)
808+
end)
809+
end
810+
811+
timer:start(
812+
delay,
813+
0,
814+
vim.schedule_wrap(function()
815+
execute_search(state, search_text, callback)
816+
end)
817+
)
818+
end,
819+
destroy = cleanup,
820+
reset = function()
821+
last_search = ''
822+
last_results = {}
823+
is_searching = false
824+
pending_search = nil
825+
end,
826+
}
827+
end
828+
731829
Browser.State = {
732830
create = function(path)
733831
local width = math.floor(vim.o.columns * 0.8)
@@ -740,13 +838,15 @@ Browser.State = {
740838

741839
return F.IO.chain(UI.Window.create(dimensions), function(state)
742840
return F.IO.chain(UI.Window.event(state), function(s)
841+
---@diagnostic disable-next-line: redefined-local
743842
return F.IO.chain(UI.Window.monitor(s), function(s)
744843
s.current_path = path
745844
s.entries = {}
746845
s.show_hidden = Config.show_hidden
747846
s.original_entries = {}
748847
s.clipboard = {}
749848
s.shortcut_manager = create_shortcut_manager()
849+
s.search_engine = create_debounced_search()
750850
s.initialized = false
751851

752852
-- Function to update display with entries
@@ -780,7 +880,7 @@ Browser.State = {
780880

781881
vim.bo[new_state.buf].modifiable = true
782882
for i, entry in ipairs(entries_to_show) do
783-
UI.Entry.render(new_state, i - 1, entry, i)
883+
UI.Entry.render(new_state, i - 1, entry)
784884
end
785885
end
786886

@@ -798,57 +898,25 @@ Browser.State = {
798898
end
799899

800900
if not s.initialized then
801-
local timer = assert(vim.uv.new_timer())
802901
-- Attach buffer for search
803902
api.nvim_buf_attach(state.search_buf, false, {
804-
on_lines = function(...)
903+
on_lines = function()
805904
-- Get search text without prompt path
806-
local text =
905+
local query =
807906
api.nvim_get_current_line():gsub(state.abbr_path or state.current_path, '')
808907

809-
if text == '' or text:match(SEPARATOR .. '$') then
908+
if query == '' or query:match(SEPARATOR .. '$') then
810909
update_display(state, state.entries)
811910
return
812911
end
813-
814-
-- Clear previous timer if exists
815-
if timer:is_active() then
816-
timer:stop()
817-
end
818-
819-
-- Set new timer for delayed search
820-
timer:start(
821-
50,
822-
0,
823-
vim.schedule_wrap(function()
824-
if
825-
api
826-
.nvim_get_current_line()
827-
:gsub(state.abbr_path or state.current_path, '')
828-
== text
829-
then
830-
local filtered_entries = {}
831-
for _, entry in ipairs(s.entries) do
832-
local match = vim.fn.matchfuzzypos({ entry.name }, text)
833-
if #match[3] > 0 and match[3][1] > 0 then
834-
entry.match_pos = match[2][1]
835-
entry.score = match[3][1]
836-
table.insert(filtered_entries, entry)
837-
end
838-
end
839-
table.sort(filtered_entries, function(a, b)
840-
return a.score > b.score
841-
end)
842-
update_display(state, filtered_entries, false)
843-
end
844-
end)
845-
)
912+
state.search_engine.search(state, query, function(filtered_entries)
913+
update_display(state, filtered_entries, false)
914+
end, 80)
846915
end,
847916
on_detach = function()
848-
if timer:is_active() then
849-
timer:stop()
917+
if state.search_engine then
918+
state.search_engine.destroy()
850919
end
851-
timer:close()
852920
end,
853921
})
854922
end

0 commit comments

Comments
 (0)