8000 mini.nvim/lua/mini/pick.lua at main · max-farver/mini.nvim · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
3701 lines (3277 loc) · 148 KB

pick.lua

File metadata and controls

3701 lines (3277 loc) · 148 KB
--- to not show icons for some |MiniPick.builtin| pickers (see |MiniPick-examples|).
--- See |MiniPick-source| for more information.
---
--- # Window ~
---
--- `config.window` contains window specific configurations.
---
--- `window.config` defines a (parts of) default floating window config for the main
--- picker window. This can be either a table overriding some parts or a callable
--- returning such table. See |MiniPick-examples| for some examples.
---
--- `window.prompt_caret` defines how caret is displayed in window's prompt.
--- Default: '▏'.
---
--- `window.prompt_prefix` defines what prefix is used in window's prompt.
--- Default: '> '.
MiniPick.config = {
-- Delays (in ms; should be at least 1)
delay = {
-- Delay between forcing asynchronous behavior
async = 10,
-- Delay between computation start and visual feedback about it
busy = 50,
},
-- Keys for performing actions. See `:h MiniPick-actions`.
mappings = {
caret_left = '<Left>',
caret_right = '<Right>',
choose = '<CR>',
choose_in_split = '<C-s>',
choose_in_tabpage = '<C-t>',
choose_in_vsplit = '<C-v>',
choose_marked = '<M-CR>',
delete_char = '<BS>',
delete_char_right = '<Del>',
delete_left = '<C-u>',
delete_word = '<C-w>',
mark = '<C-x>',
mark_all = '<C-a>',
move_down = '<C-n>',
move_start = '<C-g>',
move_up = '<C-p>',
paste = '<C-r>',
refine = '<C-Space>',
refine_marked = '<M-Space>',
scroll_down = '<C-f>',
scroll_left = '<C-h>',
scroll_right = '<C-l>',
scroll_up = '<C-b>',
stop = '<Esc>',
toggle_info = '<S-Tab>',
toggle_preview = '<Tab>',
},
-- General options
options = {
-- Whether to show content from bottom to top
content_from_bottom = false,
-- Whether to cache matches (more speed and memory on repeated prompts)
use_cache = false,
},
-- Source definition. See `:h MiniPick-source`.
source = {
items = nil,
name = nil,
cwd = nil,
match = nil,
show = nil,
preview = nil,
choose = nil,
choose_marked = nil,
},
-- Window related options
window = {
-- Float window config (table or callable returning it)
config = nil,
-- String to use as caret in prompt
prompt_caret = '▏',
-- String to use as prefix in prompt
prompt_prefix = '> ',
},
}
--minidoc_afterlines_end
--- Start picker
---
--- Notes:
--- - If there is currently an active picker, it is properly stopped and new one
--- is started "soon" in the main event-loop (see |vim.schedule()|).
--- - Current window at the moment of this function call is treated as "target".
--- It will be set back as current after |MiniPick.stop()|.
--- See |MiniPick.get_picker_state()| and |MiniPick.set_picker_target_window()|.
---
---@param opts table|nil Options. Should have same structure as |MiniPick.config|.
--- Default values are inferred from there.
--- Usually should have proper |MiniPick-source.items| defined.
---
---@return any Item which was current when picker is stopped; `nil` if aborted.
MiniPick.start = function(opts)
if MiniPick.is_picker_active() then
-- Try proper 'key query process' stop
MiniPick.stop()
-- NOTE: Needs `defer_fn()` for `stop()` to properly finish code flow and
-- not be executed before it
return vim.defer_fn(function()
-- NOTE: if `MiniPick.stop()` still didn't stop, force abort
if MiniPick.is_picker_active() then H.picker_stop(H.pickers.active, true) end
MiniPick.start(opts)
end, 0.5)
end
H.cache = {}
opts = H.validate_picker_opts(opts)
local picker = H.picker_new(opts)
H.pickers.active = picker
H.picker_set_busy(picker, true)
local items = H.expand_callable(opts.source.items)
-- - Set items on next event loop to not block when computing stritems
if H.islist(items) then vim.schedule(function() MiniPick.set_picker_items(items) end) end
H.picker_track_lost_focus(picker)
return H.picker_advance(picker)
end
--- Stop active picker
MiniPick.stop = function()
if not MiniPick.is_picker_active() then return end
H.cache.is_force_stop_advance = true
if H.cache.is_in_getcharstr then vim.api.nvim_feedkeys('\3', 't', true) end
end
--- Refresh active picker
MiniPick.refresh = function()
if not MiniPick.is_picker_active() then return end
H.picker_update(H.pickers.active, false, true)
end
--- Default match
---
--- Filter target stritems to contain query and sort from best to worst matches.
---
--- Implements default value for |MiniPick-source.match|.
---
--- By default (if no special modes apply) it does the following fuzzy matching:
---
--- - Stritem contains query if it contains all its elements verbatim in the same
--- order (possibly with gaps, i.e. not strictly one after another).
--- Note: empty query and empty string element is contained in any string.
---
--- - Sorting is done with the following ordering (same as in |mini.fuzzy|):
--- - The smaller the match width (end column minus start column) the better.
--- - Among same match width, the smaller start column the better.
--- - Among same match width and start column, preserve original order.
---
--- Notes:
--- - Most common interactive usage results into `query` containing one typed
--- character per element.
---
--- # Special modes ~
---
--- - Forced modes:
--- - Query starts with "*": match the rest fuzzy (without other modes).
--- - Query starts with "'": match the rest exactly (without gaps).
---
--- - Place modes:
--- - Query starts with '^': match the rest exactly at start.
--- - Query ends with '$': match the rest exactly at end.
--- - Both modes can be used simultaneously.
---
--- - Grouped: query contains at least one whitespace element. Output is computed
--- as if query is split at whitespace indexes with concatenation between them.
---
--- Precedence of modes:
--- "forced exact" = "forced fuzzy" > "place start/end" > "grouped" > "default"
---
--- # Examples ~
---
--- Assuming `stritems` are `{ '_abc', 'a_bc', 'ab_c', 'abc_' }`, here are some
--- example matches based on prompt (concatenated query): >
---
--- | Prompt | Matches |
--- |--------|------------------------|
--- | abc | All |
--- | *abc | All |
--- | | |
--- | 'abc | abc_, _abc |
--- | *'abc | None (no "'" in items) |
--- | | |
--- | ^abc | abc_ |
--- | *^abc | None (no "^" in items) |
--- | | |
--- | abc$ | _abc |
--- | *abc$ | None (no "$" in items) |
--- | | |
--- | ab c | abc_, _abc, ab_c |
--- | *ab c | None (no " " in items) |
--- <
--- Having query `{ 'ab', 'c' }` is the same as "ab c" prompt.
---
--- You can have a feel of how this works with this command: >lua
---
--- MiniPick.start({ source = { items = { '_abc', 'a_bc', 'ab_c', 'abc_' } } })
--- <
---@param stritems table Array of all stritems.
---@param inds table Array of `stritems` indexes to match. All of them should point
0