neovim

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

langmap_spec.lua (8717B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 
      4 local eq, neq, call = t.eq, t.neq, n.call
      5 local eval, feed, clear = n.eval, n.feed, n.clear
      6 local command, insert, expect = n.command, n.insert, n.expect
      7 local feed_command = n.feed_command
      8 local curwin = n.api.nvim_get_current_win
      9 
     10 describe("'langmap'", function()
     11  before_each(function()
     12    clear()
     13    insert('iii www')
     14    command('set langmap=iw,wi')
     15    feed('gg0')
     16  end)
     17 
     18  it('converts keys in normal mode', function()
     19    feed('ix')
     20    expect('iii ww')
     21    feed('whello<esc>')
     22    expect('iii helloww')
     23  end)
     24  it('gives characters that are mapped by :nmap.', function()
     25    command('map i 0x')
     26    feed('w')
     27    expect('ii www')
     28  end)
     29  describe("'langnoremap' option.", function()
     30    before_each(function()
     31      command('nmapclear')
     32    end)
     33    it("'langnoremap' is by default ON", function()
     34      eq(1, eval('&langnoremap'))
     35    end)
     36    it("Results of maps are not converted when 'langnoremap' ON.", function()
     37      command('nmap x i')
     38      feed('xdl<esc>')
     39      expect('dliii www')
     40    end)
     41    it('applies when deciding whether to map recursively', function()
     42      command('nmap l i')
     43      command('nmap w j')
     44      feed('ll')
     45      expect('liii www')
     46    end)
     47    it("does not stop applying 'langmap' on first character of a mapping", function()
     48      command('1t1')
     49      command('1t1')
     50      command('goto 1')
     51      command('nmap w j')
     52      feed('iiahello')
     53      expect([[
     54      iii www
     55      iii www
     56      ihelloii www]])
     57    end)
     58    it("Results of maps are converted when 'langnoremap' OFF.", function()
     59      command('set nolangnoremap')
     60      command('nmap x i')
     61      feed('xdl<esc>')
     62      expect('iii ww')
     63    end)
     64  end)
     65  -- e.g. CTRL-W_j  ,  mj , 'j and "jp
     66  it('conversions are applied to keys in middle of command', function()
     67    -- Works in middle of window command
     68    feed('<C-w>s')
     69    local origwin = curwin()
     70    feed('<C-w>i')
     71    neq(origwin, curwin())
     72    -- Works when setting a mark
     73    feed('yy3p3gg0mwgg0mi')
     74    eq({ 0, 3, 1, 0 }, call('getpos', "'i"))
     75    eq({ 0, 1, 1, 0 }, call('getpos', "'w"))
     76    feed('3dd')
     77    -- Works when moving to a mark
     78    feed("'i")
     79    eq({ 0, 1, 1, 0 }, call('getpos', '.'))
     80    -- Works when selecting a register
     81    feed('qillqqwhhq')
     82    eq('hh', eval('@i'))
     83    eq('ll', eval('@w'))
     84    feed('a<C-r>i<esc>')
     85    expect('illii www')
     86    feed('"ip')
     87    expect('illllii www')
     88    -- Works with i_CTRL-O
     89    feed('0a<C-O>ihi<esc>')
     90    expect('illllii hiwww')
     91  end)
     92 
     93  describe('exceptions', function()
     94    -- All "command characters" that 'langmap' does not apply to.
     95    -- These tests consist of those places where some subset of ASCII
     96    -- characters define certain commands, yet 'langmap' is not applied to
     97    -- them.
     98    -- n.b. I think these shouldn't be exceptions.
     99    it(':s///c confirmation', function()
    100      command('set langmap=yn,ny')
    101      feed('qa')
    102      feed_command('s/i/w/gc')
    103      feed('yynq')
    104      expect('wwi www')
    105      feed('u@a')
    106      expect('wwi www')
    107      eq(':s/i/w/gc\ryyn', eval('@a'))
    108    end)
    109    it('insert-mode CTRL-G', function()
    110      command('set langmap=jk,kj')
    111      command('d')
    112      insert([[
    113      hello
    114      hello
    115      hello]])
    116      expect([[
    117      hello
    118      hello
    119      hello]])
    120      feed('qa')
    121      feed('gg3|ahello<C-G>jx<esc>')
    122      feed('q')
    123      expect([[
    124      helhellolo
    125      helxlo
    126      hello]])
    127      eq('gg3|ahellojx', eval('@a'))
    128    end)
    129    it('command-line CTRL-\\', function()
    130      command('set langmap=en,ne')
    131      feed(':<C-\\>e\'hello\'\r<C-B>put ="<C-E>"<CR>')
    132      expect([[
    133      iii www
    134      hello]])
    135    end)
    136    it('command-line CTRL-R', function()
    137      n.source([[
    138        let i_value = 0
    139        let j_value = 0
    140        call setreg('i', 'i_value')
    141        call setreg('j', 'j_value')
    142        set langmap=ij,ji
    143      ]])
    144      feed(':let <C-R>i=1<CR>')
    145      eq(1, eval('i_value'))
    146      eq(0, eval('j_value'))
    147    end)
    148    -- it('-- More -- prompt', function()
    149    --   -- The 'b' 'j' 'd' 'f' commands at the -- More -- prompt
    150    -- end)
    151    it('ask yes/no after backwards range', function()
    152      command('set langmap=yn,ny')
    153      feed('dd')
    154      insert([[
    155      hello
    156      there
    157      these
    158      are
    159      some
    160      lines
    161      ]])
    162      feed_command('4,2d')
    163      feed('n')
    164      expect([[
    165      hello
    166      there
    167      these
    168      are
    169      some
    170      lines
    171      ]])
    172    end)
    173    it('prompt for number', function()
    174      command('set langmap=12,21')
    175      n.source([[
    176        let gotten_one = 0
    177        function Map()
    178          let answer = inputlist(['a', '1.', '2.', '3.'])
    179          if answer == 1
    180            let g:gotten_one = 1
    181          endif
    182        endfunction
    183        nnoremap x :call Map()<CR>
    184      ]])
    185      feed('x1<CR>')
    186      eq(1, eval('gotten_one'))
    187      command('let g:gotten_one = 0')
    188      feed_command('call Map()')
    189      feed('1<CR>')
    190      eq(1, eval('gotten_one'))
    191    end)
    192  end)
    193  it('conversions are not applied during setreg()', function()
    194    call('setreg', 'i', 'ww')
    195    eq('ww', eval('@i'))
    196  end)
    197  it('conversions not applied in insert mode', function()
    198    feed('aiiiwww')
    199    expect('iiiiwwwii www')
    200  end)
    201  it('conversions not applied in search mode', function()
    202    feed('/iii<cr>x')
    203    expect('ii www')
    204  end)
    205  it('conversions not applied in cmdline mode', function()
    206    feed(':call append(1, "iii")<cr>')
    207    expect([[
    208    iii www
    209    iii]])
    210  end)
    211 
    212  local function testrecording(command_string, expect_string, setup_function, expect_macro)
    213    if setup_function then
    214      setup_function()
    215    end
    216    feed('qa' .. command_string .. 'q')
    217    expect(expect_string)
    218    eq(expect_macro or n.fn.nvim_replace_termcodes(command_string, true, true, true), eval('@a'))
    219    if setup_function then
    220      setup_function()
    221    end
    222    -- n.b. may need nvim_replace_termcodes() here.
    223    feed('@a')
    224    expect(expect_string)
    225  end
    226 
    227  local function local_setup()
    228    -- Can't use `insert` as it uses `i` and we've swapped the meaning of that
    229    -- with the `langmap` setting.
    230    command('%d')
    231    command("put ='hello'")
    232    command('1d')
    233  end
    234 
    235  it('does not affect recording special keys', function()
    236    testrecording('A<BS><esc>', 'hell', local_setup)
    237    testrecording('>><lt><lt>', 'hello', local_setup)
    238    command('nnoremap \\ x')
    239    testrecording('\\', 'ello', local_setup)
    240    testrecording('A<C-V><BS><esc>', 'hello<BS>', local_setup)
    241  end)
    242  pending('Translates modified keys correctly', function()
    243    command('nnoremap <M-i> x')
    244    command('nnoremap <M-w> l')
    245    testrecording('<M-w>', 'ello', local_setup)
    246    testrecording('<M-i>x', 'hllo', local_setup)
    247  end)
    248  pending('handles multi-byte characters', function()
    249    command('set langmap=ïx')
    250    testrecording('ï', 'ello', local_setup)
    251    -- The test below checks that what's recorded is correct.
    252    -- It doesn't check the behaviour, as in order to cause some behaviour we
    253    -- need to map the multi-byte character, and there is a known bug
    254    -- preventing this from working (see the test below).
    255    command('set langmap=xï')
    256    testrecording('x', 'hello', local_setup)
    257  end)
    258  pending('handles multibyte mappings', function()
    259    -- See this vim issue for the problem, may as well add a test.
    260    -- https://github.com/vim/vim/issues/297
    261    command('set langmap=ïx')
    262    command('nnoremap x diw')
    263    testrecording('ï', '', local_setup)
    264    command('set nolangnoremap')
    265    command('set langmap=xï')
    266    command('nnoremap ï ix<esc>')
    267    testrecording('x', 'xhello', local_setup)
    268  end)
    269  it('does not crash when mapping char < 256 to char >= 256', function()
    270    -- Note: this warning should be removed when the pending tests above are fixed.
    271    local wmsg = table.concat({
    272      "'langmap': Mapping from e to ε will not work properly",
    273      "'langmap': Mapping from ü to μ will not work properly",
    274    }, '\n')
    275    -- ä ë ï ö ü ÿ < 256, β γ ε μ >= 256
    276    command('set langmap=iw,wi,äë,ëä,ïx,xï,βγ,γβ,eε,εe,üμ,μü,ÿy,yÿ')
    277    eq(wmsg, n.exec_capture('messages'))
    278    command('messages clear | set langmap=iwäëïxβγeεüμÿy;wiëäxïγβεeμüyÿ')
    279    eq(wmsg, n.exec_capture('messages'))
    280  end)
    281  -- This test is to ensure the behaviour doesn't change from what's already
    282  -- around. I (hardenedapple) personally think this behaviour should be
    283  -- changed.
    284  it('treats control modified keys as characters', function()
    285    command('nnoremap <C-w> iw<esc>')
    286    command('nnoremap <C-i> ii<esc>')
    287    testrecording('<C-w>', 'whello', local_setup, eval([["\<*C-w>"]]))
    288    testrecording('<C-i>', 'ihello', local_setup, eval([["\<*C-i>"]]))
    289  end)
    290 end)