Skip to content

Commit 61bd92f

Browse files
committed
update
1 parent 1dc8a94 commit 61bd92f

1 file changed

Lines changed: 169 additions & 161 deletions

File tree

lua/dired/init.lua

Lines changed: 169 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,9 @@ end
197197
Format.friendly_time = function(timestamp)
198198
local now = os.time()
199199
local diff = now - timestamp
200-
if diff < 60 then
200+
if diff < 0 then
201+
return os.date('%Y %b %d %H:%M', timestamp)
202+
elseif diff < 60 then
201203
return string.format('%d secs ago', diff)
202204
elseif diff < 3600 then
203205
return string.format('%d mins ago', math.floor(diff / 60))
@@ -726,105 +728,6 @@ local function create_shortcut_manager()
726728
}
727729
end
728730

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-
local function cleanup()
737-
if timer then
738-
if timer:is_active() then
739-
timer:stop()
740-
end
741-
timer:close()
742-
timer = nil
743-
end
744-
end
745-
746-
local function execute_search(state, search_text, callback)
747-
if search_text == last_search and #last_results > 0 then
748-
return vim.schedule(function()
749-
callback(last_results)
750-
end)
751-
end
752-
753-
is_searching = true
754-
last_search = search_text
755-
756-
vim.schedule(function()
757-
local filtered_entries = {}
758-
759-
for _, entry in ipairs(state.entries) do
760-
local match = vim.fn.matchfuzzypos({ entry.name }, search_text)
761-
if #match[3] > 0 and match[3][1] > 0 then
762-
entry.match_pos = match[2][1]
763-
entry.score = match[3][1]
764-
table.insert(filtered_entries, entry)
765-
end
766-
end
767-
768-
table.sort(filtered_entries, function(a, b)
769-
return a.score > b.score
770-
end)
771-
last_results = filtered_entries
772-
is_searching = false
773-
774-
if pending_search then
775-
local pending = pending_search
776-
pending_search = nil
777-
execute_search(state, pending.text, pending.callback)
778-
return
779-
end
780-
781-
vim.schedule(function()
782-
callback(filtered_entries)
783-
end)
784-
end)
785-
end
786-
787-
return {
788-
search = function(state, search_text, callback, delay)
789-
delay = delay or 100
790-
if is_searching then
791-
pending_search = { text = search_text, callback = callback }
792-
return
793-
end
794-
if not timer then
795-
timer = assert(vim.uv.new_timer())
796-
end
797-
798-
if timer:is_active() then
799-
timer:stop()
800-
end
801-
802-
if #search_text == 0 then
803-
last_search = ''
804-
last_results = {}
805-
return vim.schedule(function()
806-
callback(state.entries)
807-
end)
808-
end
809-
810-
timer:start(
811-
delay,
812-
0,
813-
vim.schedule_wrap(function()
814-
execute_search(state, search_text, callback)
815-
end)
816-
)
817-
end,
818-
destroy = cleanup,
819-
reset = function()
820-
last_search = ''
821-
last_results = {}
822-
is_searching = false
823-
pending_search = nil
824-
end,
825-
}
826-
end
827-
828731
local function parse_fd_output(line, current_path)
829732
local perms, links, user, group, size_str, month, day, time, path
830733
perms, links, user, group, size_str, month, day, time, path =
@@ -915,6 +818,167 @@ local function parse_fd_output(line, current_path)
915818
return entry
916819
end
917820

821+
local function create_debounced_search()
822+
local timer = nil
823+
local last_search = ''
824+
local is_searching = false
825+
local current_job = nil
826+
local pending_search = nil
827+
828+
local function cleanup()
829+
if timer then
830+
if timer:is_active() then
831+
timer:stop()
832+
end
833+
timer:close()
834+
timer = nil
835+
end
836+
837+
if current_job and current_job.kill then
838+
current_job.kill(9)
839+
current_job = nil
840+
end
841+
end
842+
843+
local function process_and_display_results(results, search_text, callback)
844+
local filters = {}
845+
846+
if #results > 0 then
847+
local names = Iter(results):map(function(entry)
848+
return entry.name
849+
end):totable()
850+
851+
local res = vim.fn.matchfuzzypos(names, search_text)
852+
for _, entry in ipairs(results) do
853+
for k, v in ipairs(res[1]) do
854+
if v == entry.name then
855+
entry.match_pos = res[2][k]
856+
entry.score = res[3][k] or 0
857+
table.insert(filters, entry)
858+
end
859+
end
860+
end
861+
862+
table.sort(filters, function(a, b)
863+
return a.score > b.score
864+
end)
865+
end
866+
867+
callback(filters)
868+
end
869+
870+
local function execute_search(state, search_text, callback)
871+
if search_text == last_search and not pending_search then
872+
return
873+
end
874+
875+
if current_job and current_job.kill then
876+
current_job.kill(9)
877+
current_job = nil
878+
end
879+
880+
is_searching = true
881+
last_search = search_text
882+
883+
local results = {}
884+
current_job = vim.system({
885+
'fd',
886+
'-l',
887+
'-i',
888+
'-H',
889+
'--color',
890+
'never',
891+
search_text,
892+
state.current_path,
893+
}, {
894+
text = true,
895+
stdout = function(_, data)
896+
if data then
897+
for _, line in ipairs(vim.split(data, '\n')) do
898+
if #line > 0 then
899+
local entry = parse_fd_output(line, state.current_path)
900+
if entry then
901+
local len = #entry.name + (entry.stat.type == 'directory' and 1 or 0)
902+
state.maxwidth = math.max(state.maxwidth or 0, len)
903+
table.insert(results, entry)
904+
end
905+
end
906+
end
907+
908+
if #results >= 50 then
909+
local current_results = vim.deepcopy(results)
910+
vim.schedule(function()
911+
process_and_display_results(current_results, search_text, callback)
912+
end)
913+
end
914+
end
915+
end,
916+
}, function(obj)
917+
if obj.code ~= 0 and obj.code ~= 1 then
918+
Notify.err('Search error: ' .. (obj.stderr or 'Unknown error'))
919+
end
920+
921+
vim.schedule(function()
922+
process_and_display_results(results, search_text, callback)
923+
924+
is_searching = false
925+
current_job = nil
926+
927+
if pending_search then
928+
local pending = pending_search
929+
pending_search = nil
930+
execute_search(state, pending.text, pending.callback)
931+
end
932+
end)
933+
end)
934+
end
935+
936+
return {
937+
search = function(state, search_text, callback, delay)
938+
delay = delay or 100
939+
940+
if is_searching then
941+
pending_search = { text = search_text, callback = callback }
942+
return
943+
end
944+
945+
if not timer then
946+
timer = assert(vim.uv.new_timer())
947+
end
948+
949+
if timer:is_active() then
950+
timer:stop()
951+
end
952+
953+
if #search_text == 0 then
954+
last_search = ''
955+
return vim.schedule(function()
956+
callback(state.entries)
957+
end)
958+
end
959+
960+
timer:start(
961+
delay,
962+
0,
963+
vim.schedule_wrap(function()
964+
execute_search(state, search_text, callback)
965+
end)
966+
)
967+
end,
968+
destroy = cleanup,
969+
reset = function()
970+
last_search = ''
971+
is_searching = false
972+
pending_search = nil
973+
974+
if current_job and current_job.kill then
975+
current_job.kill(9) -- SIGKILL
976+
current_job = nil
977+
end
978+
end,
979+
}
980+
end
981+
918982
Browser.State = {
919983
create = function(path)
920984
local width = math.floor(vim.o.columns * 0.8)
@@ -993,73 +1057,17 @@ Browser.State = {
9931057
if not s.initialized then
9941058
api.nvim_buf_attach(state.search_buf, false, {
9951059
on_lines = function()
996-
-- Get search text without prompt path
997-
local query =
998-
api.nvim_get_current_line():gsub(state.abbr_path or state.current_path, '')
1060+
local line = api.nvim_buf_get_text(state.search_buf, 0, 0, 0, -1, {})[1]
1061+
local query = line:gsub(state.abbr_path or state.current_path, '')
9991062

10001063
-- Empty query or directory navigation
10011064
if query == '' or query:match(SEPARATOR .. '$') then
10021065
update_display(state, state.entries)
10031066
return
10041067
end
1005-
1006-
if vim.fn.executable('rg') == 1 then
1007-
vim.system({
1008-
'fd',
1009-
'-l',
1010-
'-i',
1011-
'-H',
1012-
'--color',
1013-
'never',
1014-
query,
1015-
state.current_path,
1016-
}, {
1017-
text = true,
1018-
}, function(obj)
1019-
local results = {}
1020-
if obj.code ~= 0 and obj.code ~= 1 then
1021-
Notify.err(vim.inspect(obj))
1022-
return
1023-
end
1024-
if obj.stdout and #obj.stdout > 0 then
1025-
for _, line in ipairs(vim.split(obj.stdout, '\n')) do
1026-
if #line > 0 then
1027-
local entry = parse_fd_output(line, state.current_path)
1028-
if entry then
1029-
local len = #entry.name
1030-
+ (entry.stat.type == 'directory' and 1 or 0)
1031-
state.maxwidth = math.max(state.maxwidth, len)
1032-
table.insert(results, entry)
1033-
end
1034-
end
1035-
end
1036-
end
1037-
1038-
vim.schedule(function()
1039-
local filters = {}
1040-
if #results > 0 then
1041-
local names = Iter(results):map(function(entry)
1042-
return entry.name
1043-
end):totable()
1044-
local res = vim.fn.matchfuzzypos(names, query)
1045-
for _, entry in ipairs(results) do
1046-
for k, v in ipairs(res[1]) do
1047-
if v == entry.name then
1048-
entry.match_pos = res[2][k]
1049-
entry.score = res[3][k] or 0
1050-
table.insert(filters, entry)
1051-
end
1052-
end
1053-
end
1054-
table.sort(filters, function(a, b)
1055-
return a.score > b.score
1056-
end)
1057-
state.search_results = results
1058-
end
1059-
update_display(state, filters, false)
1060-
end)
1061-
end)
1062-
end
1068+
state.search_engine.search(state, query, function(entries)
1069+
update_display(state, entries)
1070+
end, 80)
10631071
end,
10641072
on_detach = function()
10651073
if state.search_engine then

0 commit comments

Comments
 (0)