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)