Skip to content

Commit

Permalink
fix(dap-keymap): simplify keymap implementation (ayamir#905)
Browse files Browse the repository at this point in the history
* fix(dap-keymap): simplify keymap implementation

* Implement keymap module

* fix(dap-keymap)!: simplify keymap implementation
  • Loading branch information
Jint-lzxy authored Jul 28, 2023
1 parent 430375e commit 372d3c9
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 71 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint_code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ jobs:
- uses: actions/checkout@v3
- uses: lunarmodules/luacheck@v1
with:
args: . --std luajit --globals vim _toggle_lazygit _command_panel _lspkeymap_loaded_bufnr --max-line-length 150 --no-config
args: . --std luajit --globals vim _toggle_lazygit _command_panel _debugging --max-line-length 150 --no-config
6 changes: 1 addition & 5 deletions lua/core/event.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,10 @@ function autocmd.nvim_create_augroups(definitions)
end

local mapping = require("keymap.completion")
_G._lspkeymap_loaded_bufnr = {}
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("LspKeymapLoader", { clear = true }),
callback = function(event)
if not _lspkeymap_loaded_bufnr[event.buf] then
mapping.lsp(event.buf)
_lspkeymap_loaded_bufnr[event.buf] = true
end
mapping.lsp(event.buf)
end,
})

Expand Down
63 changes: 3 additions & 60 deletions lua/modules/configs/tool/dap/dap-keymap.lua
Original file line number Diff line number Diff line change
@@ -1,78 +1,21 @@
local M = {}

local bind = require("keymap.bind")
local map_cr = bind.map_cr
local map_cmd = bind.map_cmd

local did_load_debug_mappings = false
local keymap_info_debug = {
n = { K = false },
v = { K = false },
}
local keymap_info_original = {
n = { K = true },
v = { K = false },
}
local debug_keymap = {
["nv|K"] = map_cmd("<Cmd>lua require('dapui').eval()<CR>")
:with_noremap()
:with_nowait()
:with_desc("debug: Evaluate expression under cursor"),
}
local original_keymap = {
["n|K"] = map_cr("Lspsaga hover_doc"):with_noremap():with_silent():with_desc("lsp: Show doc"),
["v|K"] = map_cmd(":m '<-2<CR>gv=gv"),
:with_desc("Evaluate expression under cursor"),
}

local function del_keymap(mappings, keymap_info)
for key in pairs(mappings) do
local modes, keymap = key:match("([^|]*)|?(.*)")
for _, mode in ipairs(vim.split(modes, "")) do
if vim.fn.maparg(keymap, mode, false) ~= "" then
if keymap_info[mode][keymap] == true then
vim.api.nvim_buf_del_keymap(0, mode, keymap)
else
vim.api.nvim_del_keymap(mode, keymap)
end
end
end
end
end

local function load_keymap(mappings, keymap_info)
for key, value in pairs(mappings) do
local modes, keymap = key:match("([^|]*)|?(.*)")
if type(value) == "table" then
for _, mode in ipairs(vim.split(modes, "")) do
local rhs = value.cmd
local options = value.options
if keymap_info[mode][keymap] == true then
for buf in pairs(_G._lspkeymap_loaded_bufnr) do
-- Restore lsp keymaps
vim.api.nvim_buf_set_keymap(buf, mode, keymap, rhs, options)
end
else
vim.api.nvim_set_keymap(mode, keymap, rhs, options)
end
end
end
end
end

function M.load()
function M.load_extras()
if not did_load_debug_mappings then
del_keymap(original_keymap, keymap_info_original)
load_keymap(debug_keymap, keymap_info_debug)
require("modules.utils.keymap").amend("Debugging", "_debugging", debug_keymap)
did_load_debug_mappings = true
end
end

function M.restore()
if did_load_debug_mappings then
del_keymap(debug_keymap, keymap_info_debug)
load_keymap(original_keymap, keymap_info_original)
did_load_debug_mappings = false
end
end

return M
9 changes: 4 additions & 5 deletions lua/modules/configs/tool/dap/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ return function()
local mappings = require("tool.dap.dap-keymap")

-- Initialize debug hooks
local _debugging = false
_G._debugging = false
local function debug_init_cb()
_debugging = true
mappings.load()
_G._debugging = true
mappings.load_extras()
dapui.open({ reset = true })
end
local function debug_terminate_cb()
if _debugging then
_debugging = false
mappings.restore()
_G._debugging = false
dapui.close()
end
end
Expand Down
150 changes: 150 additions & 0 deletions lua/modules/utils/keymap.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
local M = {}

---Shortcut for `nvim_replace_termcodes`.
---@param keys string
---@return string
local function termcodes(keys)
return vim.api.nvim_replace_termcodes(keys, true, true, true)
end

---Returns if two key sequence are equal or not.
---@param a string
---@param b string
---@return boolean
local function keymap_equals(a, b)
return termcodes(a) == termcodes(b)
end

---Get map
---@param mode string
---@param lhs string
---@return table
local function get_map(mode, lhs)
for _, map in ipairs(vim.api.nvim_buf_get_keymap(0, mode)) do
if keymap_equals(map.lhs, lhs) then
return {
lhs = map.lhs,
rhs = map.rhs or "",
expr = map.expr == 1,
callback = map.callback,
noremap = map.noremap == 1,
script = map.script == 1,
silent = map.silent == 1,
nowait = map.nowait == 1,
buffer = true,
}
end
end

for _, map in ipairs(vim.api.nvim_get_keymap(mode)) do
if keymap_equals(map.lhs, lhs) then
return {
lhs = map.lhs,
rhs = map.rhs or "",
expr = map.expr == 1,
callback = map.callback,
noremap = map.noremap == 1,
script = map.script == 1,
silent = map.silent == 1,
nowait = map.nowait == 1,
buffer = false,
}
end
end

return {
lhs = lhs,
rhs = lhs,
expr = false,
callback = nil,
noremap = true,
script = false,
silent = true,
nowait = false,
buffer = false,
}
end

---Returns the function constructed from the passed keymap object on call of
---which the original keymapping will be executed.
---@param map table keymap object
---@return function
local function get_fallback(map)
return function()
local keys, fmode
if map.expr then
if map.callback then
keys = map.callback()
else
keys = vim.api.nvim_eval(map.rhs)
end
elseif map.callback then
map.callback()
return
else
keys = map.rhs
end
keys = termcodes(keys)
fmode = map.noremap and "in" or "im"
vim.api.nvim_feedkeys(keys, fmode, false)
end
end

---@param cond string
---@param mode string
---@param lhs string
---@param rhs function
---@param opts? table
local function amend(cond, mode, lhs, rhs, opts)
local map = get_map(mode, lhs)
local fallback = get_fallback(map)
local options = vim.deepcopy(opts) or {}
options.desc = table.concat({
"[" .. cond,
(options.desc and ": " .. options.desc or ""),
"]",
(map.desc and " / " .. map.desc or ""),
})
vim.keymap.set(mode, lhs, function()
rhs(fallback)
end, options)
end

---Amend the existing keymap.
---@param cond string
---@param mode string | string[]
---@param lhs string
---@param rhs function
---@param opts? table
local function modes_amend(cond, mode, lhs, rhs, opts)
if type(mode) == "table" then
for _, m in ipairs(mode) do
amend(cond, m, lhs, rhs, opts)
end
else
amend(cond, mode, lhs, rhs, opts)
end
end

---@param cond string
---@param global_flag string
---@param mapping table<string, map_rhs>
function M.amend(cond, global_flag, mapping)
for key, value in pairs(mapping) do
local modes, keymap = key:match("([^|]*)|?(.*)")
if type(value) == "table" then
local rhs = value.cmd
local options = value.options
modes_amend(cond, vim.split(modes, ""), keymap, function(fallback)
if _G[global_flag] then
local fmode = options.noremap and "in" or "im"
vim.api.nvim_feedkeys(termcodes(rhs), fmode, false)
else
fallback()
end
end, options)
end
end
end

return M

0 comments on commit 372d3c9

Please sign in to comment.