feat: multiselect icon (#1572)
* feat: add `multi_icon` option to pickers and corresponding highlight * feat: allow `multi_icon` to be any length * fix: adjust `selection_caret` highlighting
This commit is contained in:
@@ -184,6 +184,15 @@ telescope.setup({opts}) *telescope.setup()*
|
|||||||
|
|
||||||
Default: ' '
|
Default: ' '
|
||||||
|
|
||||||
|
*telescope.defaults.multi_icon*
|
||||||
|
multi_icon: ~
|
||||||
|
Symbol to add in front of a multi-selected result entry.
|
||||||
|
Replaces final character of |telescope.defaults.selection_caret| and
|
||||||
|
|telescope.defaults.entry_prefix| as appropriate.
|
||||||
|
To have no icon, set to the empty string.
|
||||||
|
|
||||||
|
Default: '+'
|
||||||
|
|
||||||
*telescope.defaults.initial_mode*
|
*telescope.defaults.initial_mode*
|
||||||
initial_mode: ~
|
initial_mode: ~
|
||||||
Determines in which mode telescope starts. Valid Keys:
|
Determines in which mode telescope starts. Valid Keys:
|
||||||
|
|||||||
@@ -245,6 +245,18 @@ append(
|
|||||||
Default: ' ']]
|
Default: ' ']]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
append(
|
||||||
|
"multi_icon",
|
||||||
|
"+",
|
||||||
|
[[
|
||||||
|
Symbol to add in front of a multi-selected result entry.
|
||||||
|
Replaces final character of |telescope.defaults.selection_caret| and
|
||||||
|
|telescope.defaults.entry_prefix| as appropriate.
|
||||||
|
To have no icon, set to the empty string.
|
||||||
|
|
||||||
|
Default: '+']]
|
||||||
|
)
|
||||||
|
|
||||||
append(
|
append(
|
||||||
"initial_mode",
|
"initial_mode",
|
||||||
"insert",
|
"insert",
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ local MultiSelect = require "telescope.pickers.multi"
|
|||||||
|
|
||||||
local get_default = utils.get_default
|
local get_default = utils.get_default
|
||||||
|
|
||||||
|
local truncate = require("plenary.strings").truncate
|
||||||
|
local strdisplaywidth = require("plenary.strings").strdisplaywidth
|
||||||
|
|
||||||
local ns_telescope_matching = a.nvim_create_namespace "telescope_matching"
|
local ns_telescope_matching = a.nvim_create_namespace "telescope_matching"
|
||||||
local ns_telescope_prompt = a.nvim_create_namespace "telescope_prompt"
|
local ns_telescope_prompt = a.nvim_create_namespace "telescope_prompt"
|
||||||
local ns_telescope_prompt_prefix = a.nvim_create_namespace "telescope_prompt_prefix"
|
local ns_telescope_prompt_prefix = a.nvim_create_namespace "telescope_prompt_prefix"
|
||||||
@@ -68,6 +71,8 @@ function Picker:new(opts)
|
|||||||
prompt_prefix = get_default(opts.prompt_prefix, config.values.prompt_prefix),
|
prompt_prefix = get_default(opts.prompt_prefix, config.values.prompt_prefix),
|
||||||
selection_caret = get_default(opts.selection_caret, config.values.selection_caret),
|
selection_caret = get_default(opts.selection_caret, config.values.selection_caret),
|
||||||
entry_prefix = get_default(opts.entry_prefix, config.values.entry_prefix),
|
entry_prefix = get_default(opts.entry_prefix, config.values.entry_prefix),
|
||||||
|
multi_icon = get_default(opts.multi_icon, config.values.multi_icon),
|
||||||
|
|
||||||
initial_mode = get_default(opts.initial_mode, config.values.initial_mode),
|
initial_mode = get_default(opts.initial_mode, config.values.initial_mode),
|
||||||
debounce = get_default(tonumber(opts.debounce), nil),
|
debounce = get_default(tonumber(opts.debounce), nil),
|
||||||
|
|
||||||
@@ -923,29 +928,45 @@ function Picker:set_selection(row)
|
|||||||
-- Not sure.
|
-- Not sure.
|
||||||
local set_ok, set_errmsg = pcall(function()
|
local set_ok, set_errmsg = pcall(function()
|
||||||
local prompt = self:_get_prompt()
|
local prompt = self:_get_prompt()
|
||||||
|
local prefix = function(sel, multi)
|
||||||
|
local t
|
||||||
|
if sel then
|
||||||
|
t = self.selection_caret
|
||||||
|
else
|
||||||
|
t = self.entry_prefix
|
||||||
|
end
|
||||||
|
if multi and type(self.multi_icon) == "string" then
|
||||||
|
t = truncate(t, strdisplaywidth(t) - strdisplaywidth(self.multi_icon), "") .. self.multi_icon
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
-- This block handles removing the caret from beginning of previous selection (if still visible)
|
-- This block handles removing the caret from beginning of previous selection (if still visible)
|
||||||
-- Check if previous selection is still visible
|
-- Check if previous selection is still visible
|
||||||
if self._selection_entry and self.manager:find_entry(self._selection_entry) then
|
if self._selection_entry and self.manager:find_entry(self._selection_entry) then
|
||||||
-- Find the (possibly new) row of the old selection
|
-- Find the (possibly new) row of the old selection
|
||||||
local row_old_selection = self:get_row(self.manager:find_entry(self._selection_entry))
|
local row_old_selection = self:get_row(self.manager:find_entry(self._selection_entry))
|
||||||
|
local old_multiselected = self:is_multi_selected(self._selection_entry)
|
||||||
local line = a.nvim_buf_get_lines(results_bufnr, row_old_selection, row_old_selection + 1, false)[1]
|
local line = a.nvim_buf_get_lines(results_bufnr, row_old_selection, row_old_selection + 1, false)[1]
|
||||||
|
|
||||||
--Check if that row still has the caret
|
--Check if that row still has the caret
|
||||||
if string.sub(line, 0, #self.selection_caret) == self.selection_caret then
|
local old_caret = string.sub(line, 0, #prefix(true)) == prefix(true) and prefix(true)
|
||||||
|
or string.sub(line, 0, #prefix(true, true)) == prefix(true, true) and prefix(true, true)
|
||||||
|
if old_caret then
|
||||||
-- Only change the first couple characters, nvim_buf_set_text leaves the existing highlights
|
-- Only change the first couple characters, nvim_buf_set_text leaves the existing highlights
|
||||||
a.nvim_buf_set_text(
|
a.nvim_buf_set_text(
|
||||||
results_bufnr,
|
results_bufnr,
|
||||||
row_old_selection,
|
row_old_selection,
|
||||||
0,
|
0,
|
||||||
row_old_selection,
|
row_old_selection,
|
||||||
#self.selection_caret,
|
#old_caret,
|
||||||
{ self.entry_prefix }
|
{ prefix(false, old_multiselected) }
|
||||||
)
|
)
|
||||||
self.highlighter:hi_multiselect(row_old_selection, self:is_multi_selected(self._selection_entry))
|
self.highlighter:hi_multiselect(row_old_selection, old_multiselected)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local caret = self.selection_caret
|
local caret = prefix(true, self:is_multi_selected(entry))
|
||||||
|
|
||||||
local display, display_highlights = entry_display.resolve(self, entry)
|
local display, display_highlights = entry_display.resolve(self, entry)
|
||||||
display = caret .. display
|
display = caret .. display
|
||||||
@@ -958,8 +979,8 @@ function Picker:set_selection(row)
|
|||||||
end
|
end
|
||||||
a.nvim_buf_set_lines(results_bufnr, row, row + 1, false, { display })
|
a.nvim_buf_set_lines(results_bufnr, row, row + 1, false, { display })
|
||||||
|
|
||||||
-- don't highlight the ' ' at the end of caret
|
-- don't highlight any whitespace at the end of caret
|
||||||
self.highlighter:hi_selection(row, caret:sub(1, -2))
|
self.highlighter:hi_selection(row, caret:match "(.*%S)")
|
||||||
self.highlighter:hi_display(row, caret, display_highlights)
|
self.highlighter:hi_display(row, caret, display_highlights)
|
||||||
self.highlighter:hi_sorter(row, prompt, display)
|
self.highlighter:hi_sorter(row, prompt, display)
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,20 @@ function Highlighter:hi_multiselect(row, is_selected)
|
|||||||
|
|
||||||
if is_selected then
|
if is_selected then
|
||||||
vim.api.nvim_buf_add_highlight(results_bufnr, ns_telescope_multiselection, "TelescopeMultiSelection", row, 0, -1)
|
vim.api.nvim_buf_add_highlight(results_bufnr, ns_telescope_multiselection, "TelescopeMultiSelection", row, 0, -1)
|
||||||
|
if self.picker.multi_icon then
|
||||||
|
local line = vim.api.nvim_buf_get_lines(results_bufnr, row, row + 1, false)[1]
|
||||||
|
local pos = line:find(self.picker.multi_icon)
|
||||||
|
if pos and pos <= math.max(#self.picker.selection_caret, #self.picker.entry_prefix) then
|
||||||
|
vim.api.nvim_buf_add_highlight(
|
||||||
|
results_bufnr,
|
||||||
|
ns_telescope_multiselection,
|
||||||
|
"TelescopeMultiIcon",
|
||||||
|
row,
|
||||||
|
pos - 1,
|
||||||
|
pos - 1 + #self.picker.multi_icon
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
local existing_marks = vim.api.nvim_buf_get_extmarks(
|
local existing_marks = vim.api.nvim_buf_get_extmarks(
|
||||||
results_bufnr,
|
results_bufnr,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ let g:loaded_telescope = 1
|
|||||||
highlight default link TelescopeSelection Visual
|
highlight default link TelescopeSelection Visual
|
||||||
highlight default link TelescopeSelectionCaret TelescopeSelection
|
highlight default link TelescopeSelectionCaret TelescopeSelection
|
||||||
highlight default link TelescopeMultiSelection Type
|
highlight default link TelescopeMultiSelection Type
|
||||||
|
highlight default link TelescopeMultiIcon Identifier
|
||||||
|
|
||||||
" "Normal" in the floating windows created by telescope.
|
" "Normal" in the floating windows created by telescope.
|
||||||
highlight default link TelescopeNormal Normal
|
highlight default link TelescopeNormal Normal
|
||||||
|
|||||||
Reference in New Issue
Block a user