docs: functions in pickers.lua (#1554)

This commit is contained in:
Luke Kershaw
2021-12-05 08:45:50 +00:00
committed by GitHub
parent d0083f9e4c
commit e9759b0405

View File

@@ -35,8 +35,9 @@ local pickers = {}
-- TODO: Add overscroll option for results buffer -- TODO: Add overscroll option for results buffer
---@class Picker
--- Picker is the main UI that shows up to interact w/ your results. --- Picker is the main UI that shows up to interact w/ your results.
-- Takes a filter & a previewr -- Takes a filter & a previewer
local Picker = {} local Picker = {}
Picker.__index = Picker Picker.__index = Picker
@@ -161,8 +162,8 @@ end
--- Take an index and get a row. --- Take an index and get a row.
---@note: Rows are 0-indexed, and `index` is 1 indexed (table index) ---@note: Rows are 0-indexed, and `index` is 1 indexed (table index)
---@param index number: The index in line_manager ---@param index number: the index in line_manager
---@return number: The row for the picker to display in ---@return number: the row for the picker to display in
function Picker:get_row(index) function Picker:get_row(index)
if self.sorting_strategy == "ascending" then if self.sorting_strategy == "ascending" then
return index - 1 return index - 1
@@ -183,6 +184,8 @@ function Picker:get_index(row)
end end
end end
--- Get the row number of the "best" entry
---@return number: the number of the "reset" row
function Picker:get_reset_row() function Picker:get_reset_row()
if self.sorting_strategy == "ascending" then if self.sorting_strategy == "ascending" then
return 0 return 0
@@ -191,12 +194,17 @@ function Picker:get_reset_row()
end end
end end
--- Check if the picker is no longer in use
---@return boolean|nil: `true` if picker is closed, `nil` otherwise
function Picker:is_done() function Picker:is_done()
if not self.manager then if not self.manager then
return true return true
end end
end end
--- Clear rows that are after the final remaining entry
---@note: useful when number of remaining results is narrowed down
---@param results_bufnr number: the buffer number of the results buffer
function Picker:clear_extra_rows(results_bufnr) function Picker:clear_extra_rows(results_bufnr)
if self:is_done() then if self:is_done() then
log.trace "Not clearing due to being already complete" log.trace "Not clearing due to being already complete"
@@ -235,6 +243,11 @@ function Picker:clear_extra_rows(results_bufnr)
log.trace("Clearing:", worst_line) log.trace("Clearing:", worst_line)
end end
--- Highlight the entry corresponding to the given row
---@param results_bufnr number: the buffer number of the results buffer
---@param prompt table: table with information about the prompt buffer
---@param display string: the text corresponding to the given row
---@param row number: the number of the chosen row
function Picker:highlight_one_row(results_bufnr, prompt, display, row) function Picker:highlight_one_row(results_bufnr, prompt, display, row)
if not self.sorter.highlighter then if not self.sorter.highlighter then
return return
@@ -267,6 +280,9 @@ function Picker:highlight_one_row(results_bufnr, prompt, display, row)
self.highlighter:hi_multiselect(row, self:is_multi_selected(entry)) self.highlighter:hi_multiselect(row, self:is_multi_selected(entry))
end end
--- Check if the given row number can be selected
---@param row number: the number of the chosen row in the results buffer
---@return boolean
function Picker:can_select_row(row) function Picker:can_select_row(row)
if self.sorting_strategy == "ascending" then if self.sorting_strategy == "ascending" then
return row <= self.manager:num_results() return row <= self.manager:num_results()
@@ -275,6 +291,7 @@ function Picker:can_select_row(row)
end end
end end
--TODO: document what `find_id` is for
function Picker:_next_find_id() function Picker:_next_find_id()
local find_id = self._find_id + 1 local find_id = self._find_id + 1
self._find_id = find_id self._find_id = find_id
@@ -282,6 +299,10 @@ function Picker:_next_find_id()
return find_id return find_id
end end
--- A helper function for creating each of the windows in a picker
---@param bufnr number: the buffer number to be used in the window
---@param popup_opts table: options to pass to `popup.create`
---@param nowrap boolean: is |'wrap'| disabled in the created window
function Picker:_create_window(bufnr, popup_opts, nowrap) function Picker:_create_window(bufnr, popup_opts, nowrap)
local what = bufnr or "" local what = bufnr or ""
local win, opts = popup.create(what, popup_opts) local win, opts = popup.create(what, popup_opts)
@@ -297,6 +318,8 @@ function Picker:_create_window(bufnr, popup_opts, nowrap)
return win, opts, border_win return win, opts, border_win
end end
--- Opens the given picker for the user to interact with
---@note: this is the main function for pickers, as it actually creates the interface for users
function Picker:find() function Picker:find()
self:close_existing_pickers() self:close_existing_pickers()
self:reset_selection() self:reset_selection()
@@ -514,6 +537,7 @@ function Picker:find()
main_loop() main_loop()
end end
--- A helper function to update picker windows when layout options are changed
function Picker:recalculate_layout() function Picker:recalculate_layout()
local line_count = vim.o.lines - vim.o.cmdheight local line_count = vim.o.lines - vim.o.cmdheight
if vim.o.laststatus ~= 0 then if vim.o.laststatus ~= 0 then
@@ -607,6 +631,7 @@ local update_scroll = function(win, oldinfo, oldcursor, strategy, buf_maxline)
end end
end end
--- A wrapper for `Picker:recalculate_layout()` that also handles maintaining cursor position
function Picker:full_layout_update() function Picker:full_layout_update()
local oldinfo = vim.fn.getwininfo(self.results_win)[1] local oldinfo = vim.fn.getwininfo(self.results_win)[1]
local oldcursor = vim.api.nvim_win_get_cursor(self.results_win) local oldcursor = vim.api.nvim_win_get_cursor(self.results_win)
@@ -682,6 +707,9 @@ function Picker:set_prompt(str)
vim.api.nvim_feedkeys(str, "n", false) vim.api.nvim_feedkeys(str, "n", false)
end end
--- Closes the windows for the prompt, results and preview
---@param status table: table containing information on the picker
--- and associated windows. Generally obtained from `state.get_status`
function Picker.close_windows(status) function Picker.close_windows(status)
local prompt_win = status.prompt_win local prompt_win = status.prompt_win
local results_win = status.results_win local results_win = status.results_win
@@ -705,18 +733,26 @@ function Picker.close_windows(status)
state.clear_status(status.prompt_bufnr) state.clear_status(status.prompt_bufnr)
end end
--- Get the entry table of the current selection
---@return table
function Picker:get_selection() function Picker:get_selection()
return self._selection_entry return self._selection_entry
end end
--- Get the row number of the current selection
---@return number
function Picker:get_selection_row() function Picker:get_selection_row()
return self._selection_row or self.max_results return self._selection_row or self.max_results
end end
--- Move the current selection by `change` steps
---@param change number
function Picker:move_selection(change) function Picker:move_selection(change)
self:set_selection(self:get_selection_row() + change) self:set_selection(self:get_selection_row() + change)
end end
--- Add the entry of the given row to the multi-select object
---@param row number: the number of the chosen row
function Picker:add_selection(row) function Picker:add_selection(row)
local entry = self.manager:get_entry(self:get_index(row)) local entry = self.manager:get_entry(self:get_index(row))
self._multi:add(entry) self._multi:add(entry)
@@ -724,6 +760,8 @@ function Picker:add_selection(row)
self.highlighter:hi_multiselect(row, true) self.highlighter:hi_multiselect(row, true)
end end
--- Remove the entry of the given row to the multi-select object
---@param row number: the number of the chosen row
function Picker:remove_selection(row) function Picker:remove_selection(row)
local entry = self.manager:get_entry(self:get_index(row)) local entry = self.manager:get_entry(self:get_index(row))
self._multi:drop(entry) self._multi:drop(entry)
@@ -731,14 +769,23 @@ function Picker:remove_selection(row)
self.highlighter:hi_multiselect(row, false) self.highlighter:hi_multiselect(row, false)
end end
--- Check if the given row is in the multi-select object
---@param entry table: table with information about the chosen entry
---@return number: the "count" associated to the entry in the multi-select
--- object (if present), `nil` otherwise
function Picker:is_multi_selected(entry) function Picker:is_multi_selected(entry)
return self._multi:is_selected(entry) return self._multi:is_selected(entry)
end end
--- Get a table containing all of the currently selected entries
---@return table: an integer indexed table of selected entries
function Picker:get_multi_selection() function Picker:get_multi_selection()
return self._multi:get() return self._multi:get()
end end
--- Toggle the given row in and out of the multi-select object.
--- Also updates the highlighting for the given entry
---@param row number: the number of the chosen row
function Picker:toggle_selection(row) function Picker:toggle_selection(row)
local entry = self.manager:get_entry(self:get_index(row)) local entry = self.manager:get_entry(self:get_index(row))
self._multi:toggle(entry) self._multi:toggle(entry)
@@ -746,6 +793,8 @@ function Picker:toggle_selection(row)
self.highlighter:hi_multiselect(row, self._multi:is_selected(entry)) self.highlighter:hi_multiselect(row, self._multi:is_selected(entry))
end end
--- Set the current selection to `nil`
---@note: generally used when a picker is first activated with `find()`
function Picker:reset_selection() function Picker:reset_selection()
self._selection_entry = nil self._selection_entry = nil
self._selection_row = nil self._selection_row = nil
@@ -769,6 +818,9 @@ end
-- TODO(conni2461): Maybe _ prefix these next two functions -- TODO(conni2461): Maybe _ prefix these next two functions
-- TODO(conni2461): Next two functions only work together otherwise color doesn't work -- TODO(conni2461): Next two functions only work together otherwise color doesn't work
-- Probably a issue with prompt buffers -- Probably a issue with prompt buffers
--- Change the prefix in the prompt to be `new_prefix` and apply `hl_group`
---@param new_prefix string: the string to be used as the new prefix
---@param hl_group string: the name of the chosen highlight
function Picker:change_prompt_prefix(new_prefix, hl_group) function Picker:change_prompt_prefix(new_prefix, hl_group)
if not new_prefix then if not new_prefix then
return return
@@ -784,6 +836,8 @@ function Picker:change_prompt_prefix(new_prefix, hl_group)
self:_reset_prefix_color(hl_group) self:_reset_prefix_color(hl_group)
end end
--- Reset the prompt to the provided `text`
---@param text string
function Picker:reset_prompt(text) function Picker:reset_prompt(text)
local prompt_text = self.prompt_prefix .. (text or "") local prompt_text = self.prompt_prefix .. (text or "")
vim.api.nvim_buf_set_lines(self.prompt_bufnr, 0, -1, false, { prompt_text }) vim.api.nvim_buf_set_lines(self.prompt_bufnr, 0, -1, false, { prompt_text })
@@ -821,6 +875,8 @@ function Picker:refresh(finder, opts)
self._on_lines(nil, nil, nil, 0, 1) self._on_lines(nil, nil, nil, 0, 1)
end end
---Set the selection to the provided `row`
---@param row number
function Picker:set_selection(row) function Picker:set_selection(row)
if not self.manager then if not self.manager then
return return
@@ -925,6 +981,7 @@ function Picker:set_selection(row)
vim.api.nvim_win_set_cursor(self.results_win, { row + 1, 0 }) vim.api.nvim_win_set_cursor(self.results_win, { row + 1, 0 })
end end
--- Refresh the previewer based on the current `status` of the picker
function Picker:refresh_previewer() function Picker:refresh_previewer()
local status = state.get_status(self.prompt_bufnr) local status = state.get_status(self.prompt_bufnr)
if not self._selection_entry then if not self._selection_entry then
@@ -970,6 +1027,10 @@ function Picker:cycle_previewers(next)
end end
end end
--- Handler for when entries are added by `self.manager`
---@param index number: the index to add the entry at
---@param entry table: the entry that has been added to the manager
---@param insert boolean: whether the entry has been "inserted" or not
function Picker:entry_adder(index, entry, _, insert) function Picker:entry_adder(index, entry, _, insert)
if not entry then if not entry then
return return
@@ -1036,6 +1097,7 @@ function Picker:entry_adder(index, entry, _, insert)
end end
end end
--- Reset tracked information for this picker
function Picker:_reset_track() function Picker:_reset_track()
self.stats.processed = 0 self.stats.processed = 0
self.stats.displayed = 0 self.stats.displayed = 0
@@ -1047,10 +1109,14 @@ function Picker:_reset_track()
self.stats.highlights = 0 self.stats.highlights = 0
end end
--- Increment the count of the tracked info at `self.stats[key]`
---@param key string
function Picker:_increment(key) function Picker:_increment(key)
self.stats[key] = (self.stats[key] or 0) + 1 self.stats[key] = (self.stats[key] or 0) + 1
end end
--- Decrement the count of the tracked info at `self.stats[key]`
---@param key string
function Picker:_decrement(key) function Picker:_decrement(key)
self.stats[key] = (self.stats[key] or 0) - 1 self.stats[key] = (self.stats[key] or 0) - 1
end end
@@ -1071,12 +1137,18 @@ function Picker:_on_complete()
end end
end end
--- Close all open Telescope pickers
function Picker:close_existing_pickers() function Picker:close_existing_pickers()
for _, prompt_bufnr in ipairs(state.get_existing_prompts()) do for _, prompt_bufnr in ipairs(state.get_existing_prompts()) do
pcall(actions.close, prompt_bufnr) pcall(actions._close, prompt_bufnr, true)
end end
end end
--- Returns a function that sets virtual text for the count indicator
--- e.g. "10/50" as "filtered"/"processed"
---@param prompt_win number
---@param prompt_bufnr number
---@return function
function Picker:get_status_updater(prompt_win, prompt_bufnr) function Picker:get_status_updater(prompt_win, prompt_bufnr)
return function(opts) return function(opts)
if self.closed or not vim.api.nvim_buf_is_valid(prompt_bufnr) then if self.closed or not vim.api.nvim_buf_is_valid(prompt_bufnr) then
@@ -1103,6 +1175,13 @@ function Picker:get_status_updater(prompt_win, prompt_bufnr)
end end
end end
--- Returns a function that will process an element.
--- Returned function handles updating the "filtered" and "processed" counts
--- as appropriate and runs the sorters score function
---@param find_id number
---@param prompt string
---@param status_updater function
---@return function
function Picker:get_result_processor(find_id, prompt, status_updater) function Picker:get_result_processor(find_id, prompt, status_updater)
local count = 0 local count = 0
@@ -1153,6 +1232,11 @@ function Picker:get_result_processor(find_id, prompt, status_updater)
end end
end end
--- Handles updating the picker after all the entries are scored/processed.
---@param results_bufnr number
---@param find_id number
---@param prompt string
---@param status_updater function
function Picker:get_result_completor(results_bufnr, find_id, prompt, status_updater) function Picker:get_result_completor(results_bufnr, find_id, prompt, status_updater)
return vim.schedule_wrap(function() return vim.schedule_wrap(function()
if self.closed == true or self:is_done() then if self.closed == true or self:is_done() then
@@ -1210,6 +1294,11 @@ function Picker:_do_selection(prompt)
end end
end end
--- Wrapper function for `Picker:new` that incorporates user provided `opts`
--- with the telescope `defaults`
---@param opts table
---@param defaults table
---@return Picker
pickers.new = function(opts, defaults) pickers.new = function(opts, defaults)
opts = opts or {} opts = opts or {}
defaults = defaults or {} defaults = defaults or {}
@@ -1247,6 +1336,8 @@ pickers.new = function(opts, defaults)
return Picker:new(result) return Picker:new(result)
end end
--- Close the picker which has prompt with buffer number `prompt_bufnr`
---@param prompt_bufnr number
function pickers.on_close_prompt(prompt_bufnr) 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