@@ -43,6 +43,22 @@ local get_find_command = function(state)
4343 return state .find_command
4444end
4545
46+ local running_jobs = {}
47+ M .cancel = function ()
48+ while # running_jobs > 0 do
49+ local job = table.remove (running_jobs , 1 )
50+ local pid = job .pid
51+ job :shutdown ()
52+ if pid ~= nil then
53+ if utils .is_windows then
54+ vim .fn .system (" taskkill /F /T /PID " .. pid )
55+ else
56+ vim .fn .system (" kill -9 " .. pid )
57+ end
58+ end
59+ end
60+ end
61+
4662--- @class FileTypes
4763--- @field file boolean
4864--- @field directory boolean
6884--- @param on_insert ? fun ( err : string , line : string ): any Executed for each line of stdout and stderr.
6985--- @param on_exit ? fun ( return_val : table ): any Executed at the end.
7086M .filter_files_external = function (cmd , path , glob , regex , full_path , types , ignore , limit , find_args , on_insert , on_exit )
87+ -- First cancel the last job if it is still running
88+ M .cancel ()
89+
7190 if glob ~= nil and regex ~= nil then
7291 local log_msg = string.format ([[ glob: %s, regex: %s]] , glob , regex )
73- log .warning (" both glob and regex are set. glob will take precedence. " .. log_msg )
92+ log .warn (" both glob and regex are set. glob will take precedence. " .. log_msg )
7493 end
7594 ignore = ignore or {}
7695 types = types or {}
@@ -182,7 +201,7 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
182201 limit = math.huge -- `fd` manages limit on its own
183202 end
184203 local item_count = 0
185- Job :new ({
204+ local job = Job :new ({
186205 command = cmd ,
187206 cwd = path ,
188207 args = args ,
@@ -204,7 +223,10 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
204223 on_exit (return_val )
205224 end
206225 end ,
207- }):start ()
226+ })
227+ M .cancel ()
228+ job :start ()
229+ table.insert (running_jobs , job )
208230end
209231
210232local function fzy_sort_get_total_score (terms , path )
@@ -247,11 +269,24 @@ M.fzy_sort_files = function(opts, state)
247269 for term in string.gmatch (opts .term , " [^%s]+" ) do -- space split opts.term
248270 terms [# terms + 1 ] = term
249271 end
272+
273+ -- The base search is anything that contains the characters in the term
274+ -- The fzy score is then used to sort the results
275+ local chars = {}
276+ local regex = " .*"
277+ for _ , term in ipairs (terms ) do
278+ for c in term :gmatch (" ." ) do
279+ if not chars [c ] then
280+ regex = regex .. c .. " +.*"
281+ end
282+ chars [c ] = true
283+ end
284+ end
285+
250286 local result_counter = 0
251287
252- -- fetch file list for the first time and calculate scores along the way
253288 local index = 1
254- state .fzy_sort_result_scores = { foo = 0 , baz = 0 }
289+ state .fzy_sort_result_scores = {}
255290 local function on_insert (err , path )
256291 if not err then
257292 if result_counter >= limit then
@@ -262,6 +297,9 @@ M.fzy_sort_files = function(opts, state)
262297 relative_path = " ./" .. path :sub (pwd_length + 1 )
263298 end
264299 index = index + 1
300+ if state .fzy_sort_result_scores == nil then
301+ state .fzy_sort_result_scores = {}
302+ end
265303 state .fzy_sort_result_scores [path ] = 0
266304 local score = fzy_sort_get_total_score (terms , relative_path )
267305 if score > 0 then
@@ -273,11 +311,11 @@ M.fzy_sort_files = function(opts, state)
273311 end
274312 end
275313
276- M .filter_files_external (get_find_command (state ), pwd , nil , nil , true ,
314+ M .filter_files_external (get_find_command (state ), pwd , nil , regex , true ,
277315 { directory = fuzzy_finder_mode == " directory" , file = fuzzy_finder_mode ~= " directory" },
278316 { dotfiles = not filters .visible and filters .hide_dotfiles ,
279317 gitignore = not filters .visible and filters .hide_gitignored },
280- nil , opts .find_args , on_insert , opts .on_exit )
318+ limit * 10 , opts .find_args , on_insert , opts .on_exit )
281319end
282320
283321M .find_files = function (opts )
0 commit comments