mirror of
https://github.com/neovim/neovim.git
synced 2025-12-16 03:15:39 +00:00
API: nvim_set_keymap, nvim_del_keymap #9924
closes #9136 - Treat empty {rhs} like <Nop> - getchar.c: Pull "repl. MapArg termcodes" into func The "preprocessing code" surrounding the replace_termcodes calls needs to invoke replace_termcodes, and also check if RHS is equal to "<Nop>". To reduce code duplication, factor this out into a helper function. Also add an rhs_is_noop flag to MapArguments; buf_do_map_explicit expects an empty {rhs} string for "<Nop>", but also needs to distinguish that from something like ":map lhs<cr>" where no {rhs} was provided. - getchar.c: Use allocated buffer for rhs in MapArgs Since the MAXMAPLEN limit does not apply to the RHS of a mapping (or else an RHS that calls a really long autoload function from a plugin would be incorrectly rejected as being too long), use an allocated buffer for RHS rather than a static buffer of length MAXMAPLEN + 1. - Mappings LHS and RHS can contain literal space characters, newlines, etc. - getchar.c: replace_termcodes in str_to_mapargs It makes sense to do this; str_to_mapargs is, intuitively, supposed to take a "raw" command string and parse it into a totally "do_map-ready" struct. - api/vim.c: Update lhs, rhs len after replace_termcodes Fixes a bug in which replace_termcodes changes the length of lhs or rhs, but the later search through the mappings/abbreviations hashtables still uses the old length value. This would cause the search to fail erroneously and throw 'E31: No such mapping' errors or 'E24: No such abbreviation' errors. - getchar: Create new map_arguments struct So that a string of map arguments can be parsed into a more useful, more portable data structure. - getchar.c: Add buf_do_map function Exactly the same as the old do_map, but replace the hardcoded references to the global `buf_T* curbuf` with a function parameter so that we can invoke it from nvim_buf_set_keymap. - Remove gettext calls in do_map error handling
This commit is contained in:
committed by
Justin M. Keyes
parent
24f9dd73d5
commit
fbf2c414ad
@@ -1,15 +1,19 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local global_helpers = require('test.helpers')
|
||||
|
||||
local bufmeths = helpers.bufmeths
|
||||
local clear = helpers.clear
|
||||
local command = helpers.command
|
||||
local curbufmeths = helpers.curbufmeths
|
||||
local eq = helpers.eq
|
||||
local eq, neq = helpers.eq, helpers.neq
|
||||
local expect_err = helpers.expect_err
|
||||
local feed = helpers.feed
|
||||
local funcs = helpers.funcs
|
||||
local meths = helpers.meths
|
||||
local source = helpers.source
|
||||
|
||||
local shallowcopy = global_helpers.shallowcopy
|
||||
local sleep = global_helpers.sleep
|
||||
|
||||
describe('nvim_get_keymap', function()
|
||||
before_each(clear)
|
||||
@@ -308,3 +312,502 @@ describe('nvim_get_keymap', function()
|
||||
eq({space_table}, meths.get_keymap('n'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_[set/del]_keymap', function()
|
||||
before_each(clear)
|
||||
|
||||
-- generate_expected is truthy when we want to generate an expected output for
|
||||
-- maparg(); mapargs() won't take '!' as an input, though it will return '!'
|
||||
-- in its output if getting a mapping set with |:map!|
|
||||
local function normalize_mapmode(mode, generate_expected)
|
||||
if not generate_expected and mode == '!' then
|
||||
-- can't retrieve mapmode-ic mappings with '!', but can with 'i' or 'c'.
|
||||
mode = 'i'
|
||||
elseif mode == '' or mode == ' ' or mode == 'm' then
|
||||
mode = generate_expected and ' ' or 'm'
|
||||
end
|
||||
return mode
|
||||
end
|
||||
|
||||
-- Generate a mapargs dict, for comparison against the mapping that was
|
||||
-- actually set
|
||||
local function generate_mapargs(mode, lhs, rhs, opts)
|
||||
if not opts then
|
||||
opts = {}
|
||||
end
|
||||
|
||||
local to_return = {}
|
||||
to_return.mode = normalize_mapmode(mode, true)
|
||||
to_return.noremap = not opts.noremap and 0 or 1
|
||||
to_return.lhs = lhs
|
||||
to_return.rhs = rhs
|
||||
to_return.silent = not opts.silent and 0 or 1
|
||||
to_return.nowait = not opts.nowait and 0 or 1
|
||||
to_return.expr = not opts.expr and 0 or 1
|
||||
to_return.sid = not opts.sid and 0 or opts.sid
|
||||
to_return.buffer = not opts.buffer and 0 or opts.buffer
|
||||
|
||||
-- mode 't' doesn't print when calling maparg
|
||||
if mode == 't' then
|
||||
to_return.mode = ''
|
||||
end
|
||||
|
||||
return to_return
|
||||
end
|
||||
|
||||
-- Retrieve a mapargs dict from neovim, if one exists
|
||||
local function get_mapargs(mode, lhs)
|
||||
return funcs.maparg(lhs, normalize_mapmode(mode), false, true)
|
||||
end
|
||||
|
||||
-- Test error handling
|
||||
it('throws errors when given empty lhs', function()
|
||||
-- escape parentheses in lua string, else comparison fails erroneously
|
||||
expect_err('Invalid %(empty%) LHS',
|
||||
meths.set_keymap, '', '', 'rhs', {})
|
||||
expect_err('Invalid %(empty%) LHS',
|
||||
meths.set_keymap, '', '', '', {})
|
||||
|
||||
expect_err('Invalid %(empty%) LHS', meths.del_keymap, '', '')
|
||||
end)
|
||||
|
||||
it('throws errors when given an lhs longer than MAXMAPLEN', function()
|
||||
-- assume MAXMAPLEN of 50 chars, as declared in vim.h
|
||||
local MAXMAPLEN = 50
|
||||
local lhs = ''
|
||||
for i=1,MAXMAPLEN do
|
||||
lhs = lhs..(i % 10)
|
||||
end
|
||||
|
||||
-- exactly 50 chars should be fine
|
||||
meths.set_keymap('', lhs, 'rhs', {})
|
||||
|
||||
-- del_keymap should unmap successfully
|
||||
meths.del_keymap('', lhs)
|
||||
eq({}, get_mapargs('', lhs))
|
||||
|
||||
-- 51 chars should produce an error
|
||||
lhs = lhs..'1'
|
||||
expect_err('LHS exceeds maximum map length: '..lhs,
|
||||
meths.set_keymap, '', lhs, 'rhs', {})
|
||||
expect_err('LHS exceeds maximum map length: '..lhs,
|
||||
meths.del_keymap, '', lhs)
|
||||
end)
|
||||
|
||||
it('does not throw errors when rhs is longer than MAXMAPLEN', function()
|
||||
local MAXMAPLEN = 50
|
||||
local rhs = ''
|
||||
for i=1,MAXMAPLEN do
|
||||
rhs = rhs..(i % 10)
|
||||
end
|
||||
rhs = rhs..'1'
|
||||
meths.set_keymap('', 'lhs', rhs, {})
|
||||
eq(generate_mapargs('', 'lhs', rhs),
|
||||
get_mapargs('', 'lhs'))
|
||||
end)
|
||||
|
||||
it('throws errors when given too-long mode shortnames', function()
|
||||
expect_err('Shortname is too long: map',
|
||||
meths.set_keymap, 'map', 'lhs', 'rhs', {})
|
||||
|
||||
expect_err('Shortname is too long: vmap',
|
||||
meths.set_keymap, 'vmap', 'lhs', 'rhs', {})
|
||||
|
||||
expect_err('Shortname is too long: xnoremap',
|
||||
meths.set_keymap, 'xnoremap', 'lhs', 'rhs', {})
|
||||
|
||||
expect_err('Shortname is too long: map', meths.del_keymap, 'map', 'lhs')
|
||||
expect_err('Shortname is too long: vmap', meths.del_keymap, 'vmap', 'lhs')
|
||||
expect_err('Shortname is too long: xnoremap', meths.del_keymap, 'xnoremap', 'lhs')
|
||||
end)
|
||||
|
||||
it('throws errors when given unrecognized mode shortnames', function()
|
||||
expect_err('Invalid mode shortname: ?',
|
||||
meths.set_keymap, '?', 'lhs', 'rhs', {})
|
||||
|
||||
expect_err('Invalid mode shortname: y',
|
||||
meths.set_keymap, 'y', 'lhs', 'rhs', {})
|
||||
|
||||
expect_err('Invalid mode shortname: p',
|
||||
meths.set_keymap, 'p', 'lhs', 'rhs', {})
|
||||
|
||||
expect_err('Invalid mode shortname: ?', meths.del_keymap, '?', 'lhs')
|
||||
expect_err('Invalid mode shortname: y', meths.del_keymap, 'y', 'lhs')
|
||||
expect_err('Invalid mode shortname: p', meths.del_keymap, 'p', 'lhs')
|
||||
end)
|
||||
|
||||
it('throws errors when optnames are almost right', function()
|
||||
expect_err('Invalid key: silentt',
|
||||
meths.set_keymap, 'n', 'lhs', 'rhs', {silentt = true})
|
||||
expect_err('Invalid key: sidd',
|
||||
meths.set_keymap, 'n', 'lhs', 'rhs', {sidd = false})
|
||||
expect_err('Invalid key: nowaiT',
|
||||
meths.set_keymap, 'n', 'lhs', 'rhs', {nowaiT = false})
|
||||
end)
|
||||
|
||||
it('does not recognize <buffer> as an option', function()
|
||||
expect_err('Invalid key: buffer',
|
||||
meths.set_keymap, 'n', 'lhs', 'rhs', {buffer = true})
|
||||
end)
|
||||
|
||||
local optnames = {'nowait', 'silent', 'script', 'expr', 'unique'}
|
||||
for _, opt in ipairs(optnames) do
|
||||
-- note: need '%' to escape hyphens, which have special meaning in lua
|
||||
it('throws an error when given non-boolean value for '..opt, function()
|
||||
local opts = {}
|
||||
opts[opt] = 2
|
||||
expect_err('Gave non%-boolean value for an opt: '..opt,
|
||||
meths.set_keymap, 'n', 'lhs', 'rhs', opts)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Perform tests of basic functionality
|
||||
it('can set ordinary mappings', function()
|
||||
meths.set_keymap('n', 'lhs', 'rhs', {})
|
||||
eq(generate_mapargs('n', 'lhs', 'rhs'), get_mapargs('n', 'lhs'))
|
||||
|
||||
meths.set_keymap('v', 'lhs', 'rhs', {})
|
||||
eq(generate_mapargs('v', 'lhs', 'rhs'), get_mapargs('v', 'lhs'))
|
||||
end)
|
||||
|
||||
it('doesn\'t throw when lhs or rhs have leading/trailing WS', function()
|
||||
meths.set_keymap('n', ' lhs', 'rhs', {})
|
||||
eq(generate_mapargs('n', '<Space><Space><Space>lhs', 'rhs'),
|
||||
get_mapargs('n', ' lhs'))
|
||||
|
||||
meths.set_keymap('n', 'lhs ', 'rhs', {})
|
||||
eq(generate_mapargs('n', 'lhs<Space><Space><Space><Space>', 'rhs'),
|
||||
get_mapargs('n', 'lhs '))
|
||||
|
||||
meths.set_keymap('v', ' lhs ', '\trhs\t\f', {})
|
||||
eq(generate_mapargs('v', '<Space>lhs<Space><Space>', '\trhs\t\f'),
|
||||
get_mapargs('v', ' lhs '))
|
||||
end)
|
||||
|
||||
it('can set noremap mappings', function()
|
||||
meths.set_keymap('x', 'lhs', 'rhs', {noremap = true})
|
||||
eq(generate_mapargs('x', 'lhs', 'rhs', {noremap = true}),
|
||||
get_mapargs('x', 'lhs'))
|
||||
|
||||
meths.set_keymap('t', 'lhs', 'rhs', {noremap = true})
|
||||
eq(generate_mapargs('t', 'lhs', 'rhs', {noremap = true}),
|
||||
get_mapargs('t', 'lhs'))
|
||||
end)
|
||||
|
||||
it('can unmap mappings', function()
|
||||
meths.set_keymap('v', 'lhs', 'rhs', {})
|
||||
meths.del_keymap('v', 'lhs')
|
||||
eq({}, get_mapargs('v', 'lhs'))
|
||||
|
||||
meths.set_keymap('t', 'lhs', 'rhs', {noremap = true})
|
||||
meths.del_keymap('t', 'lhs')
|
||||
eq({}, get_mapargs('t', 'lhs'))
|
||||
end)
|
||||
|
||||
-- Test some edge cases
|
||||
it('accepts "!" and " " and "" as synonyms for mapmode-nvo', function()
|
||||
local nvo_shortnames = {'', ' ', '!'}
|
||||
for _, name in ipairs(nvo_shortnames) do
|
||||
meths.set_keymap(name, 'lhs', 'rhs', {})
|
||||
meths.del_keymap(name, 'lhs')
|
||||
eq({}, get_mapargs(name, 'lhs'))
|
||||
end
|
||||
end)
|
||||
|
||||
local special_chars = {'<C-U>', '<S-Left>', '<F12><F2><Tab>', '<Space><Tab>'}
|
||||
for _, lhs in ipairs(special_chars) do
|
||||
for _, rhs in ipairs(special_chars) do
|
||||
local mapmode = '!'
|
||||
it('can set mappings with special characters, lhs: '..lhs..', rhs: '..rhs,
|
||||
function()
|
||||
meths.set_keymap(mapmode, lhs, rhs, {})
|
||||
eq(generate_mapargs(mapmode, lhs, rhs), get_mapargs(mapmode, lhs))
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
it('can set mappings containing literal keycodes', function()
|
||||
meths.set_keymap('n', '\n\r\n', 'rhs', {})
|
||||
local expected = generate_mapargs('n', '<NL><CR><NL>', 'rhs')
|
||||
eq(expected, get_mapargs('n', '<C-j><CR><C-j>'))
|
||||
end)
|
||||
|
||||
it('can set mappings whose RHS is a <Nop>', function()
|
||||
meths.set_keymap('i', 'lhs', '<Nop>', {})
|
||||
command('normal ilhs')
|
||||
eq({''}, curbufmeths.get_lines(0, -1, 0)) -- imap to <Nop> does nothing
|
||||
eq(generate_mapargs('i', 'lhs', '<Nop>', {}),
|
||||
get_mapargs('i', 'lhs'))
|
||||
|
||||
-- also test for case insensitivity
|
||||
meths.set_keymap('i', 'lhs', '<nOp>', {})
|
||||
command('normal ilhs')
|
||||
eq({''}, curbufmeths.get_lines(0, -1, 0))
|
||||
-- note: RHS in returned mapargs() dict reflects the original RHS
|
||||
-- provided by the user
|
||||
eq(generate_mapargs('i', 'lhs', '<nOp>', {}),
|
||||
get_mapargs('i', 'lhs'))
|
||||
|
||||
meths.set_keymap('i', 'lhs', '<NOP>', {})
|
||||
command('normal ilhs')
|
||||
eq({''}, curbufmeths.get_lines(0, -1, 0))
|
||||
eq(generate_mapargs('i', 'lhs', '<NOP>', {}),
|
||||
get_mapargs('i', 'lhs'))
|
||||
end)
|
||||
|
||||
it('treats an empty RHS in a mapping like a <Nop>', function()
|
||||
meths.set_keymap('i', 'lhs', '', {})
|
||||
command('normal ilhs')
|
||||
eq({''}, curbufmeths.get_lines(0, -1, 0))
|
||||
eq(generate_mapargs('i', 'lhs', '', {}),
|
||||
get_mapargs('i', 'lhs'))
|
||||
end)
|
||||
|
||||
it('can set and unset <M-">', function()
|
||||
-- Taken from the legacy test: test_mapping.vim. Exposes a bug in which
|
||||
-- replace_termcodes changes the length of the mapping's LHS, but
|
||||
-- do_map continues to use the *old* length of LHS.
|
||||
meths.set_keymap('i', '<M-">', 'foo', {})
|
||||
meths.del_keymap('i', '<M-">')
|
||||
eq({}, get_mapargs('i', '<M-">'))
|
||||
end)
|
||||
|
||||
it('interprets control sequences in expr-quotes correctly when called '
|
||||
..'inside vim', function()
|
||||
command([[call nvim_set_keymap('i', "\<space>", "\<tab>", {})]])
|
||||
eq(generate_mapargs('i', '<Space>', '\t', {}),
|
||||
get_mapargs('i', '<Space>'))
|
||||
feed('i ')
|
||||
eq({'\t'}, curbufmeths.get_lines(0, -1, 0))
|
||||
end)
|
||||
|
||||
it('throws appropriate error messages when setting <unique> maps', function()
|
||||
meths.set_keymap('l', 'lhs', 'rhs', {})
|
||||
expect_err('E227: mapping already exists for lhs',
|
||||
meths.set_keymap, 'l', 'lhs', 'rhs', {unique = true})
|
||||
-- different mapmode, no error should be thrown
|
||||
meths.set_keymap('t', 'lhs', 'rhs', {unique = true})
|
||||
end)
|
||||
|
||||
it('can set <expr> mappings whose RHS change dynamically', function()
|
||||
meths.command_output([[
|
||||
function! FlipFlop() abort
|
||||
if !exists('g:flip') | let g:flip = 0 | endif
|
||||
let g:flip = !g:flip
|
||||
return g:flip
|
||||
endfunction
|
||||
]])
|
||||
eq(1, meths.call_function('FlipFlop', {}))
|
||||
eq(0, meths.call_function('FlipFlop', {}))
|
||||
eq(1, meths.call_function('FlipFlop', {}))
|
||||
eq(0, meths.call_function('FlipFlop', {}))
|
||||
|
||||
meths.set_keymap('i', 'lhs', 'FlipFlop()', {expr = true})
|
||||
command('normal ilhs')
|
||||
eq({'1'}, curbufmeths.get_lines(0, -1, 0))
|
||||
|
||||
command('normal! ggVGd')
|
||||
|
||||
command('normal ilhs')
|
||||
eq({'0'}, curbufmeths.get_lines(0, -1, 0))
|
||||
end)
|
||||
|
||||
it('can set mappings that do trigger other mappings', function()
|
||||
meths.set_keymap('i', 'mhs', 'rhs', {})
|
||||
meths.set_keymap('i', 'lhs', 'mhs', {})
|
||||
|
||||
command('normal imhs')
|
||||
eq({'rhs'}, curbufmeths.get_lines(0, -1, 0))
|
||||
|
||||
command('normal! ggVGd')
|
||||
|
||||
command('normal ilhs')
|
||||
eq({'rhs'}, curbufmeths.get_lines(0, -1, 0))
|
||||
end)
|
||||
|
||||
it("can set noremap mappings that don't trigger other mappings", function()
|
||||
meths.set_keymap('i', 'mhs', 'rhs', {})
|
||||
meths.set_keymap('i', 'lhs', 'mhs', {noremap = true})
|
||||
|
||||
command('normal imhs')
|
||||
eq({'rhs'}, curbufmeths.get_lines(0, -1, 0))
|
||||
|
||||
command('normal! ggVGd')
|
||||
|
||||
command('normal ilhs') -- shouldn't trigger mhs-to-rhs mapping
|
||||
eq({'mhs'}, curbufmeths.get_lines(0, -1, 0))
|
||||
end)
|
||||
|
||||
it("can set nowait mappings that fire without waiting", function()
|
||||
meths.set_keymap('i', '123456', 'longer', {})
|
||||
meths.set_keymap('i', '123', 'shorter', {nowait = true})
|
||||
|
||||
-- feed keys one at a time; if all keys arrive atomically, the longer
|
||||
-- mapping will trigger
|
||||
local keys = 'i123456'
|
||||
for c in string.gmatch(keys, '.') do
|
||||
feed(c)
|
||||
sleep(5)
|
||||
end
|
||||
eq({'shorter456'}, curbufmeths.get_lines(0, -1, 0))
|
||||
end)
|
||||
|
||||
-- Perform exhaustive tests of basic functionality
|
||||
local mapmodes = {'n', 'v', 'x', 's', 'o', '!', 'i', 'l', 'c', 't', ' ', ''}
|
||||
for _, mapmode in ipairs(mapmodes) do
|
||||
it('can set/unset normal mappings in mapmode '..mapmode, function()
|
||||
meths.set_keymap(mapmode, 'lhs', 'rhs', {})
|
||||
eq(generate_mapargs(mapmode, 'lhs', 'rhs'),
|
||||
get_mapargs(mapmode, 'lhs'))
|
||||
|
||||
-- some mapmodes (like 'o') will prevent other mapmodes (like '!') from
|
||||
-- taking effect, so unmap after each mapping
|
||||
meths.del_keymap(mapmode, 'lhs')
|
||||
eq({}, get_mapargs(mapmode, 'lhs'))
|
||||
end)
|
||||
end
|
||||
|
||||
for _, mapmode in ipairs(mapmodes) do
|
||||
it('can set/unset noremap mappings using mapmode '..mapmode, function()
|
||||
meths.set_keymap(mapmode, 'lhs', 'rhs', {noremap = true})
|
||||
eq(generate_mapargs(mapmode, 'lhs', 'rhs', {noremap = true}),
|
||||
get_mapargs(mapmode, 'lhs'))
|
||||
|
||||
meths.del_keymap(mapmode, 'lhs')
|
||||
eq({}, get_mapargs(mapmode, 'lhs'))
|
||||
end)
|
||||
end
|
||||
|
||||
-- Test map-arguments, using optnames from above
|
||||
-- remove some map arguments that are harder to test, or were already tested
|
||||
optnames = {'nowait', 'silent', 'expr', 'noremap'}
|
||||
for _, mapmode in ipairs(mapmodes) do
|
||||
local printable_mode = normalize_mapmode(mapmode)
|
||||
|
||||
-- Test with single mappings
|
||||
for _, maparg in ipairs(optnames) do
|
||||
it('can set/unset '..printable_mode..'-mappings with maparg: '..maparg,
|
||||
function()
|
||||
meths.set_keymap(mapmode, 'lhs', 'rhs', {[maparg] = true})
|
||||
eq(generate_mapargs(mapmode, 'lhs', 'rhs', {[maparg] = true}),
|
||||
get_mapargs(mapmode, 'lhs'))
|
||||
meths.del_keymap(mapmode, 'lhs')
|
||||
eq({}, get_mapargs(mapmode, 'lhs'))
|
||||
end)
|
||||
it ('can set/unset '..printable_mode..'-mode mappings with maparg '..
|
||||
maparg..', whose value is false', function()
|
||||
meths.set_keymap(mapmode, 'lhs', 'rhs', {[maparg] = false})
|
||||
eq(generate_mapargs(mapmode, 'lhs', 'rhs'),
|
||||
get_mapargs(mapmode, 'lhs'))
|
||||
meths.del_keymap(mapmode, 'lhs')
|
||||
eq({}, get_mapargs(mapmode, 'lhs'))
|
||||
end)
|
||||
end
|
||||
|
||||
-- Test with triplets of mappings, one of which is false
|
||||
for i = 1, (#optnames - 2) do
|
||||
local opt1, opt2, opt3 = optnames[i], optnames[i + 1], optnames[i + 2]
|
||||
it('can set/unset '..printable_mode..'-mode mappings with mapargs '..
|
||||
opt1..', '..opt2..', '..opt3, function()
|
||||
local opts = {[opt1] = true, [opt2] = false, [opt3] = true}
|
||||
meths.set_keymap(mapmode, 'lhs', 'rhs', opts)
|
||||
eq(generate_mapargs(mapmode, 'lhs', 'rhs', opts),
|
||||
get_mapargs(mapmode, 'lhs'))
|
||||
meths.del_keymap(mapmode, 'lhs')
|
||||
eq({}, get_mapargs(mapmode, 'lhs'))
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
describe('nvim_buf_[set/del]_keymap', function()
|
||||
before_each(clear)
|
||||
|
||||
-- nvim_set_keymap is implemented as a wrapped call to nvim_buf_set_keymap,
|
||||
-- so its tests also effectively test nvim_buf_set_keymap
|
||||
|
||||
-- here, we mainly test for buffer specificity and other special cases
|
||||
|
||||
-- switch to the given buffer, abandoning any changes in the current buffer
|
||||
local function switch_to_buf(bufnr)
|
||||
command(bufnr..'buffer!')
|
||||
end
|
||||
|
||||
-- `set hidden`, then create two buffers and return their bufnr's
|
||||
-- If start_from_first is truthy, the first buffer will be open when
|
||||
-- the function returns; if falsy, the second buffer will be open.
|
||||
local function make_two_buffers(start_from_first)
|
||||
command('set hidden')
|
||||
|
||||
local first_buf = meths.call_function('bufnr', {'%'})
|
||||
command('new')
|
||||
local second_buf = meths.call_function('bufnr', {'%'})
|
||||
neq(second_buf, first_buf) -- sanity check
|
||||
|
||||
if start_from_first then
|
||||
switch_to_buf(first_buf)
|
||||
end
|
||||
|
||||
return first_buf, second_buf
|
||||
end
|
||||
|
||||
it('rejects negative bufnr values', function()
|
||||
expect_err('Wrong type for argument 1, expecting Buffer',
|
||||
bufmeths.set_keymap, -1, '', 'lhs', 'rhs', {})
|
||||
end)
|
||||
|
||||
it('can set mappings active in the current buffer but not others', function()
|
||||
local first, second = make_two_buffers(true)
|
||||
|
||||
bufmeths.set_keymap(0, '', 'lhs', 'irhs<Esc>', {})
|
||||
command('normal lhs')
|
||||
eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1))
|
||||
|
||||
-- mapping should have no effect in new buffer
|
||||
switch_to_buf(second)
|
||||
command('normal lhs')
|
||||
eq({''}, bufmeths.get_lines(0, 0, 1, 1))
|
||||
|
||||
-- mapping should remain active in old buffer
|
||||
switch_to_buf(first)
|
||||
command('normal ^lhs')
|
||||
eq({'rhsrhs'}, bufmeths.get_lines(0, 0, 1, 1))
|
||||
end)
|
||||
|
||||
it('can set local mappings in buffer other than current', function()
|
||||
local first = make_two_buffers(false)
|
||||
bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {})
|
||||
|
||||
-- shouldn't do anything
|
||||
command('normal lhs')
|
||||
eq({''}, bufmeths.get_lines(0, 0, 1, 1))
|
||||
|
||||
-- should take effect
|
||||
switch_to_buf(first)
|
||||
command('normal lhs')
|
||||
eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1))
|
||||
end)
|
||||
|
||||
it('can disable mappings made in another buffer, inside that buffer', function()
|
||||
local first = make_two_buffers(false)
|
||||
bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {})
|
||||
bufmeths.del_keymap(first, '', 'lhs')
|
||||
switch_to_buf(first)
|
||||
|
||||
-- shouldn't do anything
|
||||
command('normal lhs')
|
||||
eq({''}, bufmeths.get_lines(0, 0, 1, 1))
|
||||
end)
|
||||
|
||||
it("can't disable mappings given wrong buffer handle", function()
|
||||
local first, second = make_two_buffers(false)
|
||||
bufmeths.set_keymap(first, '', 'lhs', 'irhs<Esc>', {})
|
||||
expect_err('E31: No such mapping',
|
||||
bufmeths.del_keymap, second, '', 'lhs')
|
||||
|
||||
-- should still work
|
||||
switch_to_buf(first)
|
||||
command('normal lhs')
|
||||
eq({'rhs'}, bufmeths.get_lines(0, 0, 1, 1))
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user