feat: allow caching and resuming picker (#1051)
* expose `cache_picker` in telescope.setup to configure caching, see `:h telescope.defaults.cache_picker` * add builtin.resume and builtin.pickers picker
This commit is contained in:
@@ -439,6 +439,8 @@ Built-in functions. Ready to be bound to any key you like. :smile:
|
|||||||
| `builtin.highlights` | Lists all available highlights |
|
| `builtin.highlights` | Lists all available highlights |
|
||||||
| `builtin.current_buffer_fuzzy_find` | Live fuzzy search inside of the currently open buffer |
|
| `builtin.current_buffer_fuzzy_find` | Live fuzzy search inside of the currently open buffer |
|
||||||
| `builtin.current_buffer_tags` | Lists all of the tags for the currently open buffer, with a preview |
|
| `builtin.current_buffer_tags` | Lists all of the tags for the currently open buffer, with a preview |
|
||||||
|
| `builtin.resume` | Lists the results incl. multi-selections of the previous picker |
|
||||||
|
| `builtin.pickers` | Lists the previous pickers incl. multi-selections (see `:h telescope.defaults.cache_picker`) |
|
||||||
|
|
||||||
### Neovim LSP Pickers
|
### Neovim LSP Pickers
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,28 @@ telescope.setup({opts}) *telescope.setup()*
|
|||||||
|
|
||||||
Default: true
|
Default: true
|
||||||
|
|
||||||
|
*telescope.defaults.cache_picker*
|
||||||
|
cache_picker: ~
|
||||||
|
This field handles the configuration for picker caching.
|
||||||
|
By default it is a table, with default values (more below).
|
||||||
|
To disable caching, set it to false.
|
||||||
|
|
||||||
|
Caching preserves all previous multi selections and results and
|
||||||
|
therefore may result in slowdown or increased RAM occupation
|
||||||
|
if too many pickers (`cache_picker.num_pickers`) or entries
|
||||||
|
('cache_picker.limit_entries`) are cached.
|
||||||
|
|
||||||
|
Fields:
|
||||||
|
- num_pickers: The number of pickers to be cached.
|
||||||
|
Set to -1 to preserve all pickers of your session.
|
||||||
|
If passed to a picker, the cached pickers with
|
||||||
|
indices larger than `cache_picker.num_pickers` will
|
||||||
|
be cleared.
|
||||||
|
Default: 1
|
||||||
|
- limit_entries: The amount of entries that will be written in the
|
||||||
|
Default: 1000
|
||||||
|
|
||||||
|
|
||||||
*telescope.defaults.default_mappings*
|
*telescope.defaults.default_mappings*
|
||||||
default_mappings: ~
|
default_mappings: ~
|
||||||
Not recommended to use except for advanced users.
|
Not recommended to use except for advanced users.
|
||||||
@@ -367,8 +389,8 @@ builtin.live_grep({opts}) *builtin.live_grep()*
|
|||||||
{opts} (table) options to pass to the picker
|
{opts} (table) options to pass to the picker
|
||||||
|
|
||||||
Fields: ~
|
Fields: ~
|
||||||
{cwd} (string) directory path to search from (default
|
{cwd} (string) root dir to search from (default is cwd,
|
||||||
is cwd, use utils.buffer_dir() to search
|
use utils.buffer_dir() to search
|
||||||
relative to open buffer)
|
relative to open buffer)
|
||||||
{grep_open_files} (boolean) if true, restrict search to open files
|
{grep_open_files} (boolean) if true, restrict search to open files
|
||||||
only, mutually exclusive with
|
only, mutually exclusive with
|
||||||
@@ -388,8 +410,8 @@ builtin.grep_string({opts}) *builtin.grep_string()*
|
|||||||
{opts} (table) options to pass to the picker
|
{opts} (table) options to pass to the picker
|
||||||
|
|
||||||
Fields: ~
|
Fields: ~
|
||||||
{cwd} (string) directory path to search from (default
|
{cwd} (string) root dir to search from (default is cwd,
|
||||||
is cwd, use utils.buffer_dir() to search
|
use utils.buffer_dir() to search
|
||||||
relative to open buffer)
|
relative to open buffer)
|
||||||
{search} (string) the query to search
|
{search} (string) the query to search
|
||||||
{search_dirs} (table) directory/directories to search in
|
{search_dirs} (table) directory/directories to search in
|
||||||
@@ -408,9 +430,9 @@ builtin.find_files({opts}) *builtin.find_files()*
|
|||||||
{opts} (table) options to pass to the picker
|
{opts} (table) options to pass to the picker
|
||||||
|
|
||||||
Fields: ~
|
Fields: ~
|
||||||
{cwd} (string) directory path to search from (default is
|
{cwd} (string) root dir to search from (default is cwd, use
|
||||||
cwd, use utils.buffer_dir() to search
|
utils.buffer_dir() to search relative to
|
||||||
relative to open buffer)
|
open buffer)
|
||||||
{find_command} (table) command line arguments for `find_files` to
|
{find_command} (table) command line arguments for `find_files` to
|
||||||
use for the search, overrides default config
|
use for the search, overrides default config
|
||||||
{follow} (boolean) if true, follows symlinks (i.e. uses `-L`
|
{follow} (boolean) if true, follows symlinks (i.e. uses `-L`
|
||||||
@@ -446,8 +468,8 @@ builtin.file_browser({opts}) *builtin.file_browser()*
|
|||||||
{opts} (table) options to pass to the picker
|
{opts} (table) options to pass to the picker
|
||||||
|
|
||||||
Fields: ~
|
Fields: ~
|
||||||
{cwd} (string) directory path to browse (default is cwd, use
|
{cwd} (string) root dir to browse from (default is cwd, use
|
||||||
utils.buffer_dir() to browse relative to open
|
utils.buffer_dir() to search relative to open
|
||||||
buffer)
|
buffer)
|
||||||
{depth} (number) file tree depth to display (default is 1)
|
{depth} (number) file tree depth to display (default is 1)
|
||||||
{dir_icon} (string) change the icon for a directory. default:
|
{dir_icon} (string) change the icon for a directory. default:
|
||||||
@@ -679,6 +701,35 @@ builtin.search_history({opts}) *builtin.search_history()*
|
|||||||
{opts} (table) options to pass to the picker
|
{opts} (table) options to pass to the picker
|
||||||
|
|
||||||
|
|
||||||
|
builtin.resume({opts}) *builtin.resume()*
|
||||||
|
Opens the previous picker in the identical state (incl. multi selections)
|
||||||
|
- Notes:
|
||||||
|
- Requires `cache_picker` in setup or when having invoked pickers, see
|
||||||
|
|telescope.defaults.cache_picker|
|
||||||
|
|
||||||
|
|
||||||
|
Parameters: ~
|
||||||
|
{opts} (table) options to pass to the picker
|
||||||
|
|
||||||
|
Fields: ~
|
||||||
|
{cache_index} (number) what picker to resume, where 1 denotes most
|
||||||
|
recent (default 1)
|
||||||
|
|
||||||
|
|
||||||
|
builtin.pickers({opts}) *builtin.pickers()*
|
||||||
|
Opens a picker over previously cached pickers in there preserved states
|
||||||
|
(incl. multi selections)
|
||||||
|
- Default keymaps:
|
||||||
|
- `<C-x>`: delete the selected cached picker
|
||||||
|
- Notes:
|
||||||
|
- Requires `cache_picker` in setup or when having invoked pickers, see
|
||||||
|
|telescope.defaults.cache_picker|
|
||||||
|
|
||||||
|
|
||||||
|
Parameters: ~
|
||||||
|
{opts} (table) options to pass to the picker
|
||||||
|
|
||||||
|
|
||||||
builtin.vim_options({opts}) *builtin.vim_options()*
|
builtin.vim_options({opts}) *builtin.vim_options()*
|
||||||
Lists vim options, allows you to edit the current value on `<cr>`
|
Lists vim options, allows you to edit the current value on `<cr>`
|
||||||
|
|
||||||
@@ -1582,6 +1633,16 @@ actions.cycle_previewers_prev({prompt_bufnr})*actions.cycle_previewers_prev()*
|
|||||||
{prompt_bufnr} (number) The prompt bufnr
|
{prompt_bufnr} (number) The prompt bufnr
|
||||||
|
|
||||||
|
|
||||||
|
actions.remove_selected_picker({prompt_bufnr})*actions.remove_selected_picker()*
|
||||||
|
Removes the selected picker in |builtin.pickers|.
|
||||||
|
This action is not mapped by default and only intended for
|
||||||
|
|builtin.pickers|.
|
||||||
|
|
||||||
|
|
||||||
|
Parameters: ~
|
||||||
|
{prompt_bufnr} (number) The prompt bufnr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
*telescope.actions.state*
|
*telescope.actions.state*
|
||||||
|
|||||||
@@ -832,6 +832,21 @@ actions.cycle_previewers_prev = function(prompt_bufnr)
|
|||||||
actions.get_current_picker(prompt_bufnr):cycle_previewers(-1)
|
actions.get_current_picker(prompt_bufnr):cycle_previewers(-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Removes the selected picker in |builtin.pickers|.<br>
|
||||||
|
--- This action is not mapped by default and only intended for |builtin.pickers|.
|
||||||
|
---@param prompt_bufnr number: The prompt bufnr
|
||||||
|
actions.remove_selected_picker = function(prompt_bufnr)
|
||||||
|
local current_picker = action_state.get_current_picker(prompt_bufnr)
|
||||||
|
local selection_index = current_picker:get_index(current_picker:get_selection_row())
|
||||||
|
local cached_pickers = state.get_global_key "cached_pickers"
|
||||||
|
current_picker:delete_selection(function()
|
||||||
|
table.remove(cached_pickers, selection_index)
|
||||||
|
end)
|
||||||
|
if #cached_pickers == 0 then
|
||||||
|
actions.close(prompt_bufnr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- ==================================================
|
-- ==================================================
|
||||||
-- Transforms modules and sets the corect metatables.
|
-- Transforms modules and sets the corect metatables.
|
||||||
-- ==================================================
|
-- ==================================================
|
||||||
|
|||||||
@@ -215,4 +215,41 @@ function LinkedList:ipairs()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function LinkedList:truncate(max_results)
|
||||||
|
if max_results >= self.size then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local current_node
|
||||||
|
if max_results < self.size - max_results then
|
||||||
|
local index = 1
|
||||||
|
current_node = self.head
|
||||||
|
while index < max_results do
|
||||||
|
local node = current_node
|
||||||
|
if not node.next then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
current_node = current_node.next
|
||||||
|
index = index + 1
|
||||||
|
end
|
||||||
|
self.size = max_results
|
||||||
|
else
|
||||||
|
current_node = self.tail
|
||||||
|
while self.size > max_results do
|
||||||
|
if current_node.prev == nil then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
current_node = current_node.prev
|
||||||
|
self.size = self.size - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.tail = current_node
|
||||||
|
self.tail.next = nil
|
||||||
|
if max_results < self.track_at then
|
||||||
|
self.track_at = max_results
|
||||||
|
self.tracked = current_node.item
|
||||||
|
self._tracked_node = current_node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return LinkedList
|
return LinkedList
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ local builtin = {}
|
|||||||
|
|
||||||
--- Search for a string and get results live as you type (respecting .gitignore)
|
--- Search for a string and get results live as you type (respecting .gitignore)
|
||||||
---@param opts table: options to pass to the picker
|
---@param opts table: options to pass to the picker
|
||||||
---@field cwd string: directory path to search from (default is cwd, use utils.buffer_dir() to search relative to open buffer)
|
---@field cwd string: root dir to search from (default is cwd, use utils.buffer_dir() to search relative to open buffer)
|
||||||
---@field grep_open_files boolean: if true, restrict search to open files only, mutually exclusive with `search_dirs`
|
---@field grep_open_files boolean: if true, restrict search to open files only, mutually exclusive with `search_dirs`
|
||||||
---@field search_dirs table: directory/directories to search in, mutually exclusive with `grep_open_files`
|
---@field search_dirs table: directory/directories to search in, mutually exclusive with `grep_open_files`
|
||||||
---@field additional_args function: function(opts) which returns a table of additional arguments to be passed on
|
---@field additional_args function: function(opts) which returns a table of additional arguments to be passed on
|
||||||
@@ -76,7 +76,7 @@ builtin.live_grep = require("telescope.builtin.files").live_grep
|
|||||||
|
|
||||||
--- Searches for the string under your cursor in your current working directory
|
--- Searches for the string under your cursor in your current working directory
|
||||||
---@param opts table: options to pass to the picker
|
---@param opts table: options to pass to the picker
|
||||||
---@field cwd string: directory path to search from (default is cwd, use utils.buffer_dir() to search relative to open buffer)
|
---@field cwd string: root dir to search from (default is cwd, use utils.buffer_dir() to search relative to open buffer)
|
||||||
---@field search string: the query to search
|
---@field search string: the query to search
|
||||||
---@field search_dirs table: directory/directories to search in
|
---@field search_dirs table: directory/directories to search in
|
||||||
---@field use_regex boolean: if true, special characters won't be escaped, allows for using regex (default is false)
|
---@field use_regex boolean: if true, special characters won't be escaped, allows for using regex (default is false)
|
||||||
@@ -85,7 +85,7 @@ builtin.grep_string = require("telescope.builtin.files").grep_string
|
|||||||
|
|
||||||
--- Search for files (respecting .gitignore)
|
--- Search for files (respecting .gitignore)
|
||||||
---@param opts table: options to pass to the picker
|
---@param opts table: options to pass to the picker
|
||||||
---@field cwd string: directory path to search from (default is cwd, use utils.buffer_dir() to search relative to open buffer)
|
---@field cwd string: root dir to search from (default is cwd, use utils.buffer_dir() to search relative to open buffer)
|
||||||
---@field find_command table: command line arguments for `find_files` to use for the search, overrides default config
|
---@field find_command table: command line arguments for `find_files` to use for the search, overrides default config
|
||||||
---@field follow boolean: if true, follows symlinks (i.e. uses `-L` flag for the `find` command)
|
---@field follow boolean: if true, follows symlinks (i.e. uses `-L` flag for the `find` command)
|
||||||
---@field hidden boolean: determines whether to show hidden files or not (default is false)
|
---@field hidden boolean: determines whether to show hidden files or not (default is false)
|
||||||
@@ -105,7 +105,7 @@ builtin.fd = builtin.find_files
|
|||||||
--- create the file `init.lua` inside of `lua/telescope` and will create the necessary folders (similar to how
|
--- create the file `init.lua` inside of `lua/telescope` and will create the necessary folders (similar to how
|
||||||
--- `mkdir -p` would work) if they do not already exist
|
--- `mkdir -p` would work) if they do not already exist
|
||||||
---@param opts table: options to pass to the picker
|
---@param opts table: options to pass to the picker
|
||||||
---@field cwd string: directory path to browse (default is cwd, use utils.buffer_dir() to browse relative to open buffer)
|
---@field cwd string: root dir to browse from (default is cwd, use utils.buffer_dir() to search relative to open buffer)
|
||||||
---@field depth number: file tree depth to display (default is 1)
|
---@field depth number: file tree depth to display (default is 1)
|
||||||
---@field dir_icon string: change the icon for a directory. default:
|
---@field dir_icon string: change the icon for a directory. default:
|
||||||
---@field hidden boolean: determines whether to show hidden files or not (default is false)
|
---@field hidden boolean: determines whether to show hidden files or not (default is false)
|
||||||
@@ -243,6 +243,21 @@ builtin.command_history = require("telescope.builtin.internal").command_history
|
|||||||
---@param opts table: options to pass to the picker
|
---@param opts table: options to pass to the picker
|
||||||
builtin.search_history = require("telescope.builtin.internal").search_history
|
builtin.search_history = require("telescope.builtin.internal").search_history
|
||||||
|
|
||||||
|
--- Opens the previous picker in the identical state (incl. multi selections)
|
||||||
|
--- - Notes:
|
||||||
|
--- - Requires `cache_picker` in setup or when having invoked pickers, see |telescope.defaults.cache_picker|
|
||||||
|
---@param opts table: options to pass to the picker
|
||||||
|
---@field cache_index number: what picker to resume, where 1 denotes most recent (default 1)
|
||||||
|
builtin.resume = require("telescope.builtin.internal").resume
|
||||||
|
|
||||||
|
--- Opens a picker over previously cached pickers in there preserved states (incl. multi selections)
|
||||||
|
--- - Default keymaps:
|
||||||
|
--- - `<C-x>`: delete the selected cached picker
|
||||||
|
--- - Notes:
|
||||||
|
--- - Requires `cache_picker` in setup or when having invoked pickers, see |telescope.defaults.cache_picker|
|
||||||
|
---@param opts table: options to pass to the picker
|
||||||
|
builtin.pickers = require("telescope.builtin.internal").pickers
|
||||||
|
|
||||||
--- Lists vim options, allows you to edit the current value on `<cr>`
|
--- Lists vim options, allows you to edit the current value on `<cr>`
|
||||||
---@param opts table: options to pass to the picker
|
---@param opts table: options to pass to the picker
|
||||||
builtin.vim_options = require("telescope.builtin.internal").vim_options
|
builtin.vim_options = require("telescope.builtin.internal").vim_options
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ local make_entry = require "telescope.make_entry"
|
|||||||
local Path = require "plenary.path"
|
local Path = require "plenary.path"
|
||||||
local pickers = require "telescope.pickers"
|
local pickers = require "telescope.pickers"
|
||||||
local previewers = require "telescope.previewers"
|
local previewers = require "telescope.previewers"
|
||||||
|
local p_window = require "telescope.pickers.window"
|
||||||
local sorters = require "telescope.sorters"
|
local sorters = require "telescope.sorters"
|
||||||
|
local state = require "telescope.state"
|
||||||
local utils = require "telescope.utils"
|
local utils = require "telescope.utils"
|
||||||
|
|
||||||
local conf = require("telescope.config").values
|
local conf = require("telescope.config").values
|
||||||
@@ -71,6 +73,80 @@ internal.builtin = function(opts)
|
|||||||
}):find()
|
}):find()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
internal.resume = function(opts)
|
||||||
|
opts = opts or {}
|
||||||
|
opts.cache_index = vim.F.if_nil(opts.cache_index, 1)
|
||||||
|
|
||||||
|
local cached_pickers = state.get_global_key "cached_pickers"
|
||||||
|
if cached_pickers == nil or vim.tbl_isempty(cached_pickers) then
|
||||||
|
print "No picker(s) cached."
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local picker = cached_pickers[opts.cache_index]
|
||||||
|
if picker == nil then
|
||||||
|
print("Index too large as there are only %s pickers cached", #cached_pickers)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- reset layout strategy and get_window_options if default as only one is valid
|
||||||
|
-- and otherwise unclear which was actually set
|
||||||
|
if picker.layout_strategy == conf.layout_strategy then
|
||||||
|
picker.layout_strategy = nil
|
||||||
|
end
|
||||||
|
if picker.get_window_options == p_window.get_window_options then
|
||||||
|
picker.get_window_options = nil
|
||||||
|
end
|
||||||
|
picker.cache_picker.index = opts.cache_index
|
||||||
|
|
||||||
|
-- avoid partial `opts.cache_picker` at picker creation
|
||||||
|
if opts.cache_picker ~= false then
|
||||||
|
picker.cache_picker = vim.tbl_extend("keep", opts.cache_picker or {}, picker.cache_picker)
|
||||||
|
else
|
||||||
|
picker.cache_picker.disabled = true
|
||||||
|
end
|
||||||
|
opts.cache_picker = nil
|
||||||
|
pickers.new(opts, picker):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
internal.pickers = function(opts)
|
||||||
|
local cached_pickers = state.get_global_key "cached_pickers"
|
||||||
|
if cached_pickers == nil or vim.tbl_isempty(cached_pickers) then
|
||||||
|
print "No picker(s) cached."
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
opts = opts or {}
|
||||||
|
|
||||||
|
-- clear cache picker for immediate pickers.new and pass option to resumed picker
|
||||||
|
if opts.cache_picker ~= nil then
|
||||||
|
opts._cache_picker = opts.cache_picker
|
||||||
|
opts.cache_picker = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
pickers.new(opts, {
|
||||||
|
prompt_title = "Pickers",
|
||||||
|
finder = finders.new_table {
|
||||||
|
results = cached_pickers,
|
||||||
|
entry_maker = make_entry.gen_from_picker(opts),
|
||||||
|
},
|
||||||
|
previewer = previewers.pickers.new(opts),
|
||||||
|
sorter = conf.generic_sorter(opts),
|
||||||
|
cache_picker = false,
|
||||||
|
attach_mappings = function(_, map)
|
||||||
|
actions.select_default:replace(function(prompt_bufnr)
|
||||||
|
local current_picker = action_state.get_current_picker(prompt_bufnr)
|
||||||
|
local selection_index = current_picker:get_index(current_picker:get_selection_row())
|
||||||
|
actions._close(prompt_bufnr, cached_pickers[selection_index].initial_mode == "insert")
|
||||||
|
opts.cache_picker = opts._cache_picker
|
||||||
|
opts["cache_index"] = selection_index
|
||||||
|
internal.resume(opts)
|
||||||
|
end)
|
||||||
|
map("i", "<C-x>", actions.remove_selected_picker)
|
||||||
|
map("n", "<C-x>", actions.remove_selected_picker)
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
}):find()
|
||||||
|
end
|
||||||
|
|
||||||
internal.planets = function(opts)
|
internal.planets = function(opts)
|
||||||
local show_pluto = opts.show_pluto or false
|
local show_pluto = opts.show_pluto or false
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,22 @@ local smarter_depth_2_extend = function(priority, base)
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local resolve_table_opts = function(priority, base)
|
||||||
|
if priority == false or (priority == nil and base == false) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if priority == nil and type(base) == "table" then
|
||||||
|
return base
|
||||||
|
end
|
||||||
|
return smarter_depth_2_extend(priority, base)
|
||||||
|
end
|
||||||
|
|
||||||
-- TODO: Add other major configuration points here.
|
-- TODO: Add other major configuration points here.
|
||||||
-- selection_strategy
|
-- selection_strategy
|
||||||
|
|
||||||
local config = {}
|
local config = {}
|
||||||
config.smarter_depth_2_extend = smarter_depth_2_extend
|
config.smarter_depth_2_extend = smarter_depth_2_extend
|
||||||
|
config.resolve_table_opts = resolve_table_opts
|
||||||
|
|
||||||
config.values = _TelescopeConfigurationValues
|
config.values = _TelescopeConfigurationValues
|
||||||
config.descriptions = {}
|
config.descriptions = {}
|
||||||
@@ -286,6 +297,33 @@ local telescope_defaults = {
|
|||||||
]],
|
]],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cache_picker = {
|
||||||
|
{
|
||||||
|
num_pickers = 1,
|
||||||
|
limit_entries = 1000,
|
||||||
|
},
|
||||||
|
[[
|
||||||
|
This field handles the configuration for picker caching.
|
||||||
|
By default it is a table, with default values (more below).
|
||||||
|
To disable caching, set it to false.
|
||||||
|
|
||||||
|
Caching preserves all previous multi selections and results and
|
||||||
|
therefore may result in slowdown or increased RAM occupation
|
||||||
|
if too many pickers (`cache_picker.num_pickers`) or entries
|
||||||
|
('cache_picker.limit_entries`) are cached.
|
||||||
|
|
||||||
|
Fields:
|
||||||
|
- num_pickers: The number of pickers to be cached.
|
||||||
|
Set to -1 to preserve all pickers of your session.
|
||||||
|
If passed to a picker, the cached pickers with
|
||||||
|
indices larger than `cache_picker.num_pickers` will
|
||||||
|
be cleared.
|
||||||
|
Default: 1
|
||||||
|
- limit_entries: The amount of entries that will be written in the
|
||||||
|
Default: 1000
|
||||||
|
]],
|
||||||
|
},
|
||||||
|
|
||||||
-- Builtin configuration
|
-- Builtin configuration
|
||||||
|
|
||||||
-- List that will be executed.
|
-- List that will be executed.
|
||||||
@@ -416,7 +454,7 @@ function config.set_defaults(user_defaults, tele_defaults)
|
|||||||
vim.tbl_deep_extend("keep", if_nil(config.values[name], {}), if_nil(default_val, {}))
|
vim.tbl_deep_extend("keep", if_nil(config.values[name], {}), if_nil(default_val, {}))
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
if name == "history" then
|
if name == "history" or name == "cache_picker" then
|
||||||
if user_defaults[name] == false or config.values[name] == false then
|
if user_defaults[name] == false or config.values[name] == false then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -662,6 +662,32 @@ function make_entry.gen_from_highlights()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function make_entry.gen_from_picker(opts)
|
||||||
|
local displayer = entry_display.create {
|
||||||
|
separator = " ",
|
||||||
|
items = {
|
||||||
|
{ width = 30 },
|
||||||
|
{ remaining = true },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local make_display = function(entry)
|
||||||
|
return displayer {
|
||||||
|
entry.value.prompt_title,
|
||||||
|
entry.value.default_text,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(entry)
|
||||||
|
return {
|
||||||
|
value = entry,
|
||||||
|
text = entry.prompt_title,
|
||||||
|
ordinal = string.format("%s %s", entry.prompt_title, utils.get_default(entry.default_text, "")),
|
||||||
|
display = make_display,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function make_entry.gen_from_buffer_lines(opts)
|
function make_entry.gen_from_buffer_lines(opts)
|
||||||
local displayer = entry_display.create {
|
local displayer = entry_display.create {
|
||||||
separator = " │ ",
|
separator = " │ ",
|
||||||
|
|||||||
@@ -85,7 +85,11 @@ function Picker:new(opts)
|
|||||||
|
|
||||||
_find_id = 0,
|
_find_id = 0,
|
||||||
_completion_callbacks = {},
|
_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),
|
track = get_default(opts.track, false),
|
||||||
stats = {},
|
stats = {},
|
||||||
@@ -104,6 +108,8 @@ function Picker:new(opts)
|
|||||||
border = get_default(opts.border, config.values.border),
|
border = get_default(opts.border, config.values.border),
|
||||||
borderchars = get_default(opts.borderchars, config.values.borderchars),
|
borderchars = get_default(opts.borderchars, config.values.borderchars),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cache_picker = config.resolve_table_opts(opts.cache_picker, vim.deepcopy(config.values.cache_picker)),
|
||||||
}, self)
|
}, self)
|
||||||
|
|
||||||
obj.get_window_options = opts.get_window_options or p_window.get_window_options
|
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
|
if prompt_border_win then
|
||||||
vim.api.nvim_win_set_option(prompt_border_win, "winhl", "Normal:TelescopePromptBorder")
|
vim.api.nvim_win_set_option(prompt_border_win, "winhl", "Normal:TelescopePromptBorder")
|
||||||
end
|
end
|
||||||
|
self.prompt_bufnr = prompt_bufnr
|
||||||
|
|
||||||
-- Prompt prefix
|
-- Prompt prefix
|
||||||
local prompt_prefix = self.prompt_prefix
|
local prompt_prefix = self.prompt_prefix
|
||||||
@@ -416,6 +423,8 @@ function Picker:find()
|
|||||||
self.finder = new_finder
|
self.finder = new_finder
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 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.sorter:_start(prompt)
|
||||||
self.manager = EntryManager:new(self.max_results, self.entry_adder, self.stats)
|
self.manager = EntryManager:new(self.max_results, self.entry_adder, self.stats)
|
||||||
|
|
||||||
@@ -434,6 +443,28 @@ function Picker:find()
|
|||||||
if self.debounce and diff_time < self.debounce then
|
if self.debounce and diff_time < self.debounce then
|
||||||
async.util.sleep(self.debounce - diff_time)
|
async.util.sleep(self.debounce - diff_time)
|
||||||
end
|
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
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -444,7 +475,6 @@ function Picker:find()
|
|||||||
|
|
||||||
self._result_completed = false
|
self._result_completed = false
|
||||||
status_updater { completed = false }
|
status_updater { completed = false }
|
||||||
|
|
||||||
tx.send(...)
|
tx.send(...)
|
||||||
end,
|
end,
|
||||||
on_detach = function()
|
on_detach = function()
|
||||||
@@ -463,8 +493,6 @@ function Picker:find()
|
|||||||
vim.cmd(on_buf_leave)
|
vim.cmd(on_buf_leave)
|
||||||
vim.cmd [[augroup END]]
|
vim.cmd [[augroup END]]
|
||||||
|
|
||||||
self.prompt_bufnr = prompt_bufnr
|
|
||||||
|
|
||||||
local preview_border = preview_opts and preview_opts.border
|
local preview_border = preview_opts and preview_opts.border
|
||||||
self.preview_border = preview_border
|
self.preview_border = preview_border
|
||||||
local preview_border_win = (preview_border and preview_border.win_id) and preview_border.win_id
|
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 status = state.get_status(prompt_bufnr)
|
||||||
local picker = status.picker
|
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
|
if picker.sorter then
|
||||||
picker.sorter:_destroy()
|
picker.sorter:_destroy()
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -247,6 +247,8 @@ previewers.new_buffer_previewer = function(opts)
|
|||||||
buf_delete(bufnr)
|
buf_delete(bufnr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- enable resuming picker with existing previewer to avoid lookup of deleted bufs
|
||||||
|
bufname_table = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
function opts.preview_fn(self, entry, status)
|
function opts.preview_fn(self, entry, status)
|
||||||
@@ -853,6 +855,83 @@ previewers.highlights = defaulter(function(_)
|
|||||||
}
|
}
|
||||||
end, {})
|
end, {})
|
||||||
|
|
||||||
|
previewers.pickers = defaulter(function(_)
|
||||||
|
local ns_telescope_multiselection = vim.api.nvim_create_namespace "telescope_mulitselection"
|
||||||
|
local get_row = function(picker, preview_height, index)
|
||||||
|
if picker.sorting_strategy == "ascending" then
|
||||||
|
return index - 1
|
||||||
|
else
|
||||||
|
return preview_height - index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return previewers.new_buffer_previewer {
|
||||||
|
|
||||||
|
dyn_title = function(_, entry)
|
||||||
|
if entry.value.default_text and entry.value.default_text ~= "" then
|
||||||
|
return string.format("%s ─ %s", entry.value.prompt_title, entry.value.default_text)
|
||||||
|
end
|
||||||
|
return entry.value.prompt_title
|
||||||
|
end,
|
||||||
|
|
||||||
|
get_buffer_by_name = function(_, entry)
|
||||||
|
return tostring(entry.value.prompt_bufnr)
|
||||||
|
end,
|
||||||
|
|
||||||
|
teardown = function(self)
|
||||||
|
if self.state and self.state.last_set_bufnr and vim.api.nvim_buf_is_valid(self.state.last_set_bufnr) then
|
||||||
|
vim.api.nvim_buf_clear_namespace(self.state.last_set_bufnr, ns_telescope_multiselection, 0, -1)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
define_preview = function(self, entry, status)
|
||||||
|
putils.with_preview_window(status, nil, function()
|
||||||
|
local ns_telescope_entry = vim.api.nvim_create_namespace "telescope_entry"
|
||||||
|
local preview_height = vim.api.nvim_win_get_height(status.preview_win)
|
||||||
|
|
||||||
|
if self.state.bufname then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local picker = entry.value
|
||||||
|
-- prefill buffer to be able to set lines individually
|
||||||
|
local placeholder = utils.repeated_table(preview_height, "")
|
||||||
|
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, placeholder)
|
||||||
|
|
||||||
|
for index = 1, math.min(preview_height, picker.manager:num_results()) do
|
||||||
|
local row = get_row(picker, preview_height, index)
|
||||||
|
local e = picker.manager:get_entry(index)
|
||||||
|
local display, display_highlight = e:display()
|
||||||
|
|
||||||
|
vim.api.nvim_buf_set_lines(self.state.bufnr, row, row + 1, false, { display })
|
||||||
|
|
||||||
|
if display_highlight ~= nil then
|
||||||
|
for _, hl_block in ipairs(display_highlight) do
|
||||||
|
vim.api.nvim_buf_add_highlight(
|
||||||
|
self.state.bufnr,
|
||||||
|
ns_telescope_entry,
|
||||||
|
hl_block[2],
|
||||||
|
row,
|
||||||
|
hl_block[1][1],
|
||||||
|
hl_block[1][2]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if picker._multi:is_selected(e) then
|
||||||
|
vim.api.nvim_buf_add_highlight(
|
||||||
|
self.state.bufnr,
|
||||||
|
ns_telescope_multiselection,
|
||||||
|
"TelescopeMultiSelection",
|
||||||
|
row,
|
||||||
|
0,
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end, {})
|
||||||
|
|
||||||
previewers.display_content = defaulter(function(_)
|
previewers.display_content = defaulter(function(_)
|
||||||
return previewers.new_buffer_previewer {
|
return previewers.new_buffer_previewer {
|
||||||
define_preview = function(self, entry, status)
|
define_preview = function(self, entry, status)
|
||||||
|
|||||||
@@ -306,6 +306,7 @@ previewers.man = buffer_previewer.man
|
|||||||
previewers.autocommands = buffer_previewer.autocommands
|
previewers.autocommands = buffer_previewer.autocommands
|
||||||
previewers.highlights = buffer_previewer.highlights
|
previewers.highlights = buffer_previewer.highlights
|
||||||
previewers.buffers = buffer_previewer.buffers
|
previewers.buffers = buffer_previewer.buffers
|
||||||
|
previewers.pickers = buffer_previewer.pickers
|
||||||
|
|
||||||
--- A deprecated way of displaying content more easily. Was written at a time,
|
--- A deprecated way of displaying content more easily. Was written at a time,
|
||||||
--- where the buffer_previewer interface wasn't present. Nowadays it's easier
|
--- where the buffer_previewer interface wasn't present. Nowadays it's easier
|
||||||
|
|||||||
Reference in New Issue
Block a user