Skip to content

Commit 8b9af0c

Browse files
committed
fix: ensure keymaps are buffer-aware
Fixes zbirenbaum#573
1 parent 46e9895 commit 8b9af0c

File tree

5 files changed

+65
-44
lines changed

5 files changed

+65
-44
lines changed

lua/copilot/client/init.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ function M.buf_attach(force, bufnr)
101101
end
102102

103103
vim.lsp.buf_attach_client(bufnr, M.id)
104+
require("copilot.suggestion").set_keymap(bufnr)
105+
require("copilot.nes").set_keymap(bufnr)
106+
104107
util.set_buffer_previous_ft(bufnr, vim.bo[bufnr].filetype)
105108
if force then
106109
logger.debug("force attached to buffer")
@@ -116,6 +119,8 @@ function M.buf_detach_if_attached(bufnr)
116119
bufnr = bufnr or vim.api.nvim_get_current_buf()
117120
if M.buf_is_attached(bufnr) then
118121
vim.lsp.buf_detach_client(bufnr, M.id)
122+
require("copilot.suggestion").unset_keymap(bufnr)
123+
require("copilot.nes").unset_keymap(bufnr)
119124
util.set_buffer_attach_status(bufnr, util.ATTACH_STATUS_NOT_ATTACHED_PREFIX .. "detached")
120125
end
121126
end

lua/copilot/keymaps/init.lua

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ end
3030
---@param key string
3131
---@param action function: boolean
3232
---@param desc string
33-
function M.register_keymap_with_passthrough(mode, key, action, desc)
33+
---@param bufnr integer
34+
function M.register_keymap_with_passthrough(mode, key, action, desc, bufnr)
3435
if not key then
3536
return
3637
end
@@ -86,17 +87,19 @@ function M.register_keymap_with_passthrough(mode, key, action, desc)
8687
desc = desc,
8788
expr = true,
8889
silent = true,
90+
buffer = bufnr,
8991
})
9092
end
9193

9294
---@param mode string
9395
---@param key string|false
94-
function M.unset_keymap_if_exists(mode, key)
96+
---@param bufnr integer
97+
function M.unset_keymap_if_exists(mode, key, bufnr)
9598
if not key then
9699
return
97100
end
98101

99-
local ok, err = pcall(vim.api.nvim_del_keymap, mode, key)
102+
local ok, err = pcall(vim.api.nvim_del_buf_keymap, bufnr, mode, key)
100103

101104
if not ok then
102105
local suggestion_keymaps = config.suggestion.keymap or {}

lua/copilot/nes/init.lua

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,37 @@ local function accept_suggestion(goto_end)
1919
return result
2020
end
2121

22-
---@class NesKeymap
23-
local function set_keymap(keymap)
22+
---@param bufnr integer
23+
function M.set_keymap(bufnr)
24+
if not config.nes.enabled then
25+
return
26+
end
27+
28+
local keymap = config.nes.keymap
29+
2430
keymaps.register_keymap_with_passthrough("n", keymap.accept_and_goto, function()
2531
return accept_suggestion(true)
26-
end, "[copilot] (nes) accept suggestion and go to end")
32+
end, "[copilot] (nes) accept suggestion and go to end", bufnr)
2733

2834
keymaps.register_keymap_with_passthrough("n", keymap.accept, function()
2935
return accept_suggestion(false)
30-
end, "[copilot] (nes) accept suggestion")
36+
end, "[copilot] (nes) accept suggestion", bufnr)
3137

3238
keymaps.register_keymap_with_passthrough("n", keymap.dismiss, function()
3339
return nes_api.nes_clear()
34-
end, "[copilot] (nes) dismiss suggestion")
40+
end, "[copilot] (nes) dismiss suggestion", bufnr)
3541
end
3642

37-
---@param keymap NesKeymap
38-
local function unset_keymap(keymap)
39-
keymaps.unset_keymap_if_exists("n", keymap.accept_and_goto)
40-
keymaps.unset_keymap_if_exists("n", keymap.accept)
41-
keymaps.unset_keymap_if_exists("n", keymap.dismiss)
43+
---@param bufnr integer
44+
function M.unset_keymap(bufnr)
45+
if not config.nes.enabled then
46+
return
47+
end
48+
49+
local keymap = config.nes.keymap
50+
keymaps.unset_keymap_if_exists("n", keymap.accept_and_goto, bufnr)
51+
keymaps.unset_keymap_if_exists("n", keymap.accept, bufnr)
52+
keymaps.unset_keymap_if_exists("n", keymap.dismiss, bufnr)
4253
end
4354

4455
---@param lsp_client vim.lsp.Client
@@ -59,16 +70,13 @@ function M.setup(lsp_client)
5970
logger.error("copilot-lsp nes failed to load:", err)
6071
end
6172

62-
set_keymap(config.nes.keymap)
6373
M.initialized = true
6474
end
6575

6676
function M.teardown()
6777
if not M.initialized then
6878
return
6979
end
70-
71-
unset_keymap(config.nes.keymap)
7280
end
7381

7482
return M

lua/copilot/panel/init.lua

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ function panel:accept()
238238
end
239239

240240
function panel:close()
241+
keymaps.unset_keymap_if_exists("i", panel.keymap.open, self.bufnr)
242+
keymaps.unset_keymap_if_exists("n", panel.keymap.accept, self.bufnr)
243+
keymaps.unset_keymap_if_exists("n", panel.keymap.jump_prev, self.bufnr)
244+
keymaps.unset_keymap_if_exists("n", panel.keymap.jump_next, self.bufnr)
245+
keymaps.unset_keymap_if_exists("n", panel.keymap.refresh, self.bufnr)
246+
241247
if self.bufnr and vim.api.nvim_win_is_valid(self.bufnr) then
242248
self:unlock():clear():lock()
243249
end
@@ -598,15 +604,6 @@ function M.teardown()
598604
return
599605
end
600606

601-
keymaps.unset_keymap_if_exists("i", panel.keymap.open)
602-
603-
if M.keymaps_set then
604-
keymaps.unset_keymap_if_exists("n", panel.keymap.accept)
605-
keymaps.unset_keymap_if_exists("n", panel.keymap.jump_prev)
606-
keymaps.unset_keymap_if_exists("n", panel.keymap.jump_next)
607-
keymaps.unset_keymap_if_exists("n", panel.keymap.refresh)
608-
end
609-
610607
panel:close()
611608
panel.setup_done = false
612609
end

lua/copilot/suggestion/init.lua

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,14 @@ local function reset_ctx(ctx)
119119
ctx.accepted_partial = nil
120120
end
121121

122-
local function set_keymap(keymap)
122+
---@param bufnr integer
123+
function M.set_keymap(bufnr)
124+
if not config.suggestion.enabled then
125+
return
126+
end
127+
128+
local keymap = config.suggestion.keymap or {}
129+
123130
keymaps.register_keymap_with_passthrough("i", keymap.accept, function()
124131
local ctx = get_ctx()
125132
if (config.suggestion.trigger_on_accept and not ctx.first) or M.is_visible() then
@@ -128,12 +135,12 @@ local function set_keymap(keymap)
128135
end
129136

130137
return false
131-
end, "[copilot] accept suggestion")
138+
end, "[copilot] accept suggestion", bufnr)
132139

133-
keymaps.register_keymap("i", keymap.accept_word, M.accept_word, "[copilot] accept suggestion (word)")
134-
keymaps.register_keymap("i", keymap.accept_line, M.accept_line, "[copilot] accept suggestion (line)")
135-
keymaps.register_keymap("i", keymap.next, M.next, "[copilot] next suggestion")
136-
keymaps.register_keymap("i", keymap.prev, M.prev, "[copilot] prev suggestion")
140+
keymaps.register_keymap("i", keymap.accept_word, M.accept_word, "[copilot] accept suggestion (word)", bufnr)
141+
keymaps.register_keymap("i", keymap.accept_line, M.accept_line, "[copilot] accept suggestion (line)", bufnr)
142+
keymaps.register_keymap("i", keymap.next, M.next, "[copilot] next suggestion", bufnr)
143+
keymaps.register_keymap("i", keymap.prev, M.prev, "[copilot] prev suggestion", bufnr)
137144

138145
keymaps.register_keymap_with_passthrough("i", keymap.dismiss, function()
139146
if M.is_visible() then
@@ -142,16 +149,22 @@ local function set_keymap(keymap)
142149
end
143150

144151
return false
145-
end, "[copilot] dismiss suggestion")
152+
end, "[copilot] dismiss suggestion", bufnr)
146153
end
147154

148-
local function unset_keymap(keymap)
149-
keymaps.unset_keymap_if_exists("i", keymap.accept)
150-
keymaps.unset_keymap_if_exists("i", keymap.accept_word)
151-
keymaps.unset_keymap_if_exists("i", keymap.accept_line)
152-
keymaps.unset_keymap_if_exists("i", keymap.next)
153-
keymaps.unset_keymap_if_exists("i", keymap.prev)
154-
keymaps.unset_keymap_if_exists("i", keymap.dismiss)
155+
---@param bufnr integer
156+
function M.unset_keymap(bufnr)
157+
if not config.suggestion.enabled then
158+
return
159+
end
160+
161+
local keymap = config.suggestion.keymap or {}
162+
keymaps.unset_keymap_if_exists("i", keymap.accept, bufnr)
163+
keymaps.unset_keymap_if_exists("i", keymap.accept_word, bufnr)
164+
keymaps.unset_keymap_if_exists("i", keymap.accept_line, bufnr)
165+
keymaps.unset_keymap_if_exists("i", keymap.next, bufnr)
166+
keymaps.unset_keymap_if_exists("i", keymap.prev, bufnr)
167+
keymaps.unset_keymap_if_exists("i", keymap.dismiss, bufnr)
155168
end
156169

157170
local function stop_timer()
@@ -839,8 +852,6 @@ function M.setup()
839852
return
840853
end
841854

842-
set_keymap(opts.keymap or {})
843-
844855
copilot.auto_trigger = opts.auto_trigger
845856
copilot.hide_during_completion = opts.hide_during_completion
846857

@@ -860,10 +871,7 @@ function M.teardown()
860871
return
861872
end
862873

863-
unset_keymap(opts.keymap or {})
864-
865874
vim.api.nvim_clear_autocmds({ group = copilot.augroup })
866-
867875
copilot.setup_done = false
868876
end
869877

0 commit comments

Comments
 (0)