1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-02 23:20:04 +08:00

perf(guide): improve key binding guide

This commit is contained in:
Eric Wong 2024-06-01 22:51:47 +08:00
parent d6a34e3aff
commit 24712351a1
2 changed files with 161 additions and 112 deletions

View File

@ -7,8 +7,6 @@
--=============================================================================
local M = {}
local system = require('spacevim.api').import('system')
function M.eval(l)
if vim.api ~= nil then
return vim.api.nvim_eval(l)
@ -17,6 +15,27 @@ function M.eval(l)
end
end
function M.islist(val)
if vim.islist then
return vim.islist(val)
---@diagnostic disable-next-line
elseif vim.tbl_islist then
---@diagnostic disable-next-line
return vim.tbl_islist(val)
else
if type(val) ~= 'table' then
return false
else
for k, _ in pairs(val) do
if type(k) ~= 'number' then
return false
end
end
return true
end
end
end
if vim.command ~= nil then
function M.cmd(command)
return vim.command(command)
@ -31,7 +50,7 @@ end
local function build_argv(...)
local str = ''
for index, value in ipairs(...) do
for _, value in ipairs(...) do
if str ~= '' then
str = str .. ','
end
@ -49,10 +68,10 @@ function M.call(funcname, ...)
return vim.call(funcname, ...)
else
if vim.api ~= nil then
return vim.api.nvim_call_function(funcname, {...})
return vim.api.nvim_call_function(funcname, { ... })
else
-- call not call vim script function in lua
vim.command('let g:lua_rst = ' .. funcname .. '(' .. build_argv({...}) .. ')')
vim.command('let g:lua_rst = ' .. funcname .. '(' .. build_argv({ ... }) .. ')')
return M.eval('g:lua_rst')
end
end
@ -64,7 +83,7 @@ M.fn = setmetatable({}, {
local _fn
if vim.api ~= nil and vim.api[key] ~= nil then
_fn = function()
error(string.format("Tried to call API function with vim.fn: use vim.api.%s instead", key))
error(string.format('Tried to call API function with vim.fn: use vim.api.%s instead', key))
end
else
_fn = function(...)
@ -73,7 +92,7 @@ M.fn = setmetatable({}, {
end
t[key] = _fn
return _fn
end
end,
})
-- This is for vim and old neovim to use vim.o
@ -89,14 +108,14 @@ M.vim_options = setmetatable({}, {
end
t[key] = _fn
return _fn
end
end,
})
function M.echo(msg)
if vim.api ~= nil then
vim.api.nvim_echo({{msg}}, false, {})
vim.api.nvim_echo({ { msg } }, false, {})
else
vim.command('echo ' .. build_argv({msg}))
vim.command('echo ' .. build_argv({ msg }))
end
end
@ -116,7 +135,7 @@ if M.has('patch-7.4.279') then
end
else
function M.globpath(dir, expr)
return M.fn.split(fn.globpath(dir, expr), "\n")
return M.fn.split(vim.fn.globpath(dir, expr), '\n')
end
end

View File

@ -15,6 +15,7 @@ local cmp = require('spacevim.api').import('vim.compatible')
local buffer = require('spacevim.api').import('vim.buffer')
local VIM = require('spacevim.api').import('vim')
local SL = require('spacevim.api').import('vim.statusline')
local hl = require('spacevim.api.vim.highlight')
-- all local values should be listed here:
@ -164,27 +165,27 @@ local function add_map_to_dict(map, level, dict)
local nlevel = level + 1
if not dict[curkey] then
dict[curkey] = { name = vim.g.leaderGuide_default_group_name }
elseif vim.tbl_islist(dict[curkey]) and vim.g.leaderGuide_flatten == 1 then
elseif cmp.islist(dict[curkey]) and vim.g.leaderGuide_flatten == 1 then
local cmd = escape_mappings(map)
curkey = table.concat(map.lhs, '', level)
nlevel = level
if not dict[curkey] then
dict[curkey] = { cmd, map.display }
end
elseif vim.tbl_islist(dict[curkey]) and vim.g.leaderGuide_flatten == 0 then
elseif cmp.islist(dict[curkey]) and vim.g.leaderGuide_flatten == 0 then
curkey = curkey .. 'm'
if not dict[curkey] then
dict[curkey] = { name = vim.g.leaderGuide_default_group_name }
end
end
if not vim.tbl_islist(dict[curkey]) then
if not cmp.islist(dict[curkey]) then
add_map_to_dict(map, nlevel, dict[curkey])
end
else
local cmd = escape_mappings(map)
if not dict[map.lhs[level]] then
dict[map.lhs[level]] = { cmd, map.display }
elseif not vim.tbl_islist(dict[map.lhs[level]]) and vim.g.leaderGuide_flatten == 1 then
elseif not cmp.islist(dict[map.lhs[level]]) and vim.g.leaderGuide_flatten == 1 then
local childmap = flattenmap(dict[map.lhs[level]], map.lhs[level])
for it, _ in pairs(childmap) do
dict[it] = childmap[it]
@ -282,22 +283,44 @@ local function start_parser(key, dict)
end
end
---@param v string key board string
---@return string # displayed string of each item
local function get_displaystring(v)
local desc = ''
if lmap[v].name then
desc = lmap[v].name
else
desc = lmap[v][2] or ''
end
local offset = string.rep(' ', 8 - #v)
local displaystring
if vim.g.spacevim_leader_guide_theme == 'whichkey' then
displaystring = offset .. v .. ' -> ' .. desc
else
displaystring = offset .. '[' .. v .. '] ' .. desc
end
return displaystring
end
local function calc_layout()
local ret = {}
local smap = {}
for k, v in pairs(lmap) do
if v ~= 'name' then
smap[k] = v
end
end
local smap = vim.fn.filter(vim.fn.copy(lmap), 'v:key !=# "name"')
ret.n_items = vim.fn.len(smap)
local length = {}
for k, v in pairs(smap) do
if v.name then
table.insert(length, vim.fn.strdisplaywidth('[' .. k .. ']' .. v.name))
else
table.insert(length, vim.fn.strdisplaywidth('[' .. k .. ']' .. v[2]))
end
log.debug('smap is:' .. vim.inspect(smap))
for k, _ in pairs(smap) do
table.insert(length, vim.fn.strdisplaywidth(get_displaystring(k)))
end
local maxlength = vim.fn.max(length) + vim.g.leaderGuide_hspace
log.debug('maxlength is:' .. maxlength)
if vim.g.leaderGuide_vertical == 1 then
ret.n_rows = vim.fn.winheight(0) - 2
ret.n_cols = math.floor(ret.n_items / ret.n_rows)
@ -319,6 +342,7 @@ local function calc_layout()
end
ret.win_dim = ret.n_rows
end
log.debug('layout is:' .. vim.inspect(ret))
return ret
end
@ -396,19 +420,7 @@ local function create_string(layout)
table.sort(smap, compare_key)
for _, k in ipairs(smap) do
local desc = ''
if lmap[k].name then
desc = lmap[k].name
else
desc = lmap[k][2] or ''
end
local offset = string.rep(' ', 8 - #k)
local displaystring
if vim.g.spacevim_leader_guide_theme == 'whichkey' then
displaystring = offset .. k .. ' -> ' .. desc
else
displaystring = offset .. '[' .. k .. '] ' .. desc
end
local displaystring = get_displaystring(k)
crow = rows[row] or {}
if #crow == 0 then
@ -416,10 +428,10 @@ local function create_string(layout)
end
-- if the displaystring is too long
if #displaystring > l.col_width then
table.insert(crow, string.sub(displaystring, 1, l.col_width -5) .. '... ')
table.insert(crow, string.sub(displaystring, 1, l.col_width - 5) .. '... ')
else
table.insert(crow, displaystring)
table.insert(crow, vim.fn['repeat'](' ', l.col_width - vim.fn.strdisplaywidth(displaystring)))
table.insert(crow, string.rep(' ', l.col_width - vim.fn.strdisplaywidth(displaystring)))
end
if vim.g.leaderGuide_sort_horizontal == 0 then
if row > n_rows then
@ -455,8 +467,16 @@ local function create_string(layout)
return r
end
local cursor_highlight_info
local function highlight_cursor()
vim.cmd('hi! def link SpaceVimGuideCursor Cursor')
cursor_highlight_info = hl.group2dict('Cursor')
local hlinfo = {
name = 'SpaceVimGuideCursor',
guibg = cursor_highlight_info.guibg,
ctermbg = cursor_highlight_info.ctermbg,
}
hl.hi(hlinfo)
hl.hide_in_normal('Cursor')
if vis == 'gv' then
local _begin = vim.fn.getpos("'<")
local _end = vim.fn.getpos("'>")
@ -480,6 +500,7 @@ local function highlight_cursor()
end
local function remove_cursor_highlight()
hl.hi(cursor_highlight_info)
pcall(vim.fn.matchdelete, cursor_hilight_id)
end
@ -505,14 +526,23 @@ local function updateStatusline()
end
local keys = prefix_key_inp
local separators = {
arrow = '',
curve = '',
slant = '',
brace = '',
fire = '',
['nil'] = '',
}
local sep = separators[vim.g.spacevim_statusline_separator] or separators.arrow
SL.open_float({
{ 'Guide: ', 'LeaderGuiderPrompt' },
{ '', 'LeaderGuiderSep1' },
{ sep .. ' ', 'LeaderGuiderSep1' },
{
vim.fn['SpaceVim#mapping#leader#getName'](prefix_key) .. table.concat(keys, '') .. gname,
'LeaderGuiderName',
},
{ '', 'LeaderGuiderSep2' },
{ sep .. ' ', 'LeaderGuiderSep2' },
{ guide_help_msg(false), 'LeaderGuiderFill' },
{ string.rep(' ', 999), 'LeaderGuiderFill' },
})
@ -563,11 +593,12 @@ local function winopen()
winfixwidth = true,
winfixheight = true,
})
updateStatusline()
return winid, bufnr
end
local function start_buffer()
if not vim.api.nvim_win_is_valid(winid) or not vim.api.nvim_buf_is_valid(bufnr) then
winid, bufnr = winopen()
end
local layout = calc_layout()
local text = create_string(layout)
if vim.g.leaderGuide_max_size then
@ -583,12 +614,13 @@ local function start_buffer()
col = 0,
})
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, text)
updateStatusline()
cmp.fn.setbufvar(bufnr, '&modifiable', 0)
vim.cmd('redraw!')
vim.cmd('redraw')
wait_for_input()
end
@ -603,11 +635,11 @@ local function winclose()
end
local function handle_input(input)
winclose()
if not vim.tbl_islist(input) then
if not cmp.islist(input) then
lmap = input
start_buffer()
else
winclose()
prefix_key_inp = {}
cmp.fn.feedkeys(vis .. reg .. count, 'ti')
@ -628,7 +660,6 @@ local function page_down()
end
local function page_undo()
winclose()
if #prefix_key_inp then
table.remove(prefix_key_inp)
end
@ -639,7 +670,6 @@ local function page_undo()
end
local function page_up()
-- vim.api.nvim_feedkeys(Key.t('<C-c>'), 'n', false)
vim.api.nvim_feedkeys(Key.t('<C-u>'), 'x', false)
vim.cmd('redraw!')