neovim

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

history_spec.lua (9288B)


      1 -- ShaDa history saving/reading support
      2 local t = require('test.testutil')
      3 local n = require('test.functional.testnvim')()
      4 local t_shada = require('test.functional.shada.testutil')
      5 
      6 local nvim_command, fn, api, nvim_feed, eq = n.command, n.fn, n.api, n.feed, t.eq
      7 local assert_alive = n.assert_alive
      8 local expect_exit = n.expect_exit
      9 local pcall_err = t.pcall_err
     10 
     11 local reset, clear = t_shada.reset, t_shada.clear
     12 
     13 describe('ShaDa support code', function()
     14  before_each(reset)
     15  after_each(clear)
     16 
     17  it('is able to dump and read back command-line history', function()
     18    nvim_command("set shada='0")
     19    nvim_feed(':" Test\n')
     20    nvim_command('wshada')
     21    reset()
     22    nvim_command("set shada='0")
     23    nvim_command('rshada')
     24    eq('" Test', fn.histget(':', -1))
     25  end)
     26 
     27  it('is able to dump and read back 2 items in command-line history', function()
     28    nvim_command("set shada='0 history=2")
     29    nvim_feed(':" Test\n')
     30    nvim_feed(':" Test 2\n')
     31    expect_exit(nvim_command, 'qall')
     32    reset()
     33    nvim_command("set shada='0 history=2")
     34    nvim_command('rshada')
     35    eq('" Test 2', fn.histget(':', -1))
     36    eq('" Test', fn.histget(':', -2))
     37  end)
     38 
     39  it('respects &history when dumping', function()
     40    nvim_command("set shada='0 history=1")
     41    nvim_feed(':" Test\n')
     42    nvim_feed(':" Test 2\n')
     43    nvim_command('wshada')
     44    reset()
     45    nvim_command("set shada='0 history=2")
     46    nvim_command('rshada')
     47    eq('" Test 2', fn.histget(':', -1))
     48    eq('', fn.histget(':', -2))
     49  end)
     50 
     51  it('respects &history when loading', function()
     52    nvim_command("set shada='0 history=2")
     53    nvim_feed(':" Test\n')
     54    nvim_feed(':" Test 2\n')
     55    nvim_command('wshada')
     56    reset()
     57    nvim_command("set shada='0 history=1")
     58    nvim_command('rshada')
     59    eq('" Test 2', fn.histget(':', -1))
     60    eq('', fn.histget(':', -2))
     61  end)
     62 
     63  it('dumps only requested amount of command-line history items', function()
     64    nvim_command("set shada='0,:1")
     65    nvim_feed(':" Test\n')
     66    nvim_feed(':" Test 2\n')
     67    nvim_command('wshada')
     68    -- Regression test: :wshada should not alter or free history.
     69    eq('" Test 2', fn.histget(':', -1))
     70    eq('" Test', fn.histget(':', -2))
     71    reset()
     72    nvim_command("set shada='0")
     73    nvim_command('rshada')
     74    eq('" Test 2', fn.histget(':', -1))
     75    eq('', fn.histget(':', -2))
     76  end)
     77 
     78  it('does not respect number in &shada when loading history', function()
     79    nvim_command("set shada='0")
     80    nvim_feed(':" Test\n')
     81    nvim_feed(':" Test 2\n')
     82    nvim_command('wshada')
     83    reset()
     84    nvim_command("set shada='0,:1")
     85    nvim_command('rshada')
     86    eq('" Test 2', fn.histget(':', -1))
     87    eq('" Test', fn.histget(':', -2))
     88  end)
     89 
     90  it('dumps and loads all kinds of histories', function()
     91    nvim_command('debuggreedy')
     92    nvim_feed(':debug echo "Test"\n" Test 2\nc\n') -- Debug history.
     93    nvim_feed(':call input("")\nTest 2\n') -- Input history.
     94    nvim_feed('"="Test"\nyy') -- Expression history.
     95    nvim_feed('/Test\n') -- Search history
     96    nvim_feed(':" Test\n') -- Command-line history
     97    nvim_command('0debuggreedy')
     98    nvim_command('wshada')
     99    reset()
    100    nvim_command('rshada')
    101    eq('" Test', fn.histget(':', -1))
    102    eq('Test', fn.histget('/', -1))
    103    eq('"Test"', fn.histget('=', -1))
    104    eq('Test 2', fn.histget('@', -1))
    105    eq('c', fn.histget('>', -1))
    106  end)
    107 
    108  it('does not dump last search pattern if /0 in shada', function()
    109    nvim_command('set shada+=/0')
    110    nvim_command('silent! /test/')
    111    expect_exit(nvim_command, 'qall!')
    112    reset()
    113    nvim_command('language C')
    114    local err = pcall_err(n.exec_capture, 'normal! n')
    115    eq('nvim_exec2(), line 1: Vim(normal):E35: No previous regular expression', err)
    116  end)
    117 
    118  it('dumps and loads last search pattern with offset', function()
    119    api.nvim_set_option_value('wrapscan', false, {})
    120    fn.setline('.', { 'foo', 'bar--' })
    121    nvim_feed('gg0/a/e+1\n')
    122    eq({ 0, 2, 3, 0 }, fn.getpos('.'))
    123    nvim_command('wshada')
    124    reset()
    125    api.nvim_set_option_value('wrapscan', false, {})
    126    fn.setline('.', { 'foo', 'bar--' })
    127    nvim_feed('gg0n')
    128    eq({ 0, 2, 3, 0 }, fn.getpos('.'))
    129    eq(1, api.nvim_get_vvar('searchforward'))
    130    -- Autocommands shouldn't cause search pattern to change
    131    nvim_command('autocmd User * :')
    132    nvim_command('doautocmd User')
    133    nvim_feed('gg0n')
    134    eq({ 0, 2, 3, 0 }, fn.getpos('.'))
    135    eq(1, api.nvim_get_vvar('searchforward'))
    136  end)
    137 
    138  it('dumps and loads last search pattern with offset and backward direction', function()
    139    api.nvim_set_option_value('wrapscan', false, {})
    140    fn.setline('.', { 'foo', 'bar--' })
    141    nvim_feed('G$?a?e+1\n')
    142    eq({ 0, 2, 3, 0 }, fn.getpos('.'))
    143    nvim_command('wshada')
    144    reset()
    145    api.nvim_set_option_value('wrapscan', false, {})
    146    fn.setline('.', { 'foo', 'bar--' })
    147    nvim_feed('G$n')
    148    eq({ 0, 2, 3, 0 }, fn.getpos('.'))
    149    eq(0, api.nvim_get_vvar('searchforward'))
    150    -- Autocommands shouldn't cause search pattern to change
    151    nvim_command('autocmd User * :')
    152    nvim_command('doautocmd User')
    153    nvim_feed('G$n')
    154    eq({ 0, 2, 3, 0 }, fn.getpos('.'))
    155    eq(0, api.nvim_get_vvar('searchforward'))
    156  end)
    157 
    158  it('saves v:hlsearch=1', function()
    159    nvim_command('set hlsearch shada-=h')
    160    nvim_feed('/test\n')
    161    eq(1, api.nvim_get_vvar('hlsearch'))
    162    expect_exit(nvim_command, 'qall')
    163    reset()
    164    eq(1, api.nvim_get_vvar('hlsearch'))
    165  end)
    166 
    167  it('saves v:hlsearch=0 with :nohl', function()
    168    nvim_command('set hlsearch shada-=h')
    169    nvim_feed('/test\n')
    170    nvim_command('nohlsearch')
    171    expect_exit(nvim_command, 'qall')
    172    reset()
    173    eq(0, api.nvim_get_vvar('hlsearch'))
    174  end)
    175 
    176  it('saves v:hlsearch=0 with default &shada', function()
    177    nvim_command('set hlsearch')
    178    nvim_feed('/test\n')
    179    eq(1, api.nvim_get_vvar('hlsearch'))
    180    expect_exit(nvim_command, 'qall')
    181    reset()
    182    eq(0, api.nvim_get_vvar('hlsearch'))
    183  end)
    184 
    185  it('dumps and loads last substitute pattern and replacement string', function()
    186    fn.setline('.', { 'foo', 'bar' })
    187    nvim_command('%s/f/g/g')
    188    eq('goo', fn.getline(1))
    189    nvim_command('wshada')
    190    reset()
    191    fn.setline('.', { 'foo', 'bar' })
    192    nvim_command('&')
    193    eq('goo', fn.getline(1))
    194  end)
    195 
    196  it('does not dump last substitute pattern or replacement string if /0 in shada', function()
    197    nvim_command('set shada+=/0')
    198    fn.setline('.', { 'foo', 'bar' })
    199    nvim_command('%s/f/g/g')
    200    eq('goo', fn.getline(1))
    201    expect_exit(nvim_command, 'qall!')
    202    reset()
    203    fn.setline('.', { 'foo', 'bar' })
    204    nvim_command('language C')
    205    local err = pcall_err(nvim_command, '&')
    206    eq('Vim(&):E33: No previous substitute regular expression', err)
    207    nvim_feed('/f\n')
    208    err = pcall_err(nvim_command, '~&')
    209    eq('Vim(~):E33: No previous substitute regular expression', err)
    210  end)
    211 
    212  it('dumps and loads history with UTF-8 characters', function()
    213    reset()
    214    nvim_feed(':echo "«"\n')
    215    expect_exit(nvim_command, 'qall')
    216    reset()
    217    eq('echo "«"', fn.histget(':', -1))
    218  end)
    219 
    220  it('dumps and loads replacement with UTF-8 characters', function()
    221    nvim_command('substitute/./«/ge')
    222    expect_exit(nvim_command, 'qall!')
    223    reset()
    224    fn.setline('.', { '.' })
    225    nvim_command('&')
    226    eq('«', fn.getline('.'))
    227  end)
    228 
    229  it('dumps and loads substitute pattern with UTF-8 characters', function()
    230    nvim_command('substitute/«/./ge')
    231    expect_exit(nvim_command, 'qall!')
    232    reset()
    233    fn.setline('.', { \171' })
    234    nvim_command('&')
    235    eq('.\171', fn.getline('.'))
    236  end)
    237 
    238  it('dumps and loads search pattern with UTF-8 characters', function()
    239    nvim_command('silent! /«/')
    240    expect_exit(nvim_command, 'qall!')
    241    reset()
    242    fn.setline('.', { 'foo', '\171«' })
    243    nvim_feed('gg0n')
    244    eq({ 0, 2, 2, 0 }, fn.getpos('.'))
    245    eq('\171«', fn.getline('.'))
    246    eq('', fn.histget('/', -1))
    247  end)
    248 
    249  it('dumps and loads search pattern with 8-bit single-byte', function()
    250    -- \171 is U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK in latin1
    251    nvim_command('silent! /\171/')
    252    expect_exit(nvim_command, 'qall!')
    253    reset()
    254    fn.setline('.', { 'foo', '\171«' })
    255    nvim_feed('gg0n')
    256    eq({ 0, 2, 1, 0 }, fn.getpos('.'))
    257    eq('\171«', fn.getline('.'))
    258    eq('', fn.histget('/', -1))
    259  end)
    260 
    261  it('does not crash when dumping last search pattern (#10945)', function()
    262    nvim_command('edit Xtest-functional-shada-history_spec')
    263    -- Save jump list
    264    nvim_command('wshada')
    265    -- Wipe out buffer list (jump list entry gets removed)
    266    nvim_command('%bwipeout')
    267    -- Restore jump list
    268    nvim_command('rshada')
    269    nvim_command('silent! /pat/')
    270    nvim_command('au BufNew * echo')
    271    nvim_command('wshada')
    272  end)
    273 
    274  it('does not crash when number of history save to zero (#11497)', function()
    275    nvim_command("set shada='10")
    276    nvim_feed(':" Test\n')
    277    nvim_command('wshada')
    278    nvim_command("set shada='10,:0")
    279    nvim_command('wshada')
    280    assert_alive()
    281  end)
    282 
    283  it('does not dump empty replacement string', function()
    284    expect_exit(nvim_command, 'qall!')
    285    reset()
    286    fn.setline('.', { 'foo', 'bar' })
    287    nvim_command('language C')
    288    nvim_feed('/f\n')
    289    local err = pcall_err(nvim_command, '~&')
    290    eq('Vim(~):E33: No previous substitute regular expression', err)
    291  end)
    292 end)