diff --git a/README.md b/README.md index a5f7e4d..e712a11 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ **Neovim v0.7 or higher is required** This plugin allows to amend the exisintg keybinding in Neovim. It is done with the -function which is required from the `keymap-amend` module. The signature of this function +function which is required from the `keymap-amend` module. The signature of this function is equal to **vim.keymap.set** function (`:help vim.keymap.set()`) with one exception: the `rhs` parameter should be a function that receives one parameter — a function on call of which the original keymapping will be executed. This function is constructed and passed -automaticaly. You only need to "accept" it in your `rhs` function and call on need. +automaticaly. You only need to "accept" it in your `rhs` function and call on need. ```lua local keymap = vim.keymap @@ -21,7 +21,21 @@ end, opts) You need to watch that the amendment happens after the original keymap is set. -## Instalation +We also provide a helper function for getting the original keymap and a function that +executes the original 'lhs' mapping for use with other methods of creating keymaps + +```lua +vim.keymap.get = require('keymap-amend').get +local original = vim.keymap.get(mode, lhs):original() +``` + +This is equivalent to the `original` parameter in keymap.amend +the get() function also returns other information about the keymapping: +It contains all the field from nvim_get_keymap, +as well as a buffer parameter that is false for global keymaps, +as well as the `original` method to get a callable + +## Installation With [packer](https://github.com/wbthomason/packer.nvim): @@ -95,5 +109,4 @@ multiple cursors. This plugin was inspired with [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) fallback mechanics. - diff --git a/doc/keymap-amend.txt b/doc/keymap-amend.txt index 421bd61..acea0b7 100644 --- a/doc/keymap-amend.txt +++ b/doc/keymap-amend.txt @@ -19,6 +19,21 @@ function and call on need. original() -- execute the original 'lhs' mapping end, opts) < + +We also provide a helper function for getting the original keymap and a function that +executes the original 'lhs' mapping for use with other methods of creating keymaps + +> + vim.keymap.get = require('keymap-amend').get + local original = vim.keymap.get(mode, lhs):original() +< + +This is equivalent to the `original` parameter in keymap.amend +the get() function also returns other information about the keymapping: +It contains all the field from nvim_get_keymap, +as well as a buffer parameter that is false for global keymaps, +as well as the `original` method to get a callable + ================================================================================ EXAMPLES > diff --git a/lua/keymap-amend.lua b/lua/keymap-amend.lua index 38e5cfb..1175ef8 100644 --- a/lua/keymap-amend.lua +++ b/lua/keymap-amend.lua @@ -4,7 +4,7 @@ local api = vim.api ---@param keys string ---@return string local function termcodes(keys) - return api.nvim_replace_termcodes(keys, true, true, true) --[[@as string]] + return api.nvim_replace_termcodes(keys, true, true, true) --[[@as string]] end ---Returns if two key sequence are equal or not. @@ -12,7 +12,32 @@ end ---@param b string ---@return boolean local function keymap_equals(a, b) - return termcodes(a) == termcodes(b) + return termcodes(a) == termcodes(b) +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_original(map) + return function() + local keys, fmode + if map.expr then + if map.callback then + keys = map.callback() + else + keys = 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" + api.nvim_feedkeys(keys, fmode, false) + end end ---Get map @@ -20,74 +45,59 @@ end ---@param lhs string ---@return table local function get_map(mode, lhs) - for _, map in ipairs(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 + local res - for _, map in ipairs(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 + for _, map in ipairs(api.nvim_buf_get_keymap(0, mode)) do + if keymap_equals(map.lhs, lhs) then + res = { + 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 - return { - lhs = lhs, - rhs = lhs, - expr = false, - callback = nil, - noremap = true, - script = false, - silent = true, - nowait = false, - buffer = false, - } -end + if not res then + for _, map in ipairs(api.nvim_get_keymap(mode)) do + if keymap_equals(map.lhs, lhs) then + res = { + 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 + 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_original(map) - return function() - local keys, fmode - if map.expr then - if map.callback then - keys = map.callback() - else - keys = 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' - api.nvim_feedkeys(keys, fmode, false) - end + if not res then + res = { + lhs = lhs, + rhs = lhs, + expr = false, + callback = nil, + noremap = true, + script = false, + silent = true, + nowait = false, + buffer = false, + } + end + + res.original = get_original + + return res end ---@param mode string @@ -95,14 +105,18 @@ end ---@param rhs string | function ---@param opts? table local function amend(mode, lhs, rhs, opts) - local map = get_map(mode, lhs) - local original = get_original(map) - opts = opts or {} - opts.desc = table.concat{ - '[keymap-amend.nvim', (opts.desc and ': '..opts.desc or ''), '] ', - map.desc or '' - } - vim.keymap.set(mode, lhs, function() rhs(original) end, opts) + local map = get_map(mode, lhs) + local original = map:original() + opts = opts or {} + opts.desc = table.concat({ + "[keymap-amend.nvim", + (opts.desc and ": " .. opts.desc or ""), + "] ", + map.desc or "", + }) + vim.keymap.set(mode, lhs, function() + rhs(original) + end, opts) end ---Amend the existing keymap. @@ -111,13 +125,20 @@ end ---@param rhs string | function ---@param opts? table local function modes_amend(mode, lhs, rhs, opts) - if type(mode) == 'table' then - for _, m in ipairs(mode) do - amend(m, lhs, rhs, opts) - end - else - amend(mode, lhs, rhs, opts) - end + if type(mode) == "table" then + for _, m in ipairs(mode) do + amend(m, lhs, rhs, opts) + end + else + amend(mode, lhs, rhs, opts) + end end -return modes_amend +return setmetatable({ + get = get_map, + amend = modes_amend, +}, { + __call = function(t, ...) + modes_amend(...) + end, +})