@@ -43,6 +43,24 @@ 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+ print (" cancelling job" , job )
51+ local pid = job .pid
52+ job :shutdown ()
53+ if pid ~= nil then
54+ print (" killing pid" , pid )
55+ if utils .is_windows then
56+ vim .fn .system (" taskkill /F /T /PID " .. pid )
57+ else
58+ vim .fn .system (" kill -9 " .. pid )
59+ end
60+ end
61+ end
62+ end
63+
4664--- @class FileTypes
4765--- @field file boolean
4866--- @field directory boolean
6886--- @param on_insert ? fun ( err : string , line : string ): any Executed for each line of stdout and stderr.
6987--- @param on_exit ? fun ( return_val : table ): any Executed at the end.
7088M .filter_files_external = function (cmd , path , glob , regex , full_path , types , ignore , limit , find_args , on_insert , on_exit )
89+ -- First cancel the last job if it is still running
90+ M .cancel ()
91+
7192 if glob ~= nil and regex ~= nil then
7293 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 )
94+ log .warn (" both glob and regex are set. glob will take precedence. " .. log_msg )
7495 end
7596 ignore = ignore or {}
7697 types = types or {}
@@ -182,7 +203,7 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
182203 limit = math.huge -- `fd` manages limit on its own
183204 end
184205 local item_count = 0
185- Job :new ({
206+ local job = Job :new ({
186207 command = cmd ,
187208 cwd = path ,
188209 args = args ,
@@ -204,7 +225,10 @@ M.filter_files_external = function(cmd, path, glob, regex, full_path, types, ign
204225 on_exit (return_val )
205226 end
206227 end ,
207- }):start ()
228+ })
229+ M .cancel ()
230+ job :start ()
231+ table.insert (running_jobs , job )
208232end
209233
210234local function fzy_sort_get_total_score (terms , path )
@@ -247,11 +271,24 @@ M.fzy_sort_files = function(opts, state)
247271 for term in string.gmatch (opts .term , " [^%s]+" ) do -- space split opts.term
248272 terms [# terms + 1 ] = term
249273 end
274+
275+ -- The base search is anything that contains the characters in the term
276+ -- The fzy score is then used to sort the results
277+ local chars = {}
278+ local regex = " .*"
279+ for _ , term in ipairs (terms ) do
280+ for c in term :gmatch (" ." ) do
281+ if not chars [c ] then
282+ regex = regex .. c .. " +.*"
283+ end
284+ chars [c ] = true
285+ end
286+ end
287+
250288 local result_counter = 0
251289
252- -- fetch file list for the first time and calculate scores along the way
253290 local index = 1
254- state .fzy_sort_result_scores = { foo = 0 , baz = 0 }
291+ state .fzy_sort_result_scores = {}
255292 local function on_insert (err , path )
256293 if not err then
257294 if result_counter >= limit then
@@ -262,6 +299,9 @@ M.fzy_sort_files = function(opts, state)
262299 relative_path = " ./" .. path :sub (pwd_length + 1 )
263300 end
264301 index = index + 1
302+ if state .fzy_sort_result_scores == nil then
303+ state .fzy_sort_result_scores = {}
304+ end
265305 state .fzy_sort_result_scores [path ] = 0
266306 local score = fzy_sort_get_total_score (terms , relative_path )
267307 if score > 0 then
@@ -273,11 +313,11 @@ M.fzy_sort_files = function(opts, state)
273313 end
274314 end
275315
276- M .filter_files_external (get_find_command (state ), pwd , nil , nil , true ,
316+ M .filter_files_external (get_find_command (state ), pwd , nil , regex , true ,
277317 { directory = fuzzy_finder_mode == " directory" , file = fuzzy_finder_mode ~= " directory" },
278318 { dotfiles = not filters .visible and filters .hide_dotfiles ,
279319 gitignore = not filters .visible and filters .hide_gitignored },
280- nil , opts .find_args , on_insert , opts .on_exit )
320+ limit * 10 , opts .find_args , on_insert , opts .on_exit )
281321end
282322
283323M .find_files = function (opts )
0 commit comments