neovim

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

textyankpost_spec.lua (5941B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 
      4 local clear, eval, eq = n.clear, n.eval, t.eq
      5 local feed, command, expect = n.feed, n.command, n.expect
      6 local api, fn, neq = n.api, n.fn, t.neq
      7 
      8 describe('TextYankPost', function()
      9  before_each(function()
     10    clear()
     11 
     12    -- emulate the clipboard so system clipboard isn't affected
     13    command('set rtp^=test/functional/fixtures')
     14 
     15    command('let g:count = 0')
     16    command('autocmd TextYankPost * let g:event = copy(v:event)')
     17    command('autocmd TextYankPost * let g:count += 1')
     18 
     19    api.nvim_buf_set_lines(0, 0, -1, true, {
     20      'foo\0bar',
     21      'baz text',
     22    })
     23  end)
     24 
     25  it('is executed after yank and handles register types', function()
     26    feed('yy')
     27    eq({
     28      inclusive = false,
     29      operator = 'y',
     30      regcontents = { 'foo\nbar' },
     31      regname = '',
     32      regtype = 'V',
     33      visual = false,
     34    }, eval('g:event'))
     35    eq(1, eval('g:count'))
     36 
     37    -- v:event is cleared after the autocommand is done
     38    eq({}, eval('v:event'))
     39 
     40    feed('+yw')
     41    eq({
     42      inclusive = false,
     43      operator = 'y',
     44      regcontents = { 'baz ' },
     45      regname = '',
     46      regtype = 'v',
     47      visual = false,
     48    }, eval('g:event'))
     49    eq(2, eval('g:count'))
     50 
     51    feed('<c-v>eky')
     52    eq({
     53      inclusive = true,
     54      operator = 'y',
     55      regcontents = { 'foo', 'baz' },
     56      regname = '',
     57      regtype = '\0223', -- ^V + block width
     58      visual = true,
     59    }, eval('g:event'))
     60    eq(3, eval('g:count'))
     61  end)
     62 
     63  it('makes v:event immutable', function()
     64    feed('yy')
     65    eq({
     66      inclusive = false,
     67      operator = 'y',
     68      regcontents = { 'foo\nbar' },
     69      regname = '',
     70      regtype = 'V',
     71      visual = false,
     72    }, eval('g:event'))
     73 
     74    command('set debug=msg')
     75    -- the regcontents should not be changed without copy.
     76    local status, err = pcall(command, 'call extend(g:event.regcontents, ["more text"])')
     77    eq(false, status)
     78    neq(nil, string.find(err, ':E742:'))
     79 
     80    -- can't mutate keys inside the autocommand
     81    command('autocmd! TextYankPost * let v:event.regcontents = 0')
     82    status, err = pcall(command, 'normal yy')
     83    eq(false, status)
     84    neq(nil, string.find(err, ':E46:'))
     85 
     86    -- can't add keys inside the autocommand
     87    command('autocmd! TextYankPost * let v:event.mykey = 0')
     88    status, err = pcall(command, 'normal yy')
     89    eq(false, status)
     90    neq(nil, string.find(err, ':E742:'))
     91  end)
     92 
     93  it('is not invoked recursively', function()
     94    command('autocmd TextYankPost * normal "+yy')
     95    feed('yy')
     96    eq({
     97      inclusive = false,
     98      operator = 'y',
     99      regcontents = { 'foo\nbar' },
    100      regname = '',
    101      regtype = 'V',
    102      visual = false,
    103    }, eval('g:event'))
    104    eq(1, eval('g:count'))
    105    eq({ 'foo\nbar' }, fn.getreg('+', 1, 1))
    106  end)
    107 
    108  it('is executed after delete and change', function()
    109    feed('dw')
    110    eq({
    111      inclusive = false,
    112      operator = 'd',
    113      regcontents = { 'foo' },
    114      regname = '',
    115      regtype = 'v',
    116      visual = false,
    117    }, eval('g:event'))
    118    eq(1, eval('g:count'))
    119 
    120    feed('dd')
    121    eq({
    122      inclusive = false,
    123      operator = 'd',
    124      regcontents = { '\nbar' },
    125      regname = '',
    126      regtype = 'V',
    127      visual = false,
    128    }, eval('g:event'))
    129    eq(2, eval('g:count'))
    130 
    131    feed('cwspam<esc>')
    132    eq({
    133      inclusive = true,
    134      operator = 'c',
    135      regcontents = { 'baz' },
    136      regname = '',
    137      regtype = 'v',
    138      visual = false,
    139    }, eval('g:event'))
    140    eq(3, eval('g:count'))
    141  end)
    142 
    143  it('is not executed after black-hole operation', function()
    144    feed('"_dd')
    145    eq(0, eval('g:count'))
    146 
    147    feed('"_cwgood<esc>')
    148    eq(0, eval('g:count'))
    149 
    150    expect([[
    151      good text]])
    152    feed('"_yy')
    153    eq(0, eval('g:count'))
    154 
    155    command('delete _')
    156    eq(0, eval('g:count'))
    157  end)
    158 
    159  it('gives the correct register name', function()
    160    feed('$"byiw')
    161    eq({
    162      inclusive = true,
    163      operator = 'y',
    164      regcontents = { 'bar' },
    165      regname = 'b',
    166      regtype = 'v',
    167      visual = false,
    168    }, eval('g:event'))
    169 
    170    feed('"*yy')
    171    eq({
    172      inclusive = true,
    173      operator = 'y',
    174      regcontents = { 'foo\nbar' },
    175      regname = '*',
    176      regtype = 'V',
    177      visual = false,
    178    }, eval('g:event'))
    179 
    180    command('set clipboard=unnamed')
    181 
    182    -- regname still shows the name the user requested
    183    feed('yy')
    184    eq({
    185      inclusive = true,
    186      operator = 'y',
    187      regcontents = { 'foo\nbar' },
    188      regname = '',
    189      regtype = 'V',
    190      visual = false,
    191    }, eval('g:event'))
    192 
    193    feed('"*yy')
    194    eq({
    195      inclusive = true,
    196      operator = 'y',
    197      regcontents = { 'foo\nbar' },
    198      regname = '*',
    199      regtype = 'V',
    200      visual = false,
    201    }, eval('g:event'))
    202  end)
    203 
    204  it('works with Ex commands', function()
    205    command('1delete +')
    206    eq({
    207      inclusive = false,
    208      operator = 'd',
    209      regcontents = { 'foo\nbar' },
    210      regname = '+',
    211      regtype = 'V',
    212      visual = false,
    213    }, eval('g:event'))
    214    eq(1, eval('g:count'))
    215 
    216    command('yank')
    217    eq({
    218      inclusive = false,
    219      operator = 'y',
    220      regcontents = { 'baz text' },
    221      regname = '',
    222      regtype = 'V',
    223      visual = false,
    224    }, eval('g:event'))
    225    eq(2, eval('g:count'))
    226 
    227    command('normal yw')
    228    eq({
    229      inclusive = false,
    230      operator = 'y',
    231      regcontents = { 'baz ' },
    232      regname = '',
    233      regtype = 'v',
    234      visual = false,
    235    }, eval('g:event'))
    236    eq(3, eval('g:count'))
    237 
    238    command('normal! dd')
    239    eq({
    240      inclusive = false,
    241      operator = 'd',
    242      regcontents = { 'baz text' },
    243      regname = '',
    244      regtype = 'V',
    245      visual = false,
    246    }, eval('g:event'))
    247    eq(4, eval('g:count'))
    248  end)
    249 
    250  it('updates numbered registers correctly #10225', function()
    251    command('autocmd TextYankPost * let g:reg = getreg("1")')
    252    feed('"adj')
    253    eq('foo\nbar\nbaz text\n', eval('g:reg'))
    254  end)
    255 end)