diff --git a/lua/blink/cmp/keymap.lua b/lua/blink/cmp/keymap.lua index 8efd909d..8caf4c5e 100644 --- a/lua/blink/cmp/keymap.lua +++ b/lua/blink/cmp/keymap.lua @@ -42,39 +42,32 @@ function keymap.setup(opts) -- we set on the buffer directly to avoid buffer-local keymaps (such as from autopairs) -- from overriding our mappings local set_buffer_keymap = function() + -- insert mode for key, _ in pairs(insert_keys_to_commands) do - vim.api.nvim_buf_set_keymap(0, 'i', key, '', { - callback = function() - for _, command in ipairs(insert_keys_to_commands[key] or {}) do - local did_run = require('blink.cmp')[command]() - if did_run then return end - end - for _, command in ipairs(snippet_keys_to_commands[key] or {}) do - local did_run = require('blink.cmp')[command]() - if did_run then return end - end - return key - end, - expr = true, - silent = true, - noremap = true, - replace_keycodes = true, - }) + keymap.set('i', key, function() + for _, command in ipairs(insert_keys_to_commands[key] or {}) do + local did_run = require('blink.cmp')[command]() + if did_run then return end + end + for _, command in ipairs(snippet_keys_to_commands[key] or {}) do + local did_run = require('blink.cmp')[command]() + if did_run then return end + end + + return keymap.run_non_blink_keymap('i', key) + end) end + + -- snippet mode for key, _ in pairs(snippet_keys_to_commands) do - vim.api.nvim_buf_set_keymap(0, 's', key, '', { - callback = function() - for _, command in ipairs(snippet_keys_to_commands[key] or {}) do - local did_run = require('blink.cmp')[command]() - if did_run then return end - end - return key - end, - expr = true, - silent = true, - noremap = true, - replace_keycodes = true, - }) + keymap.set('s', key, function() + for _, command in ipairs(snippet_keys_to_commands[key] or {}) do + local did_run = require('blink.cmp')[command]() + if did_run then return end + end + + return keymap.run_non_blink_keymap('s', key) + end) end end @@ -82,4 +75,46 @@ function keymap.setup(opts) vim.api.nvim_create_autocmd('BufEnter', { callback = set_buffer_keymap }) end +--- Gets the first non blink.cmp keymap for the given mode and key +function keymap.get_non_blink_mapping_for_key(mode, key) + local normalized_key = vim.api.nvim_replace_termcodes(key, true, true, true) + + -- get buffer local and global mappings + local mappings = vim.api.nvim_buf_get_keymap(0, mode) + vim.list_extend(mappings, vim.api.nvim_get_keymap(mode)) + + for _, mapping in ipairs(mappings) do + local mapping_key = vim.api.nvim_replace_termcodes(mapping.lhs, true, true, true) + if mapping_key == normalized_key and mapping.desc ~= 'blink.cmp' then return mapping end + end +end + +--- Runs the first non blink.cmp keymap for the given mode and key +function keymap.run_non_blink_keymap(mode, key) + local mapping = keymap.get_non_blink_mapping_for_key(mode, key) or {} + + -- todo: there's likely many edge cases here. the nvim-cmp version is lacking documentation + -- and is quite complex. we should look to see if we can simplify their logic + -- https://github.com/hrsh7th/nvim-cmp/blob/ae644feb7b67bf1ce4260c231d1d4300b19c6f30/lua/cmp/utils/keymap.lua + if type(mapping.callback) == 'function' then + return mapping.callback() + elseif mapping.rhs then + return vim.api.nvim_eval(vim.api.nvim_replace_termcodes(mapping.rhs, true, true, true)) + end + + -- pass the key along as usual + return vim.api.nvim_replace_termcodes(key, true, true, true) +end + +function keymap.set(mode, key, callback) + vim.api.nvim_buf_set_keymap(0, mode, key, '', { + callback = callback, + expr = true, + silent = true, + noremap = true, + replace_keycodes = false, + desc = 'blink.cmp', + }) +end + return keymap