local helpers = require('test.functional.helpers')(after_each) local bufmeths = helpers.bufmeths local clear = helpers.clear local command = helpers.command local curbufmeths = helpers.curbufmeths local eq, neq = helpers.eq, helpers.neq local exec_lua = helpers.exec_lua local exec = helpers.exec local feed = helpers.feed local funcs = helpers.funcs local meths = helpers.meths local source = helpers.source local pcall_err = helpers.pcall_err local shallowcopy = helpers.shallowcopy local sleep = helpers.sleep local sid_api_client = -9 local sid_lua = -8 local mode_bits_map = { ['n'] = 0x01, ['x'] = 0x02, ['o'] = 0x04, ['c'] = 0x08, ['i'] = 0x10, ['l'] = 0x20, ['s'] = 0x40, ['t'] = 0x80, [' '] = 0x47, ['v'] = 0x42, ['!'] = 0x18, } describe('nvim_get_keymap', function() before_each(clear) -- Basic mapping and table to be used to describe results local foo_bar_string = 'nnoremap foo bar' local foo_bar_map_table = { lhs='foo', lhsraw='foo', script=0, silent=0, rhs='bar', expr=0, sid=0, scriptversion=1, buffer=0, nowait=0, mode='n', mode_bits=0x01, abbr=0, noremap=1, lnum=0, } it('returns empty list when no map', function() eq({}, meths.get_keymap('n')) end) it('returns list of all applicable mappings', function() command(foo_bar_string) -- Only one mapping available -- Should be the same as the dictionary we supplied earlier -- and the dictionary you would get from maparg -- since this is a global map, and not script local eq({foo_bar_map_table}, meths.get_keymap('n')) eq({funcs.maparg('foo', 'n', false, true)}, meths.get_keymap('n') ) -- Add another mapping command('nnoremap foo_longer bar_longer') local foolong_bar_map_table = shallowcopy(foo_bar_map_table) foolong_bar_map_table['lhs'] = 'foo_longer' foolong_bar_map_table['lhsraw'] = 'foo_longer' foolong_bar_map_table['rhs'] = 'bar_longer' eq({foolong_bar_map_table, foo_bar_map_table}, meths.get_keymap('n') ) -- Remove a mapping command('unmap foo_longer') eq({foo_bar_map_table}, meths.get_keymap('n') ) end) it('works for other modes', function() -- Add two mappings, one in insert and one normal -- We'll only check the insert mode one command('nnoremap not_going to_check') command('inoremap foo bar') -- The table will be the same except for the mode local insert_table = shallowcopy(foo_bar_map_table) insert_table['mode'] = 'i' insert_table['mode_bits'] = 0x10 eq({insert_table}, meths.get_keymap('i')) end) it('considers scope', function() -- change the map slightly command('nnoremap foo_longer bar_longer') local foolong_bar_map_table = shallowcopy(foo_bar_map_table) foolong_bar_map_table['lhs'] = 'foo_longer' foolong_bar_map_table['lhsraw'] = 'foo_longer' foolong_bar_map_table['rhs'] = 'bar_longer' local buffer_table = shallowcopy(foo_bar_map_table) buffer_table['buffer'] = 1 command('nnoremap foo bar') -- The buffer mapping should not show up eq({foolong_bar_map_table}, meths.get_keymap('n')) eq({buffer_table}, curbufmeths.get_keymap('n')) end) it('considers scope for overlapping maps', function() command('nnoremap foo bar') local buffer_table = shallowcopy(foo_bar_map_table) buffer_table['buffer'] = 1 command('nnoremap foo bar') eq({foo_bar_map_table}, meths.get_keymap('n')) eq({buffer_table}, curbufmeths.get_keymap('n')) end) it('can retrieve mapping for different buffers', function() local original_buffer = curbufmeths.get_number() -- Place something in each of the buffers to make sure they stick around -- and set hidden so we can leave them command('set hidden') command('new') command('normal! ihello 2') command('new') command('normal! ihello 3') local final_buffer = curbufmeths.get_number() command('nnoremap foo bar') -- Final buffer will have buffer mappings local buffer_table = shallowcopy(foo_bar_map_table) buffer_table['buffer'] = final_buffer eq({buffer_table}, meths.buf_get_keymap(final_buffer, 'n')) eq({buffer_table}, meths.buf_get_keymap(0, 'n')) command('buffer ' .. original_buffer) eq(original_buffer, curbufmeths.get_number()) -- Original buffer won't have any mappings eq({}, meths.get_keymap('n')) eq({}, curbufmeths.get_keymap('n')) eq({buffer_table}, meths.buf_get_keymap(final_buffer, 'n')) end) -- Test toggle switches for basic options -- @param option The key represented in the `maparg()` result dict local function global_and_buffer_test(map, option, option_token, global_on_result, buffer_on_result, global_off_result, buffer_off_result, new_windows) local function make_new_windows(number_of_windows) if new_windows == nil then return nil end for _=1,number_of_windows do command('new') end end local mode = string.sub(map, 1,1) -- Don't run this for the mapping, since it doesn't make sense if option_token ~= '' then it(string.format( 'returns %d for the key "%s" when %s is used globally with %s (%s)', global_on_result, option, option_token, map, mode), function() make_new_windows(new_windows) command(map .. ' ' .. option_token .. ' foo bar') local result = meths.get_keymap(mode)[1][option] eq(global_on_result, result) end) end it(string.format('returns %d for the key "%s" when %s is used for buffers with %s (%s)', buffer_on_result, option, option_token, map, mode), function() make_new_windows(new_windows) command(map .. ' ' .. option_token .. ' foo bar') local result = curbufmeths.get_keymap(mode)[1][option] eq(buffer_on_result, result) end) -- Don't run these for the mapping, since it doesn't make sense if option_token ~= '' then it(string.format('returns %d for the key "%s" when %s is not used globally with %s (%s)', global_off_result, option, option_token, map, mode), function() make_new_windows(new_windows) command(map .. ' baz bat') local result = meths.get_keymap(mode)[1][option] eq(global_off_result, result) end) it(string.format('returns %d for the key "%s" when %s is not used for buffers with %s (%s)', buffer_off_result, option, option_token, map, mode), function() make_new_windows(new_windows) command(map .. ' foo bar') local result = curbufmeths.get_keymap(mode)[1][option] eq(buffer_off_result, result) end) end end -- Standard modes and returns the same values in the dictionary as maparg() local mode_list = {'nnoremap', 'nmap', 'imap', 'inoremap', 'cnoremap'} for mode in pairs(mode_list) do global_and_buffer_test(mode_list[mode], 'silent', '', 1, 1, 0, 0) global_and_buffer_test(mode_list[mode], 'nowait', '', 1, 1, 0, 0) global_and_buffer_test(mode_list[mode], 'expr', '', 1, 1, 0, 0) end -- noremap will now be 2 if script was used, which is not the same as maparg() global_and_buffer_test('nmap', 'noremap', '