mirror of
https://github.com/kristoferssolo/telescope-frecency.nvim.git
synced 2025-10-21 20:10:38 +00:00
fix: reflow results to show valid ones (#123)
* fix: clear non-matched results in results buffer * fix: show high-scored results in the first view This is for sorting_strategy = 'descending'
This commit is contained in:
parent
9b17c17744
commit
2ac311a266
@ -3,17 +3,20 @@ local async = require "plenary.async" --[[@as PlenaryAsync]]
|
||||
---@class FrecencyAsyncFinder
|
||||
---@field closed boolean
|
||||
---@field entries FrecencyEntry[]
|
||||
---@field reflowed boolean
|
||||
---@field rx PlenaryAsyncControlChannelRx
|
||||
---@field state FrecencyState
|
||||
---@overload fun(_: string, process_result: (fun(entry: FrecencyEntry): nil), process_complete: fun(): nil): nil
|
||||
local AsyncFinder = {}
|
||||
|
||||
---@param fs FrecencyFS
|
||||
---@param state FrecencyState
|
||||
---@param path string
|
||||
---@param entry_maker fun(file: FrecencyFile): FrecencyEntry
|
||||
---@param initial_results FrecencyFile[]
|
||||
---@return FrecencyAsyncFinder
|
||||
AsyncFinder.new = function(fs, path, entry_maker, initial_results)
|
||||
local self = setmetatable({ closed = false, entries = {} }, {
|
||||
AsyncFinder.new = function(state, fs, path, entry_maker, initial_results)
|
||||
local self = setmetatable({ closed = false, entries = {}, reflowed = false, state = state }, {
|
||||
__index = AsyncFinder,
|
||||
---@param self FrecencyAsyncFinder
|
||||
__call = function(self, ...)
|
||||
@ -47,6 +50,7 @@ AsyncFinder.new = function(fs, path, entry_maker, initial_results)
|
||||
table.insert(self.entries, entry)
|
||||
tx.send(entry)
|
||||
if count % 1000 == 0 then
|
||||
self:reflow_results()
|
||||
-- NOTE: This is needed not to lock text input.
|
||||
async.util.sleep(50)
|
||||
end
|
||||
@ -88,4 +92,32 @@ function AsyncFinder:close()
|
||||
self.closed = true
|
||||
end
|
||||
|
||||
---@return nil
|
||||
function AsyncFinder:reflow_results()
|
||||
local picker = self.state:get()
|
||||
if not picker then
|
||||
return
|
||||
end
|
||||
local bufnr = picker.results_bufnr
|
||||
local win = picker.results_win
|
||||
if not bufnr or not win then
|
||||
return
|
||||
end
|
||||
picker:clear_extra_rows(bufnr)
|
||||
if picker.sorting_strategy == "descending" then
|
||||
local manager = picker.manager
|
||||
if not manager then
|
||||
return
|
||||
end
|
||||
local worst_line = picker:get_row(manager:num_results())
|
||||
---@type WinInfo
|
||||
local wininfo = vim.fn.getwininfo(win)[1]
|
||||
local bottom = vim.api.nvim_buf_line_count(bufnr)
|
||||
if not self.reflowed or worst_line > wininfo.botline then
|
||||
self.reflowed = true
|
||||
vim.api.nvim_win_set_cursor(win, { bottom, 0 })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return AsyncFinder
|
||||
|
||||
@ -27,11 +27,12 @@ end
|
||||
---@field workspace string?
|
||||
---@field workspace_tag string?
|
||||
|
||||
---@param state FrecencyState
|
||||
---@param filepath_formatter FrecencyFilepathFormatter
|
||||
---@param initial_results table
|
||||
---@param opts FrecencyFinderOptions
|
||||
---@return table
|
||||
function Finder:start(filepath_formatter, initial_results, opts)
|
||||
function Finder:start(state, filepath_formatter, initial_results, opts)
|
||||
local entry_maker = self.entry_maker:create(filepath_formatter, opts.workspace, opts.workspace_tag)
|
||||
if not opts.need_scandir then
|
||||
return finders.new_table {
|
||||
@ -40,7 +41,7 @@ function Finder:start(filepath_formatter, initial_results, opts)
|
||||
}
|
||||
end
|
||||
log.debug { finder = opts }
|
||||
return AsyncFinder.new(self.fs, opts.workspace, entry_maker, initial_results)
|
||||
return AsyncFinder.new(state, self.fs, opts.workspace, entry_maker, initial_results)
|
||||
end
|
||||
|
||||
return Finder
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
local State = require "frecency.state"
|
||||
local log = require "plenary.log"
|
||||
local Path = require "plenary.path" --[[@as PlenaryPath]]
|
||||
local actions = require "telescope.actions"
|
||||
@ -83,8 +84,10 @@ function Picker:start(opts)
|
||||
self.results = self:fetch_results(self.workspace)
|
||||
end
|
||||
|
||||
local state = State.new()
|
||||
|
||||
local filepath_formatter = self:filepath_formatter(opts)
|
||||
local finder = self.finder:start(filepath_formatter, self.results, {
|
||||
local finder = self.finder:start(state, filepath_formatter, self.results, {
|
||||
need_scandir = self.workspace and self.config.show_unindexed and true or false,
|
||||
workspace = self.workspace,
|
||||
workspace_tag = self.config.initial_workspace_tag,
|
||||
@ -95,11 +98,12 @@ function Picker:start(opts)
|
||||
finder = finder,
|
||||
previewer = config_values.file_previewer(opts),
|
||||
sorter = sorters.get_substr_matcher(),
|
||||
on_input_filter_cb = self:on_input_filter_cb(opts),
|
||||
on_input_filter_cb = self:on_input_filter_cb(state, opts),
|
||||
attach_mappings = function(prompt_bufnr)
|
||||
return self:attach_mappings(prompt_bufnr)
|
||||
end,
|
||||
})
|
||||
state:set(picker)
|
||||
picker:find()
|
||||
self:set_prompt_options(picker.prompt_bufnr)
|
||||
end
|
||||
@ -227,9 +231,10 @@ function Picker:get_lsp_workspace()
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param state FrecencyState
|
||||
---@param picker_opts table
|
||||
---@return fun(prompt: string): table
|
||||
function Picker:on_input_filter_cb(picker_opts)
|
||||
function Picker:on_input_filter_cb(state, picker_opts)
|
||||
local filepath_formatter = self:filepath_formatter(picker_opts)
|
||||
return function(prompt)
|
||||
local workspace
|
||||
@ -243,7 +248,7 @@ function Picker:on_input_filter_cb(picker_opts)
|
||||
if self.workspace ~= workspace then
|
||||
self.workspace = workspace
|
||||
self.results = self:fetch_results(workspace)
|
||||
opts.updated_finder = self.finder:start(filepath_formatter, self.results, {
|
||||
opts.updated_finder = self.finder:start(state, filepath_formatter, self.results, {
|
||||
initial_results = self.results,
|
||||
need_scandir = self.workspace and self.config.show_unindexed and true or false,
|
||||
workspace = self.workspace,
|
||||
|
||||
21
lua/frecency/state.lua
Normal file
21
lua/frecency/state.lua
Normal file
@ -0,0 +1,21 @@
|
||||
---@class FrecencyState
|
||||
---@field picker TelescopePicker?
|
||||
local State = {}
|
||||
|
||||
---@return FrecencyState
|
||||
State.new = function()
|
||||
return setmetatable({}, { __index = State, __meta = "kv" })
|
||||
end
|
||||
|
||||
---@param picker TelescopePicker?
|
||||
---@return nil
|
||||
function State:set(picker)
|
||||
self.picker = picker
|
||||
end
|
||||
|
||||
---@return TelescopePicker?
|
||||
function State:get()
|
||||
return self.picker
|
||||
end
|
||||
|
||||
return State
|
||||
@ -1,5 +1,6 @@
|
||||
---@diagnostic disable: invisible
|
||||
local AsyncFinder = require "frecency.async_finder"
|
||||
local State = require "frecency.state"
|
||||
local FS = require "frecency.fs"
|
||||
local EntryMaker = require "frecency.entry_maker"
|
||||
local WebDevicons = require "frecency.web_devicons"
|
||||
@ -22,7 +23,7 @@ local function with_files(files, initial_results, callback)
|
||||
local initials = vim.tbl_map(function(v)
|
||||
return { path = (dir / v):absolute() }
|
||||
end, initial_results)
|
||||
local async_finder = AsyncFinder.new(fs, dir:absolute(), entry_maker, initials)
|
||||
local async_finder = AsyncFinder.new(State.new(), fs, dir:absolute(), entry_maker, initials)
|
||||
callback(async_finder, dir)
|
||||
close()
|
||||
end
|
||||
|
||||
@ -117,3 +117,20 @@ function PlenaryAsyncUtil.sleep(ms) end
|
||||
---@field path_tail fun(path: string): string
|
||||
---@field transform_path fun(opts: table, path: string): string
|
||||
---@field buf_is_loaded fun(filename: string): boolean
|
||||
|
||||
---@class TelescopePicker
|
||||
---@field clear_extra_rows fun(self: TelescopePicker, results_bufnr: integer): nil
|
||||
---@field get_row fun(self: TelescopePicker, index: integer): integer
|
||||
---@field manager TelescopeEntryManager|false
|
||||
---@field results_bufnr integer?
|
||||
---@field results_win integer?
|
||||
---@field sorting_strategy 'ascending'|'descending'
|
||||
|
||||
---@class TelescopeEntryManager
|
||||
---@field num_results fun(): integer
|
||||
|
||||
-- NOTE: types for default functions
|
||||
|
||||
---@class WinInfo
|
||||
---@field topline integer
|
||||
---@field botline integer
|
||||
|
||||
Loading…
Reference in New Issue
Block a user