Skip to content

Commit 8b553f6

Browse files
folkeSaghen
andauthored
fix(fallback): make fallback work with buffer-local mappings (#483)
* fix(fallback): make fallback work with buffer-local mappings * fix: always check global keymaps * fix: empty dictionary check on fallback keymaps --------- Co-authored-by: Liam Dyer <[email protected]>
1 parent b368f77 commit 8b553f6

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

lua/blink/cmp/keymap/apply.lua

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ function apply.keymap_to_current_buffer(keys_to_commands)
1414
for key, commands in pairs(keys_to_commands) do
1515
if #commands == 0 then goto continue end
1616

17+
local fallback = require('blink.cmp.keymap.fallback').wrap('i', key)
18+
1719
apply.set('i', key, function()
1820
for _, command in ipairs(commands) do
1921
-- special case for fallback
2022
if command == 'fallback' then
21-
return require('blink.cmp.keymap.fallback').run_non_blink_keymap('i', key)
23+
return fallback()
2224

2325
-- run user defined functions
2426
elseif type(command) == 'function' then
@@ -42,11 +44,13 @@ function apply.keymap_to_current_buffer(keys_to_commands)
4244
end
4345
if not has_snippet_command or #commands == 0 then goto continue end
4446

47+
local fallback = require('blink.cmp.keymap.fallback').wrap('s', key)
48+
4549
apply.set('s', key, function()
4650
for _, command in ipairs(keys_to_commands[key] or {}) do
4751
-- special case for fallback
4852
if command == 'fallback' then
49-
return require('blink.cmp.keymap.fallback').run_non_blink_keymap('s', key)
53+
return fallback()
5054

5155
-- run user defined functions
5256
elseif type(command) == 'function' then

lua/blink/cmp/keymap/fallback.lua

+40-10
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,57 @@
11
local fallback = {}
22

3-
--- Gets the first non blink.cmp keymap for the given mode and key
3+
--- Add missing types. Remove when fixed upstream
4+
---@class vim.api.keyset.keymap
5+
---@field lhs string
6+
---@field mode string
7+
---@field rhs? string
8+
---@field lhsraw? string
9+
---@field buffer? number
10+
11+
--- Gets the non blink.cmp global keymap for the given mode and key
412
--- @param mode string
513
--- @param key string
614
--- @return vim.api.keyset.keymap | nil
7-
function fallback.get_non_blink_mapping_for_key(mode, key)
15+
function fallback.get_non_blink_global_mapping_for_key(mode, key)
816
local normalized_key = vim.api.nvim_replace_termcodes(key, true, true, true)
917

10-
-- get buffer local and global mappings
11-
local mappings = vim.api.nvim_buf_get_keymap(0, mode)
12-
vim.list_extend(mappings, vim.api.nvim_get_keymap(mode))
18+
-- get global mappings
19+
local mappings = vim.api.nvim_get_keymap(mode)
1320

1421
for _, mapping in ipairs(mappings) do
1522
local mapping_key = vim.api.nvim_replace_termcodes(mapping.lhs, true, true, true)
1623
if mapping_key == normalized_key and mapping.desc ~= 'blink.cmp' then return mapping end
1724
end
1825
end
1926

20-
--- Runs the first non blink.cmp keymap for the given mode and key
27+
--- Gets the non blink.cmp buffer keymap for the given mode and key
2128
--- @param mode string
2229
--- @param key string
23-
--- @return string | nil
24-
function fallback.run_non_blink_keymap(mode, key)
25-
local mapping = fallback.get_non_blink_mapping_for_key(mode, key) or {}
30+
--- @return vim.api.keyset.keymap?
31+
function fallback.get_non_blink_buffer_mapping_for_key(mode, key)
32+
local ret = vim.fn.maparg(key, mode, false, true) --[[@as vim.api.keyset.keymap]]
33+
if ret and ret.buffer == 0 then return end
34+
if ret and ret.desc and ret.desc == 'blink.cmp' then return end
35+
return ret.lhs ~= nil and ret or nil
36+
end
2637

38+
--- Returns a function that will run the first non blink.cmp keymap for the given mode and key
39+
--- @param mode string
40+
--- @param key string
41+
--- @return fun(): string?
42+
function fallback.wrap(mode, key)
43+
local buffer_mapping = fallback.get_non_blink_buffer_mapping_for_key(mode, key)
44+
return function()
45+
local mapping = buffer_mapping or fallback.get_non_blink_global_mapping_for_key(mode, key)
46+
if mapping then return fallback.run_non_blink_keymap(mapping, key) end
47+
end
48+
end
49+
50+
--- Runs the first non blink.cmp keymap for the given mode and key
51+
--- @param mapping vim.api.keyset.keymap
52+
--- @param key string
53+
--- @return string | nil
54+
function fallback.run_non_blink_keymap(mapping, key)
2755
-- TODO: there's likely many edge cases here. the nvim-cmp version is lacking documentation
2856
-- and is quite complex. we should look to see if we can simplify their logic
2957
-- https://github.com/hrsh7th/nvim-cmp/blob/ae644feb7b67bf1ce4260c231d1d4300b19c6f30/lua/cmp/utils/keymap.lua
@@ -36,7 +64,9 @@ function fallback.run_non_blink_keymap(mode, key)
3664
end
3765

3866
local expr = mapping.callback()
39-
if mapping.replace_keycodes == 1 then expr = vim.api.nvim_replace_termcodes(expr, true, true, true) end
67+
if type(expr) == 'string' and mapping.replace_keycodes == 1 then
68+
expr = vim.api.nvim_replace_termcodes(expr, true, true, true)
69+
end
4070
return expr
4171
elseif mapping.rhs then
4272
local rhs = vim.api.nvim_replace_termcodes(mapping.rhs, true, true, true)

0 commit comments

Comments
 (0)