diff options
Diffstat (limited to 'lua/telescope/pickers.lua')
| -rw-r--r-- | lua/telescope/pickers.lua | 97 |
1 files changed, 80 insertions, 17 deletions
diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua index 9e5f251..42e37d9 100644 --- a/lua/telescope/pickers.lua +++ b/lua/telescope/pickers.lua @@ -85,7 +85,11 @@ function Picker:new(opts) _find_id = 0, _completion_callbacks = {}, - _multi = MultiSelect:new(), + manager = (type(opts.manager) == "table" and getmetatable(opts.manger) == getmetatable(EntryManager)) + and opts.manager, + _multi = (type(opts._multi) == "table" and getmetatable(opts._multi) == getmetatable(MultiSelect:new())) + and opts._multi + or MultiSelect:new(), track = get_default(opts.track, false), stats = {}, @@ -104,6 +108,8 @@ function Picker:new(opts) border = get_default(opts.border, config.values.border), borderchars = get_default(opts.borderchars, config.values.borderchars), }, + + cache_picker = config.resolve_table_opts(opts.cache_picker, vim.deepcopy(config.values.cache_picker)), }, self) obj.get_window_options = opts.get_window_options or p_window.get_window_options @@ -332,6 +338,7 @@ function Picker:find() if prompt_border_win then vim.api.nvim_win_set_option(prompt_border_win, "winhl", "Normal:TelescopePromptBorder") end + self.prompt_bufnr = prompt_bufnr -- Prompt prefix local prompt_prefix = self.prompt_prefix @@ -416,23 +423,47 @@ function Picker:find() self.finder = new_finder end - self.sorter:_start(prompt) - self.manager = EntryManager:new(self.max_results, self.entry_adder, self.stats) + -- TODO: Entry manager should have a "bulk" setter. This can prevent a lot of redraws from display + if self.cache_picker == false or not (self.cache_picker.is_cached == true) then + self.sorter:_start(prompt) + self.manager = EntryManager:new(self.max_results, self.entry_adder, self.stats) - local process_result = self:get_result_processor(find_id, prompt, debounced_status) - local process_complete = self:get_result_completor(self.results_bufnr, find_id, prompt, status_updater) + local process_result = self:get_result_processor(find_id, prompt, debounced_status) + local process_complete = self:get_result_completor(self.results_bufnr, find_id, prompt, status_updater) - local ok, msg = pcall(function() - self.finder(prompt, process_result, process_complete) - end) + local ok, msg = pcall(function() + self.finder(prompt, process_result, process_complete) + end) - if not ok then - log.warn("Finder failed with msg: ", msg) - end + if not ok then + log.warn("Finder failed with msg: ", msg) + end - local diff_time = (vim.loop.hrtime() - start_time) / 1e6 - if self.debounce and diff_time < self.debounce then - async.util.sleep(self.debounce - diff_time) + local diff_time = (vim.loop.hrtime() - start_time) / 1e6 + if self.debounce and diff_time < self.debounce then + async.util.sleep(self.debounce - diff_time) + end + else + -- resume previous picker + local index = 1 + for entry in self.manager:iter() do + self:entry_adder(index, entry, _, true) + index = index + 1 + end + self.cache_picker.is_cached = false + -- if text changed, required to set anew to restart finder; otherwise hl and selection + if self.cache_picker.cached_prompt ~= self.default_text then + self:reset_prompt() + self:set_prompt(self.default_text) + else + -- scheduling required to apply highlighting and selection appropriately + await_schedule(function() + self:highlight_displayed_rows(self.results_bufnr, self.cache_picker.cached_prompt) + if self.cache_picker.selection_row ~= nil then + self:set_selection(self.cache_picker.selection_row) + end + end) + end end end end) @@ -444,7 +475,6 @@ function Picker:find() self._result_completed = false status_updater { completed = false } - tx.send(...) end, on_detach = function() @@ -463,8 +493,6 @@ function Picker:find() vim.cmd(on_buf_leave) vim.cmd [[augroup END]] - self.prompt_bufnr = prompt_bufnr - local preview_border = preview_opts and preview_opts.border self.preview_border = preview_border local preview_border_win = (preview_border and preview_border.win_id) and preview_border.win_id @@ -1124,6 +1152,41 @@ function pickers.on_close_prompt(prompt_bufnr) local status = state.get_status(prompt_bufnr) local picker = status.picker + if type(picker.cache_picker) == "table" then + local cached_pickers = state.get_global_key "cached_pickers" or {} + + if type(picker.cache_picker.index) == "number" then + if not vim.tbl_isempty(cached_pickers) then + table.remove(cached_pickers, picker.cache_picker.index) + end + end + + -- if picker was disabled post-hoc (e.g. `cache_picker = false` conclude after deletion) + if picker.cache_picker.disabled ~= true then + if picker.cache_picker.limit_entries > 0 then + -- edge case: starting in normal mode and not having run a search means having no manager instantiated + if picker.manager then + picker.manager.linked_states:truncate(picker.cache_picker.limit_entries) + else + picker.manager = EntryManager:new(picker.max_results, picker.entry_adder, picker.stats) + end + end + picker.default_text = picker:_get_prompt() + picker.cache_picker.selection_row = picker._selection_row + picker.cache_picker.cached_prompt = picker:_get_prompt() + picker.cache_picker.is_cached = true + table.insert(cached_pickers, 1, picker) + + -- release pickers + if picker.cache_picker.num_pickers > 0 then + while #cached_pickers > picker.cache_picker.num_pickers do + table.remove(cached_pickers, #cached_pickers) + end + end + state.set_global_key("cached_pickers", cached_pickers) + end + end + if picker.sorter then picker.sorter:_destroy() end |
