mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-23 13:50:05 +08:00
perf(guide): improve key binding guide
This commit is contained in:
parent
d6a34e3aff
commit
24712351a1
@ -7,125 +7,144 @@
|
||||
--=============================================================================
|
||||
local M = {}
|
||||
|
||||
local system = require('spacevim.api').import('system')
|
||||
|
||||
function M.eval(l)
|
||||
if vim.api ~= nil then
|
||||
return vim.api.nvim_eval(l)
|
||||
if vim.api ~= nil then
|
||||
return vim.api.nvim_eval(l)
|
||||
else
|
||||
return vim.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
|
||||
return vim.eval(l)
|
||||
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)
|
||||
end
|
||||
function M.cmd(command)
|
||||
return vim.command(command)
|
||||
end
|
||||
else
|
||||
function M.cmd(command)
|
||||
return vim.api.nvim_command(command)
|
||||
end
|
||||
function M.cmd(command)
|
||||
return vim.api.nvim_command(command)
|
||||
end
|
||||
end
|
||||
|
||||
-- there is no want to call viml function in old vim and neovim
|
||||
|
||||
local function build_argv(...)
|
||||
local str = ''
|
||||
for index, value in ipairs(...) do
|
||||
if str ~= '' then
|
||||
str = str .. ','
|
||||
end
|
||||
if type(value) == 'string' then
|
||||
str = str .. '"' .. value .. '"'
|
||||
elseif type(value) == 'number' then
|
||||
str = str .. value
|
||||
end
|
||||
local str = ''
|
||||
for _, value in ipairs(...) do
|
||||
if str ~= '' then
|
||||
str = str .. ','
|
||||
end
|
||||
return str
|
||||
if type(value) == 'string' then
|
||||
str = str .. '"' .. value .. '"'
|
||||
elseif type(value) == 'number' then
|
||||
str = str .. value
|
||||
end
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
function M.call(funcname, ...)
|
||||
if vim.call ~= nil then
|
||||
return vim.call(funcname, ...)
|
||||
if vim.call ~= nil then
|
||||
return vim.call(funcname, ...)
|
||||
else
|
||||
if vim.api ~= nil then
|
||||
return vim.api.nvim_call_function(funcname, { ... })
|
||||
else
|
||||
if vim.api ~= nil then
|
||||
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({...}) .. ')')
|
||||
return M.eval('g:lua_rst')
|
||||
end
|
||||
-- call not call vim script function in lua
|
||||
vim.command('let g:lua_rst = ' .. funcname .. '(' .. build_argv({ ... }) .. ')')
|
||||
return M.eval('g:lua_rst')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- this is for Vim and old neovim
|
||||
M.fn = setmetatable({}, {
|
||||
__index = function(t, key)
|
||||
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))
|
||||
end
|
||||
else
|
||||
_fn = function(...)
|
||||
return M.call(key, ...)
|
||||
end
|
||||
end
|
||||
t[key] = _fn
|
||||
return _fn
|
||||
__index = function(t, key)
|
||||
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))
|
||||
end
|
||||
else
|
||||
_fn = function(...)
|
||||
return M.call(key, ...)
|
||||
end
|
||||
end
|
||||
t[key] = _fn
|
||||
return _fn
|
||||
end,
|
||||
})
|
||||
|
||||
-- This is for vim and old neovim to use vim.o
|
||||
M.vim_options = setmetatable({}, {
|
||||
__index = function(t, key)
|
||||
local _fn
|
||||
if vim.api ~= nil then
|
||||
-- for neovim
|
||||
return vim.api.nvim_get_option(key)
|
||||
else
|
||||
-- for vim
|
||||
_fn = M.eval('&' .. key)
|
||||
end
|
||||
t[key] = _fn
|
||||
return _fn
|
||||
__index = function(t, key)
|
||||
local _fn
|
||||
if vim.api ~= nil then
|
||||
-- for neovim
|
||||
return vim.api.nvim_get_option(key)
|
||||
else
|
||||
-- for vim
|
||||
_fn = M.eval('&' .. key)
|
||||
end
|
||||
t[key] = _fn
|
||||
return _fn
|
||||
end,
|
||||
})
|
||||
|
||||
function M.echo(msg)
|
||||
if vim.api ~= nil then
|
||||
vim.api.nvim_echo({{msg}}, false, {})
|
||||
else
|
||||
vim.command('echo ' .. build_argv({msg}))
|
||||
end
|
||||
if vim.api ~= nil then
|
||||
vim.api.nvim_echo({ { msg } }, false, {})
|
||||
else
|
||||
vim.command('echo ' .. build_argv({ msg }))
|
||||
end
|
||||
end
|
||||
|
||||
local has_cache = {}
|
||||
|
||||
function M.has(feature)
|
||||
if has_cache[feature] ~= nil then
|
||||
return has_cache[feature]
|
||||
else
|
||||
return M.eval('float2nr(has("' .. feature .. '"))')
|
||||
end
|
||||
if has_cache[feature] ~= nil then
|
||||
return has_cache[feature]
|
||||
else
|
||||
return M.eval('float2nr(has("' .. feature .. '"))')
|
||||
end
|
||||
end
|
||||
|
||||
if M.has('patch-7.4.279') then
|
||||
function M.globpath(dir, expr)
|
||||
return M.fn.globpath(dir, expr, 1, 1)
|
||||
end
|
||||
function M.globpath(dir, expr)
|
||||
return M.fn.globpath(dir, expr, 1, 1)
|
||||
end
|
||||
else
|
||||
function M.globpath(dir, expr)
|
||||
return M.fn.split(fn.globpath(dir, expr), "\n")
|
||||
end
|
||||
function M.globpath(dir, expr)
|
||||
return M.fn.split(vim.fn.globpath(dir, expr), '\n')
|
||||
end
|
||||
end
|
||||
|
||||
function M.execute(cmd, silent)
|
||||
return M.fn.execute(cmd, silent)
|
||||
return M.fn.execute(cmd, silent)
|
||||
end
|
||||
|
||||
function M.win_screenpos(nr)
|
||||
return vim.fn.win_screenpos(nr)
|
||||
return vim.fn.win_screenpos(nr)
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -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 = {}
|
||||
|
||||
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]))
|
||||
for k, v in pairs(lmap) do
|
||||
if v ~= 'name' then
|
||||
smap[k] = v
|
||||
end
|
||||
end
|
||||
local maxlength = vim.fn.max(length) + vim.g.leaderGuide_hspace
|
||||
|
||||
ret.n_items = vim.fn.len(smap)
|
||||
local length = {}
|
||||
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()
|
||||
winid, bufnr = winopen()
|
||||
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!')
|
||||
|
Loading…
Reference in New Issue
Block a user