From 0b891ec93402821629fb14587193f53ed033b3b9 Mon Sep 17 00:00:00 2001 From: Stef Date: Wed, 24 May 2023 10:29:36 +0100 Subject: [PATCH] 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. --- lua/telescope/finders.lua | 25 +++++++++++++++---- lua/telescope/finders/async_job_finder.lua | 6 ++++- .../finders/async_oneshot_finder.lua | 7 +++--- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lua/telescope/finders.lua b/lua/telescope/finders.lua index fe1af96..68deb9b 100644 --- a/lua/telescope/finders.lua +++ b/lua/telescope/finders.lua @@ -65,16 +65,22 @@ function JobFinder:_find(prompt, process_result, process_complete) self.job:shutdown() end + local line_num = 0 local on_output = function(_, line, _) + line_num = line_num + 1 if not line or line == "" then return end + local entry if self.entry_maker then - line = self.entry_maker(line) + entry = self.entry_maker(line) + entry.index = line_num + else + entry = line end - process_result(line) + process_result(entry) end local opts = self:fn_command(prompt) @@ -131,8 +137,12 @@ end function DynamicFinder:_find(prompt, process_result, process_complete) local results = self.fn(prompt) + local result_num = 0 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 end end @@ -204,8 +214,13 @@ finders.new_table = function(t) return async_static_finder(t) end -finders.new_dynamic = function(t) - return DynamicFinder:new(t) +--- Used to create a finder from a function. +-- +---@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 return finders diff --git a/lua/telescope/finders/async_job_finder.lua b/lua/telescope/finders/async_job_finder.lua index 20af604..b355c11 100644 --- a/lua/telescope/finders/async_job_finder.lua +++ b/lua/telescope/finders/async_job_finder.lua @@ -56,8 +56,12 @@ return function(opts) stdout = stdout, } + local line_num = 0 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 end end diff --git a/lua/telescope/finders/async_oneshot_finder.lua b/lua/telescope/finders/async_oneshot_finder.lua index bafb134..032fd3a 100644 --- a/lua/telescope/finders/async_oneshot_finder.lua +++ b/lua/telescope/finders/async_oneshot_finder.lua @@ -70,9 +70,10 @@ return function(opts) async.util.scheduler() end - local v = entry_maker(line) - results[num_results] = v - process_result(v) + local entry = entry_maker(line) + entry.index = num_results + results[num_results] = entry + process_result(entry) end process_complete()