Skip to content

Commit

Permalink
feat: implement fallback for some finders
Browse files Browse the repository at this point in the history
This implements idea "2" from here:

- #393 (comment)

> We teach the callers to interpret an empty result list as a cue to
> try again using a fallback mechanism; in an empty directory this would
> give a false negative but a relatively harmless one (ie. you might run
> `:CommandTRipgrep` in an empty folder, and Command-T would take that as
> a cue to try again with the standard scanner, which would of course
> also return an empty list).

Specifically, we do this whenever `git`, `rg`, or `find` returns no
results.

There is a bit of duplication here because we need thunks at each site;
otherwise as soon as we `require`-d the fallback finder it would do a
redundant scan. I'm not going to factor that out yet because I am still
not convinced that this is an optimal strategy. Want to let it bake for
a while and see what happens.
  • Loading branch information
wincent committed Aug 31, 2022
1 parent b229d92 commit 9e8c790
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
11 changes: 10 additions & 1 deletion lua/wincent/commandt/private/finders/find.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ local ffi = require('ffi')

-- TODO: remember cached directories
return function(directory, options)
local finder = {}
-- Use a thunk to avoid cost of fallback scanning until actually needed.
finder.fallback = (
(function(d, o)
return function()
finder.fallback = require('wincent.commandt.private.finders.file')(d ~= '' and d or '.', o)
return finder.fallback
end
end)(directory, options)
)
if vim.startswith(directory, './') then
directory = directory:sub(3, -1)
end
if directory ~= '' and directory ~= '.' then
directory = vim.fn.shellescape(directory)
end
local lib = require('wincent.commandt.private.lib')
local finder = {}
finder.scanner = require('wincent.commandt.private.scanners.find').scanner(directory)
finder.matcher = lib.matcher_new(finder.scanner, options)
finder.run = function(query)
Expand Down
11 changes: 10 additions & 1 deletion lua/wincent/commandt/private/finders/git.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,20 @@ local ffi = require('ffi')
-- the `command` scanner
-- TODO: remember cached directories
return function(directory, options)
local finder = {}
-- Use a thunk to avoid cost of fallback scanning until actually needed.
finder.fallback = (
(function(d, o)
return function()
finder.fallback = require('wincent.commandt.private.finders.file')(d ~= '' and d or '.', o)
return finder.fallback
end
end)(directory, options)
)
if directory ~= '' then
directory = vim.fn.shellescape(directory)
end
local lib = require('wincent.commandt.private.lib')
local finder = {}
finder.scanner = require('wincent.commandt.private.scanners.git').scanner(directory, options.scanners.git)
finder.matcher = lib.matcher_new(finder.scanner, options)
finder.run = function(query)
Expand Down
11 changes: 10 additions & 1 deletion lua/wincent/commandt/private/finders/rg.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ local ffi = require('ffi')

-- TODO: remember cached directories
return function(directory, options)
local finder = {}
-- Use a thunk to avoid cost of fallback scanning until actually needed.
finder.fallback = (
(function(d, o)
return function()
finder.fallback = require('wincent.commandt.private.finders.file')(d ~= '' and d or '.', o)
return finder.fallback
end
end)(directory, options)
)
if vim.startswith(directory, './') then
directory = directory:sub(3, -1)
end
if directory ~= '' and directory ~= '.' then
directory = vim.fn.shellescape(directory)
end
local lib = require('wincent.commandt.private.lib')
local finder = {}
finder.scanner = require('wincent.commandt.private.scanners.rg').scanner(directory)
finder.matcher = lib.matcher_new(finder.scanner, options)
finder.run = function(query)
Expand Down
9 changes: 8 additions & 1 deletion lua/wincent/commandt/private/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,14 @@ ui.show = function(finder, options)
margin = options.margin,
name = options.name,
on_change = function(query)
results = finder.run(query)
results = current_finder.run(query)
if #results > 0 then
-- Once we've proved a finder works, we don't ever want to use fallback.
current_finder.fallback = nil
elseif current_finder.fallback then
current_finder = current_finder.fallback()
results = current_finder.run(query)
end
if #results == 0 then
selected = nil
else
Expand Down

0 comments on commit 9e8c790

Please sign in to comment.