diff --git a/lua/cmp/utils/keymap.lua b/lua/cmp/utils/keymap.lua index 72f8a5c..f989018 100644 --- a/lua/cmp/utils/keymap.lua +++ b/lua/cmp/utils/keymap.lua @@ -1,4 +1,5 @@ local misc = require('cmp.utils.misc') +local str = require('cmp.utils.str') local cache = require('cmp.utils.cache') local keymap = {} @@ -130,7 +131,7 @@ keymap.listen = setmetatable({ existing = existing, callback = callback, }) - vim.api.nvim_buf_set_keymap(0, mode, keys, ('v:lua.cmp.utils.keymap.expr("%s", "%s")'):format(mode, keymap.escape(keys)), { + vim.api.nvim_buf_set_keymap(0, mode, keys, ('v:lua.cmp.utils.keymap.expr("%s", "%s")'):format(mode, str.escape(keymap.escape(keys), { '"' })), { expr = true, nowait = true, noremap = true, diff --git a/lua/cmp/utils/str.lua b/lua/cmp/utils/str.lua index 2572ca6..b50e577 100644 --- a/lua/cmp/utils/str.lua +++ b/lua/cmp/utils/str.lua @@ -156,6 +156,26 @@ str.oneline = function(text) return text end +---Escape special chars +---@param text string +---@param chars string[] +---@return string +str.escape = function(text, chars) + table.insert(chars, '\\') + local escaped = {} + local i = 1 + while i <= #text do + local c = string.sub(text, i, i) + if vim.tbl_contains(chars, c) then + table.insert(escaped, '\\') + table.insert(escaped, c) + else + table.insert(escaped, c) + end + i = i + 1 + end + return table.concat(escaped, '') +end + return str - diff --git a/lua/cmp/utils/str_spec.lua b/lua/cmp/utils/str_spec.lua index c07763c..2c15cec 100644 --- a/lua/cmp/utils/str_spec.lua +++ b/lua/cmp/utils/str_spec.lua @@ -21,6 +21,13 @@ describe('utils.str', function() assert.are.equal(str.remove_suffix('log()${0:placeholder}', '${0}'), 'log()${0:placeholder}') end) + it('escape', function() + assert.are.equal(str.escape('plain', {}), 'plain') + assert.are.equal(str.escape('plain\\', {}), 'plain\\\\') + assert.are.equal(str.escape('plain\\"', {}), 'plain\\\\"') + assert.are.equal(str.escape('pla"in', { '"' }), 'pla\\"in') + end) + end)