diff --git a/lua/cmp/utils/keymap.lua b/lua/cmp/utils/keymap.lua index 7492f6e..ab25ae4 100644 --- a/lua/cmp/utils/keymap.lua +++ b/lua/cmp/utils/keymap.lua @@ -1,4 +1,3 @@ -local cache = require('cmp.utils.cache') local misc = require('cmp.utils.misc') local api = require('cmp.utils.api') @@ -102,16 +101,15 @@ keymap.listen = function(mode, lhs, callback) end local bufnr = existing.buffer and vim.api.nvim_get_current_buf() or -1 - local fallback = keymap.evacuate(bufnr, mode, existing) keymap.set_map(bufnr, mode, lhs, function() if mode == 'c' and vim.fn.getcmdtype() == '=' then - return vim.api.nvim_feedkeys(keymap.t(fallback), 'it', true) + return keymap.feed_map(existing) end callback( lhs, misc.once(function() - return vim.api.nvim_feedkeys(keymap.t(fallback), 'it', true) + keymap.feed_map(existing) end) ) end, { @@ -121,59 +119,6 @@ keymap.listen = function(mode, lhs, callback) }) end ----Evacuate existing keymapping. ----@param bufnr number ----@param mode string ----@param existing table ----@return string -keymap.evacuate = setmetatable({ - cache = cache.new(), -}, { - __call = function(self, bufnr, mode, existing) - local fallback = self.cache:ensure({ bufnr, mode, existing.lhs }, function() - return string.format('(cmp.u.k.evacuate:%s)', misc.id('cmp.utils.keymap.evacuate')) - end) - - local callback = not existing.expr and existing.callback - keymap.set_map(bufnr, mode, fallback, function() - -- Make resolved key sequence. - local lhs = keymap.t(existing.lhs) - local rhs - if existing.callback then - rhs = existing.callback() - elseif existing.expr then - rhs = vim.api.nvim_eval(keymap.t(existing.rhs)) - else - rhs = keymap.t(existing.rhs) - end - - -- Resolve recursive mapping. See `:help recursive_mapping`. - if not existing.noremap then - if string.find(rhs, lhs, 1, true) == 1 then - rhs = string.gsub(rhs, '^' .. vim.pesc(lhs), string.format(keymap.t([[=v:lua.vim.json.decode(%s)]]), vim.fn.string(vim.json.encode(lhs)))) - end - end - - return rhs - end, callback and { - expr = false, - callback = callback, - noremap = existing.noremap, - script = existing.script, - silent = mode ~= 'c', - nowait = existing.nowait, - } or { - expr = true, - noremap = existing.noremap, - script = existing.script, - silent = mode ~= 'c', - nowait = existing.nowait, - }) - - return fallback - end, -}) - ---Get map ---@param mode string ---@param lhs string @@ -220,12 +165,40 @@ keymap.get_map = function(mode, lhs) callback = nil, noremap = true, script = false, - silent = true, + silent = false, nowait = false, buffer = false, } end +---Feed mapping object. +---@param map table +keymap.feed_map = function(map) + local lhs = keymap.t(map.lhs) + local rhs + if map.callback and not map.expr then + return map.callback() + elseif map.callback and map.expr then + rhs = map.callback() + elseif map.expr then + rhs = vim.api.nvim_eval(keymap.t(map.rhs)) + else + rhs = keymap.t(map.rhs) + end + + if map.noremap then + vim.api.nvim_feedkeys(rhs, 'itn', true) + else + if string.find(rhs, lhs, 1, true) == 1 then + rhs = string.gsub(rhs, '^' .. vim.pesc(lhs), '') + vim.api.nvim_feedkeys(rhs, 'itm', true) + vim.api.nvim_feedkeys(lhs, 'itn', true) + else + vim.api.nvim_feedkeys(rhs, 'itm', true) + end + end +end + ---Set keymapping keymap.set_map = setmetatable({ callbacks = {}, diff --git a/lua/cmp/utils/keymap_spec.lua b/lua/cmp/utils/keymap_spec.lua index bd6a56f..71210e4 100644 --- a/lua/cmp/utils/keymap_spec.lua +++ b/lua/cmp/utils/keymap_spec.lua @@ -1,3 +1,4 @@ +local feedkeys = require('cmp.utils.feedkeys') local spec = require('cmp.utils.spec') local keymap = require('cmp.utils.keymap') @@ -31,7 +32,7 @@ describe('keymap', function() assert.are.equal(keymap.to_keymap('|'), '') end) - describe('evacuate', function() + describe('feedmap', function() before_each(spec.before) it('expr & register', function() @@ -39,8 +40,9 @@ describe('keymap', function() expr = true, noremap = false, }) - local fallback = keymap.evacuate(0, 'i', keymap.get_map('i', '(')) - vim.api.nvim_feedkeys('i' .. keymap.t(fallback), 'x', true) + feedkeys.call('i', 'nx', function() + keymap.feed_map(keymap.get_map('i', '(')) + end) assert.are.same({ '(' }, vim.api.nvim_buf_get_lines(0, 0, -1, true)) end) @@ -53,8 +55,9 @@ describe('keymap', function() expr = false, noremap = false, }) - local fallback = keymap.evacuate(0, 'i', keymap.get_map('i', '(')) - vim.api.nvim_feedkeys('i' .. keymap.t(fallback), 'x', true) + feedkeys.call('i', 'nx', function() + keymap.feed_map(keymap.get_map('i', '(')) + end) assert.are.same({ '()' }, vim.api.nvim_buf_get_lines(0, 0, -1, true)) end) @@ -66,8 +69,10 @@ describe('keymap', function() expr = true, noremap = false, }) - local fallback = keymap.evacuate(0, 'i', keymap.get_map('i', '')) - vim.api.nvim_feedkeys('i' .. keymap.t(fallback), 'x', true) + feedkeys.call('i', 'n', function() + keymap.feed_map(keymap.get_map('i', '')) + end) + feedkeys.call('', 'x') assert.are.same({ 'foobar' }, vim.api.nvim_buf_get_lines(0, 0, -1, true)) end) it('false', function() @@ -75,8 +80,9 @@ describe('keymap', function() expr = true, noremap = false, }) - local fallback = keymap.evacuate(0, 'i', keymap.get_map('i', '')) - vim.api.nvim_feedkeys('i' .. keymap.t(fallback), 'x', true) + feedkeys.call('i', 'nx', function() + keymap.feed_map(keymap.get_map('i', '')) + end) assert.are.same({ '\taiueo' }, vim.api.nvim_buf_get_lines(0, 0, -1, true)) end) end)