mirror of
https://github.com/neovim/neovim.git
synced 2026-07-31 12:49:11 +00:00
Merge #40579 from barrettruth/fix/del-keymap-lhs-only-30258
This commit is contained in:
@@ -620,7 +620,7 @@ nvim_del_current_line() *nvim_del_current_line()*
|
||||
not allowed when |textlock| is active
|
||||
Since: 0.1.0
|
||||
|
||||
nvim_del_keymap({mode}, {lhs}) *nvim_del_keymap()*
|
||||
nvim_del_keymap({mode}, {lhs}, {opts}) *nvim_del_keymap()*
|
||||
Unmaps a global |mapping| for the given mode.
|
||||
|
||||
To unmap a buffer-local mapping, use |nvim_buf_del_keymap()|.
|
||||
@@ -629,8 +629,10 @@ nvim_del_keymap({mode}, {lhs}) *nvim_del_keymap()*
|
||||
Since: 0.4.0
|
||||
|
||||
Parameters: ~
|
||||
• {mode} (`string`)
|
||||
• {lhs} (`string`)
|
||||
• {mode} (`string`) Mode short-name ("n", "i", "v", ...)
|
||||
• {lhs} (`string`) Left-hand-side |{lhs}| of the mapping.
|
||||
• {opts} (`vim.api.keyset.keymap_del?`) Optional parameters.
|
||||
• lhs: When true, only match {lhs}, not {rhs}.
|
||||
|
||||
See also: ~
|
||||
• |nvim_set_keymap()|
|
||||
@@ -2447,7 +2449,8 @@ nvim_buf_call({buf}, {fn}) *nvim_buf_call()*
|
||||
Return: ~
|
||||
(`any`) Value(s) returned by `fn()`.
|
||||
|
||||
nvim_buf_del_keymap({buf}, {mode}, {lhs}) *nvim_buf_del_keymap()*
|
||||
*nvim_buf_del_keymap()*
|
||||
nvim_buf_del_keymap({buf}, {mode}, {lhs}, {opts})
|
||||
Unmaps a buffer-local |mapping| for the given mode.
|
||||
|
||||
Attributes: ~
|
||||
@@ -2455,8 +2458,10 @@ nvim_buf_del_keymap({buf}, {mode}, {lhs}) *nvim_buf_del_keymap()*
|
||||
|
||||
Parameters: ~
|
||||
• {buf} (`integer`) Buffer id, or 0 for current buffer
|
||||
• {mode} (`string`)
|
||||
• {lhs} (`string`)
|
||||
• {mode} (`string`) Mode short-name ("n", "i", "v", ...)
|
||||
• {lhs} (`string`) Left-hand-side |{lhs}| of the mapping.
|
||||
• {opts} (`vim.api.keyset.keymap_del?`) Optional parameters.
|
||||
• lhs: When true, only match {lhs}, not {rhs}.
|
||||
|
||||
See also: ~
|
||||
• |nvim_del_keymap()|
|
||||
|
||||
@@ -3798,6 +3798,7 @@ Lua module: vim.keymap *vim.keymap*
|
||||
|
||||
vim.keymap.del({modes}, {lhs}, {opts}) *vim.keymap.del()*
|
||||
Removes a mapping, or removes each (mode, lhs) pair if `lhs` is a list.
|
||||
|
||||
Examples: >lua
|
||||
vim.keymap.del('n', 'lhs')
|
||||
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', { buf = 5 })
|
||||
@@ -3809,6 +3810,7 @@ vim.keymap.del({modes}, {lhs}, {opts}) *vim.keymap.del()*
|
||||
• {opts} (`table?`) A table with the following fields:
|
||||
• {buf}? (`integer`) Remove a mapping from the given buffer.
|
||||
`0` for current.
|
||||
• {lhs}? (`boolean`) When true, only match {lhs}, not {rhs}.
|
||||
|
||||
See also: ~
|
||||
• |vim.keymap.set()|
|
||||
|
||||
@@ -86,8 +86,10 @@ modes.
|
||||
Remove the mapping of {lhs} for the modes where the
|
||||
map command applies. The mapping may remain defined
|
||||
for other modes where it applies.
|
||||
It also works when {lhs} matches the {rhs} of a
|
||||
mapping. This is for when an abbreviation applied.
|
||||
If no mapping with {lhs} exists, it also works when
|
||||
{lhs} matches the {rhs} of a mapping (see
|
||||
|vim.keymap.del()| to avoid that). This is for
|
||||
when an abbreviation applied.
|
||||
Note: Trailing spaces are included in the {lhs}.
|
||||
See |map-trailing-white|.
|
||||
|
||||
|
||||
@@ -432,6 +432,8 @@ These existing features changed their behavior.
|
||||
• |vim.lsp.util.open_floating_preview()| windows (e.g. |vim.lsp.buf.hover()|)
|
||||
converted to normal windows (e.g. with |CTRL-W_H|) are no longer closed
|
||||
automatically.
|
||||
• |nvim_del_keymap()|, |nvim_buf_del_keymap()| and |vim.keymap.del()| can
|
||||
match only {lhs}, not {rhs}, with `opts.lhs=true`.
|
||||
|
||||
==============================================================================
|
||||
REMOVED FEATURES *news-removed*
|
||||
|
||||
16
runtime/lua/vim/_meta/api.gen.lua
generated
16
runtime/lua/vim/_meta/api.gen.lua
generated
@@ -333,9 +333,11 @@ function vim.api.nvim_buf_del_extmark(buf, ns_id, id) end
|
||||
---
|
||||
--- @see vim.api.nvim_del_keymap
|
||||
--- @param buf integer Buffer id, or 0 for current buffer
|
||||
--- @param mode string
|
||||
--- @param lhs string
|
||||
function vim.api.nvim_buf_del_keymap(buf, mode, lhs) end
|
||||
--- @param mode string Mode short-name ("n", "i", "v", ...)
|
||||
--- @param lhs string Left-hand-side `{lhs}` of the mapping.
|
||||
--- @param opts vim.api.keyset.keymap_del? Optional parameters.
|
||||
--- - lhs: When true, only match {lhs}, not {rhs}.
|
||||
function vim.api.nvim_buf_del_keymap(buf, mode, lhs, opts) end
|
||||
|
||||
--- Deletes a named mark in the buffer. See `mark-motions`.
|
||||
---
|
||||
@@ -1069,9 +1071,11 @@ function vim.api.nvim_del_current_line() end
|
||||
--- To unmap a buffer-local mapping, use `nvim_buf_del_keymap()`.
|
||||
---
|
||||
--- @see vim.api.nvim_set_keymap
|
||||
--- @param mode string
|
||||
--- @param lhs string
|
||||
function vim.api.nvim_del_keymap(mode, lhs) end
|
||||
--- @param mode string Mode short-name ("n", "i", "v", ...)
|
||||
--- @param lhs string Left-hand-side `{lhs}` of the mapping.
|
||||
--- @param opts vim.api.keyset.keymap_del? Optional parameters.
|
||||
--- - lhs: When true, only match {lhs}, not {rhs}.
|
||||
function vim.api.nvim_del_keymap(mode, lhs, opts) end
|
||||
|
||||
--- Deletes an uppercase/file named mark. See `mark-motions`.
|
||||
---
|
||||
|
||||
3
runtime/lua/vim/_meta/api_keysets.gen.lua
generated
3
runtime/lua/vim/_meta/api_keysets.gen.lua
generated
@@ -373,6 +373,9 @@ error('Cannot require a meta file')
|
||||
--- @field silent? boolean
|
||||
--- @field unique? boolean
|
||||
|
||||
--- @class vim.api.keyset.keymap_del
|
||||
--- @field lhs? boolean
|
||||
|
||||
--- @class vim.api.keyset.ns_opts
|
||||
--- @field wins? any[]
|
||||
|
||||
|
||||
@@ -119,8 +119,11 @@ end
|
||||
---
|
||||
--- Remove a mapping from the given buffer. `0` for current.
|
||||
--- @field buf? integer
|
||||
--- When true, only match {lhs}, not {rhs}.
|
||||
--- @field lhs? boolean
|
||||
|
||||
--- Removes a mapping, or removes each (mode, lhs) pair if `lhs` is a list.
|
||||
---
|
||||
--- Examples:
|
||||
---
|
||||
--- ```lua
|
||||
@@ -152,12 +155,14 @@ function keymap.del(modes, lhs, opts)
|
||||
buf = opts.buffer == true and 0 or opts.buffer --[[@as integer?]]
|
||||
end
|
||||
|
||||
local api_opts = { lhs = opts.lhs }
|
||||
|
||||
for _, m in ipairs(modes) do
|
||||
for _, l in ipairs(lhs) do
|
||||
if buf then
|
||||
vim.api.nvim_buf_del_keymap(buf, m, l)
|
||||
vim.api.nvim_buf_del_keymap(buf, m, l, api_opts)
|
||||
else
|
||||
vim.api.nvim_del_keymap(m, l)
|
||||
vim.api.nvim_del_keymap(m, l, api_opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -143,26 +143,36 @@ local function process_proto(item, state)
|
||||
cur_obj.name = item.name
|
||||
cur_obj.params = cur_obj.params or {}
|
||||
|
||||
local documented = {} --- @type table<string,nvim.cdoc.parser.param>
|
||||
local matched = {} --- @type table<nvim.cdoc.parser.param,true>
|
||||
local params = {} --- @type nvim.cdoc.parser.param[]
|
||||
|
||||
for _, p in ipairs(cur_obj.params) do
|
||||
documented[p.name] = documented[p.name] or p
|
||||
end
|
||||
|
||||
for _, p in ipairs(item.parameters) do
|
||||
local event_type = 'vim.api.keyset.events|vim.api.keyset.events[]'
|
||||
local event = (item.name == 'nvim_create_autocmd' or item.name == 'nvim_exec_autocmds')
|
||||
and p[2] == 'event'
|
||||
local param = { name = p[2], type = event and event_type or api_type(p[1]) }
|
||||
local added = false
|
||||
|
||||
for _, cp in ipairs(cur_obj.params) do
|
||||
if cp.name == param.name then
|
||||
cp.type = param.type
|
||||
added = true
|
||||
break
|
||||
end
|
||||
local param = documented[p[2]]
|
||||
if param then
|
||||
matched[param] = true
|
||||
else
|
||||
param = { name = p[2] } --[[@as nvim.cdoc.parser.param]]
|
||||
end
|
||||
param.type = event and event_type or api_type(p[1])
|
||||
params[#params + 1] = param
|
||||
end
|
||||
|
||||
if not added then
|
||||
table.insert(cur_obj.params, param)
|
||||
for _, p in ipairs(cur_obj.params) do
|
||||
if not matched[p] then
|
||||
params[#params + 1] = p
|
||||
end
|
||||
end
|
||||
|
||||
cur_obj.params = params
|
||||
|
||||
cur_obj.returns = cur_obj.returns or { {
|
||||
name = '',
|
||||
type = '',
|
||||
|
||||
@@ -890,19 +890,25 @@ void nvim_buf_set_keymap(uint64_t channel_id, Buffer buf, String mode, String lh
|
||||
Dict(keymap) *opts, Error *err)
|
||||
FUNC_API_SINCE(6)
|
||||
{
|
||||
modify_keymap(channel_id, buf, false, mode, lhs, rhs, opts, err);
|
||||
modify_keymap(channel_id, buf, MAPTYPE_MAP, mode, lhs, rhs, opts, err);
|
||||
}
|
||||
|
||||
/// Unmaps a buffer-local |mapping| for the given mode.
|
||||
///
|
||||
/// @see |nvim_del_keymap()|
|
||||
///
|
||||
/// @param buf Buffer id, or 0 for current buffer
|
||||
void nvim_buf_del_keymap(uint64_t channel_id, Buffer buf, String mode, String lhs, Error *err)
|
||||
/// @param buf Buffer id, or 0 for current buffer
|
||||
/// @param mode Mode short-name ("n", "i", "v", ...)
|
||||
/// @param lhs Left-hand-side |{lhs}| of the mapping.
|
||||
/// @param opts Optional parameters.
|
||||
/// - lhs: When true, only match {lhs}, not {rhs}.
|
||||
void nvim_buf_del_keymap(uint64_t channel_id, Buffer buf, String mode, String lhs,
|
||||
Dict(keymap_del) *opts, Error *err)
|
||||
FUNC_API_SINCE(6)
|
||||
{
|
||||
String rhs = { .data = "", .size = 0 };
|
||||
modify_keymap(channel_id, buf, true, mode, lhs, rhs, NULL, err);
|
||||
int maptype = opts && opts->lhs ? MAPTYPE_UNMAP_LHS : MAPTYPE_UNMAP;
|
||||
modify_keymap(channel_id, buf, maptype, mode, lhs, rhs, NULL, err);
|
||||
}
|
||||
|
||||
/// Sets a buffer-scoped (b:) variable
|
||||
|
||||
@@ -94,6 +94,11 @@ typedef struct {
|
||||
Boolean replace_keycodes;
|
||||
} Dict(keymap);
|
||||
|
||||
typedef struct {
|
||||
OptionalKeys is_set__keymap_del_;
|
||||
Boolean lhs;
|
||||
} Dict(keymap_del);
|
||||
|
||||
typedef struct {
|
||||
Boolean builtin;
|
||||
} Dict(get_commands);
|
||||
|
||||
@@ -1630,18 +1630,24 @@ void nvim_set_keymap(uint64_t channel_id, String mode, String lhs, String rhs, D
|
||||
Error *err)
|
||||
FUNC_API_SINCE(6)
|
||||
{
|
||||
modify_keymap(channel_id, -1, false, mode, lhs, rhs, opts, err);
|
||||
modify_keymap(channel_id, -1, MAPTYPE_MAP, mode, lhs, rhs, opts, err);
|
||||
}
|
||||
|
||||
/// Unmaps a global |mapping| for the given mode.
|
||||
///
|
||||
/// To unmap a buffer-local mapping, use |nvim_buf_del_keymap()|.
|
||||
///
|
||||
/// @param mode Mode short-name ("n", "i", "v", ...)
|
||||
/// @param lhs Left-hand-side |{lhs}| of the mapping.
|
||||
/// @param opts Optional parameters.
|
||||
/// - lhs: When true, only match {lhs}, not {rhs}.
|
||||
///
|
||||
/// @see |nvim_set_keymap()|
|
||||
void nvim_del_keymap(uint64_t channel_id, String mode, String lhs, Error *err)
|
||||
void nvim_del_keymap(uint64_t channel_id, String mode, String lhs, Dict(keymap_del) *opts,
|
||||
Error *err)
|
||||
FUNC_API_SINCE(6)
|
||||
{
|
||||
nvim_buf_del_keymap(channel_id, -1, mode, lhs, err);
|
||||
nvim_buf_del_keymap(channel_id, -1, mode, lhs, opts, err);
|
||||
}
|
||||
|
||||
/// Returns a 2-tuple (Array), where item 0 is the current channel id and item
|
||||
|
||||
@@ -2738,11 +2738,13 @@ void ex_abclear(exarg_T *eap)
|
||||
/// Arguments are handled like @ref nvim_set_keymap unless noted.
|
||||
/// @param buffer Buffer handle for a specific buffer, or 0 for the current
|
||||
/// buffer, or -1 to signify global behavior ("all buffers")
|
||||
/// @param is_unmap When true, removes the mapping that matches {lhs}.
|
||||
void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mode, String lhs,
|
||||
/// @param maptype MAPTYPE_MAP to set a mapping, MAPTYPE_UNMAP to remove the mapping that
|
||||
/// matches {lhs} or {rhs}, MAPTYPE_UNMAP_LHS to only match {lhs}.
|
||||
void modify_keymap(uint64_t channel_id, Buffer buffer, int maptype, String mode, String lhs,
|
||||
String rhs, Dict(keymap) *opts, Error *err)
|
||||
{
|
||||
LuaRef lua_funcref = LUA_NOREF;
|
||||
bool is_unmap = maptype == MAPTYPE_UNMAP || maptype == MAPTYPE_UNMAP_LHS;
|
||||
bool global = (buffer == -1);
|
||||
if (global) {
|
||||
buffer = 0;
|
||||
@@ -2834,14 +2836,11 @@ void modify_keymap(uint64_t channel_id, Buffer buffer, bool is_unmap, String mod
|
||||
}
|
||||
|
||||
// buf_do_map() reads noremap/unmap as its own argument.
|
||||
int maptype_val = MAPTYPE_MAP;
|
||||
if (is_unmap) {
|
||||
maptype_val = MAPTYPE_UNMAP;
|
||||
} else if (is_noremap) {
|
||||
maptype_val = MAPTYPE_NOREMAP;
|
||||
if (maptype == MAPTYPE_MAP && is_noremap) {
|
||||
maptype = MAPTYPE_NOREMAP;
|
||||
}
|
||||
|
||||
switch (buf_do_map(maptype_val, &parsed_args, mode_val, is_abbrev, target_buf)) {
|
||||
switch (buf_do_map(maptype, &parsed_args, mode_val, is_abbrev, target_buf)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
|
||||
@@ -594,6 +594,39 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
|
||||
eq('Invalid (empty) LHS', pcall_err(api.nvim_del_keymap, '', ''))
|
||||
end)
|
||||
|
||||
it('del_keymap preserves {rhs} fallback by default #30258', function()
|
||||
api.nvim_set_keymap('n', 'ge', 'q', {})
|
||||
api.nvim_del_keymap('n', 'q')
|
||||
eq({}, get_mapargs('n', 'ge'))
|
||||
end)
|
||||
|
||||
it('del_keymap with opts.lhs matches only {lhs}, never {rhs} #30258', function()
|
||||
api.nvim_set_keymap('n', 'ge', 'q', {})
|
||||
eq('E31: No such mapping', pcall_err(api.nvim_del_keymap, 'n', 'q', { lhs = true }))
|
||||
eq(generate_mapargs('n', 'ge', 'q'), get_mapargs('n', 'ge'))
|
||||
|
||||
api.nvim_del_keymap('n', 'ge', { lhs = true })
|
||||
eq({}, get_mapargs('n', 'ge'))
|
||||
end)
|
||||
|
||||
it('del_keymap for abbreviations with opts.lhs matches only {lhs}, never {rhs} #30258', function()
|
||||
api.nvim_set_keymap('ia', 'foo', 'bar', {})
|
||||
eq('E31: No such mapping', pcall_err(api.nvim_del_keymap, 'ia', 'bar', { lhs = true }))
|
||||
eq(generate_mapargs('ia', 'foo', 'bar'), get_mapargs('ia', 'foo'))
|
||||
|
||||
api.nvim_del_keymap('ia', 'foo', { lhs = true })
|
||||
eq({}, get_mapargs('ia', 'foo'))
|
||||
end)
|
||||
|
||||
it('buf_del_keymap with opts.lhs matches only {lhs}, never {rhs} #30258', function()
|
||||
api.nvim_buf_set_keymap(0, 'n', 'ge', 'q', {})
|
||||
eq('E31: No such mapping', pcall_err(api.nvim_buf_del_keymap, 0, 'n', 'q', { lhs = true }))
|
||||
eq(generate_mapargs('n', 'ge', 'q', { buffer = 1 }), get_mapargs('n', 'ge'))
|
||||
|
||||
api.nvim_buf_del_keymap(0, 'n', 'ge', { lhs = true })
|
||||
eq({}, get_mapargs('n', 'ge'))
|
||||
end)
|
||||
|
||||
it('error if LHS longer than MAXMAPLEN', function()
|
||||
-- assume MAXMAPLEN of 50 chars, as declared in mapping_defs.h
|
||||
local MAXMAPLEN = 50
|
||||
|
||||
@@ -93,6 +93,9 @@ describe('api metadata', function()
|
||||
error(('"%s": parameter %d was optional, now required'):format(old_fn.name, idx))
|
||||
end
|
||||
end
|
||||
while #new_fn.parameters > #old_fn.parameters and new_fn.parameters[#new_fn.parameters][3] do
|
||||
table.remove(new_fn.parameters)
|
||||
end
|
||||
old_fn = normalize_func_metadata(old_fn)
|
||||
new_fn = normalize_func_metadata(new_fn)
|
||||
if old_fn.return_type == 'void' then
|
||||
@@ -248,6 +251,22 @@ describe('api metadata', function()
|
||||
)
|
||||
end)
|
||||
|
||||
it('optional param may be added', function()
|
||||
assert_func_backcompat({
|
||||
name = 'nvim_example',
|
||||
method = false,
|
||||
since = 1,
|
||||
return_type = 'void',
|
||||
parameters = { { 'String', 'src', false } },
|
||||
}, {
|
||||
name = 'nvim_example',
|
||||
method = false,
|
||||
since = 1,
|
||||
return_type = 'void',
|
||||
parameters = { { 'String', 'src', false }, { 'Dict', 'opts', true } },
|
||||
})
|
||||
end)
|
||||
|
||||
it('UI events are compatible with old metadata or have new level', function()
|
||||
local ui_events_new = name_table(api_info.ui_events)
|
||||
local ui_events_compat = {}
|
||||
|
||||
@@ -3049,6 +3049,23 @@ describe('vim.keymap', function()
|
||||
eq('\nNo mapping found', n.exec_capture('nmap qwer'))
|
||||
end)
|
||||
|
||||
it('unmap with lhs option', function()
|
||||
eq(
|
||||
'q',
|
||||
exec_lua [[
|
||||
vim.keymap.set('n', 'ge', 'q')
|
||||
local ok, err = pcall(vim.keymap.del, 'n', 'q', { lhs = true })
|
||||
assert(not ok and err:match('E31: No such mapping'), err)
|
||||
return vim.fn.maparg('ge', 'n')
|
||||
]]
|
||||
)
|
||||
|
||||
exec_lua [[
|
||||
vim.keymap.del('n', 'ge', { lhs = true })
|
||||
]]
|
||||
eq('\nNo mapping found', n.exec_capture('nmap ge'))
|
||||
end)
|
||||
|
||||
it('buffer-local mappings', function()
|
||||
eq(
|
||||
0,
|
||||
|
||||
Reference in New Issue
Block a user