From ebe040b1a9e35ef9f7989da7e7f270eb2045e7b7 Mon Sep 17 00:00:00 2001 From: hrsh7th Date: Sat, 16 Oct 2021 13:27:36 +0900 Subject: [PATCH] Fix #279 --- lua/cmp/context.lua | 2 +- lua/cmp/entry.lua | 2 +- lua/cmp/source.lua | 2 +- lua/cmp/utils/keymap.lua | 30 +++++++++++++----------------- lua/cmp/utils/misc.lua | 14 ++++++++++++++ lua/cmp/utils/str_spec.lua | 1 + lua/cmp/utils/window.lua | 2 +- 7 files changed, 32 insertions(+), 21 deletions(-) diff --git a/lua/cmp/context.lua b/lua/cmp/context.lua index 46ce0ff..2a3e539 100644 --- a/lua/cmp/context.lua +++ b/lua/cmp/context.lua @@ -38,7 +38,7 @@ context.new = function(prev_context, option) option = option or {} local self = setmetatable({}, { __index = context }) - self.id = misc.id('context') + self.id = misc.id('cmp.context.new') self.cache = cache.new() self.prev_context = prev_context or context.empty() self.option = option or { reason = types.cmp.ContextReason.None } diff --git a/lua/cmp/entry.lua b/lua/cmp/entry.lua index 78085df..686c0de 100644 --- a/lua/cmp/entry.lua +++ b/lua/cmp/entry.lua @@ -32,7 +32,7 @@ local entry = {} ---@return cmp.Entry entry.new = function(ctx, source, completion_item) local self = setmetatable({}, { __index = entry }) - self.id = misc.id('entry') + self.id = misc.id('entry.new') self.cache = cache.new() self.match_cache = cache.new() self.score = 0 diff --git a/lua/cmp/source.lua b/lua/cmp/source.lua index b80d370..af90215 100644 --- a/lua/cmp/source.lua +++ b/lua/cmp/source.lua @@ -34,7 +34,7 @@ source.SourceStatus.COMPLETED = 3 ---@return cmp.Source source.new = function(name, s) local self = setmetatable({}, { __index = source }) - self.id = misc.id('source') + self.id = misc.id('cmp.source.new') self.name = name self.source = s self.cache = cache.new() diff --git a/lua/cmp/utils/keymap.lua b/lua/cmp/utils/keymap.lua index ad7269b..05a5cb1 100644 --- a/lua/cmp/utils/keymap.lua +++ b/lua/cmp/utils/keymap.lua @@ -136,46 +136,42 @@ end) keymap.listen = setmetatable({ cache = cache.new(), }, { - __call = function(self, mode, keys, callback) - keys = keymap.to_keymap(keys) - + __call = function(self, mode, keys_or_chars, callback) + local keys = keymap.to_keymap(keys_or_chars) local bufnr = vim.api.nvim_get_current_buf() local existing = keymap.find_map_by_lhs(mode, keys) local done = true done = done and string.match(existing.rhs, vim.pesc('v:lua.cmp.utils.keymap.listen.run')) - done = done and self.cache:get({ mode, bufnr, keys }) ~= nil + done = done and self.cache:get({ 'id', mode, bufnr, keys }) ~= nil if done then return end + self.cache:set({ 'id', mode, bufnr, keys }, misc.id('cmp.utils.keymap.listen')) local fallback = keymap.evacuate(mode, keys) - vim.api.nvim_buf_set_keymap(0, mode, keys, ('call v:lua.cmp.utils.keymap.listen.run("%s", "%s")'):format(mode, str.escape(keymap.escape(keys), { '"' })), { + vim.api.nvim_buf_set_keymap(0, mode, keys, ('call v:lua.cmp.utils.keymap.listen.run(%s)'):format(self.cache:get({ 'id', mode, bufnr, keys })), { expr = false, noremap = true, silent = true, nowait = true, }) - self.cache:set({ mode, bufnr, keys }, { + self.cache:set({ 'definition', self.cache:get({ 'id', mode, bufnr, keys }) }, { + keys = keys, mode = mode, + bufnr = bufnr, callback = callback, fallback = fallback, existing = existing, }) end, }) -misc.set(_G, { 'cmp', 'utils', 'keymap', 'listen', 'run' }, function(mode, keys) - local bufnr = vim.api.nvim_get_current_buf() - local fallback = keymap.listen.cache:get({ mode, bufnr, keys }).fallback - local callback = keymap.listen.cache:get({ mode, bufnr, keys }).callback - local done = false - callback(keys, function() - if not done then - done = true - keymap.feedkeys(keymap.t(fallback), 'i') - end - end) +misc.set(_G, { 'cmp', 'utils', 'keymap', 'listen', 'run' }, function(id) + local definition = keymap.listen.cache:get({ 'definition', id }) + definition.callback(definition.keys, misc.once(function() + keymap.feedkeys(keymap.t(definition.fallback), 'i') + end)) return keymap.t('') end) diff --git a/lua/cmp/utils/misc.lua b/lua/cmp/utils/misc.lua index 66feaac..270bae5 100644 --- a/lua/cmp/utils/misc.lua +++ b/lua/cmp/utils/misc.lua @@ -1,5 +1,19 @@ local misc = {} +---Create once callback +---@param callback function +---@return function +misc.once = function(callback) + local done = false + return function() + if done then + return + end + done = true + callback() + end +end + ---Return concatenated list ---@param list1 any[] ---@param list2 any[] diff --git a/lua/cmp/utils/str_spec.lua b/lua/cmp/utils/str_spec.lua index 1d1066d..d4e492e 100644 --- a/lua/cmp/utils/str_spec.lua +++ b/lua/cmp/utils/str_spec.lua @@ -25,5 +25,6 @@ describe('utils.str', function() assert.are.equal(str.escape('plain\\', {}), 'plain\\\\') assert.are.equal(str.escape('plain\\"', {}), 'plain\\\\"') assert.are.equal(str.escape('pla"in', { '"' }), 'pla\\"in') + assert.are.equal(str.escape('call("")', { '"' }), 'call(\\"\\")') end) end) diff --git a/lua/cmp/utils/window.lua b/lua/cmp/utils/window.lua index bc4a223..0f2cd3d 100644 --- a/lua/cmp/utils/window.lua +++ b/lua/cmp/utils/window.lua @@ -24,7 +24,7 @@ local window = {} ---@return cmp.Window window.new = function() local self = setmetatable({}, { __index = window }) - self.name = misc.id('cmp.utils.window') + self.name = misc.id('cmp.utils.window.new') self.win = nil self.swin1 = nil self.swin2 = nil