fix: always add index to entry (#2442)

59497d6 introduced `sorters.fuzzy_with_index_bias`, which gives a
scoring boost to earlier entries.

However, this sorter relies on an `index` key existing for the entry, which is
only populated by the static finder currently. We should set it from the
other finders, too.

This will allow us to use said sorter everywhere. It will also let us
replicate the behaviour of `fzf --tiebreak=index`:

```
  return pickers.new(opts, {
    finder = finders.new_oneshot_job(...)
    sorter = telescope.extensions.fzf.native_fzf_sorter(),
    tiebreak = function(current_entry, existing_entry, _)
      return current_entry.index < existing_entry.index
    end
  }):find()
```

This gives me better results for my "recently opened files" picker.
Other builtin pickers might benefit from this, too.
This commit is contained in:
Stef
2023-05-24 10:29:36 +01:00
committed by GitHub
parent 6dec8cf723
commit 0b891ec934
3 changed files with 29 additions and 9 deletions

View File

@@ -65,16 +65,22 @@ function JobFinder:_find(prompt, process_result, process_complete)
self.job:shutdown() self.job:shutdown()
end end
local line_num = 0
local on_output = function(_, line, _) local on_output = function(_, line, _)
line_num = line_num + 1
if not line or line == "" then if not line or line == "" then
return return
end end
local entry
if self.entry_maker then if self.entry_maker then
line = self.entry_maker(line) entry = self.entry_maker(line)
entry.index = line_num
else
entry = line
end end
process_result(line) process_result(entry)
end end
local opts = self:fn_command(prompt) local opts = self:fn_command(prompt)
@@ -131,8 +137,12 @@ end
function DynamicFinder:_find(prompt, process_result, process_complete) function DynamicFinder:_find(prompt, process_result, process_complete)
local results = self.fn(prompt) local results = self.fn(prompt)
local result_num = 0
for _, result in ipairs(results) do for _, result in ipairs(results) do
if process_result(self.entry_maker(result)) then result_num = result_num + 1
local entry = self.entry_maker(result)
entry.index = result_num
if process_result(entry) then
return return
end end
end end
@@ -204,8 +214,13 @@ finders.new_table = function(t)
return async_static_finder(t) return async_static_finder(t)
end end
finders.new_dynamic = function(t) --- Used to create a finder from a function.
return DynamicFinder:new(t) --
---@param opts table: stuff
-- @key fn function() => list[string]
-- @key entry_maker function Optional: function(line: string) => table
finders.new_dynamic = function(opts)
return DynamicFinder:new(opts)
end end
return finders return finders

View File

@@ -56,8 +56,12 @@ return function(opts)
stdout = stdout, stdout = stdout,
} }
local line_num = 0
for line in stdout:iter(true) do for line in stdout:iter(true) do
if process_result(entry_maker(line)) then line_num = line_num + 1
local entry = entry_maker(line)
entry.index = line_num
if process_result(entry) then
return return
end end
end end

View File

@@ -70,9 +70,10 @@ return function(opts)
async.util.scheduler() async.util.scheduler()
end end
local v = entry_maker(line) local entry = entry_maker(line)
results[num_results] = v entry.index = num_results
process_result(v) results[num_results] = entry
process_result(entry)
end end
process_complete() process_complete()