8000 mini.nvim/lua/mini/extra.lua at main · DJARUUN/mini.nvim · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
2034 lines (1784 loc) · 77.9 KB

extra.lua

File metadata and controls

2034 lines (1784 loc) · 77.9 KB
highlighter_width = math.max(highlighter_width, vim.fn.strchars(match.highlighter))
end
end
for _, item in ipairs(items) do
--stylua: ignore
item.text = string.format(
'%s │ %s│%d│%d│%s',
H.ensure_text_width(item.highlighter, highlighter_width),
item.buf_name, item.lnum, item.col, item.line
)
item.buf_name, item.line = nil, nil
end
local show = function(buf_id, items_to_show, query)
pick.default_show(buf_id, items_to_show, query)
H.pick_clear_namespace(buf_id, H.ns_id.pickers)
for i, item in ipairs(items_to_show) do
local end_col = string.len(item.highlighter)
local extmark_opts = { hl_group = item.hl_group, end_row = i - 1, end_col = end_col, priority = 1 }
vim.api.nvim_buf_set_extmark(buf_id, H.ns_id.pickers, i - 1, 0, extmark_opts)
end
end
local name = string.format('Mini.hipatterns matches (%s)', scope)
return H.pick_start(items, { source = { name = name, show = show } }, opts)
end
--- Neovim history picker
---
--- Pick from output of |:history|.
--- Notes:
--- - Has no preview.
--- - Choosing action depends on scope:
--- - For "cmd" / ":" scopes, the command is executed.
--- - For "search" / "/" / "?" scopes, search is redone.
--- - For other scopes nothing is done (but chosen item is still returned).
---
--- Examples ~
---
--- - Command history: `MiniExtra.pickers.history({ scope = ':' })`
--- - Search history: `:Pick history scope='/'`
---
---@param local_opts __extra_pickers_local_opts
--- Possible fields:
--- - <scope> `(string)` - any allowed {name} flag of |:history| command.
--- Note: word abbreviations are not allowed. Default: "all".
---@param opts __extra_pickers_opts
---
---@return __extra_pickers_return
MiniExtra.pickers.history = function(local_opts, opts)
local pick = H.validate_pick('history')
local_opts = vim.tbl_deep_extend('force', { scope = 'all' }, local_opts or {})
local allowed_scope = { 'all', 'cmd', 'search', 'expr', 'input', 'debug', ':', '/', '?', '=', '@', '>' }
local scope = H.pick_validate_scope(local_opts, allowed_scope, 'history')
--stylua: ignore
local type_ids = {
cmd = ':', search = '/', expr = '=', input = '@', debug = '>',
[':'] = ':', ['/'] = '/', ['='] = '=', ['@'] = '@', ['>'] = '>',
['?'] = '?',
}
-- Construct items
local items = {}
local names = scope == 'all' and { 'cmd', 'search', 'expr', 'input', 'debug' } or { scope }
for _, cur_name in ipairs(names) do
local cmd_output = vim.api.nvim_exec(':history ' .. cur_name, true)
local lines = vim.split(cmd_output, '\n')
local id = type_ids[cur_name]
-- Output of `:history` is sorted from oldest to newest
for i = #lines, 2, -1 do
local hist_entry = lines[i]:match('^.-%-?%d+%s+(.*)$')
table.insert(items, string.format('%s %s', id, hist_entry))
end
end
-- Define source
local preview = H.pick_make_no_preview('history')
local choose = function(item)
if not (type(item) == 'string' and vim.fn.mode() == 'n') then return end
local id, entry = item:match('^(.) (.*)$')
if id == ':' or id == '/' or id == '?' then
vim.schedule(function() vim.fn.feedkeys(id .. entry .. '\r', 'nx') end)
end
end
local default_source = { name = string.format('History (%s)', scope), preview = preview, choose = choose }
return H.pick_start(items, { source = default_source }, opts)
end
--- Highlight groups picker
---
--- Pick and preview highlight groups.
--- Notes:
--- - Item line is colored with same highlight group it represents.
--- - Preview shows highlight's definition (as in |:highlight| with {group-name}).
--- - Choosing places highlight definition in Command line to update and apply.
---
---@param local_opts __extra_pickers_local_opts
--- Not used at the moment.
---@param opts __extra_pickers_opts
---
---@return __extra_pickers_return
MiniExtra.pickers.hl_groups = function(local_opts, opts)
local pick = H.validate_pick('hl_groups')
-- Construct items
local group_data = vim.split(vim.api.nvim_exec('highlight', true), '\n')
local items = {}
for _, l in ipairs(group_data) do
local group = l:match('^(%S+)')
if group ~= nil then table.insert(items, group) end
end
local show = function(buf_id, items_to_show, query)
H.set_buflines(buf_id, items_to_show)
H.pick_clear_namespace(buf_id, H.ns_id.pickers)
-- Highlight line with highlight group of its item
for i = 1, #items_to_show do
H.pick_highlight_line(buf_id, i, items_to_show[i], 300)
end
end
-- Define source
local preview = function(buf_id, item)
local lines = vim.split(vim.api.nvim_exec('hi ' .. item, true), '\n')
H.set_buflines(buf_id, lines)
end
local choose = function(item)
local hl_def = vim.split(vim.api.nvim_exec('hi ' .. item, true), '\n')[1]
hl_def = hl_def:gsub('^(%S+)%s+xxx%s+', '%1 ')
vim.schedule(function() vim.fn.feedkeys(':hi ' .. hl_def, 'n') end)
end
local default_source = { name = 'Highlight groups', show = show, preview = preview, choose = choose }
return H.pick_start(items, { source = default_source }, opts)
end
--- Neovim keymaps picker
---
--- Pick and preview data about Neovim keymaps.
--- Notes:
--- - Item line contains data about keymap mode, whether it is buffer local, its
--- left hand side, and inferred description.
--- - Preview shows keymap data or callback source (if present and reachable).
--- - Choosing emulates pressing the left hand side of the keymap.
---
---@param local_opts __extra_pickers_local_opts
--- Possible fields:
--- - <mode> `(string)` - modes to show. One of "all" or appropriate mode
--- for |nvim_set_keymap()|. Default: "all".
--- - <scope> `(string)` - scope to show. One of "all", "global", "buf".
--- Default: "all".
---@param opts __extra_pickers_opts
---
---@return __extra_pickers_return
MiniExtra.pickers.keymaps = function(local_opts, opts)
local pick = H.validate_pick('keymaps')
local_opts = vim.tbl_deep_extend('force', { mode = 'all', scope = 'all' }, local_opts or {})
local mode = H.pick_validate_one_of('mode', local_opts, { 'all', 'n', 'x', 's', 'o', 'i', 'l', 'c', 't' }, 'keymaps')
local scope = H.pick_validate_scope(local_opts, { 'all', 'global', 'buf' }, 'keymaps')
-- Create items
local items = {}
local populate_modes = mode == 'all' and { 'n', 'x', 's', 'o', 'i', 'l', 'c', 't' } or { mode }
local max_lhs_width = 0
local populate_items = function(source)
for _, m in ipairs(populate_modes) do
for _, maparg in ipairs(source(m)) do
local desc = maparg.desc ~= nil and vim.inspect(maparg.desc) or maparg.rhs
local lhs = vim.fn.keytrans(maparg.lhsraw or maparg.lhs)
max_lhs_width = math.max(vim.fn.strchars(lhs), max_lhs_width)
table.insert(items, { lhs = lhs, desc = desc, maparg = maparg })
end
end
end
if scope == 'all' or scope == 'buf' then populate_items(function(m) return vim.api.nvim_buf_get_keymap(0, m) end) end
if scope == 'all' or scope == 'global' then populate_items(vim.api.nvim_get_keymap) end
for _, item in ipairs(items) do
local buf_map_indicator = item.maparg.buffer == 0 and ' ' or '@'
local lhs_text = H.ensure_text_width(item.lhs, max_lhs_width)
item.text = string.format('%s %s │ %s │ %s', item.maparg.mode, buf_map_indicator, lhs_text, item.desc or '')
end
-- Define source
local get_callback_pos = function(maparg)
if type(maparg.callback) ~= 'function' then return nil, nil end
local info = debug.getinfo(maparg.callback)
local path = info.source:gsub('^@', '')
if vim.fn.filereadable(path) == 0 then return nil, nil end
0