-
Notifications
You must be signed in to change notification settings - Fork 464
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(dap-keymap): simplify keymap implementation (#905)
* fix(dap-keymap): simplify keymap implementation * Implement keymap module * fix(dap-keymap)!: simplify keymap implementation
- Loading branch information
Showing
5 changed files
with
159 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |