summaryrefslogtreecommitdiff
path: root/lua/blink/cmp/keymap/fallback.lua
diff options
context:
space:
mode:
authorMike Vink <mike@pionative.com>2025-01-19 13:52:52 +0100
committerMike Vink <mike@pionative.com>2025-01-19 13:52:52 +0100
commitb77413ff8f59f380612074f0c9bd49093d8db695 (patch)
tree32c39a811ba96ed4ab0a1c81cce9f8d518ed7e31 /lua/blink/cmp/keymap/fallback.lua
Squashed 'mut/neovim/pack/plugins/start/blink.cmp/' content from commit 1cc3b1a
git-subtree-dir: mut/neovim/pack/plugins/start/blink.cmp git-subtree-split: 1cc3b1a908fbcfd15451c4772759549724f38524
Diffstat (limited to 'lua/blink/cmp/keymap/fallback.lua')
-rw-r--r--lua/blink/cmp/keymap/fallback.lua91
1 files changed, 91 insertions, 0 deletions
diff --git a/lua/blink/cmp/keymap/fallback.lua b/lua/blink/cmp/keymap/fallback.lua
new file mode 100644
index 0000000..a73d69e
--- /dev/null
+++ b/lua/blink/cmp/keymap/fallback.lua
@@ -0,0 +1,91 @@
+local fallback = {}
+
+--- Add missing types. Remove when fixed upstream
+---@class blink.cmp.Fallback : vim.api.keyset.keymap
+---@field lhs string
+---@field mode string
+---@field rhs? string
+---@field lhsraw? string
+---@field buffer? number
+
+--- Gets the non blink.cmp global keymap for the given mode and key
+--- @param mode string
+--- @param key string
+--- @return blink.cmp.Fallback | nil
+function fallback.get_non_blink_global_mapping_for_key(mode, key)
+ local normalized_key = vim.api.nvim_replace_termcodes(key, true, true, true)
+
+ -- get global mappings
+ local mappings = vim.api.nvim_get_keymap(mode)
+
+ for _, mapping in ipairs(mappings) do
+ --- @cast mapping blink.cmp.Fallback
+ 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
+
+--- Gets the non blink.cmp buffer keymap for the given mode and key
+--- @param mode string
+--- @param key string
+--- @return blink.cmp.Fallback?
+function fallback.get_non_blink_buffer_mapping_for_key(mode, key)
+ local normalized_key = vim.api.nvim_replace_termcodes(key, true, true, true)
+
+ local buffer_mappings = vim.api.nvim_buf_get_keymap(0, mode)
+
+ for _, mapping in ipairs(buffer_mappings) do
+ --- @cast mapping blink.cmp.Fallback
+ 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
+
+--- Returns a function that will run the first non blink.cmp keymap for the given mode and key
+--- @param mode string
+--- @param key string
+--- @return fun(): string?
+function fallback.wrap(mode, key)
+ -- In default mode, there can't be multiple mappings on a single key for buffer local mappings
+ -- In cmdline mode, there can't be multiple mappings on a single key for global mappings
+ local buffer_mapping = mode ~= 'c' and fallback.get_non_blink_buffer_mapping_for_key(mode, key)
+ or fallback.get_non_blink_global_mapping_for_key(mode, key)
+ return function()
+ local mapping = buffer_mapping or fallback.get_non_blink_global_mapping_for_key(mode, key)
+ if mapping then return fallback.run_non_blink_keymap(mapping, key) end
+ return vim.api.nvim_replace_termcodes(key, true, true, true)
+ end
+end
+
+--- Runs the first non blink.cmp keymap for the given mode and key
+--- @param mapping blink.cmp.Fallback
+--- @param key string
+--- @return string | nil
+function fallback.run_non_blink_keymap(mapping, key)
+ -- 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
+ -- with expr = true, which we use, we can't modify the buffer without scheduling
+ -- so if the keymap does not use expr, we must schedule it
+ if mapping.expr ~= 1 then
+ vim.schedule(mapping.callback)
+ return
+ end
+
+ local expr = mapping.callback()
+ if type(expr) == 'string' and mapping.replace_keycodes == 1 then
+ expr = vim.api.nvim_replace_termcodes(expr, true, true, true)
+ end
+ return expr
+ elseif mapping.rhs then
+ local rhs = vim.api.nvim_replace_termcodes(mapping.rhs, true, true, true)
+ if mapping.expr == 1 then rhs = vim.api.nvim_eval(rhs) end
+ return rhs
+ end
+
+ -- pass the key along as usual
+ return vim.api.nvim_replace_termcodes(key, true, true, true)
+end
+
+return fallback