diff --git a/lua/cmp/autocmd.lua b/lua/cmp/autocmd.lua index 3d37407..4af766a 100644 --- a/lua/cmp/autocmd.lua +++ b/lua/cmp/autocmd.lua @@ -24,6 +24,7 @@ end ---Emit autocmd ---@param event string autocmd.emit = function(event) + debug.log(' ') debug.log(string.format('>>> %s', event)) autocmd.events[event] = autocmd.events[event] or {} for _, callback in ipairs(autocmd.events[event]) do diff --git a/lua/cmp/core.lua b/lua/cmp/core.lua index a50cc7d..cea51b9 100644 --- a/lua/cmp/core.lua +++ b/lua/cmp/core.lua @@ -18,7 +18,7 @@ core.SOURCE_TIMEOUT = 500 core.menu = menu.new({ on_select = function(e) for _, c in ipairs(e:get_commit_characters()) do - keymap.listen(c, core.on_keymap) + keymap.listen('i', c, core.on_keymap) end end, }) @@ -102,8 +102,16 @@ end ---Prepare completion core.prepare = function() - for keys in pairs(config.get().mapping) do - keymap.listen(keys, core.on_keymap) + for keys, action in pairs(config.get().mapping) do + if type(action) == 'function' then + action = { + modes = { 'i' }, + action = action, + } + end + for _, mode in ipairs(action.modes) do + keymap.listen(mode, keys, core.on_keymap) + end end end diff --git a/lua/cmp/mapping.lua b/lua/cmp/mapping.lua index 31094ef..465f250 100644 --- a/lua/cmp/mapping.lua +++ b/lua/cmp/mapping.lua @@ -2,55 +2,66 @@ local types = require('cmp.types') local mapping = {} +mapping.mode = function(modes, action) + return setmetatable({ + modes = modes or { 'i' }, + action = action, + }, { + __call = function(_, ...) + action(...) + end, + }) +end + mapping.complete = function() - return function(core) + return mapping.mode({ 'i' }, function(core) core.complete(core.get_context({ reason = types.cmp.ContextReason.Manual })) - end + end) end mapping.close = function() - return function(core, fallback) + return mapping.mode({ 'i' }, function(core, fallback) if vim.fn.pumvisible() == 1 then core.reset() else fallback() end - end + end) end mapping.scroll = function(delta) - return function(core, fallback) + return mapping.mode({ 'i' }, function(core, fallback) if core.menu.float:is_visible() then core.menu.float:scroll(delta) else fallback() end - end + end) end mapping.next_item = function() - return function(_, fallback) + return mapping.mode({ 'i' }, function(_, fallback) if vim.fn.pumvisible() == 1 then vim.fn.feedkeys(vim.api.nvim_replace_termcodes('', true, true, true), 'n') else fallback() end - end + end) end mapping.prev_item = function() - return function(_, fallback) + return mapping.mode({ 'i' }, function(_, fallback) if vim.fn.pumvisible() == 1 then vim.fn.feedkeys(vim.api.nvim_replace_termcodes('', true, true, true), 'n') else fallback() end - end + end) end mapping.confirm = function(option) option = option or {} - return function(core, fallback) + return mapping.mode({ 'i' }, function(core, fallback) local e = core.menu:get_selected_entry() or (option.select and core.menu:get_first_entry() or nil) if e then core.confirm(e, { @@ -61,7 +72,7 @@ mapping.confirm = function(option) else fallback() end - end + end) end return mapping diff --git a/lua/cmp/menu.lua b/lua/cmp/menu.lua index 2203b8c..aee6be7 100644 --- a/lua/cmp/menu.lua +++ b/lua/cmp/menu.lua @@ -74,8 +74,8 @@ menu.update = check.wrap(function(self, ctx, sources) -- check the source triggered by character local has_triggered_by_symbol_source = false for _, s in ipairs(sources) do - if s:has_items() then - if #s:get_entries(ctx) > 0 and s.is_triggered_by_symbol then + if #s:get_entries(ctx) > 0 then + if s.is_triggered_by_symbol then has_triggered_by_symbol_source = true break end @@ -85,7 +85,7 @@ menu.update = check.wrap(function(self, ctx, sources) -- create filtered entries. local offset = ctx.cursor.col for i, s in ipairs(sources) do - if s:has_items() and s.offset <= offset then + if s.offset <= offset then if not has_triggered_by_symbol_source or s.is_triggered_by_symbol then -- source order priority bonus. local priority = (#sources - (i - 1)) * config.get().sorting.priority_weight diff --git a/lua/cmp/utils/keymap.lua b/lua/cmp/utils/keymap.lua index 204325f..0b33eed 100644 --- a/lua/cmp/utils/keymap.lua +++ b/lua/cmp/utils/keymap.lua @@ -91,16 +91,16 @@ end) keymap.listen = setmetatable({ cache = cache.new(), }, { - __call = function(_, keys, callback) + __call = function(_, mode, keys, callback) keys = keymap.to_keymap(keys) local bufnr = vim.api.nvim_get_current_buf() - if keymap.listen.cache:get({ bufnr, keys }) then + if keymap.listen.cache:get({ mode, bufnr, keys }) then return end local existing = nil - for _, map in ipairs(vim.api.nvim_buf_get_keymap(0, 'i')) do + for _, map in ipairs(vim.api.nvim_buf_get_keymap(0, mode)) do if existing then break end @@ -108,7 +108,7 @@ keymap.listen = setmetatable({ existing = map end end - for _, map in ipairs(vim.api.nvim_get_keymap('i')) do + for _, map in ipairs(vim.api.nvim_get_keymap(mode)) do if existing then break end @@ -125,11 +125,12 @@ keymap.listen = setmetatable({ noremap = 1, } - keymap.listen.cache:set({ bufnr, keys }, { + keymap.listen.cache:set({ mode, bufnr, keys }, { + mode = mode, existing = existing, callback = callback, }) - vim.api.nvim_buf_set_keymap(0, 'i', keys, ('v:lua.cmp.utils.keymap.expr("%s")'):format(keymap.escape(keys)), { + vim.api.nvim_buf_set_keymap(0, mode, keys, ('v:lua.cmp.utils.keymap.expr("%s", "%s")'):format(mode, keymap.escape(keys)), { expr = true, nowait = true, noremap = true, @@ -137,13 +138,13 @@ keymap.listen = setmetatable({ }) end, }) -misc.set(_G, { 'cmp', 'utils', 'keymap', 'expr' }, function(keys) +misc.set(_G, { 'cmp', 'utils', 'keymap', 'expr' }, function(mode, keys) local bufnr = vim.api.nvim_get_current_buf() - local existing = keymap.listen.cache:get({ bufnr, keys }).existing - local callback = keymap.listen.cache:get({ bufnr, keys }).callback + local existing = keymap.listen.cache:get({ mode, bufnr, keys }).existing + local callback = keymap.listen.cache:get({ mode, bufnr, keys }).callback callback(keys, function() - vim.api.nvim_buf_set_keymap(0, 'i', '(cmp-utils-keymap:_)', existing.rhs, { + vim.api.nvim_buf_set_keymap(0, mode, '(cmp-utils-keymap:_)', existing.rhs, { expr = existing.expr ~= 0, noremap = existing.noremap ~= 0, script = existing.script ~= 0,