Skip to content

Commit 372d3c9

Browse files
authored
fix(dap-keymap): simplify keymap implementation (#905)
* fix(dap-keymap): simplify keymap implementation * Implement keymap module * fix(dap-keymap)!: simplify keymap implementation
1 parent 430375e commit 372d3c9

File tree

5 files changed

+159
-71
lines changed

5 files changed

+159
-71
lines changed

.github/workflows/lint_code.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ jobs:
77
- uses: actions/checkout@v3
88
- uses: lunarmodules/luacheck@v1
99
with:
10-
args: . --std luajit --globals vim _toggle_lazygit _command_panel _lspkeymap_loaded_bufnr --max-line-length 150 --no-config
10+
args: . --std luajit --globals vim _toggle_lazygit _command_panel _debugging --max-line-length 150 --no-config

lua/core/event.lua

+1-5
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,10 @@ function autocmd.nvim_create_augroups(definitions)
1414
end
1515

1616
local mapping = require("keymap.completion")
17-
_G._lspkeymap_loaded_bufnr = {}
1817
vim.api.nvim_create_autocmd("LspAttach", {
1918
group = vim.api.nvim_create_augroup("LspKeymapLoader", { clear = true }),
2019
callback = function(event)
21-
if not _lspkeymap_loaded_bufnr[event.buf] then
22-
mapping.lsp(event.buf)
23-
_lspkeymap_loaded_bufnr[event.buf] = true
24-
end
20+
mapping.lsp(event.buf)
2521
end,
2622
})
2723

+3-60
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,21 @@
11
local M = {}
22

33
local bind = require("keymap.bind")
4-
local map_cr = bind.map_cr
54
local map_cmd = bind.map_cmd
65

76
local did_load_debug_mappings = false
8-
local keymap_info_debug = {
9-
n = { K = false },
10-
v = { K = false },
11-
}
12-
local keymap_info_original = {
13-
n = { K = true },
14-
v = { K = false },
15-
}
167
local debug_keymap = {
178
["nv|K"] = map_cmd("<Cmd>lua require('dapui').eval()<CR>")
189
:with_noremap()
1910
:with_nowait()
20-
:with_desc("debug: Evaluate expression under cursor"),
21-
}
22-
local original_keymap = {
23-
["n|K"] = map_cr("Lspsaga hover_doc"):with_noremap():with_silent():with_desc("lsp: Show doc"),
24-
["v|K"] = map_cmd(":m '<-2<CR>gv=gv"),
11+
:with_desc("Evaluate expression under cursor"),
2512
}
2613

27-
local function del_keymap(mappings, keymap_info)
28-
for key in pairs(mappings) do
29-
local modes, keymap = key:match("([^|]*)|?(.*)")
30-
for _, mode in ipairs(vim.split(modes, "")) do
31-
if vim.fn.maparg(keymap, mode, false) ~= "" then
32-
if keymap_info[mode][keymap] == true then
33-
vim.api.nvim_buf_del_keymap(0, mode, keymap)
34-
else
35-
vim.api.nvim_del_keymap(mode, keymap)
36-
end
37-
end
38-
end
39-
end
40-
end
41-
42-
local function load_keymap(mappings, keymap_info)
43-
for key, value in pairs(mappings) do
44-
local modes, keymap = key:match("([^|]*)|?(.*)")
45-
if type(value) == "table" then
46-
for _, mode in ipairs(vim.split(modes, "")) do
47-
local rhs = value.cmd
48-
local options = value.options
49-
if keymap_info[mode][keymap] == true then
50-
for buf in pairs(_G._lspkeymap_loaded_bufnr) do
51-
-- Restore lsp keymaps
52-
vim.api.nvim_buf_set_keymap(buf, mode, keymap, rhs, options)
53-
end
54-
else
55-
vim.api.nvim_set_keymap(mode, keymap, rhs, options)
56-
end
57-
end
58-
end
59-
end
60-
end
61-
62-
function M.load()
14+
function M.load_extras()
6315
if not did_load_debug_mappings then
64-
del_keymap(original_keymap, keymap_info_original)
65-
load_keymap(debug_keymap, keymap_info_debug)
16+
require("modules.utils.keymap").amend("Debugging", "_debugging", debug_keymap)
6617
did_load_debug_mappings = true
6718
end
6819
end
6920

70-
function M.restore()
71-
if did_load_debug_mappings then
72-
del_keymap(debug_keymap, keymap_info_debug)
73-
load_keymap(original_keymap, keymap_info_original)
74-
did_load_debug_mappings = false
75-
end
76-
end
77-
7821
return M

lua/modules/configs/tool/dap/init.lua

+4-5
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ return function()
88
local mappings = require("tool.dap.dap-keymap")
99

1010
-- Initialize debug hooks
11-
local _debugging = false
11+
_G._debugging = false
1212
local function debug_init_cb()
13-
_debugging = true
14-
mappings.load()
13+
_G._debugging = true
14+
mappings.load_extras()
1515
dapui.open({ reset = true })
1616
end
1717
local function debug_terminate_cb()
1818
if _debugging then
19-
_debugging = false
20-
mappings.restore()
19+
_G._debugging = false
2120
dapui.close()
2221
end
2322
end

lua/modules/utils/keymap.lua

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
local M = {}
2+
3+
---Shortcut for `nvim_replace_termcodes`.
4+
---@param keys string
5+
---@return string
6+
local function termcodes(keys)
7+
return vim.api.nvim_replace_termcodes(keys, true, true, true)
8+
end
9+
10+
---Returns if two key sequence are equal or not.
11+
---@param a string
12+
---@param b string
13+
---@return boolean
14+
local function keymap_equals(a, b)
15+
return termcodes(a) == termcodes(b)
16+
end
17+
18+
---Get map
19+
---@param mode string
20+
---@param lhs string
21+
---@return table
22+
local function get_map(mode, lhs)
23+
for _, map in ipairs(vim.api.nvim_buf_get_keymap(0, mode)) do
24+
if keymap_equals(map.lhs, lhs) then
25+
return {
26+
lhs = map.lhs,
27+
rhs = map.rhs or "",
28+
expr = map.expr == 1,
29+
callback = map.callback,
30+
noremap = map.noremap == 1,
31+
script = map.script == 1,
32+
silent = map.silent == 1,
33+
nowait = map.nowait == 1,
34+
buffer = true,
35+
}
36+
end
37+
end
38+
39+
for _, map in ipairs(vim.api.nvim_get_keymap(mode)) do
40+
if keymap_equals(map.lhs, lhs) then
41+
return {
42+
lhs = map.lhs,
43+
rhs = map.rhs or "",
44+
expr = map.expr == 1,
45+
callback = map.callback,
46+
noremap = map.noremap == 1,
47+
script = map.script == 1,
48+
silent = map.silent == 1,
49+
nowait = map.nowait == 1,
50+
buffer = false,
51+
}
52+
end
53+
end
54+
55+
return {
56+
lhs = lhs,
57+
rhs = lhs,
58+
expr = false,
59+
callback = nil,
60+
noremap = true,
61+
script = false,
62+
silent = true,
63+
nowait = false,
64+
buffer = false,
65+
}
66+
end
67+
68+
---Returns the function constructed from the passed keymap object on call of
69+
---which the original keymapping will be executed.
70+
---@param map table keymap object
71+
---@return function
72+
local function get_fallback(map)
73+
return function()
74+
local keys, fmode
75+
if map.expr then
76+
if map.callback then
77+
keys = map.callback()
78+
else
79+
keys = vim.api.nvim_eval(map.rhs)
80+
end
81+
elseif map.callback then
82+
map.callback()
83+
return
84+
else
85+
keys = map.rhs
86+
end
87+
keys = termcodes(keys)
88+
fmode = map.noremap and "in" or "im"
89+
vim.api.nvim_feedkeys(keys, fmode, false)
90+
end
91+
end
92+
93+
---@param cond string
94+
---@param mode string
95+
---@param lhs string
96+
---@param rhs function
97+
---@param opts? table
98+
local function amend(cond, mode, lhs, rhs, opts)
99+
local map = get_map(mode, lhs)
100+
local fallback = get_fallback(map)
101+
local options = vim.deepcopy(opts) or {}
102+
options.desc = table.concat({
103+
"[" .. cond,
104+
(options.desc and ": " .. options.desc or ""),
105+
"]",
106+
(map.desc and " / " .. map.desc or ""),
107+
})
108+
vim.keymap.set(mode, lhs, function()
109+
rhs(fallback)
110+
end, options)
111+
end
112+
113+
---Amend the existing keymap.
114+
---@param cond string
115+
---@param mode string | string[]
116+
---@param lhs string
117+
---@param rhs function
118+
---@param opts? table
119+
local function modes_amend(cond, mode, lhs, rhs, opts)
120+
if type(mode) == "table" then
121+
for _, m in ipairs(mode) do
122+
amend(cond, m, lhs, rhs, opts)
123+
end
124+
else
125+
amend(cond, mode, lhs, rhs, opts)
126+
end
127+
end
128+
129+
---@param cond string
130+
---@param global_flag string
131+
---@param mapping table<string, map_rhs>
132+
function M.amend(cond, global_flag, mapping)
133+
for key, value in pairs(mapping) do
134+
local modes, keymap = key:match("([^|]*)|?(.*)")
135+
if type(value) == "table" then
136+
local rhs = value.cmd
137+
local options = value.options
138+
modes_amend(cond, vim.split(modes, ""), keymap, function(fallback)
139+
if _G[global_flag] then
140+
local fmode = options.noremap and "in" or "im"
141+
vim.api.nvim_feedkeys(termcodes(rhs), fmode, false)
142+
else
143+
fallback()
144+
end
145+
end, options)
146+
end
147+
end
148+
end
149+
150+
return M

0 commit comments

Comments
 (0)