diff --git a/lua/cmp/config/default.lua b/lua/cmp/config/default.lua index cf7e37e..498a40e 100644 --- a/lua/cmp/config/default.lua +++ b/lua/cmp/config/default.lua @@ -29,6 +29,10 @@ return function() winhighlight = 'NormalFloat:CmpDocumentation,FloatBorder:CmpDocumentationBorder', maxwidth = math.floor((WIDE_HEIGHT * 2) * (vim.o.columns / (WIDE_HEIGHT * 2 * 16 / 9))), maxheight = math.floor(WIDE_HEIGHT * (WIDE_HEIGHT / vim.o.lines)), + mapping = { + [''] = types.cmp.ScrollDirection.Up, + [''] = types.cmp.ScrollDirection.Down, + } }, confirmation = { diff --git a/lua/cmp/core.lua b/lua/cmp/core.lua index a994b07..3c2e5e7 100644 --- a/lua/cmp/core.lua +++ b/lua/cmp/core.lua @@ -69,6 +69,16 @@ end ---Keypress handler core.on_keymap = function(keys, fallback) + -- Documentation scroll + if config.get().documentation.mapping[keys] then + if config.get().documentation.mapping[keys] == types.cmp.ScrollDirection.Up then + core.menu.float:scroll(-4) + elseif config.get().documentation.mapping[keys] == types.cmp.ScrollDirection.Down then + core.menu.float:scroll(4) + end + return + end + -- Confirm character if config.get().confirmation.mapping[keys] then local c = config.get().confirmation.mapping[keys] @@ -110,6 +120,9 @@ core.prepare = function() for keys in pairs(config.get().confirmation.mapping) do keymap.listen(keys, core.on_keymap) end + for keys in pairs(config.get().documentation.mapping) do + keymap.listen(keys, core.on_keymap) + end end ---Check auto-completion diff --git a/lua/cmp/float.lua b/lua/cmp/float.lua index 7755d1c..0f3883c 100644 --- a/lua/cmp/float.lua +++ b/lua/cmp/float.lua @@ -112,4 +112,21 @@ float.close = async.throttle( 20 ) +float.scroll = function(self, delta) + if self.win and vim.api.nvim_win_is_valid(self.win) then + local info = vim.fn.getwininfo(self.win)[1] or {} + local buf = vim.api.nvim_win_get_buf(self.win) + local top = info.topline or 1 + top = top + delta + top = math.max(top, 1) + top = math.min(top, vim.api.nvim_buf_line_count(buf) - info.height + 1) + + vim.defer_fn(function() + vim.api.nvim_buf_call(buf, function() + vim.cmd('normal! ' .. top .. 'zt') + end) + end, 0) + end +end + return float diff --git a/lua/cmp/types/cmp.lua b/lua/cmp/types/cmp.lua index 3d4122f..7c8f963 100644 --- a/lua/cmp/types/cmp.lua +++ b/lua/cmp/types/cmp.lua @@ -17,6 +17,11 @@ cmp.TriggerEvent = {} cmp.TriggerEvent.InsertEnter = 'InsertEnter' cmp.TriggerEvent.TextChanged = 'TextChanged' +---@alias cmp.ScrollDirection "'up'" | "'down'" +cmp.ScrollDirection = {} +cmp.ScrollDirection.Up = 'up' +cmp.ScrollDirection.Down = 'down' + ---@class cmp.ContextOption ---@field public reason cmp.ContextReason|nil @@ -59,6 +64,7 @@ cmp.TriggerEvent.TextChanged = 'TextChanged' ---@field public winhighlight string ---@field public maxwidth number|nil ---@field public maxheight number|nil +---@field public mapping table ---@class cmp.ConfirmationConfig ---@field public default_behavior cmp.ConfirmBehavior diff --git a/lua/cmp/utils/keymap.lua b/lua/cmp/utils/keymap.lua index 5c5adc5..f3c110e 100644 --- a/lua/cmp/utils/keymap.lua +++ b/lua/cmp/utils/keymap.lua @@ -19,6 +19,21 @@ keymap.t = function(keys) return vim.api.nvim_replace_termcodes(keys, true, true, true) end +---Escape keymap with +keymap.escape = function(keys) + local i = 1 + while i <= #keys do + if string.sub(keys, i, i) == '<' then + if not vim.tbl_contains({ '', '', '', '' }, string.sub(keys, i, i + 3)) then + keys = string.sub(keys, 1, i -1) .. '' .. string.sub(keys, i + 1) + i = i + 3 + end + end + i = i + 1 + end + return keys +end + ---Return vim notation keymapping (simple conversion). ---@param s string ---@return string @@ -107,7 +122,7 @@ keymap.listen = setmetatable({ existing = existing, callback = callback, }) - vim.api.nvim_buf_set_keymap(0, 'i', keys, ('v:lua.cmp.utils.keymap.expr("%s")'):format(keys), { + vim.api.nvim_buf_set_keymap(0, 'i', keys, ('v:lua.cmp.utils.keymap.expr("%s")'):format(keymap.escape(keys)), { expr = true, nowait = true, noremap = true, @@ -115,7 +130,6 @@ keymap.listen = setmetatable({ end, }) misc.set(_G, { 'cmp', 'utils', 'keymap', 'expr' }, function(keys) - keys = keymap.to_keymap(keys) local bufnr = vim.api.nvim_get_current_buf() local existing = keymap.listen.cache:get({ bufnr, keys }).existing diff --git a/lua/cmp/utils/keymap_spec.lua b/lua/cmp/utils/keymap_spec.lua index 6024904..359204b 100644 --- a/lua/cmp/utils/keymap_spec.lua +++ b/lua/cmp/utils/keymap_spec.lua @@ -10,4 +10,10 @@ describe('keymap', function() assert.are.equal(keymap.to_keymap(''), '') assert.are.equal(keymap.to_keymap('|'), '') end) + + it('escape', function() + assert.are.equal(keymap.escape(''), 'C-d>') + assert.are.equal(keymap.escape(''), 'C-d>C-f>') + assert.are.equal(keymap.escape('C-d>'), 'C-d>') + end) end)