Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expose require'keymap-amend'.get #3

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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):

Expand Down Expand Up @@ -95,5 +109,4 @@ multiple cursors.
This plugin was inspired with [nvim-cmp](https://github.com/hrsh7th/nvim-cmp)
fallback mechanics.


<!-- vim: set tw=90: -->
15 changes: 15 additions & 0 deletions doc/keymap-amend.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
>
Expand Down
187 changes: 104 additions & 83 deletions lua/keymap-amend.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,105 +4,119 @@ 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.
---@param a string
---@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
---@param mode string
---@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
---@param lhs string
---@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.
Expand All @@ -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,
})