neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

map_functions_spec.lua (8160B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 
      4 local clear = n.clear
      5 local eq = t.eq
      6 local eval = n.eval
      7 local exec = n.exec
      8 local exec_lua = n.exec_lua
      9 local expect = n.expect
     10 local feed = n.feed
     11 local fn = n.fn
     12 local api = n.api
     13 local source = n.source
     14 local command = n.command
     15 local exec_capture = n.exec_capture
     16 local pcall_err = t.pcall_err
     17 
     18 describe('maparg()', function()
     19  before_each(clear)
     20 
     21  local foo_bar_map_table = {
     22    lhs = 'foo',
     23    lhsraw = 'foo',
     24    script = 0,
     25    silent = 0,
     26    rhs = 'bar',
     27    expr = 0,
     28    replace_keycodes = 0,
     29    sid = 0,
     30    scriptversion = 1,
     31    buffer = 0,
     32    nowait = 0,
     33    mode = 'n',
     34    mode_bits = 0x01,
     35    abbr = 0,
     36    noremap = 1,
     37    lnum = 0,
     38  }
     39 
     40  it('returns a dict', function()
     41    command('nnoremap foo bar')
     42    eq('bar', fn.maparg('foo'))
     43    eq(foo_bar_map_table, fn.maparg('foo', 'n', false, true))
     44  end)
     45 
     46  it('returns 1 for silent when <silent> is used', function()
     47    command('nnoremap <silent> foo bar')
     48    eq(1, fn.maparg('foo', 'n', false, true)['silent'])
     49 
     50    command('nnoremap baz bat')
     51    eq(0, fn.maparg('baz', 'n', false, true)['silent'])
     52  end)
     53 
     54  it('returns an empty string when no map is present', function()
     55    eq('', fn.maparg('not a mapping'))
     56  end)
     57 
     58  it('returns an empty dict when no map is present and dict is requested', function()
     59    eq({}, fn.maparg('not a mapping', 'n', false, true))
     60  end)
     61 
     62  it('returns the same value for noremap and <script>', function()
     63    command('inoremap <script> hello world')
     64    command('inoremap this that')
     65    eq(
     66      fn.maparg('hello', 'i', false, true)['noremap'],
     67      fn.maparg('this', 'i', false, true)['noremap']
     68    )
     69  end)
     70 
     71  it('returns a boolean for buffer', function()
     72    -- Open enough windows to know we aren't on buffer number 1
     73    command('new')
     74    command('new')
     75    command('new')
     76    command('cnoremap <buffer> this that')
     77    eq(1, fn.maparg('this', 'c', false, true)['buffer'])
     78 
     79    -- Global will return 0 always
     80    command('nnoremap other another')
     81    eq(0, fn.maparg('other', 'n', false, true)['buffer'])
     82  end)
     83 
     84  it('returns script numbers', function()
     85    source([[
     86      function! s:maparg_test_function() abort
     87        return 'testing'
     88      endfunction
     89 
     90      nnoremap fizz :call <SID>maparg_test_function()<CR>
     91    ]])
     92    eq(1, fn.maparg('fizz', 'n', false, true)['sid'])
     93    eq('testing', api.nvim_call_function('<SNR>1_maparg_test_function', {}))
     94  end)
     95 
     96  it('works with <F12> and others', function()
     97    source([[
     98      let g:maparg_test_var = 0
     99 
    100      nnoremap <F12> :let g:maparg_test_var = 1<CR>
    101    ]])
    102    eq(0, eval('g:maparg_test_var'))
    103    source([[
    104      call feedkeys("\<F12>")
    105    ]])
    106    eq(1, eval('g:maparg_test_var'))
    107 
    108    eq(':let g:maparg_test_var = 1<CR>', fn.maparg('<F12>', 'n', false, true)['rhs'])
    109  end)
    110 
    111  it('works with <expr>', function()
    112    source([[
    113      let counter = 0
    114      inoremap <expr> <C-L> ListItem()
    115      inoremap <expr> <C-R> ListReset()
    116 
    117      func ListItem()
    118        let g:counter += 1
    119        return g:counter . '. '
    120      endfunc
    121 
    122      func ListReset()
    123        let g:counter = 0
    124        return ''
    125      endfunc
    126 
    127      call feedkeys("i\<C-L>")
    128    ]])
    129    eq(1, eval('g:counter'))
    130 
    131    local map_dict = fn.maparg('<C-L>', 'i', false, true)
    132    eq(1, map_dict['expr'])
    133    eq('i', map_dict['mode'])
    134  end)
    135 
    136  it('works with combining characters', function()
    137    -- Using addacutes to make combining character better visible
    138    local function ac(s)
    139      local acute = '\204\129' -- U+0301 COMBINING ACUTE ACCENT
    140      local ret = s:gsub('`', acute)
    141      return ret
    142    end
    143    command(ac([[
    144      nnoremap a  b`
    145      nnoremap c` d
    146      nnoremap e` f`
    147    ]]))
    148    eq(ac('b`'), fn.maparg(ac('a')))
    149    eq(ac(''), fn.maparg(ac('c')))
    150    eq(ac('d'), fn.maparg(ac('c`')))
    151    eq(ac('f`'), fn.maparg(ac('e`')))
    152 
    153    local function acmap(lhs, rhs)
    154      return {
    155        lhs = ac(lhs),
    156        lhsraw = ac(lhs),
    157        rhs = ac(rhs),
    158 
    159        buffer = 0,
    160        expr = 0,
    161        replace_keycodes = 0,
    162        mode = 'n',
    163        mode_bits = 0x01,
    164        abbr = 0,
    165        noremap = 1,
    166        nowait = 0,
    167        script = 0,
    168        sid = 0,
    169        scriptversion = 1,
    170        silent = 0,
    171        lnum = 0,
    172      }
    173    end
    174 
    175    eq({}, fn.maparg(ac('c'), 'n', 0, 1))
    176    eq(acmap('a', 'b`'), fn.maparg(ac('a'), 'n', 0, 1))
    177    eq(acmap('c`', 'd'), fn.maparg(ac('c`'), 'n', 0, 1))
    178    eq(acmap('e`', 'f`'), fn.maparg(ac('e`'), 'n', 0, 1))
    179  end)
    180 end)
    181 
    182 describe('mapset()', function()
    183  before_each(clear)
    184 
    185  it('can restore mapping with backslash in lhs', function()
    186    api.nvim_set_keymap('n', '\\ab', 'a', {})
    187    eq('\nn  \\ab           a', exec_capture('nmap \\ab'))
    188    local mapargs = fn.maparg('\\ab', 'n', false, true)
    189    api.nvim_set_keymap('n', '\\ab', 'b', {})
    190    eq('\nn  \\ab           b', exec_capture('nmap \\ab'))
    191    fn.mapset('n', false, mapargs)
    192    eq('\nn  \\ab           a', exec_capture('nmap \\ab'))
    193  end)
    194 
    195  it('can restore mapping description from the dict returned by maparg()', function()
    196    api.nvim_set_keymap('n', 'lhs', 'rhs', { desc = 'map description' })
    197    eq('\nn  lhs           rhs\n                 map description', exec_capture('nmap lhs'))
    198    local mapargs = fn.maparg('lhs', 'n', false, true)
    199    api.nvim_set_keymap('n', 'lhs', 'rhs', { desc = 'MAP DESCRIPTION' })
    200    eq('\nn  lhs           rhs\n                 MAP DESCRIPTION', exec_capture('nmap lhs'))
    201    fn.mapset('n', false, mapargs)
    202    eq('\nn  lhs           rhs\n                 map description', exec_capture('nmap lhs'))
    203  end)
    204 
    205  it('can restore "replace_keycodes" from the dict returned by maparg()', function()
    206    api.nvim_set_keymap('i', 'foo', [['<l' .. 't>']], { expr = true, replace_keycodes = true })
    207    feed('Afoo')
    208    expect('<')
    209    local mapargs = fn.maparg('foo', 'i', false, true)
    210    api.nvim_set_keymap('i', 'foo', [['<l' .. 't>']], { expr = true })
    211    feed('foo')
    212    expect('<<lt>')
    213    fn.mapset('i', false, mapargs)
    214    feed('foo')
    215    expect('<<lt><')
    216  end)
    217 
    218  it('replaces an abbreviation of the same lhs #20320', function()
    219    command('inoreabbr foo bar')
    220    eq('\ni  foo         * bar', exec_capture('iabbr foo'))
    221    feed('ifoo ')
    222    expect('bar ')
    223    local mapargs = fn.maparg('foo', 'i', true, true)
    224    command('inoreabbr foo BAR')
    225    eq('\ni  foo         * BAR', exec_capture('iabbr foo'))
    226    feed('foo ')
    227    expect('bar BAR ')
    228    fn.mapset('i', true, mapargs)
    229    eq('\ni  foo         * bar', exec_capture('iabbr foo'))
    230    feed('foo<Esc>')
    231    expect('bar BAR bar')
    232  end)
    233 
    234  it('can restore Lua callback from the dict returned by maparg()', function()
    235    eq(
    236      0,
    237      exec_lua([[
    238      GlobalCount = 0
    239      vim.api.nvim_set_keymap('n', 'asdf', '', {
    240        callback = function() GlobalCount = GlobalCount + 1 end,
    241      })
    242      return GlobalCount
    243    ]])
    244    )
    245    feed('asdf')
    246    eq(1, exec_lua([[return GlobalCount]]))
    247 
    248    exec_lua([[
    249      _G.saved_asdf_map = vim.fn.maparg('asdf', 'n', false, true)
    250      vim.api.nvim_set_keymap('n', 'asdf', '', {
    251        callback = function() GlobalCount = GlobalCount + 10 end,
    252      })
    253    ]])
    254    feed('asdf')
    255    eq(11, exec_lua([[return GlobalCount]]))
    256 
    257    exec_lua([[vim.fn.mapset('n', false, _G.saved_asdf_map)]])
    258    feed('asdf')
    259    eq(12, exec_lua([[return GlobalCount]]))
    260 
    261    exec([[
    262      let g:saved_asdf_map = maparg('asdf', 'n', v:false, v:true)
    263      lua <<
    264      vim.api.nvim_set_keymap('n', 'asdf', '', {
    265        callback = function() GlobalCount = GlobalCount + 10 end,
    266      })
    267    ]])
    268    feed('asdf')
    269    eq(22, exec_lua([[return GlobalCount]]))
    270 
    271    command([[call mapset('n', v:false, g:saved_asdf_map)]])
    272    feed('asdf')
    273    eq(23, exec_lua([[return GlobalCount]]))
    274  end)
    275 
    276  it('does not leak memory if lhs is missing', function()
    277    eq(
    278      'Vim:E460: Entries missing in mapset() dict argument',
    279      pcall_err(exec_lua, [[vim.fn.mapset('n', false, {rhs = 'foo'})]])
    280    )
    281    eq(
    282      'Vim:E460: Entries missing in mapset() dict argument',
    283      pcall_err(exec_lua, [[vim.fn.mapset('n', false, {callback = function() end})]])
    284    )
    285  end)
    286 end)