mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 01:40:05 +08:00
perf(guide): improve key binding guide
This commit is contained in:
parent
d6a34e3aff
commit
24712351a1
@ -7,8 +7,6 @@
|
|||||||
--=============================================================================
|
--=============================================================================
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
local system = require('spacevim.api').import('system')
|
|
||||||
|
|
||||||
function M.eval(l)
|
function M.eval(l)
|
||||||
if vim.api ~= nil then
|
if vim.api ~= nil then
|
||||||
return vim.api.nvim_eval(l)
|
return vim.api.nvim_eval(l)
|
||||||
@ -17,6 +15,27 @@ function M.eval(l)
|
|||||||
end
|
end
|
||||||
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
|
if vim.command ~= nil then
|
||||||
function M.cmd(command)
|
function M.cmd(command)
|
||||||
return vim.command(command)
|
return vim.command(command)
|
||||||
@ -31,7 +50,7 @@ end
|
|||||||
|
|
||||||
local function build_argv(...)
|
local function build_argv(...)
|
||||||
local str = ''
|
local str = ''
|
||||||
for index, value in ipairs(...) do
|
for _, value in ipairs(...) do
|
||||||
if str ~= '' then
|
if str ~= '' then
|
||||||
str = str .. ','
|
str = str .. ','
|
||||||
end
|
end
|
||||||
@ -49,10 +68,10 @@ function M.call(funcname, ...)
|
|||||||
return vim.call(funcname, ...)
|
return vim.call(funcname, ...)
|
||||||
else
|
else
|
||||||
if vim.api ~= nil then
|
if vim.api ~= nil then
|
||||||
return vim.api.nvim_call_function(funcname, {...})
|
return vim.api.nvim_call_function(funcname, { ... })
|
||||||
else
|
else
|
||||||
-- call not call vim script function in lua
|
-- 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')
|
return M.eval('g:lua_rst')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -64,7 +83,7 @@ M.fn = setmetatable({}, {
|
|||||||
local _fn
|
local _fn
|
||||||
if vim.api ~= nil and vim.api[key] ~= nil then
|
if vim.api ~= nil and vim.api[key] ~= nil then
|
||||||
_fn = function()
|
_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
|
end
|
||||||
else
|
else
|
||||||
_fn = function(...)
|
_fn = function(...)
|
||||||
@ -73,7 +92,7 @@ M.fn = setmetatable({}, {
|
|||||||
end
|
end
|
||||||
t[key] = _fn
|
t[key] = _fn
|
||||||
return _fn
|
return _fn
|
||||||
end
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- This is for vim and old neovim to use vim.o
|
-- This is for vim and old neovim to use vim.o
|
||||||
@ -89,14 +108,14 @@ M.vim_options = setmetatable({}, {
|
|||||||
end
|
end
|
||||||
t[key] = _fn
|
t[key] = _fn
|
||||||
return _fn
|
return _fn
|
||||||
end
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
function M.echo(msg)
|
function M.echo(msg)
|
||||||
if vim.api ~= nil then
|
if vim.api ~= nil then
|
||||||
vim.api.nvim_echo({{msg}}, false, {})
|
vim.api.nvim_echo({ { msg } }, false, {})
|
||||||
else
|
else
|
||||||
vim.command('echo ' .. build_argv({msg}))
|
vim.command('echo ' .. build_argv({ msg }))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -116,7 +135,7 @@ if M.has('patch-7.4.279') then
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
function M.globpath(dir, expr)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ local cmp = require('spacevim.api').import('vim.compatible')
|
|||||||
local buffer = require('spacevim.api').import('vim.buffer')
|
local buffer = require('spacevim.api').import('vim.buffer')
|
||||||
local VIM = require('spacevim.api').import('vim')
|
local VIM = require('spacevim.api').import('vim')
|
||||||
local SL = require('spacevim.api').import('vim.statusline')
|
local SL = require('spacevim.api').import('vim.statusline')
|
||||||
|
local hl = require('spacevim.api.vim.highlight')
|
||||||
|
|
||||||
-- all local values should be listed here:
|
-- all local values should be listed here:
|
||||||
|
|
||||||
@ -164,27 +165,27 @@ local function add_map_to_dict(map, level, dict)
|
|||||||
local nlevel = level + 1
|
local nlevel = level + 1
|
||||||
if not dict[curkey] then
|
if not dict[curkey] then
|
||||||
dict[curkey] = { name = vim.g.leaderGuide_default_group_name }
|
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)
|
local cmd = escape_mappings(map)
|
||||||
curkey = table.concat(map.lhs, '', level)
|
curkey = table.concat(map.lhs, '', level)
|
||||||
nlevel = level
|
nlevel = level
|
||||||
if not dict[curkey] then
|
if not dict[curkey] then
|
||||||
dict[curkey] = { cmd, map.display }
|
dict[curkey] = { cmd, map.display }
|
||||||
end
|
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'
|
curkey = curkey .. 'm'
|
||||||
if not dict[curkey] then
|
if not dict[curkey] then
|
||||||
dict[curkey] = { name = vim.g.leaderGuide_default_group_name }
|
dict[curkey] = { name = vim.g.leaderGuide_default_group_name }
|
||||||
end
|
end
|
||||||
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])
|
add_map_to_dict(map, nlevel, dict[curkey])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local cmd = escape_mappings(map)
|
local cmd = escape_mappings(map)
|
||||||
if not dict[map.lhs[level]] then
|
if not dict[map.lhs[level]] then
|
||||||
dict[map.lhs[level]] = { cmd, map.display }
|
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])
|
local childmap = flattenmap(dict[map.lhs[level]], map.lhs[level])
|
||||||
for it, _ in pairs(childmap) do
|
for it, _ in pairs(childmap) do
|
||||||
dict[it] = childmap[it]
|
dict[it] = childmap[it]
|
||||||
@ -282,22 +283,44 @@ local function start_parser(key, dict)
|
|||||||
end
|
end
|
||||||
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 function calc_layout()
|
||||||
local ret = {}
|
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)
|
ret.n_items = vim.fn.len(smap)
|
||||||
local length = {}
|
local length = {}
|
||||||
for k, v in pairs(smap) do
|
log.debug('smap is:' .. vim.inspect(smap))
|
||||||
if v.name then
|
for k, _ in pairs(smap) do
|
||||||
table.insert(length, vim.fn.strdisplaywidth('[' .. k .. ']' .. v.name))
|
table.insert(length, vim.fn.strdisplaywidth(get_displaystring(k)))
|
||||||
else
|
|
||||||
table.insert(length, vim.fn.strdisplaywidth('[' .. k .. ']' .. v[2]))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
local maxlength = vim.fn.max(length) + vim.g.leaderGuide_hspace
|
local maxlength = vim.fn.max(length) + vim.g.leaderGuide_hspace
|
||||||
|
log.debug('maxlength is:' .. maxlength)
|
||||||
if vim.g.leaderGuide_vertical == 1 then
|
if vim.g.leaderGuide_vertical == 1 then
|
||||||
ret.n_rows = vim.fn.winheight(0) - 2
|
ret.n_rows = vim.fn.winheight(0) - 2
|
||||||
ret.n_cols = math.floor(ret.n_items / ret.n_rows)
|
ret.n_cols = math.floor(ret.n_items / ret.n_rows)
|
||||||
@ -319,6 +342,7 @@ local function calc_layout()
|
|||||||
end
|
end
|
||||||
ret.win_dim = ret.n_rows
|
ret.win_dim = ret.n_rows
|
||||||
end
|
end
|
||||||
|
log.debug('layout is:' .. vim.inspect(ret))
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -396,19 +420,7 @@ local function create_string(layout)
|
|||||||
table.sort(smap, compare_key)
|
table.sort(smap, compare_key)
|
||||||
|
|
||||||
for _, k in ipairs(smap) do
|
for _, k in ipairs(smap) do
|
||||||
local desc = ''
|
local displaystring = get_displaystring(k)
|
||||||
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
|
|
||||||
crow = rows[row] or {}
|
crow = rows[row] or {}
|
||||||
|
|
||||||
if #crow == 0 then
|
if #crow == 0 then
|
||||||
@ -416,10 +428,10 @@ local function create_string(layout)
|
|||||||
end
|
end
|
||||||
-- if the displaystring is too long
|
-- if the displaystring is too long
|
||||||
if #displaystring > l.col_width then
|
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
|
else
|
||||||
table.insert(crow, displaystring)
|
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
|
end
|
||||||
if vim.g.leaderGuide_sort_horizontal == 0 then
|
if vim.g.leaderGuide_sort_horizontal == 0 then
|
||||||
if row > n_rows then
|
if row > n_rows then
|
||||||
@ -455,8 +467,16 @@ local function create_string(layout)
|
|||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local cursor_highlight_info
|
||||||
local function highlight_cursor()
|
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
|
if vis == 'gv' then
|
||||||
local _begin = vim.fn.getpos("'<")
|
local _begin = vim.fn.getpos("'<")
|
||||||
local _end = vim.fn.getpos("'>")
|
local _end = vim.fn.getpos("'>")
|
||||||
@ -480,6 +500,7 @@ local function highlight_cursor()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function remove_cursor_highlight()
|
local function remove_cursor_highlight()
|
||||||
|
hl.hi(cursor_highlight_info)
|
||||||
pcall(vim.fn.matchdelete, cursor_hilight_id)
|
pcall(vim.fn.matchdelete, cursor_hilight_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -505,14 +526,23 @@ local function updateStatusline()
|
|||||||
end
|
end
|
||||||
local keys = prefix_key_inp
|
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({
|
SL.open_float({
|
||||||
{ 'Guide: ', 'LeaderGuiderPrompt' },
|
{ 'Guide: ', 'LeaderGuiderPrompt' },
|
||||||
{ ' ', 'LeaderGuiderSep1' },
|
{ sep .. ' ', 'LeaderGuiderSep1' },
|
||||||
{
|
{
|
||||||
vim.fn['SpaceVim#mapping#leader#getName'](prefix_key) .. table.concat(keys, '') .. gname,
|
vim.fn['SpaceVim#mapping#leader#getName'](prefix_key) .. table.concat(keys, '') .. gname,
|
||||||
'LeaderGuiderName',
|
'LeaderGuiderName',
|
||||||
},
|
},
|
||||||
{ ' ', 'LeaderGuiderSep2' },
|
{ sep .. ' ', 'LeaderGuiderSep2' },
|
||||||
{ guide_help_msg(false), 'LeaderGuiderFill' },
|
{ guide_help_msg(false), 'LeaderGuiderFill' },
|
||||||
{ string.rep(' ', 999), 'LeaderGuiderFill' },
|
{ string.rep(' ', 999), 'LeaderGuiderFill' },
|
||||||
})
|
})
|
||||||
@ -563,11 +593,12 @@ local function winopen()
|
|||||||
winfixwidth = true,
|
winfixwidth = true,
|
||||||
winfixheight = true,
|
winfixheight = true,
|
||||||
})
|
})
|
||||||
updateStatusline()
|
|
||||||
return winid, bufnr
|
return winid, bufnr
|
||||||
end
|
end
|
||||||
local function start_buffer()
|
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()
|
winid, bufnr = winopen()
|
||||||
|
end
|
||||||
local layout = calc_layout()
|
local layout = calc_layout()
|
||||||
local text = create_string(layout)
|
local text = create_string(layout)
|
||||||
if vim.g.leaderGuide_max_size then
|
if vim.g.leaderGuide_max_size then
|
||||||
@ -583,12 +614,13 @@ local function start_buffer()
|
|||||||
col = 0,
|
col = 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, text)
|
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, text)
|
||||||
|
|
||||||
|
updateStatusline()
|
||||||
|
|
||||||
cmp.fn.setbufvar(bufnr, '&modifiable', 0)
|
cmp.fn.setbufvar(bufnr, '&modifiable', 0)
|
||||||
|
|
||||||
vim.cmd('redraw!')
|
vim.cmd('redraw')
|
||||||
|
|
||||||
wait_for_input()
|
wait_for_input()
|
||||||
end
|
end
|
||||||
@ -603,11 +635,11 @@ local function winclose()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function handle_input(input)
|
local function handle_input(input)
|
||||||
winclose()
|
if not cmp.islist(input) then
|
||||||
if not vim.tbl_islist(input) then
|
|
||||||
lmap = input
|
lmap = input
|
||||||
start_buffer()
|
start_buffer()
|
||||||
else
|
else
|
||||||
|
winclose()
|
||||||
prefix_key_inp = {}
|
prefix_key_inp = {}
|
||||||
cmp.fn.feedkeys(vis .. reg .. count, 'ti')
|
cmp.fn.feedkeys(vis .. reg .. count, 'ti')
|
||||||
|
|
||||||
@ -628,7 +660,6 @@ local function page_down()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function page_undo()
|
local function page_undo()
|
||||||
winclose()
|
|
||||||
if #prefix_key_inp then
|
if #prefix_key_inp then
|
||||||
table.remove(prefix_key_inp)
|
table.remove(prefix_key_inp)
|
||||||
end
|
end
|
||||||
@ -639,7 +670,6 @@ local function page_undo()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function page_up()
|
local function page_up()
|
||||||
|
|
||||||
-- vim.api.nvim_feedkeys(Key.t('<C-c>'), 'n', false)
|
-- vim.api.nvim_feedkeys(Key.t('<C-c>'), 'n', false)
|
||||||
vim.api.nvim_feedkeys(Key.t('<C-u>'), 'x', false)
|
vim.api.nvim_feedkeys(Key.t('<C-u>'), 'x', false)
|
||||||
vim.cmd('redraw!')
|
vim.cmd('redraw!')
|
||||||
|
Loading…
Reference in New Issue
Block a user