Skip to content

Commit 304fc5f

Browse files
committed
refactor: rework the duplicated keymap logic
1 parent 6fba227 commit 304fc5f

File tree

3 files changed

+53
-52
lines changed

3 files changed

+53
-52
lines changed

lua/copilot/config/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ function M.validate(config)
8080
require("copilot.config.root_dir").validate(config.root_dir)
8181
require("copilot.config.should_attach").validate(config.should_attach)
8282
require("copilot.config.nes").validate(config.nes)
83+
require("copilot.keymaps").validate(config)
8384
end
8485

8586
return M

lua/copilot/keymaps/init.lua

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
local logger = require("copilot.logger")
2-
local config = require("copilot.config")
32

43
local M = {}
54
local previous_keymaps = {}
65

6+
---@param bufnr integer
7+
---@param mode string
8+
---@param key string
79
local function get_keymap_key(bufnr, mode, key)
10+
if not bufnr or not mode or not key then
11+
logger.error("Invalid parameters to get_keymap_key" .. vim.inspect({ bufnr, mode, key }))
12+
return "invalid"
13+
end
14+
815
return bufnr .. ":" .. mode .. ":" .. key
916
end
1017
---@param mode string
@@ -22,6 +29,12 @@ function M.register_keymap(mode, key, action, desc, bufnr)
2229
return
2330
end
2431

32+
local keymap_key = get_keymap_key(bufnr, mode, key)
33+
if previous_keymaps[keymap_key] then
34+
logger.trace("Keymap already registered for " .. keymap_key)
35+
return
36+
end
37+
2538
vim.keymap.set(mode, key, function()
2639
action()
2740
end, {
@@ -30,7 +43,7 @@ function M.register_keymap(mode, key, action, desc, bufnr)
3043
buffer = bufnr,
3144
})
3245

33-
previous_keymaps[get_keymap_key(bufnr, mode, key)] = { type = "none", value = nil }
46+
previous_keymaps[keymap_key] = { type = "none", value = nil }
3447
end
3548

3649
---@param mode string
@@ -109,33 +122,48 @@ end
109122
---@param key string|false
110123
---@param bufnr integer
111124
function M.unset_keymap_if_exists(mode, key, bufnr)
112-
if not key then
125+
if not key or not bufnr then
113126
return
114127
end
115128

116129
local ok, err = pcall(vim.api.nvim_buf_del_keymap, bufnr, mode, key)
117130
previous_keymaps[get_keymap_key(bufnr, mode, key)] = nil
118131

119132
if not ok then
120-
local suggestion_keymaps = config.suggestion.keymap or {}
121-
local nes_keymaps = config.nes.keymap or {}
122-
local panel_keymaps = config.panel.keymap or {}
123-
local found = false
124-
125-
for _, tbl in ipairs({ suggestion_keymaps, nes_keymaps, panel_keymaps }) do
126-
for _, v in pairs(tbl) do
127-
if v == key then
128-
if found then
129-
logger.error("Keymap " .. key .. " is used for two different actions, please review your configuration.")
130-
return
131-
else
132-
found = true
133-
end
134-
end
133+
logger.error("Could not unset keymap for " .. (mode or "nil") .. " " .. key .. ", bufnr " .. bufnr .. ": " .. err)
134+
end
135+
end
136+
137+
---@param config CopilotConfig
138+
function M.validate(config)
139+
local suggestion_keymaps = config.suggestion.keymap or {}
140+
local nes_keymaps = config.nes.keymap or {}
141+
local panel_keymaps = config.panel.keymap or {}
142+
local seen = {}
143+
local duplicates = {}
144+
145+
for _, cfg in ipairs({ suggestion_keymaps, nes_keymaps, panel_keymaps }) do
146+
for action, km in pairs(cfg) do
147+
if not km then
148+
goto continue
149+
end
150+
151+
-- TODO: find a better way to determine mode, this is prone to maintenance bugs
152+
-- TODO: Not sure how to validate keymaps, since some COULD be duplicates and valid
153+
local mode = (action == config.panel.keymap.open or vim.tbl_contains(config.nes.keymap, action)) and "n" or "i"
154+
local keymap_key = get_keymap_key(0, mode, km)
155+
if seen[keymap_key] then
156+
duplicates[keymap_key] = (duplicates[keymap_key] or 1) + 1
157+
else
158+
seen[keymap_key] = true
135159
end
160+
161+
::continue::
136162
end
163+
end
137164

138-
logger.error("Could not unset keymap for " .. mode .. " " .. key .. ", bufnr " .. bufnr .. ": " .. err)
165+
for key, count in pairs(duplicates) do
166+
logger.error("Duplicate keymap detected: " .. key .. " (" .. count .. " times), please review your configuration.")
139167
end
140168
end
141169

lua/copilot/panel/init.lua

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -254,38 +254,10 @@ function panel:close()
254254
end
255255

256256
function M.set_keymap(bufnr)
257-
if panel.keymap.accept then
258-
vim.keymap.set("n", panel.keymap.accept, M.accept, {
259-
buffer = bufnr,
260-
desc = "[copilot] (panel) accept",
261-
silent = true,
262-
})
263-
end
264-
265-
if panel.keymap.jump_prev then
266-
vim.keymap.set("n", panel.keymap.jump_prev, M.jump_prev, {
267-
buffer = bufnr,
268-
desc = "[copilot] (panel) jump prev",
269-
silent = true,
270-
})
271-
end
272-
273-
if panel.keymap.jump_next then
274-
vim.keymap.set("n", panel.keymap.jump_next, M.jump_next, {
275-
buffer = bufnr,
276-
desc = "[copilot] (panel) jump next",
277-
silent = true,
278-
})
279-
end
280-
281-
if panel.keymap.refresh then
282-
vim.keymap.set("n", panel.keymap.refresh, M.refresh, {
283-
buffer = bufnr,
284-
desc = "[copilot] (panel) refresh",
285-
silent = true,
286-
})
287-
end
288-
257+
keymaps.register_keymap("n", panel.keymap.accept, M.accept, "[copilot] (panel) accept", bufnr)
258+
keymaps.register_keymap("n", panel.keymap.jump_prev, M.jump_prev, "[copilot] (panel) jump prev", bufnr)
259+
keymaps.register_keymap("n", panel.keymap.jump_next, M.jump_next, "[copilot] (panel) jump next", bufnr)
260+
keymaps.register_keymap("n", panel.keymap.refresh, M.refresh, "[copilot] (panel) refresh", bufnr)
289261
M.keymaps_set = true
290262
end
291263

@@ -580,10 +552,10 @@ function M.setup()
580552
end
581553

582554
panel.auto_refresh = opts.auto_refresh or false
583-
584555
panel.keymap = opts.keymap or {}
585556
panel.layout = vim.tbl_deep_extend("force", panel.layout, opts.layout or {})
586557

558+
-- not buffer specific
587559
if panel.keymap.open then
588560
vim.keymap.set("i", panel.keymap.open, M.open, {
589561
desc = "[copilot] (panel) open",

0 commit comments

Comments
 (0)