blob: cd987ab3d0035ca127db33ff1db6ed1ac73c3ba0 [file] [log] [blame]
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001" Test for various Normal mode commands
2
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003source shared.vim
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01004source check.vim
Bram Moolenaarca68ae12020-03-30 19:32:53 +02005source view_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00006import './vim9.vim' as v9
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01007
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01008func Setup_NewWindow()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02009 10new
10 call setline(1, range(1,100))
11endfunc
12
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010013func MyFormatExpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020014 " Adds '->$' at lines having numbers followed by trailing whitespace
15 for ln in range(v:lnum, v:lnum+v:count-1)
16 let line = getline(ln)
17 if getline(ln) =~# '\d\s\+$'
18 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
19 endif
20 endfor
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020021endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020022
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010023func CountSpaces(type, ...)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020024 " for testing operatorfunc
25 " will count the number of spaces
26 " and return the result in g:a
27 let sel_save = &selection
28 let &selection = "inclusive"
29 let reg_save = @@
30
31 if a:0 " Invoked from Visual mode, use gv command.
32 silent exe "normal! gvy"
33 elseif a:type == 'line'
34 silent exe "normal! '[V']y"
35 else
36 silent exe "normal! `[v`]y"
37 endif
Bram Moolenaar777e7c22021-10-25 17:07:04 +010038 let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020039 let &selection = sel_save
40 let @@ = reg_save
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020041endfunc
42
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010043func OpfuncDummy(type, ...)
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010044 " for testing operatorfunc
Bram Moolenaar777e7c22021-10-25 17:07:04 +010045 let g:opt = &linebreak
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010046
47 if a:0 " Invoked from Visual mode, use gv command.
48 silent exe "normal! gvy"
49 elseif a:type == 'line'
50 silent exe "normal! '[V']y"
51 else
52 silent exe "normal! `[v`]y"
53 endif
54 " Create a new dummy window
55 new
Bram Moolenaar777e7c22021-10-25 17:07:04 +010056 let g:bufnr = bufnr('%')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020057endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020058
Bram Moolenaar1671f442020-03-10 07:48:13 +010059func Test_normal00_optrans()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020060 new
61 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
62 1
63 exe "norm! Sfoobar\<esc>"
64 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
65 2
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020066 exe "norm! $vbsone"
67 call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020068 norm! VS Second line here
69 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
70 %d
71 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
72 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
73
74 1
75 norm! 2D
76 call assert_equal(['3 this is the third line', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
77 set cpo+=#
78 norm! 4D
79 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
80
81 " clean up
82 set cpo-=#
83 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020084endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020085
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010086func Test_normal01_keymodel()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020087 call Setup_NewWindow()
88 " Test 1: depending on 'keymodel' <s-down> does something different
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020089 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020090 call feedkeys("V\<S-Up>y", 'tx')
91 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020092 set keymodel=startsel
93 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020094 call feedkeys("V\<S-Up>y", 'tx')
95 call assert_equal(['49', '50'], getline("'<", "'>"))
96 " Start visual mode when keymodel = startsel
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020097 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020098 call feedkeys("\<S-Up>y", 'tx')
99 call assert_equal(['49', '5'], getreg(0, 0, 1))
Bram Moolenaar1671f442020-03-10 07:48:13 +0100100 " Use the different Shift special keys
101 50
102 call feedkeys("\<S-Right>\<S-Left>\<S-Up>\<S-Down>\<S-Home>\<S-End>y", 'tx')
103 call assert_equal(['50'], getline("'<", "'>"))
104 call assert_equal(['50', ''], getreg(0, 0, 1))
105
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200106 " Do not start visual mode when keymodel=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200107 set keymodel=
108 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200109 call feedkeys("\<S-Up>y$", 'tx')
110 call assert_equal(['42'], getreg(0, 0, 1))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200111 " Stop visual mode when keymodel=stopsel
112 set keymodel=stopsel
113 50
114 call feedkeys("Vkk\<Up>yy", 'tx')
115 call assert_equal(['47'], getreg(0, 0, 1))
116
117 set keymodel=
118 50
119 call feedkeys("Vkk\<Up>yy", 'tx')
120 call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200121
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200122 " Test for using special keys to start visual selection
123 %d
124 call setline(1, ['red fox tail', 'red fox tail', 'red fox tail'])
125 set keymodel=startsel
126 " Test for <S-PageUp> and <S-PageDown>
127 call cursor(1, 1)
128 call feedkeys("\<S-PageDown>y", 'xt')
129 call assert_equal([0, 1, 1, 0], getpos("'<"))
130 call assert_equal([0, 3, 1, 0], getpos("'>"))
131 call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
132 call assert_equal([0, 2, 1, 0], getpos("'<"))
133 call assert_equal([0, 3, 8, 0], getpos("'>"))
134 " Test for <S-C-Home> and <S-C-End>
135 call cursor(2, 12)
136 call feedkeys("\<S-C-Home>y", 'xt')
137 call assert_equal([0, 1, 1, 0], getpos("'<"))
138 call assert_equal([0, 2, 12, 0], getpos("'>"))
139 call cursor(1, 4)
140 call feedkeys("\<S-C-End>y", 'xt')
141 call assert_equal([0, 1, 4, 0], getpos("'<"))
142 call assert_equal([0, 3, 13, 0], getpos("'>"))
143 " Test for <S-C-Left> and <S-C-Right>
144 call cursor(2, 5)
145 call feedkeys("\<S-C-Right>y", 'xt')
146 call assert_equal([0, 2, 5, 0], getpos("'<"))
147 call assert_equal([0, 2, 9, 0], getpos("'>"))
148 call cursor(2, 9)
149 call feedkeys("\<S-C-Left>y", 'xt')
150 call assert_equal([0, 2, 5, 0], getpos("'<"))
151 call assert_equal([0, 2, 9, 0], getpos("'>"))
152
153 set keymodel&
154
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200155 " clean up
156 bw!
157endfunc
158
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100159func Test_normal03_join()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200160 " basic join test
161 call Setup_NewWindow()
162 50
163 norm! VJ
164 call assert_equal('50 51', getline('.'))
165 $
166 norm! J
167 call assert_equal('100', getline('.'))
168 $
169 norm! V9-gJ
170 call assert_equal('919293949596979899100', getline('.'))
171 call setline(1, range(1,100))
172 $
173 :j 10
174 call assert_equal('100', getline('.'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200175 call assert_beeps('normal GVJ')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200176 " clean up
177 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200178endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200179
Bram Moolenaar004a6782020-04-11 17:09:31 +0200180" basic filter test
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100181func Test_normal04_filter()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200182 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200183 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200184 call Setup_NewWindow()
185 1
186 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
187 call assert_equal('| 1', getline('.'))
188 90
189 :sil :!echo one
190 call feedkeys('.', 'tx')
191 call assert_equal('| 90', getline('.'))
192 95
193 set cpo+=!
194 " 2 <CR>, 1: for executing the command,
195 " 2: clear hit-enter-prompt
196 call feedkeys("!!\n", 'tx')
197 call feedkeys(":!echo one\n\n", 'tx')
198 call feedkeys(".", 'tx')
199 call assert_equal('one', getline('.'))
200 set cpo-=!
201 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200202endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200203
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100204func Test_normal05_formatexpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200205 " basic formatexpr test
206 call Setup_NewWindow()
207 %d_
208 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
209 1
210 set formatexpr=MyFormatExpr()
211 norm! gqG
212 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
213 set formatexpr=
214 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200215endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200216
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200217func Test_normal05_formatexpr_newbuf()
218 " Edit another buffer in the 'formatexpr' function
219 new
220 func! Format()
221 edit another
222 endfunc
223 set formatexpr=Format()
224 norm gqG
225 bw!
226 set formatexpr=
227endfunc
228
229func Test_normal05_formatexpr_setopt()
230 " Change the 'formatexpr' value in the function
231 new
232 func! Format()
233 set formatexpr=
234 endfunc
235 set formatexpr=Format()
236 norm gqG
237 bw!
238 set formatexpr=
239endfunc
240
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200241" When 'formatexpr' returns non-zero, internal formatting is used.
242func Test_normal_formatexpr_returns_nonzero()
243 new
244 call setline(1, ['one', 'two'])
245 func! Format()
246 return 1
247 endfunc
248 setlocal formatexpr=Format()
249 normal VGgq
250 call assert_equal(['one two'], getline(1, '$'))
251 setlocal formatexpr=
252 delfunc Format
253 close!
254endfunc
255
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000256" Test for using a script-local function for 'formatexpr'
257func Test_formatexpr_scriptlocal_func()
258 func! s:Format()
259 let g:FormatArgs = [v:lnum, v:count]
260 endfunc
261 set formatexpr=s:Format()
262 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
263 new | only
264 call setline(1, range(1, 40))
265 let g:FormatArgs = []
266 normal! 2GVjgq
267 call assert_equal([2, 2], g:FormatArgs)
268 bw!
269 set formatexpr=<SID>Format()
270 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
271 new | only
272 call setline(1, range(1, 40))
273 let g:FormatArgs = []
274 normal! 4GVjgq
275 call assert_equal([4, 2], g:FormatArgs)
276 bw!
277 let &formatexpr = 's:Format()'
278 new | only
279 call setline(1, range(1, 40))
280 let g:FormatArgs = []
281 normal! 6GVjgq
282 call assert_equal([6, 2], g:FormatArgs)
283 bw!
284 let &formatexpr = '<SID>Format()'
285 new | only
286 call setline(1, range(1, 40))
287 let g:FormatArgs = []
288 normal! 8GVjgq
289 call assert_equal([8, 2], g:FormatArgs)
290 setlocal formatexpr=
291 delfunc s:Format
292 bw!
293endfunc
294
Bram Moolenaar004a6782020-04-11 17:09:31 +0200295" basic test for formatprg
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100296func Test_normal06_formatprg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200297 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200298 CheckNotMSWindows
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100299
300 " uses sed to number non-empty lines
301 call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh')
302 call system('chmod +x ./Xsed_format.sh')
303 let text = ['a', '', 'c', '', ' ', 'd', 'e']
304 let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
305
306 10new
307 call setline(1, text)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200308 set formatprg=./Xsed_format.sh
309 norm! gggqG
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100310 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200311 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100312
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100313 call setline(1, text)
314 set formatprg=donothing
315 setlocal formatprg=./Xsed_format.sh
316 norm! gggqG
317 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200318 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100319
Bram Moolenaar004a6782020-04-11 17:09:31 +0200320 " Check for the command-line ranges added to 'formatprg'
321 set formatprg=cat
322 call setline(1, ['one', 'two', 'three', 'four', 'five'])
323 call feedkeys('gggqG', 'xt')
324 call assert_equal('.,$!cat', @:)
325 call feedkeys('2Ggq2j', 'xt')
326 call assert_equal('.,.+2!cat', @:)
327
328 bw!
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200329 " clean up
330 set formatprg=
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100331 setlocal formatprg=
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200332 call delete('Xsed_format.sh')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200333endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200334
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100335func Test_normal07_internalfmt()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200336 " basic test for internal formmatter to textwidth of 12
337 let list=range(1,11)
338 call map(list, 'v:val." "')
339 10new
340 call setline(1, list)
341 set tw=12
Bram Moolenaar004a6782020-04-11 17:09:31 +0200342 norm! ggVGgq
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200343 call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
344 " clean up
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100345 set tw=0
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200346 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200347endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200348
Bram Moolenaar004a6782020-04-11 17:09:31 +0200349" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100350func Test_normal08_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +0200351 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200352 call Setup_NewWindow()
353 50
354 setl foldenable fdm=marker
355 " First fold
356 norm! V4jzf
357 " check that folds have been created
358 call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
359 " Second fold
360 46
361 norm! V10jzf
362 " check that folds have been created
363 call assert_equal('46/*{{{*/', getline(46))
364 call assert_equal('60/*}}}*/', getline(60))
365 norm! k
366 call assert_equal('45', getline('.'))
367 norm! j
368 call assert_equal('46/*{{{*/', getline('.'))
369 norm! j
370 call assert_equal('61', getline('.'))
371 norm! k
372 " open a fold
373 norm! Vzo
374 norm! k
375 call assert_equal('45', getline('.'))
376 norm! j
377 call assert_equal('46/*{{{*/', getline('.'))
378 norm! j
379 call assert_equal('47', getline('.'))
380 norm! k
381 norm! zcVzO
382 call assert_equal('46/*{{{*/', getline('.'))
383 norm! j
384 call assert_equal('47', getline('.'))
385 norm! j
386 call assert_equal('48', getline('.'))
387 norm! j
388 call assert_equal('49', getline('.'))
389 norm! j
390 call assert_equal('50/*{{{*/', getline('.'))
391 norm! j
392 call assert_equal('51', getline('.'))
393 " delete folds
394 :46
395 " collapse fold
396 norm! V14jzC
397 " delete all folds recursively
398 norm! VzD
399 call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
400
401 " clean up
402 setl nofoldenable fdm=marker
403 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200404endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200405
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000406func Test_normal09a_operatorfunc()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200407 " Test operatorfunc
408 call Setup_NewWindow()
409 " Add some spaces for counting
410 50,60s/$/ /
411 unlet! g:a
412 let g:a=0
413 nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
414 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
415 50
416 norm V2j,,
417 call assert_equal(6, g:a)
418 norm V,,
419 call assert_equal(2, g:a)
420 norm ,,l
421 call assert_equal(0, g:a)
422 50
423 exe "norm 0\<c-v>10j2l,,"
424 call assert_equal(11, g:a)
425 50
426 norm V10j,,
427 call assert_equal(22, g:a)
428
429 " clean up
430 unmap <buffer> ,,
431 set opfunc=
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100432 unlet! g:a
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200433 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200434endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200435
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000436func Test_normal09b_operatorfunc()
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100437 " Test operatorfunc
438 call Setup_NewWindow()
439 " Add some spaces for counting
440 50,60s/$/ /
441 unlet! g:opt
442 set linebreak
443 nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
444 50
445 norm ,,j
446 exe "bd!" g:bufnr
447 call assert_true(&linebreak)
448 call assert_equal(g:opt, &linebreak)
449 set nolinebreak
450 norm ,,j
451 exe "bd!" g:bufnr
452 call assert_false(&linebreak)
453 call assert_equal(g:opt, &linebreak)
454
455 " clean up
456 unmap <buffer> ,,
457 set opfunc=
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200458 call assert_fails('normal Vg@', 'E774:')
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100459 bw!
460 unlet! g:opt
461endfunc
462
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000463func OperatorfuncRedo(_)
464 let g:opfunc_count = v:count
465endfunc
466
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000467func Underscorize(_)
468 normal! '[V']r_
469endfunc
470
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000471func Test_normal09c_operatorfunc()
472 " Test redoing operatorfunc
473 new
474 call setline(1, 'some text')
475 set operatorfunc=OperatorfuncRedo
476 normal v3g@
477 call assert_equal(3, g:opfunc_count)
478 let g:opfunc_count = 0
479 normal .
480 call assert_equal(3, g:opfunc_count)
481
482 bw!
483 unlet g:opfunc_count
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000484
485 " Test redoing Visual mode
486 set operatorfunc=Underscorize
487 new
488 call setline(1, ['first', 'first', 'third', 'third', 'second'])
naohiro ono5c75eed2022-01-03 11:15:47 +0000489 normal! 1GVjg@
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000490 normal! 5G.
491 normal! 3G.
492 call assert_equal(['_____', '_____', '_____', '_____', '______'], getline(1, '$'))
493 bwipe!
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000494 set operatorfunc=
495endfunc
496
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000497" Test for different ways of setting the 'operatorfunc' option
498func Test_opfunc_callback()
499 new
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000500 func OpFunc1(callnr, type)
501 let g:OpFunc1Args = [a:callnr, a:type]
502 endfunc
503 func OpFunc2(type)
504 let g:OpFunc2Args = [a:type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000505 endfunc
506
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000507 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000508 #" Test for using a function name
509 LET &opfunc = 'g:OpFunc2'
510 LET g:OpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000511 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000512 call assert_equal(['char'], g:OpFunc2Args)
513
514 #" Test for using a function()
515 set opfunc=function('g:OpFunc1',\ [10])
516 LET g:OpFunc1Args = []
517 normal! g@l
518 call assert_equal([10, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000519
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000520 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000521 VAR Fn = function('g:OpFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000522 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000523 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000524 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000525 call assert_equal([11, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000526
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000527 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000528 LET Fn = function('g:OpFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000529 LET &operatorfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000530 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000531 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000532 call assert_equal([12, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000533
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000534 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000535 set operatorfunc=funcref('g:OpFunc1',\ [13])
536 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000537 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000538 call assert_equal([13, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000539
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000540 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000541 LET Fn = funcref('g:OpFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000542 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000543 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000544 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000545 call assert_equal([14, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000546
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000547 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000548 LET Fn = funcref('g:OpFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000549 LET &opfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000550 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000551 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000552 call assert_equal([15, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000553
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000554 #" Test for using a lambda function using set
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000555 VAR optval = "LSTART a LMIDDLE OpFunc1(16, a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000556 LET optval = substitute(optval, ' ', '\\ ', 'g')
557 exe "set opfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000558 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000559 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000560 call assert_equal([16, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000561
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000562 #" Test for using a lambda function using LET
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000563 LET &opfunc = LSTART a LMIDDLE OpFunc1(17, a) LEND
564 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000565 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000566 call assert_equal([17, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000567
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000568 #" Set 'operatorfunc' to a string(lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000569 LET &opfunc = 'LSTART a LMIDDLE OpFunc1(18, a) LEND'
570 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000571 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000572 call assert_equal([18, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000573
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000574 #" Set 'operatorfunc' to a variable with a lambda expression
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000575 VAR Lambda = LSTART a LMIDDLE OpFunc1(19, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000576 LET &opfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000577 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000578 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000579 call assert_equal([19, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000580
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000581 #" Set 'operatorfunc' to a string(variable with a lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000582 LET Lambda = LSTART a LMIDDLE OpFunc1(20, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000583 LET &opfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000584 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000585 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000586 call assert_equal([20, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000587
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000588 #" Try to use 'operatorfunc' after the function is deleted
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000589 func g:TmpOpFunc1(type)
590 let g:TmpOpFunc1Args = [21, a:type]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000591 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000592 LET &opfunc = function('g:TmpOpFunc1')
593 delfunc g:TmpOpFunc1
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000594 call test_garbagecollect_now()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000595 LET g:TmpOpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000596 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000597 call assert_equal([], g:TmpOpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000598
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000599 #" Try to use a function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000600 func g:TmpOpFunc2(x, y)
601 let g:TmpOpFunc2Args = [a:x, a:y]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000602 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000603 set opfunc=TmpOpFunc2
604 LET g:TmpOpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000605 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000606 call assert_equal([], g:TmpOpFunc2Args)
607 delfunc TmpOpFunc2
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000608
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000609 #" Try to use a lambda function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000610 LET &opfunc = LSTART a, b LMIDDLE OpFunc1(22, b) LEND
611 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000612 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000613 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000614
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000615 #" Test for clearing the 'operatorfunc' option
616 set opfunc=''
617 set opfunc&
618 call assert_fails("set opfunc=function('abc')", "E700:")
619 call assert_fails("set opfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000620
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000621 #" set 'operatorfunc' to a non-existing function
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000622 LET &opfunc = function('g:OpFunc1', [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000623 call assert_fails("set opfunc=function('NonExistingFunc')", 'E700:')
624 call assert_fails("LET &opfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000625 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000626 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000627 call assert_equal([23, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000628 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000629 call v9.CheckTransLegacySuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000630
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000631 " Test for using a script-local function name
632 func s:OpFunc3(type)
633 let g:OpFunc3Args = [a:type]
634 endfunc
635 set opfunc=s:OpFunc3
636 let g:OpFunc3Args = []
637 normal! g@l
638 call assert_equal(['char'], g:OpFunc3Args)
639
640 let &opfunc = 's:OpFunc3'
641 let g:OpFunc3Args = []
642 normal! g@l
643 call assert_equal(['char'], g:OpFunc3Args)
644 delfunc s:OpFunc3
645
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000646 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000647 set opfunc=(a)\ =>\ OpFunc1(24,\ a)
648 let g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000649 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000650 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000651
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000652 " set 'operatorfunc' to a partial with dict. This used to cause a crash.
653 func SetOpFunc()
654 let operator = {'execute': function('OperatorExecute')}
655 let &opfunc = operator.execute
656 endfunc
657 func OperatorExecute(_) dict
658 endfunc
659 call SetOpFunc()
660 call test_garbagecollect_now()
661 set operatorfunc=
662 delfunc SetOpFunc
663 delfunc OperatorExecute
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000664
665 " Vim9 tests
666 let lines =<< trim END
667 vim9script
668
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000669 def g:Vim9opFunc(val: number, type: string): void
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000670 g:OpFunc1Args = [val, type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000671 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000672
673 # Test for using a def function with opfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000674 set opfunc=function('g:Vim9opFunc',\ [60])
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000675 g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000676 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000677 assert_equal([60, 'char'], g:OpFunc1Args)
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000678
679 # Test for using a global function name
680 &opfunc = g:OpFunc2
681 g:OpFunc2Args = []
682 normal! g@l
683 assert_equal(['char'], g:OpFunc2Args)
684 bw!
685
686 # Test for using a script-local function name
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000687 def LocalOpFunc(type: string): void
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000688 g:LocalOpFuncArgs = [type]
689 enddef
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000690 &opfunc = LocalOpFunc
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000691 g:LocalOpFuncArgs = []
692 normal! g@l
693 assert_equal(['char'], g:LocalOpFuncArgs)
694 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000695 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000696 call v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000697
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000698 " setting 'opfunc' to a script local function outside of a script context
699 " should fail
700 let cleanup =<< trim END
701 call writefile([execute('messages')], 'Xtest.out')
702 qall
703 END
704 call writefile(cleanup, 'Xverify.vim')
705 call RunVim([], [], "-c \"set opfunc=s:abc\" -S Xverify.vim")
706 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
707 call delete('Xtest.out')
708 call delete('Xverify.vim')
709
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000710 " cleanup
711 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000712 delfunc OpFunc1
713 delfunc OpFunc2
714 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000715 %bw!
716endfunc
717
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100718func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200719 " Test for expand()
720 10new
721 call setline(1, ['1', 'ifooar,,cbar'])
722 2
723 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200724 call assert_equal('cbar', expand('<cword>'))
725 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
726
727 call setline(1, ['prx = list[idx];'])
728 1
729 let expected = ['', 'prx', 'prx', 'prx',
730 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
731 \ 'idx', 'idx', 'idx', 'idx',
732 \ 'list[idx]',
733 \ '];',
734 \ ]
735 for i in range(1, 16)
736 exe 'norm ' . i . '|'
737 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
738 endfor
739
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200740 " Test for <cexpr> in state.val and ptr->val
741 call setline(1, 'x = state.val;')
742 call cursor(1, 10)
743 call assert_equal('state.val', expand('<cexpr>'))
744 call setline(1, 'x = ptr->val;')
745 call cursor(1, 9)
746 call assert_equal('ptr->val', expand('<cexpr>'))
747
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100748 if executable('echo')
749 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100750 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100751 endif
752
753 " Test expand(`=...`) i.e. backticks expression expansion
754 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100755 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100756
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200757 " clean up
758 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200759endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200760
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200761" Test for expand() in latin1 encoding
762func Test_normal_expand_latin1()
763 new
764 let save_enc = &encoding
765 set encoding=latin1
766 call setline(1, 'val = item->color;')
767 call cursor(1, 11)
768 call assert_equal('color', expand("<cword>"))
769 call assert_equal('item->color', expand("<cexpr>"))
770 let &encoding = save_enc
771 bw!
772endfunc
773
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100774func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200775 " test for 'showcmd'
776 10new
777 exe "norm! ofoobar\<esc>"
778 call assert_equal(2, line('$'))
779 set showcmd
780 exe "norm! ofoobar2\<esc>"
781 call assert_equal(3, line('$'))
782 exe "norm! VAfoobar3\<esc>"
783 call assert_equal(3, line('$'))
784 exe "norm! 0d3\<del>2l"
785 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200786 " test for the visual block size displayed in the status line
787 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
788 call feedkeys("ggl\<C-V>lljj", 'xt')
789 redraw!
790 call assert_match('3x3$', Screenline(&lines))
791 call feedkeys("\<C-V>", 'xt')
792 " test for visually selecting a multi-byte character
793 call setline(1, ["\U2206"])
794 call feedkeys("ggv", 'xt')
795 redraw!
796 call assert_match('1-3$', Screenline(&lines))
797 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200798 " test for visually selecting the end of line
799 call setline(1, ["foobar"])
800 call feedkeys("$vl", 'xt')
801 redraw!
802 call assert_match('2$', Screenline(&lines))
803 call feedkeys("y", 'xt')
804 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200805 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200806endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200807
Bram Moolenaar1671f442020-03-10 07:48:13 +0100808" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100809func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200810 10new
811 call setline(1, range(1,5))
812 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100813 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200814 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100815 call assert_beeps('normal! G2dd')
816 call assert_beeps("normal! g\<C-A>")
817 call assert_beeps("normal! g\<C-X>")
818 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100819 call assert_beeps("normal! vQ\<Esc>")
820 call assert_beeps("normal! 2[[")
821 call assert_beeps("normal! 2]]")
822 call assert_beeps("normal! 2[]")
823 call assert_beeps("normal! 2][")
824 call assert_beeps("normal! 4[z")
825 call assert_beeps("normal! 4]z")
826 call assert_beeps("normal! 4[c")
827 call assert_beeps("normal! 4]c")
828 call assert_beeps("normal! 200%")
829 call assert_beeps("normal! %")
830 call assert_beeps("normal! 2{")
831 call assert_beeps("normal! 2}")
832 call assert_beeps("normal! r\<Right>")
833 call assert_beeps("normal! 8ry")
834 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200835 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200836endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200837
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100838func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200839 " Test for F1
840 call assert_equal(1, winnr())
841 call feedkeys("\<f1>", 'txi')
842 call assert_match('help\.txt', bufname('%'))
843 call assert_equal(2, winnr('$'))
844 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200845endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200846
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100847func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200848 " basic test for Ctrl-F and Ctrl-B
849 call Setup_NewWindow()
850 exe "norm! \<c-f>"
851 call assert_equal('9', getline('.'))
852 exe "norm! 2\<c-f>"
853 call assert_equal('25', getline('.'))
854 exe "norm! 2\<c-b>"
855 call assert_equal('18', getline('.'))
856 1
857 set scrolloff=5
858 exe "norm! 2\<c-f>"
859 call assert_equal('21', getline('.'))
860 exe "norm! \<c-b>"
861 call assert_equal('13', getline('.'))
862 1
863 set scrolloff=99
864 exe "norm! \<c-f>"
865 call assert_equal('13', getline('.'))
866 set scrolloff=0
867 100
868 exe "norm! $\<c-b>"
869 call assert_equal('92', getline('.'))
870 call assert_equal([0, 92, 1, 0, 1], getcurpos())
871 100
872 set nostartofline
873 exe "norm! $\<c-b>"
874 call assert_equal('92', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +0000875 call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200876 " cleanup
877 set startofline
878 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200879endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200880
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100881func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200882 10new
883 norm oxxxxxxx
884 exe "norm 2\<c-f>"
885 " check with valgrind that cursor is put back in column 1
886 exe "norm 2\<c-b>"
887 bw!
888endfunc
889
Bram Moolenaar1671f442020-03-10 07:48:13 +0100890" Test for errors with z command
891func Test_normal_z_error()
892 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200893 call assert_beeps('normal! zq')
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000894 call assert_beeps('normal! cz1')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100895endfunc
896
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100897func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200898 " basic test for z commands that scroll the window
899 call Setup_NewWindow()
900 100
901 norm! >>
902 " Test for z<cr>
903 exe "norm! z\<cr>"
904 call assert_equal(' 100', getline('.'))
905 call assert_equal(100, winsaveview()['topline'])
906 call assert_equal([0, 100, 2, 0, 9], getcurpos())
907
908 " Test for zt
909 21
910 norm! >>0zt
911 call assert_equal(' 21', getline('.'))
912 call assert_equal(21, winsaveview()['topline'])
913 call assert_equal([0, 21, 1, 0, 8], getcurpos())
914
915 " Test for zb
916 30
917 norm! >>$ztzb
918 call assert_equal(' 30', getline('.'))
919 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
naohiro ono56200ee2022-01-01 14:59:44 +0000920 call assert_equal([0, 30, 3, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200921
922 " Test for z-
923 1
924 30
925 norm! 0z-
926 call assert_equal(' 30', getline('.'))
927 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
928 call assert_equal([0, 30, 2, 0, 9], getcurpos())
929
930 " Test for z{height}<cr>
931 call assert_equal(10, winheight(0))
932 exe "norm! z12\<cr>"
933 call assert_equal(12, winheight(0))
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000934 exe "norm! z15\<Del>0\<cr>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200935 call assert_equal(10, winheight(0))
936
937 " Test for z.
938 1
939 21
940 norm! 0z.
941 call assert_equal(' 21', getline('.'))
942 call assert_equal(17, winsaveview()['topline'])
943 call assert_equal([0, 21, 2, 0, 9], getcurpos())
944
945 " Test for zz
946 1
947 21
948 norm! 0zz
949 call assert_equal(' 21', getline('.'))
950 call assert_equal(17, winsaveview()['topline'])
951 call assert_equal([0, 21, 1, 0, 8], getcurpos())
952
953 " Test for z+
954 11
955 norm! zt
956 norm! z+
957 call assert_equal(' 21', getline('.'))
958 call assert_equal(21, winsaveview()['topline'])
959 call assert_equal([0, 21, 2, 0, 9], getcurpos())
960
961 " Test for [count]z+
962 1
963 norm! 21z+
964 call assert_equal(' 21', getline('.'))
965 call assert_equal(21, winsaveview()['topline'])
966 call assert_equal([0, 21, 2, 0, 9], getcurpos())
967
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200968 " Test for z+ with [count] greater than buffer size
969 1
970 norm! 1000z+
971 call assert_equal(' 100', getline('.'))
972 call assert_equal(100, winsaveview()['topline'])
973 call assert_equal([0, 100, 2, 0, 9], getcurpos())
974
975 " Test for z+ from the last buffer line
976 norm! Gz.z+
977 call assert_equal(' 100', getline('.'))
978 call assert_equal(100, winsaveview()['topline'])
979 call assert_equal([0, 100, 2, 0, 9], getcurpos())
980
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200981 " Test for z^
982 norm! 22z+0
983 norm! z^
984 call assert_equal(' 21', getline('.'))
985 call assert_equal(12, winsaveview()['topline'])
986 call assert_equal([0, 21, 2, 0, 9], getcurpos())
987
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200988 " Test for z^ from first buffer line
989 norm! ggz^
990 call assert_equal('1', getline('.'))
991 call assert_equal(1, winsaveview()['topline'])
992 call assert_equal([0, 1, 1, 0, 1], getcurpos())
993
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200994 " Test for [count]z^
995 1
996 norm! 30z^
997 call assert_equal(' 21', getline('.'))
998 call assert_equal(12, winsaveview()['topline'])
999 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1000
1001 " cleanup
1002 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001003endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001004
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001005func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001006 " basic test for z commands that scroll the window
1007 10new
1008 15vsp
1009 set nowrap listchars=
1010 let lineA='abcdefghijklmnopqrstuvwxyz'
1011 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1012 $put =lineA
1013 $put =lineB
1014 1d
1015
Bram Moolenaar1671f442020-03-10 07:48:13 +01001016 " Test for zl and zh with a count
1017 norm! 0z10l
1018 call assert_equal([11, 1], [col('.'), wincol()])
1019 norm! z4h
1020 call assert_equal([11, 5], [col('.'), wincol()])
1021 normal! 2gg
1022
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001023 " Test for zl
1024 1
1025 norm! 5zl
1026 call assert_equal(lineA, getline('.'))
1027 call assert_equal(6, col('.'))
1028 call assert_equal(5, winsaveview()['leftcol'])
1029 norm! yl
1030 call assert_equal('f', @0)
1031
1032 " Test for zh
1033 norm! 2zh
1034 call assert_equal(lineA, getline('.'))
1035 call assert_equal(6, col('.'))
1036 norm! yl
1037 call assert_equal('f', @0)
1038 call assert_equal(3, winsaveview()['leftcol'])
1039
1040 " Test for zL
1041 norm! zL
1042 call assert_equal(11, col('.'))
1043 norm! yl
1044 call assert_equal('k', @0)
1045 call assert_equal(10, winsaveview()['leftcol'])
1046 norm! 2zL
1047 call assert_equal(25, col('.'))
1048 norm! yl
1049 call assert_equal('y', @0)
1050 call assert_equal(24, winsaveview()['leftcol'])
1051
1052 " Test for zH
1053 norm! 2zH
1054 call assert_equal(25, col('.'))
1055 call assert_equal(10, winsaveview()['leftcol'])
1056 norm! yl
1057 call assert_equal('y', @0)
1058
1059 " Test for zs
1060 norm! $zs
1061 call assert_equal(26, col('.'))
1062 call assert_equal(25, winsaveview()['leftcol'])
1063 norm! yl
1064 call assert_equal('z', @0)
1065
1066 " Test for ze
1067 norm! ze
1068 call assert_equal(26, col('.'))
1069 call assert_equal(11, winsaveview()['leftcol'])
1070 norm! yl
1071 call assert_equal('z', @0)
1072
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001073 " Test for zs and ze with folds
1074 %fold
1075 norm! $zs
1076 call assert_equal(26, col('.'))
1077 call assert_equal(0, winsaveview()['leftcol'])
1078 norm! yl
1079 call assert_equal('z', @0)
1080 norm! ze
1081 call assert_equal(26, col('.'))
1082 call assert_equal(0, winsaveview()['leftcol'])
1083 norm! yl
1084 call assert_equal('z', @0)
1085
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001086 " cleanup
1087 set wrap listchars=eol:$
1088 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001089endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001090
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001091func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001092 " basic test for z commands that scroll the window
1093 " using 'sidescrolloff' setting
1094 10new
1095 20vsp
1096 set nowrap listchars= sidescrolloff=5
1097 let lineA='abcdefghijklmnopqrstuvwxyz'
1098 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1099 $put =lineA
1100 $put =lineB
1101 1d
1102
1103 " Test for zl
1104 1
1105 norm! 5zl
1106 call assert_equal(lineA, getline('.'))
1107 call assert_equal(11, col('.'))
1108 call assert_equal(5, winsaveview()['leftcol'])
1109 norm! yl
1110 call assert_equal('k', @0)
1111
1112 " Test for zh
1113 norm! 2zh
1114 call assert_equal(lineA, getline('.'))
1115 call assert_equal(11, col('.'))
1116 norm! yl
1117 call assert_equal('k', @0)
1118 call assert_equal(3, winsaveview()['leftcol'])
1119
1120 " Test for zL
1121 norm! 0zL
1122 call assert_equal(16, col('.'))
1123 norm! yl
1124 call assert_equal('p', @0)
1125 call assert_equal(10, winsaveview()['leftcol'])
1126 norm! 2zL
1127 call assert_equal(26, col('.'))
1128 norm! yl
1129 call assert_equal('z', @0)
1130 call assert_equal(15, winsaveview()['leftcol'])
1131
1132 " Test for zH
1133 norm! 2zH
1134 call assert_equal(15, col('.'))
1135 call assert_equal(0, winsaveview()['leftcol'])
1136 norm! yl
1137 call assert_equal('o', @0)
1138
1139 " Test for zs
1140 norm! $zs
1141 call assert_equal(26, col('.'))
1142 call assert_equal(20, winsaveview()['leftcol'])
1143 norm! yl
1144 call assert_equal('z', @0)
1145
1146 " Test for ze
1147 norm! ze
1148 call assert_equal(26, col('.'))
1149 call assert_equal(11, winsaveview()['leftcol'])
1150 norm! yl
1151 call assert_equal('z', @0)
1152
1153 " cleanup
1154 set wrap listchars=eol:$ sidescrolloff=0
1155 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001156endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001157
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001158" Test for commands that scroll the window horizontally. Test with folds.
1159" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1160func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001161 15new
1162 call setline(1, range(1, 100))
1163 exe "normal! 30ggz\<CR>"
1164 set foldenable
1165 33,36fold
1166 40,43fold
1167 46,49fold
1168 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001169
1170 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001171 " Top of the screen = 30
1172 " Folded lines = 9
1173 " Bottom of the screen = 30 + h + 9 - 1
1174 normal! 4L
1175 call assert_equal(35 + h, line('.'))
1176 normal! 4H
1177 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001178
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001179 " Test for using a large count value
1180 %d
1181 call setline(1, range(1, 4))
1182 norm! 6H
1183 call assert_equal(4, line('.'))
1184
1185 " Test for 'M' with folded lines
1186 %d
1187 call setline(1, range(1, 20))
1188 1,5fold
1189 norm! LM
1190 call assert_equal(12, line('.'))
1191
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001192 " Test for the CTRL-E and CTRL-Y commands with folds
1193 %d
1194 call setline(1, range(1, 10))
1195 3,5fold
1196 exe "normal 6G3\<C-E>"
1197 call assert_equal(6, line('w0'))
1198 exe "normal 2\<C-Y>"
1199 call assert_equal(2, line('w0'))
1200
1201 " Test for CTRL-Y on a folded line
1202 %d
1203 call setline(1, range(1, 100))
1204 exe (h + 2) .. "," .. (h + 4) .. "fold"
1205 exe h + 5
1206 normal z-
1207 exe "normal \<C-Y>\<C-Y>"
1208 call assert_equal(h + 1, line('w$'))
1209
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001210 " Test for CTRL-Y from the first line and CTRL-E from the last line
1211 %d
1212 set scrolloff=2
1213 call setline(1, range(1, 4))
1214 exe "normal gg\<C-Y>"
1215 call assert_equal(1, line('w0'))
1216 call assert_equal(1, line('.'))
1217 exe "normal G4\<C-E>\<C-E>"
1218 call assert_equal(4, line('w$'))
1219 call assert_equal(4, line('.'))
1220 set scrolloff&
1221
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001222 " Using <PageUp> and <PageDown> in an empty buffer should beep
1223 %d
1224 call assert_beeps('exe "normal \<PageUp>"')
1225 call assert_beeps('exe "normal \<C-B>"')
1226 call assert_beeps('exe "normal \<PageDown>"')
1227 call assert_beeps('exe "normal \<C-F>"')
1228
1229 " Test for <C-U> and <C-D> with fold
1230 %d
1231 call setline(1, range(1, 100))
1232 10,35fold
1233 set scroll=10
1234 exe "normal \<C-D>"
1235 call assert_equal(36, line('.'))
1236 exe "normal \<C-D>"
1237 call assert_equal(46, line('.'))
1238 exe "normal \<C-U>"
1239 call assert_equal(36, line('.'))
1240 exe "normal \<C-U>"
1241 call assert_equal(10, line('.'))
1242 exe "normal \<C-U>"
1243 call assert_equal(1, line('.'))
1244 set scroll&
1245
1246 " Test for scrolling to the top of the file with <C-U> and a fold
1247 10
1248 normal ztL
1249 exe "normal \<C-U>\<C-U>"
1250 call assert_equal(1, line('w0'))
1251
1252 " Test for CTRL-D on a folded line
1253 %d
1254 call setline(1, range(1, 100))
1255 50,100fold
1256 75
1257 normal z-
1258 exe "normal \<C-D>"
1259 call assert_equal(50, line('.'))
1260 call assert_equal(100, line('w$'))
1261 normal z.
1262 let lnum = winline()
1263 exe "normal \<C-D>"
1264 call assert_equal(lnum, winline())
1265 call assert_equal(50, line('.'))
1266 normal zt
1267 exe "normal \<C-D>"
1268 call assert_equal(50, line('w0'))
1269
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001270 " Test for <S-CR>. Page down.
1271 %d
1272 call setline(1, range(1, 100))
1273 call feedkeys("\<S-CR>", 'xt')
1274 call assert_equal(14, line('w0'))
1275 call assert_equal(28, line('w$'))
1276
1277 " Test for <S-->. Page up.
1278 call feedkeys("\<S-->", 'xt')
1279 call assert_equal(1, line('w0'))
1280 call assert_equal(15, line('w$'))
1281
Bram Moolenaar1671f442020-03-10 07:48:13 +01001282 set foldenable&
1283 close!
1284endfunc
1285
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001286func Test_scroll_in_ex_mode()
1287 " This was using invalid memory because w_botline was invalid.
1288 let lines =<< trim END
1289 diffsplit
1290 norm os00(
1291 call writefile(['done'], 'Xdone')
1292 qa!
1293 END
1294 call writefile(lines, 'Xscript')
1295 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1296 call assert_equal(['done'], readfile('Xdone'))
1297
1298 call delete('Xscript')
1299 call delete('Xdone')
1300endfunc
1301
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001302" Test for the 'sidescroll' option
1303func Test_sidescroll_opt()
1304 new
1305 20vnew
1306
1307 " scroll by 2 characters horizontally
1308 set sidescroll=2 nowrap
1309 call setline(1, repeat('a', 40))
1310 normal g$l
1311 call assert_equal(19, screenpos(0, 1, 21).col)
1312 normal l
1313 call assert_equal(20, screenpos(0, 1, 22).col)
1314 normal g0h
1315 call assert_equal(2, screenpos(0, 1, 2).col)
1316 call assert_equal(20, screenpos(0, 1, 20).col)
1317
1318 " when 'sidescroll' is 0, cursor positioned at the center
1319 set sidescroll=0
1320 normal g$l
1321 call assert_equal(11, screenpos(0, 1, 21).col)
1322 normal g0h
1323 call assert_equal(10, screenpos(0, 1, 10).col)
1324
1325 %bw!
1326 set wrap& sidescroll&
1327endfunc
1328
Bram Moolenaar004a6782020-04-11 17:09:31 +02001329" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001330func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001331 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001332 call Setup_NewWindow()
1333 50
1334 setl foldenable fdm=marker foldlevel=5
1335
Bram Moolenaar1671f442020-03-10 07:48:13 +01001336 call assert_beeps('normal! zj')
1337 call assert_beeps('normal! zk')
1338
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001339 " Test for zF
1340 " First fold
1341 norm! 4zF
1342 " check that folds have been created
1343 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1344
1345 " Test for zd
1346 51
1347 norm! 2zF
1348 call assert_equal(2, foldlevel('.'))
1349 norm! kzd
1350 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1351 norm! j
1352 call assert_equal(1, foldlevel('.'))
1353
1354 " Test for zD
1355 " also deletes partially selected folds recursively
1356 51
1357 norm! zF
1358 call assert_equal(2, foldlevel('.'))
1359 norm! kV2jzD
1360 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1361
1362 " Test for zE
1363 85
1364 norm! 4zF
1365 86
1366 norm! 2zF
1367 90
1368 norm! 4zF
1369 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1370 norm! zE
1371 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1372
1373 " Test for zn
1374 50
1375 set foldlevel=0
1376 norm! 2zF
1377 norm! zn
1378 norm! k
1379 call assert_equal('49', getline('.'))
1380 norm! j
1381 call assert_equal('50/*{{{*/', getline('.'))
1382 norm! j
1383 call assert_equal('51/*}}}*/', getline('.'))
1384 norm! j
1385 call assert_equal('52', getline('.'))
1386 call assert_equal(0, &foldenable)
1387
1388 " Test for zN
1389 49
1390 norm! zN
1391 call assert_equal('49', getline('.'))
1392 norm! j
1393 call assert_equal('50/*{{{*/', getline('.'))
1394 norm! j
1395 call assert_equal('52', getline('.'))
1396 call assert_equal(1, &foldenable)
1397
1398 " Test for zi
1399 norm! zi
1400 call assert_equal(0, &foldenable)
1401 norm! zi
1402 call assert_equal(1, &foldenable)
1403 norm! zi
1404 call assert_equal(0, &foldenable)
1405 norm! zi
1406 call assert_equal(1, &foldenable)
1407
1408 " Test for za
1409 50
1410 norm! za
1411 norm! k
1412 call assert_equal('49', getline('.'))
1413 norm! j
1414 call assert_equal('50/*{{{*/', getline('.'))
1415 norm! j
1416 call assert_equal('51/*}}}*/', getline('.'))
1417 norm! j
1418 call assert_equal('52', getline('.'))
1419 50
1420 norm! za
1421 norm! k
1422 call assert_equal('49', getline('.'))
1423 norm! j
1424 call assert_equal('50/*{{{*/', getline('.'))
1425 norm! j
1426 call assert_equal('52', getline('.'))
1427
1428 49
1429 norm! 5zF
1430 norm! k
1431 call assert_equal('48', getline('.'))
1432 norm! j
1433 call assert_equal('49/*{{{*/', getline('.'))
1434 norm! j
1435 call assert_equal('55', getline('.'))
1436 49
1437 norm! za
1438 call assert_equal('49/*{{{*/', getline('.'))
1439 norm! j
1440 call assert_equal('50/*{{{*/', getline('.'))
1441 norm! j
1442 call assert_equal('52', getline('.'))
1443 set nofoldenable
1444 " close fold and set foldenable
1445 norm! za
1446 call assert_equal(1, &foldenable)
1447
1448 50
1449 " have to use {count}za to open all folds and make the cursor visible
1450 norm! 2za
1451 norm! 2k
1452 call assert_equal('48', getline('.'))
1453 norm! j
1454 call assert_equal('49/*{{{*/', getline('.'))
1455 norm! j
1456 call assert_equal('50/*{{{*/', getline('.'))
1457 norm! j
1458 call assert_equal('51/*}}}*/', getline('.'))
1459 norm! j
1460 call assert_equal('52', getline('.'))
1461
1462 " Test for zA
1463 49
1464 set foldlevel=0
1465 50
1466 norm! zA
1467 norm! 2k
1468 call assert_equal('48', getline('.'))
1469 norm! j
1470 call assert_equal('49/*{{{*/', getline('.'))
1471 norm! j
1472 call assert_equal('50/*{{{*/', getline('.'))
1473 norm! j
1474 call assert_equal('51/*}}}*/', getline('.'))
1475 norm! j
1476 call assert_equal('52', getline('.'))
1477
Dominique Pelle923dce22021-11-21 11:36:04 +00001478 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001479 50
1480 set nofoldenable
1481 norm! zA
1482 call assert_equal(1, &foldenable)
1483 norm! k
1484 call assert_equal('48', getline('.'))
1485 norm! j
1486 call assert_equal('49/*{{{*/', getline('.'))
1487 norm! j
1488 call assert_equal('55', getline('.'))
1489
1490 " Test for zc
1491 norm! zE
1492 50
1493 norm! 2zF
1494 49
1495 norm! 5zF
1496 set nofoldenable
1497 50
1498 " There most likely is a bug somewhere:
1499 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1500 " TODO: Should this only close the inner most fold or both folds?
1501 norm! zc
1502 call assert_equal(1, &foldenable)
1503 norm! k
1504 call assert_equal('48', getline('.'))
1505 norm! j
1506 call assert_equal('49/*{{{*/', getline('.'))
1507 norm! j
1508 call assert_equal('55', getline('.'))
1509 set nofoldenable
1510 50
1511 norm! Vjzc
1512 norm! k
1513 call assert_equal('48', getline('.'))
1514 norm! j
1515 call assert_equal('49/*{{{*/', getline('.'))
1516 norm! j
1517 call assert_equal('55', getline('.'))
1518
1519 " Test for zC
1520 set nofoldenable
1521 50
1522 norm! zCk
1523 call assert_equal('48', getline('.'))
1524 norm! j
1525 call assert_equal('49/*{{{*/', getline('.'))
1526 norm! j
1527 call assert_equal('55', getline('.'))
1528
1529 " Test for zx
1530 " 1) close folds at line 49-54
1531 set nofoldenable
1532 48
1533 norm! zx
1534 call assert_equal(1, &foldenable)
1535 norm! j
1536 call assert_equal('49/*{{{*/', getline('.'))
1537 norm! j
1538 call assert_equal('55', getline('.'))
1539
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001540 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001541 51
1542 set nofoldenable
1543 norm! zx
1544 call assert_equal(1, &foldenable)
1545 norm! 3k
1546 call assert_equal('48', getline('.'))
1547 norm! j
1548 call assert_equal('49/*{{{*/', getline('.'))
1549 norm! j
1550 call assert_equal('50/*{{{*/', getline('.'))
1551 norm! j
1552 call assert_equal('51/*}}}*/', getline('.'))
1553 norm! j
1554 call assert_equal('52', getline('.'))
1555 norm! j
1556 call assert_equal('53', getline('.'))
1557 norm! j
1558 call assert_equal('54/*}}}*/', getline('.'))
1559 norm! j
1560 call assert_equal('55', getline('.'))
1561
1562 " 3) close one level of folds
1563 48
1564 set nofoldenable
1565 set foldlevel=1
1566 norm! zx
1567 call assert_equal(1, &foldenable)
1568 call assert_equal('48', getline('.'))
1569 norm! j
1570 call assert_equal('49/*{{{*/', getline('.'))
1571 norm! j
1572 call assert_equal('50/*{{{*/', getline('.'))
1573 norm! j
1574 call assert_equal('52', getline('.'))
1575 norm! j
1576 call assert_equal('53', getline('.'))
1577 norm! j
1578 call assert_equal('54/*}}}*/', getline('.'))
1579 norm! j
1580 call assert_equal('55', getline('.'))
1581
1582 " Test for zX
1583 " Close all folds
1584 set foldlevel=0 nofoldenable
1585 50
1586 norm! zX
1587 call assert_equal(1, &foldenable)
1588 norm! k
1589 call assert_equal('48', getline('.'))
1590 norm! j
1591 call assert_equal('49/*{{{*/', getline('.'))
1592 norm! j
1593 call assert_equal('55', getline('.'))
1594
1595 " Test for zm
1596 50
1597 set nofoldenable foldlevel=2
1598 norm! zm
1599 call assert_equal(1, &foldenable)
1600 call assert_equal(1, &foldlevel)
1601 norm! zm
1602 call assert_equal(0, &foldlevel)
1603 norm! zm
1604 call assert_equal(0, &foldlevel)
1605 norm! k
1606 call assert_equal('48', getline('.'))
1607 norm! j
1608 call assert_equal('49/*{{{*/', getline('.'))
1609 norm! j
1610 call assert_equal('55', getline('.'))
1611
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001612 " Test for zm with a count
1613 50
1614 set foldlevel=2
1615 norm! 3zm
1616 call assert_equal(0, &foldlevel)
1617 call assert_equal(49, foldclosed(line('.')))
1618
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001619 " Test for zM
1620 48
1621 set nofoldenable foldlevel=99
1622 norm! zM
1623 call assert_equal(1, &foldenable)
1624 call assert_equal(0, &foldlevel)
1625 call assert_equal('48', getline('.'))
1626 norm! j
1627 call assert_equal('49/*{{{*/', getline('.'))
1628 norm! j
1629 call assert_equal('55', getline('.'))
1630
1631 " Test for zr
1632 48
1633 set nofoldenable foldlevel=0
1634 norm! zr
1635 call assert_equal(0, &foldenable)
1636 call assert_equal(1, &foldlevel)
1637 set foldlevel=0 foldenable
1638 norm! zr
1639 call assert_equal(1, &foldenable)
1640 call assert_equal(1, &foldlevel)
1641 norm! zr
1642 call assert_equal(2, &foldlevel)
1643 call assert_equal('48', getline('.'))
1644 norm! j
1645 call assert_equal('49/*{{{*/', getline('.'))
1646 norm! j
1647 call assert_equal('50/*{{{*/', getline('.'))
1648 norm! j
1649 call assert_equal('51/*}}}*/', getline('.'))
1650 norm! j
1651 call assert_equal('52', getline('.'))
1652
1653 " Test for zR
1654 48
1655 set nofoldenable foldlevel=0
1656 norm! zR
1657 call assert_equal(0, &foldenable)
1658 call assert_equal(2, &foldlevel)
1659 set foldenable foldlevel=0
1660 norm! zR
1661 call assert_equal(1, &foldenable)
1662 call assert_equal(2, &foldlevel)
1663 call assert_equal('48', getline('.'))
1664 norm! j
1665 call assert_equal('49/*{{{*/', getline('.'))
1666 norm! j
1667 call assert_equal('50/*{{{*/', getline('.'))
1668 norm! j
1669 call assert_equal('51/*}}}*/', getline('.'))
1670 norm! j
1671 call assert_equal('52', getline('.'))
1672 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1673 48
1674 call assert_equal('48', getline('.'))
1675 norm! j
1676 call assert_equal('49/*{{{*/', getline('.'))
1677 norm! j
1678 call assert_equal('50/*{{{*/', getline('.'))
1679 norm! j
1680 call assert_equal('a /*{{{*/', getline('.'))
1681 norm! j
1682 call assert_equal('51/*}}}*/', getline('.'))
1683 norm! j
1684 call assert_equal('52', getline('.'))
1685 48
1686 norm! zR
1687 call assert_equal(1, &foldenable)
1688 call assert_equal(3, &foldlevel)
1689 call assert_equal('48', getline('.'))
1690 norm! j
1691 call assert_equal('49/*{{{*/', getline('.'))
1692 norm! j
1693 call assert_equal('50/*{{{*/', getline('.'))
1694 norm! j
1695 call assert_equal('a /*{{{*/', getline('.'))
1696 norm! j
1697 call assert_equal('b /*}}}*/', getline('.'))
1698 norm! j
1699 call assert_equal('51/*}}}*/', getline('.'))
1700 norm! j
1701 call assert_equal('52', getline('.'))
1702
1703 " clean up
1704 setl nofoldenable fdm=marker foldlevel=0
1705 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001706endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001707
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001708func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001709 " Reading from redirected file doesn't work on MS-Windows
1710 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001711 call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
1712 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001713 call system(GetVimCommand() .. ' -e -s < Xscript Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001714 let a=readfile('Xfile2')
1715 call assert_equal(['1', 'foo', 'bar', '2'], a)
1716
1717 " clean up
1718 for file in ['Xfile', 'Xfile2', 'Xscript']
1719 call delete(file)
1720 endfor
1721 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001722endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001723
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001724func Test_normal21_nv_hat()
1725
1726 " Edit a fresh file and wipe the buffer list so that there is no alternate
1727 " file present. Next, check for the expected command failures.
1728 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001729 call assert_fails(':buffer #', 'E86:')
1730 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001731 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001732
1733 " Test for the expected behavior when switching between two named buffers.
1734 edit Xfoo | edit Xbar
1735 call feedkeys("\<C-^>", 'tx')
1736 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1737 call feedkeys("\<C-^>", 'tx')
1738 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1739
1740 " Test for the expected behavior when only one buffer is named.
1741 enew | let l:nr = bufnr('%')
1742 call feedkeys("\<C-^>", 'tx')
1743 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1744 call feedkeys("\<C-^>", 'tx')
1745 call assert_equal('', bufname('%'))
1746 call assert_equal(l:nr, bufnr('%'))
1747
1748 " Test that no action is taken by "<C-^>" when an operator is pending.
1749 edit Xfoo
1750 call feedkeys("ci\<C-^>", 'tx')
1751 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1752
1753 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001754endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001755
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001756func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001757 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001758 " let shell = &shell
1759 " let &shell = 'sh'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001760 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001761 let args = ' -N -i NONE --noplugins -X --not-a-term'
1762 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001763 let a = readfile('Xfile')
1764 call assert_equal([], a)
1765 " Test for ZQ
1766 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001767 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001768 let a = readfile('Xfile')
1769 call assert_equal(['1', '2'], a)
1770
Bram Moolenaar1671f442020-03-10 07:48:13 +01001771 " Unsupported Z command
1772 call assert_beeps('normal! ZW')
1773
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001774 " clean up
1775 for file in ['Xfile']
1776 call delete(file)
1777 endfor
Bram Moolenaar0913a102016-09-03 19:11:59 +02001778 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001779endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001780
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001781func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001782 " Test for K command
1783 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001784 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001785 let k = &keywordprg
1786 set keywordprg=:help
1787 1
1788 norm! VK
1789 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1790 call assert_equal('help', &ft)
1791 call assert_match('\*version8.txt\*', getline('.'))
1792 helpclose
1793 norm! 0K
1794 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1795 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001796 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001797 helpclose
1798
Bram Moolenaar426f3752016-11-04 21:22:37 +01001799 set keywordprg=:new
1800 set iskeyword+=%
1801 set iskeyword+=\|
1802 2
1803 norm! K
1804 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1805 bwipe!
1806 3
1807 norm! K
1808 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1809 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001810 if !has('win32')
1811 4
1812 norm! K
1813 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1814 bwipe!
1815 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001816 set iskeyword-=%
1817 set iskeyword-=\|
1818
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001819 " Test for specifying a count to K
1820 1
1821 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1822 set keywordprg=:Kprog
1823 norm! 3K
1824 call assert_equal('3 version8', g:Kprog_Args)
1825 delcom Kprog
1826
Bram Moolenaar0913a102016-09-03 19:11:59 +02001827 " Only expect "man" to work on Unix
1828 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001829 let &keywordprg = k
1830 bw!
1831 return
1832 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001833
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001834 let not_gnu_man = has('mac') || has('bsd')
1835 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001836 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001837 set keywordprg=man\ -P\ cat
1838 else
1839 set keywordprg=man\ --pager=cat
1840 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001841 " Test for using man
1842 2
1843 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001844 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001845 call assert_match("man -P cat 'man'", a)
1846 else
1847 call assert_match("man --pager=cat 'man'", a)
1848 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001849
Bram Moolenaar1671f442020-03-10 07:48:13 +01001850 " Error cases
1851 call setline(1, '#$#')
1852 call assert_fails('normal! ggK', 'E349:')
1853 call setline(1, '---')
1854 call assert_fails('normal! ggv2lK', 'E349:')
1855 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001856 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001857 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001858 norm! V
1859 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001860
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001861 " clean up
1862 let &keywordprg = k
1863 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001864endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001865
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001866func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001867 " Testing for g?? g?g?
1868 new
1869 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1870 1
1871 norm! g??
1872 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1873 norm! g?g?
1874 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1875
1876 " clean up
1877 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001878endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001879
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001880func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001881 CheckFeature quickfix
1882
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001883 " Testing for CTRL-] g CTRL-] g]
1884 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1885 h
1886 " Test for CTRL-]
1887 call search('\<x\>$')
1888 exe "norm! \<c-]>"
1889 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1890 norm! yiW
1891 call assert_equal("*x*", @0)
1892 exe ":norm \<c-o>"
1893
1894 " Test for g_CTRL-]
1895 call search('\<v_u\>$')
1896 exe "norm! g\<c-]>"
1897 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1898 norm! yiW
1899 call assert_equal("*v_u*", @0)
1900 exe ":norm \<c-o>"
1901
1902 " Test for g]
1903 call search('\<i_<Esc>$')
1904 let a = execute(":norm! g]")
1905 call assert_match('i_<Esc>.*insert.txt', a)
1906
1907 if !empty(exepath('cscope')) && has('cscope')
1908 " setting cscopetag changes how g] works
1909 set cst
1910 exe "norm! g]"
1911 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1912 norm! yiW
1913 call assert_equal("*i_<Esc>*", @0)
1914 exe ":norm \<c-o>"
1915 " Test for CTRL-W g]
1916 exe "norm! \<C-W>g]"
1917 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1918 norm! yiW
1919 call assert_equal("*i_<Esc>*", @0)
1920 call assert_equal(3, winnr('$'))
1921 helpclose
1922 set nocst
1923 endif
1924
1925 " Test for CTRL-W g]
1926 let a = execute("norm! \<C-W>g]")
1927 call assert_match('i_<Esc>.*insert.txt', a)
1928
1929 " Test for CTRL-W CTRL-]
1930 exe "norm! \<C-W>\<C-]>"
1931 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1932 norm! yiW
1933 call assert_equal("*i_<Esc>*", @0)
1934 call assert_equal(3, winnr('$'))
1935 helpclose
1936
1937 " Test for CTRL-W g CTRL-]
1938 exe "norm! \<C-W>g\<C-]>"
1939 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1940 norm! yiW
1941 call assert_equal("*i_<Esc>*", @0)
1942 call assert_equal(3, winnr('$'))
1943 helpclose
1944
1945 " clean up
1946 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001947endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001948
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001949func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001950 " Test for ]p ]P [p and [P
1951 new
1952 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1953 1
1954 /Error/y a
1955 2
1956 norm! "a]pj"a[p
1957 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1958 1
1959 /^\s\{4}/
1960 exe "norm! \"a]P3Eldt'"
1961 exe "norm! j\"a[P2Eldt'"
1962 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
1963
1964 " clean up
1965 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001966endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001967
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001968func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001969 " Test for [' [` ]' ]`
1970 call Setup_NewWindow()
1971 1,21s/.\+/ & b/
1972 1
1973 norm! $ma
1974 5
1975 norm! $mb
1976 10
1977 norm! $mc
1978 15
1979 norm! $md
1980 20
1981 norm! $me
1982
1983 " Test for ['
1984 9
1985 norm! 2['
1986 call assert_equal(' 1 b', getline('.'))
1987 call assert_equal(1, line('.'))
1988 call assert_equal(3, col('.'))
1989
1990 " Test for ]'
1991 norm! ]'
1992 call assert_equal(' 5 b', getline('.'))
1993 call assert_equal(5, line('.'))
1994 call assert_equal(3, col('.'))
1995
1996 " No mark after line 21, cursor moves to first non blank on current line
1997 21
1998 norm! $]'
1999 call assert_equal(' 21 b', getline('.'))
2000 call assert_equal(21, line('.'))
2001 call assert_equal(3, col('.'))
2002
2003 " Test for [`
2004 norm! 2[`
2005 call assert_equal(' 15 b', getline('.'))
2006 call assert_equal(15, line('.'))
2007 call assert_equal(8, col('.'))
2008
2009 " Test for ]`
2010 norm! ]`
2011 call assert_equal(' 20 b', getline('.'))
2012 call assert_equal(20, line('.'))
2013 call assert_equal(8, col('.'))
2014
2015 " clean up
2016 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002017endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002018
Bram Moolenaar1671f442020-03-10 07:48:13 +01002019" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002020func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002021 new
2022 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2023
2024 $
2025 norm! d(
2026 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2027 norm! 2d(
2028 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2029 1
2030 norm! 0d)
2031 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2032
2033 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2034 $
2035 norm! $d(
2036 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2037
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002038 " Move to the next sentence from a paragraph macro
2039 %d
2040 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2041 call cursor(1, 1)
2042 normal )
2043 call assert_equal([2, 1], [line('.'), col('.')])
2044 normal )
2045 call assert_equal([2, 12], [line('.'), col('.')])
2046 normal ((
2047 call assert_equal([1, 1], [line('.'), col('.')])
2048
Bram Moolenaar1671f442020-03-10 07:48:13 +01002049 " It is an error if a next sentence is not found
2050 %d
2051 call setline(1, '.SH')
2052 call assert_beeps('normal )')
2053
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002054 " If only dot is present, don't treat that as a sentence
2055 call setline(1, '. This is a sentence.')
2056 normal $((
2057 call assert_equal(3, col('.'))
2058
Bram Moolenaar1671f442020-03-10 07:48:13 +01002059 " Jumping to a fold should open the fold
2060 call setline(1, ['', '', 'one', 'two', 'three'])
2061 set foldenable
2062 2,$fold
2063 call feedkeys(')', 'xt')
2064 call assert_equal(3, line('.'))
2065 call assert_equal(1, foldlevel('.'))
2066 call assert_equal(-1, foldclosed('.'))
2067 set foldenable&
2068
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002069 " clean up
2070 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002071endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002072
Bram Moolenaar1671f442020-03-10 07:48:13 +01002073" Test for { and } paragraph movements
2074func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002075 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002076 A paragraph begins after each empty line, and also at each of a set of
2077 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2078 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2079 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2080 the first column). A section boundary is also a paragraph boundary.
2081 Note that a blank line (only containing white space) is NOT a paragraph
2082 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002083
2084
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002085 Also note that this does not include a '{' or '}' in the first column. When
2086 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2087 paragraph boundary |posix|.
2088 {
2089 This is no paragraph
2090 unless the '{' is set
2091 in 'cpoptions'
2092 }
2093 .IP
2094 The nroff macros IP separates a paragraph
2095 That means, it must be a '.'
2096 followed by IP
2097 .LPIt does not matter, if afterwards some
2098 more characters follow.
2099 .SHAlso section boundaries from the nroff
2100 macros terminate a paragraph. That means
2101 a character like this:
2102 .NH
2103 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002104 [DATA]
2105
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002106 new
2107 call append(0, text)
2108 1
2109 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002110
2111 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002112 .IP
2113 The nroff macros IP separates a paragraph
2114 That means, it must be a '.'
2115 followed by IP
2116 .LPIt does not matter, if afterwards some
2117 more characters follow.
2118 .SHAlso section boundaries from the nroff
2119 macros terminate a paragraph. That means
2120 a character like this:
2121 .NH
2122 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002123
2124 [DATA]
2125 call assert_equal(expected, getline(1, '$'))
2126
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002127 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002128
2129 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002130 .LPIt does not matter, if afterwards some
2131 more characters follow.
2132 .SHAlso section boundaries from the nroff
2133 macros terminate a paragraph. That means
2134 a character like this:
2135 .NH
2136 End of text here
2137
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002138 [DATA]
2139 call assert_equal(expected, getline(1, '$'))
2140
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002141 $
2142 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002143
2144 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002145 .LPIt does not matter, if afterwards some
2146 more characters follow.
2147 .SHAlso section boundaries from the nroff
2148 macros terminate a paragraph. That means
2149 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002150
2151 [DATA]
2152 call assert_equal(expected, getline(1, '$'))
2153
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002154 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002155
2156 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002157 .LPIt does not matter, if afterwards some
2158 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002159
2160 [DATA]
2161 call assert_equal(expected, getline(1, '$'))
2162
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002163 " Test with { in cpooptions
2164 %d
2165 call append(0, text)
2166 set cpo+={
2167 1
2168 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002169
2170 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002171 {
2172 This is no paragraph
2173 unless the '{' is set
2174 in 'cpoptions'
2175 }
2176 .IP
2177 The nroff macros IP separates a paragraph
2178 That means, it must be a '.'
2179 followed by IP
2180 .LPIt does not matter, if afterwards some
2181 more characters follow.
2182 .SHAlso section boundaries from the nroff
2183 macros terminate a paragraph. That means
2184 a character like this:
2185 .NH
2186 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002187
2188 [DATA]
2189 call assert_equal(expected, getline(1, '$'))
2190
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002191 $
2192 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002193
2194 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002195 {
2196 This is no paragraph
2197 unless the '{' is set
2198 in 'cpoptions'
2199 }
2200 .IP
2201 The nroff macros IP separates a paragraph
2202 That means, it must be a '.'
2203 followed by IP
2204 .LPIt does not matter, if afterwards some
2205 more characters follow.
2206 .SHAlso section boundaries from the nroff
2207 macros terminate a paragraph. That means
2208 a character like this:
2209 .NH
2210 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002211
2212 [DATA]
2213 call assert_equal(expected, getline(1, '$'))
2214
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002215 norm! gg}
2216 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002217
2218 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002219 {
2220 This is no paragraph
2221 unless the '{' is set
2222 in 'cpoptions'
2223 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002224
2225 [DATA]
2226 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002227
Bram Moolenaar1671f442020-03-10 07:48:13 +01002228 " Jumping to a fold should open the fold
2229 %d
2230 call setline(1, ['', 'one', 'two', ''])
2231 set foldenable
2232 2,$fold
2233 call feedkeys('}', 'xt')
2234 call assert_equal(4, line('.'))
2235 call assert_equal(1, foldlevel('.'))
2236 call assert_equal(-1, foldclosed('.'))
2237 set foldenable&
2238
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002239 " clean up
2240 set cpo-={
2241 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002242endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002243
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002244" Test for section movements
2245func Test_normal_section()
2246 new
2247 let lines =<< trim [END]
2248 int foo()
2249 {
2250 if (1)
2251 {
2252 a = 1;
2253 }
2254 }
2255 [END]
2256 call setline(1, lines)
2257
2258 " jumping to a folded line using [[ should open the fold
2259 2,3fold
2260 call cursor(5, 1)
2261 call feedkeys("[[", 'xt')
2262 call assert_equal(2, line('.'))
2263 call assert_equal(-1, foldclosedend(line('.')))
2264
2265 close!
2266endfunc
2267
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002268" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002269func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002270 new
2271 call append(0, 'This is a simple test: äüöß')
2272 norm! 1ggVu
2273 call assert_equal('this is a simple test: äüöß', getline('.'))
2274 norm! VU
2275 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2276 norm! guu
2277 call assert_equal('this is a simple test: äüöss', getline('.'))
2278 norm! gUgU
2279 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2280 norm! gugu
2281 call assert_equal('this is a simple test: äüöss', getline('.'))
2282 norm! gUU
2283 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2284 norm! 010~
2285 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
2286 norm! V~
2287 call assert_equal('THIS IS A simple test: äüöss', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002288 call assert_beeps('norm! c~')
2289 %d
2290 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002291
Bram Moolenaar1671f442020-03-10 07:48:13 +01002292 " Test for changing case across lines using 'whichwrap'
2293 call setline(1, ['aaaaaa', 'aaaaaa'])
2294 normal! gg10~
2295 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2296 set whichwrap+=~
2297 normal! gg10~
2298 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2299 set whichwrap&
2300
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002301 " try changing the case with a double byte encoding (DBCS)
2302 %bw!
2303 let enc = &enc
2304 set encoding=cp932
2305 call setline(1, "\u8470")
2306 normal ~
2307 normal gU$gu$gUgUg~g~gugu
2308 call assert_equal("\u8470", getline(1))
2309 let &encoding = enc
2310
Bram Moolenaar1671f442020-03-10 07:48:13 +01002311 " clean up
2312 bw!
2313endfunc
2314
2315" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2316" is available but toupper()/tolower() don't do the right thing.
2317func Test_normal_changecase_turkish()
2318 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002319 try
2320 lang tr_TR.UTF-8
2321 set casemap=
2322 let iupper = toupper('i')
2323 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002324 call setline(1, 'iI')
2325 1normal gUU
2326 call assert_equal("\u0130I", getline(1))
2327 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002328
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002329 call setline(1, 'iI')
2330 1normal guu
2331 call assert_equal("i\u0131", getline(1))
2332 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002333 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002334 call setline(1, 'iI')
2335 1normal gUU
2336 call assert_equal("II", getline(1))
2337 call assert_equal("II", toupper("iI"))
2338
2339 call setline(1, 'iI')
2340 1normal guu
2341 call assert_equal("ii", getline(1))
2342 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002343 else
2344 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2345 endif
2346 set casemap&
2347 call setline(1, 'iI')
2348 1normal gUU
2349 call assert_equal("II", getline(1))
2350 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002351
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002352 call setline(1, 'iI')
2353 1normal guu
2354 call assert_equal("ii", getline(1))
2355 call assert_equal("ii", tolower("iI"))
2356
2357 lang en_US.UTF-8
2358 catch /E197:/
2359 " can't use Turkish locale
2360 throw 'Skipped: Turkish locale not available'
2361 endtry
Bram Moolenaar1671f442020-03-10 07:48:13 +01002362 close!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002363endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002364
Bram Moolenaar1671f442020-03-10 07:48:13 +01002365" Test for r (replace) command
2366func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002367 new
2368 call append(0, 'This is a simple test: abcd')
2369 exe "norm! 1gg$r\<cr>"
2370 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2371 exe "norm! 1gg2wlr\<cr>"
2372 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2373 exe "norm! 2gg0W5r\<cr>"
2374 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2375 set autoindent
2376 call setline(2, ['simple test: abc', ''])
2377 exe "norm! 2gg0W5r\<cr>"
2378 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2379 exe "norm! 1ggVr\<cr>"
2380 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2381 call setline(1, 'This is a')
2382 exe "norm! 1gg05rf"
2383 call assert_equal('fffffis a', getline(1))
2384
Bram Moolenaar1671f442020-03-10 07:48:13 +01002385 " When replacing characters, copy characters from above and below lines
2386 " using CTRL-Y and CTRL-E.
2387 " Different code paths are used for utf-8 and latin1 encodings
2388 set showmatch
2389 for enc in ['latin1', 'utf-8']
2390 enew!
2391 let &encoding = enc
2392 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2393 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2394 call assert_equal(' {a}x [b]x', getline(2))
2395 endfor
2396 set showmatch&
2397
2398 " r command should fail in operator pending mode
2399 call assert_beeps('normal! cr')
2400
Bram Moolenaar004a6782020-04-11 17:09:31 +02002401 " replace a tab character in visual mode
2402 %d
2403 call setline(1, ["a\tb", "c\td", "e\tf"])
2404 normal gglvjjrx
2405 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2406
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002407 " replace with a multibyte character (with multiple composing characters)
2408 %d
2409 new
2410 call setline(1, 'aaa')
2411 exe "normal $ra\u0328\u0301"
2412 call assert_equal("aaa\u0328\u0301", getline(1))
2413
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002414 " clean up
2415 set noautoindent
2416 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002417endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002418
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002419" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002420func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002421 new
2422 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2423 1
2424 norm! $g*
2425 call assert_equal('x_foo', @/)
2426 call assert_equal('x_foobar.abc', getline('.'))
2427 norm! $g#
2428 call assert_equal('abc', @/)
2429 call assert_equal('abc.x_foo', getline('.'))
2430
2431 " clean up
2432 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002433endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002434
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002435" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2436" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002437func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002438 call Setup_NewWindow()
2439 " Test for g`
2440 clearjumps
2441 norm! ma10j
2442 let a=execute(':jumps')
2443 " empty jumplist
2444 call assert_equal('>', a[-1:])
2445 norm! g`a
2446 call assert_equal('>', a[-1:])
2447 call assert_equal(1, line('.'))
2448 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002449 call cursor(10, 1)
2450 norm! g'a
2451 call assert_equal('>', a[-1:])
2452 call assert_equal(1, line('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002453
2454 " Test for g; and g,
2455 norm! g;
2456 " there is only one change in the changelist
2457 " currently, when we setup the window
2458 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002459 call assert_fails(':norm! g;', 'E662:')
2460 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002461 let &ul=&ul
2462 call append('$', ['a', 'b', 'c', 'd'])
2463 let &ul=&ul
2464 call append('$', ['Z', 'Y', 'X', 'W'])
2465 let a = execute(':changes')
2466 call assert_match('2\s\+0\s\+2', a)
2467 call assert_match('101\s\+0\s\+a', a)
2468 call assert_match('105\s\+0\s\+Z', a)
2469 norm! 3g;
2470 call assert_equal(2, line('.'))
2471 norm! 2g,
2472 call assert_equal(105, line('.'))
2473
2474 " Test for g& - global substitute
2475 %d
2476 call setline(1, range(1,10))
2477 call append('$', ['a', 'b', 'c', 'd'])
2478 $s/\w/&&/g
2479 exe "norm! /[1-8]\<cr>"
2480 norm! g&
2481 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2482
Bram Moolenaar1671f442020-03-10 07:48:13 +01002483 " Jumping to a fold using gg should open the fold
2484 set foldenable
2485 set foldopen+=jump
2486 5,8fold
2487 call feedkeys('6gg', 'xt')
2488 call assert_equal(1, foldlevel('.'))
2489 call assert_equal(-1, foldclosed('.'))
2490 set foldopen-=jump
2491 set foldenable&
2492
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002493 " Test for gv
2494 %d
2495 call append('$', repeat(['abcdefgh'], 8))
2496 exe "norm! 2gg02l\<c-v>2j2ly"
2497 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2498 " in visual mode, gv swaps current and last selected region
2499 exe "norm! G0\<c-v>4k4lgvd"
2500 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2501 exe "norm! G0\<c-v>4k4ly"
2502 exe "norm! gvood"
2503 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002504 " gv cannot be used in operator pending mode
2505 call assert_beeps('normal! cgv')
2506 " gv should beep without a previously selected visual area
2507 new
2508 call assert_beeps('normal! gv')
2509 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002510
2511 " Test for gk/gj
2512 %d
2513 15vsp
2514 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002515 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2516 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2517 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002518 $put =lineA
2519 $put =lineB
2520
2521 norm! 3gg0dgk
2522 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2523 set nu
2524 norm! 3gg0gjdgj
2525 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2526
2527 " Test for gJ
2528 norm! 2gggJ
2529 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2530 call assert_equal(16, col('.'))
2531 " shouldn't do anything
2532 norm! 10gJ
2533 call assert_equal(1, col('.'))
2534
2535 " Test for g0 g^ gm g$
2536 exe "norm! 2gg0gji "
2537 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2538 norm! g0yl
2539 call assert_equal(12, col('.'))
2540 call assert_equal(' ', getreg(0))
2541 norm! g$yl
2542 call assert_equal(22, col('.'))
2543 call assert_equal('3', getreg(0))
2544 norm! gmyl
2545 call assert_equal(17, col('.'))
2546 call assert_equal('n', getreg(0))
2547 norm! g^yl
2548 call assert_equal(15, col('.'))
2549 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002550 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002551
Bram Moolenaar74ede802021-05-29 19:18:01 +02002552 " Test for g$ with double-width character half displayed
2553 vsplit
2554 9wincmd |
2555 setlocal nowrap nonumber
2556 call setline(2, 'asdfasdfヨ')
2557 2
2558 normal 0g$
2559 call assert_equal(8, col('.'))
2560 10wincmd |
2561 normal 0g$
2562 call assert_equal(9, col('.'))
2563
2564 setlocal signcolumn=yes
2565 11wincmd |
2566 normal 0g$
2567 call assert_equal(8, col('.'))
2568 12wincmd |
2569 normal 0g$
2570 call assert_equal(9, col('.'))
2571
2572 close
2573
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002574 " Test for g_
2575 call assert_beeps('normal! 100g_')
2576 call setline(2, [' foo ', ' foobar '])
2577 normal! 2ggg_
2578 call assert_equal(5, col('.'))
2579 normal! 2g_
2580 call assert_equal(8, col('.'))
2581
2582 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002583 $put =lineC
2584
2585 " Test for gM
2586 norm! gMyl
2587 call assert_equal(73, col('.'))
2588 call assert_equal('0', getreg(0))
2589 " Test for 20gM
2590 norm! 20gMyl
2591 call assert_equal(29, col('.'))
2592 call assert_equal('S', getreg(0))
2593 " Test for 60gM
2594 norm! 60gMyl
2595 call assert_equal(87, col('.'))
2596 call assert_equal('E', getreg(0))
2597
Bram Moolenaar71c41252021-12-26 15:00:07 +00002598 " Test for gM with Tab characters
2599 call setline('.', "\ta\tb\tc\td\te\tf")
2600 norm! gMyl
2601 call assert_equal(6, col('.'))
2602 call assert_equal("c", getreg(0))
2603
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002604 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002605 call setline('.', lineC)
2606 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002607 set ff=unix
2608 let a=execute(":norm! g\<c-g>")
2609 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2610
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002611 " Test for gI
2612 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002613 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002614
2615 " Test for gi
2616 wincmd c
2617 %d
2618 set tw=0
2619 call setline(1, ['foobar', 'new line'])
2620 norm! A next word
2621 $put ='third line'
2622 norm! gi another word
2623 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002624 call setline(1, 'foobar')
2625 normal! Ggifirst line
2626 call assert_equal('foobarfirst line', getline(1))
2627 " Test gi in 'virtualedit' mode with cursor after the end of the line
2628 set virtualedit=all
2629 call setline(1, 'foo')
2630 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2631 call setline(1, 'foo')
2632 normal! Ggifirst line
2633 call assert_equal('foo first line', getline(1))
2634 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002635
Dominique Pelle923dce22021-11-21 11:36:04 +00002636 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002637 exe "normal! g\<C-\>\<C-G>"
2638 call assert_equal('foo first line', getline('.'))
2639
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002640 " clean up
2641 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002642endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002643
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002644" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002645func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002646 new
2647
2648 let a = execute(":norm! g\<c-g>")
2649 call assert_equal("\n--No lines in buffer--", a)
2650
Bram Moolenaar1671f442020-03-10 07:48:13 +01002651 " Test for CTRL-G (same as :file)
2652 let a = execute(":norm! \<c-g>")
2653 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2654
Bram Moolenaar05295832018-08-24 22:07:58 +02002655 call setline(1, ['first line', 'second line'])
2656
2657 " Test g CTRL-g with dos, mac and unix file type.
2658 norm! gojll
2659 set ff=dos
2660 let a = execute(":norm! g\<c-g>")
2661 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2662
2663 set ff=mac
2664 let a = execute(":norm! g\<c-g>")
2665 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2666
2667 set ff=unix
2668 let a = execute(":norm! g\<c-g>")
2669 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2670
2671 " Test g CTRL-g in visual mode (v)
2672 let a = execute(":norm! gojllvlg\<c-g>")
2673 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2674
2675 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2676 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2677 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2678
2679 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2680 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2681 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2682
2683 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2684 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2685 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2686
2687 " There should be one byte less with noeol
2688 set bin noeol
2689 let a = execute(":norm! \<Esc>gog\<c-g>")
2690 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2691 set bin & eol&
2692
Bram Moolenaar30276f22019-01-24 17:59:39 +01002693 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002694
Bram Moolenaar30276f22019-01-24 17:59:39 +01002695 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2696 call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002697
Bram Moolenaar30276f22019-01-24 17:59:39 +01002698 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2699 call assert_equal("\nSelected 1 of 2 Lines; 1 of 2 Words; 2 of 13 Chars; 6 of 20 Bytes", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002700
Bram Moolenaar30276f22019-01-24 17:59:39 +01002701 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2702 call assert_equal("\nSelected 4 Cols; 2 of 2 Lines; 2 of 2 Words; 6 of 13 Chars; 11 of 20 Bytes", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002703
Bram Moolenaar30276f22019-01-24 17:59:39 +01002704 set fenc=utf8 bomb
2705 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2706 call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+3 for BOM)", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002707
Bram Moolenaar30276f22019-01-24 17:59:39 +01002708 set fenc=utf16 bomb
2709 let a = execute(":norm! g\<c-g>")
2710 call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+2 for BOM)", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002711
Bram Moolenaar30276f22019-01-24 17:59:39 +01002712 set fenc=utf32 bomb
2713 let a = execute(":norm! g\<c-g>")
2714 call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+4 for BOM)", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002715
Bram Moolenaar30276f22019-01-24 17:59:39 +01002716 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002717
2718 set ff&
2719 bwipe!
2720endfunc
2721
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002722" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002723func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002724 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002725 let a=execute(':norm! 1G0g8')
2726 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002727
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002728 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2729 let a=execute(':norm! 1G$g8')
2730 call assert_equal("\nc3 b6 ", a)
2731
2732 call setline(1, "a\u0302")
2733 let a=execute(':norm! 1G0g8')
2734 call assert_equal("\n61 + cc 82 ", a)
2735
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002736 " clean up
2737 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002738endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002739
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002740" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002741func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002742 new
2743
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002744 " With invalid byte.
2745 call setline(1, "___\xff___")
2746 norm! 1G08g8g
2747 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2748
2749 " With invalid byte before the cursor.
2750 call setline(1, "___\xff___")
2751 norm! 1G$h8g8g
2752 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2753
2754 " With truncated sequence.
2755 call setline(1, "___\xE2\x82___")
2756 norm! 1G08g8g
2757 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2758
2759 " With overlong sequence.
2760 call setline(1, "___\xF0\x82\x82\xAC___")
2761 norm! 1G08g8g
2762 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2763
2764 " With valid utf8.
2765 call setline(1, "café")
2766 norm! 1G08g8
2767 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2768
2769 bw!
2770endfunc
2771
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002772" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002773func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002774 " Cannot capture its output,
2775 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002776 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002777 echo "a\nb\nc\nd"
2778 let b=execute(':norm! g<')
2779 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002780endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002781
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002782" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002783func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002784 new
2785 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002786 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002787 " Test for gp gP
2788 call append(1, range(1,10))
2789 1
2790 norm! 1yy
2791 3
2792 norm! gp
2793 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2794 $
2795 norm! gP
2796 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2797
2798 " Test for go
2799 norm! 26go
2800 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2801 norm! 27go
2802 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2803 norm! 28go
2804 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2805 set ff=dos
2806 norm! 29go
2807 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2808 set ff=unix
2809 norm! gg0
2810 norm! 101go
2811 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2812 norm! 103go
2813 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2814 " count > buffer content
2815 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002816 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002817 " clean up
2818 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002819endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002820
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002821" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002822func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002823 tabnew 1.txt
2824 tabnew 2.txt
2825 tabnew 3.txt
2826 norm! 1gt
2827 call assert_equal(1, tabpagenr())
2828 norm! 3gt
2829 call assert_equal(3, tabpagenr())
2830 norm! 1gT
2831 " count gT goes not to the absolute tabpagenumber
2832 " but, but goes to the count previous tabpagenumber
2833 call assert_equal(2, tabpagenr())
2834 " wrap around
2835 norm! 3gT
2836 call assert_equal(3, tabpagenr())
2837 " gt does not wrap around
2838 norm! 5gt
2839 call assert_equal(3, tabpagenr())
2840
2841 for i in range(3)
2842 tabclose
2843 endfor
2844 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002845 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002846endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002847
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002848" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002849func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002850 new
2851 call setline(1, range(10))
2852 $
2853 setl et sw=2
2854 norm! V10>$
2855 " count is ignored
2856 exe "norm! 10\<home>"
2857 call assert_equal(1, col('.'))
2858 exe "norm! \<home>"
2859 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2860 exe "norm! 5\<c-home>"
2861 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2862 exe "norm! \<c-home>"
2863 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002864 exe "norm! G\<c-kHome>"
2865 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002866
2867 " clean up
2868 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002869endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002870
Bram Moolenaar1671f442020-03-10 07:48:13 +01002871" Test for <End> and <C-End> keys
2872func Test_normal_nvend()
2873 new
2874 call setline(1, map(range(1, 10), '"line" .. v:val'))
2875 exe "normal! \<End>"
2876 call assert_equal(5, col('.'))
2877 exe "normal! 4\<End>"
2878 call assert_equal([4, 5], [line('.'), col('.')])
2879 exe "normal! \<C-End>"
2880 call assert_equal([10, 6], [line('.'), col('.')])
2881 close!
2882endfunc
2883
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002884" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002885func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002886 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002887 new
2888 set tw=0
2889 call append(0, 'here are some words')
2890 norm! 1gg0elcwZZZ
2891 call assert_equal('hereZZZare some words', getline('.'))
2892 norm! 1gg0elcWYYY
2893 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002894 norm! 2gg0cwfoo
2895 call assert_equal('foo', getline('.'))
2896
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002897 call setline(1, 'one; two')
2898 call cursor(1, 1)
2899 call feedkeys('cwvim', 'xt')
2900 call assert_equal('vim; two', getline(1))
2901 call feedkeys('0cWone', 'xt')
2902 call assert_equal('one two', getline(1))
2903 "When cursor is at the end of a word 'ce' will change until the end of the
2904 "next word, but 'cw' will change only one character
2905 call setline(1, 'one two')
2906 call feedkeys('0ecwce', 'xt')
2907 call assert_equal('once two', getline(1))
2908 call setline(1, 'one two')
2909 call feedkeys('0ecely', 'xt')
2910 call assert_equal('only', getline(1))
2911
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002912 " clean up
2913 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002914endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002915
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002916" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002917func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002918 new
2919 call append(0, 'here are some words')
2920 exe "norm! 1gg0a\<C-\>\<C-N>"
2921 call assert_equal('n', mode())
2922 call assert_equal(1, col('.'))
2923 call assert_equal('', visualmode())
2924 exe "norm! 1gg0viw\<C-\>\<C-N>"
2925 call assert_equal('n', mode())
2926 call assert_equal(4, col('.'))
2927 exe "norm! 1gg0a\<C-\>\<C-G>"
2928 call assert_equal('n', mode())
2929 call assert_equal(1, col('.'))
2930 "imap <buffer> , <c-\><c-n>
2931 set im
2932 exe ":norm! \<c-\>\<c-n>dw"
2933 set noim
2934 call assert_equal('are some words', getline(1))
2935 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02002936 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01002937
Bram Moolenaar21829c52021-01-26 22:42:21 +01002938 if has('cmdwin')
2939 " Using CTRL-\ CTRL-N in cmd window should close the window
2940 call feedkeys("q:\<C-\>\<C-N>", 'xt')
2941 call assert_equal('', getcmdwintype())
2942 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002943
2944 " clean up
2945 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002946endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002947
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002948" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01002949func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002950 new
2951 set sts=2 sw=2 ts=8 tw=0
2952 call append(0, ["aaa\tbbb\tccc", '', '', ''])
2953 let a=getline(1)
2954 norm! 2gg0
2955 exe "norm! a\<c-r>=a\<cr>"
2956 norm! 3gg0
2957 exe "norm! a\<c-r>\<c-r>=a\<cr>"
2958 norm! 4gg0
2959 exe "norm! a\<c-r>\<c-o>=a\<cr>"
2960 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
2961
2962 " clean up
2963 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02002964 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002965endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002966
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002967" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002968func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002969 call Setup_NewWindow()
2970 call assert_equal(5, &scroll)
2971 exe "norm! \<c-d>"
2972 call assert_equal('6', getline('.'))
2973 exe "norm! 2\<c-d>"
2974 call assert_equal('8', getline('.'))
2975 call assert_equal(2, &scroll)
2976 set scroll=5
2977 exe "norm! \<c-u>"
2978 call assert_equal('3', getline('.'))
2979 1
2980 set scrolloff=5
2981 exe "norm! \<c-d>"
2982 call assert_equal('10', getline('.'))
2983 exe "norm! \<c-u>"
2984 call assert_equal('5', getline('.'))
2985 1
2986 set scrolloff=99
2987 exe "norm! \<c-d>"
2988 call assert_equal('10', getline('.'))
2989 set scrolloff=0
2990 100
2991 exe "norm! $\<c-u>"
2992 call assert_equal('95', getline('.'))
2993 call assert_equal([0, 95, 1, 0, 1], getcurpos())
2994 100
2995 set nostartofline
2996 exe "norm! $\<c-u>"
2997 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00002998 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002999 " cleanup
3000 set startofline
3001 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003002endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003003
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003004func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003005 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003006 " The ~ register does not exist
3007 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003008 return
3009 endif
3010
3011 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003012 " unfortunately, without a gui, we can't really test much here,
3013 " so simply test that ~p fails (which uses the drop register)
3014 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003015 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003016 call assert_equal([], getreg('~', 1, 1))
3017 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003018 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003019 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003020endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003021
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003022func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003023 new
3024 " How to test this?
3025 " let's just for now test, that the buffer
3026 " does not change
3027 call feedkeys("\<c-s>", 't')
3028 call assert_equal([''], getline(1,'$'))
3029
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003030 " no valid commands
3031 exe "norm! \<char-0x100>"
3032 call assert_equal([''], getline(1,'$'))
3033
3034 exe "norm! ä"
3035 call assert_equal([''], getline(1,'$'))
3036
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003037 " clean up
3038 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003039endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003040
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003041func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003042 " This was causing a crash or ml_get error.
3043 enew!
3044 call setline(1,'xxx')
3045 normal $
3046 new
3047 call setline(1, range(1,2))
3048 2
3049 exe "norm \<C-V>$"
3050 bw!
3051 norm yp
3052 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003053endfunc
3054
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003055func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003056 new
3057 exe "norm! \<c-w>c"
3058 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003059 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003060endfunc
3061
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003062func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003063 new
3064 call setline(1, 'one two three four five six seven eight nine ten')
3065 1
3066 norm! 3d2w
3067 call assert_equal('seven eight nine ten', getline(1))
3068 bw!
3069endfunc
3070
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003071func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003072 CheckFeature timers
3073 CheckFeature cmdline_hist
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003074 func! DoTimerWork(id)
3075 call assert_equal('[Command Line]', bufname(''))
3076 " should fail, with E11, but does fail with E23?
3077 "call feedkeys("\<c-^>", 'tm')
3078
3079 " should also fail with E11
Bram Moolenaare2e40752020-09-04 21:18:46 +02003080 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003081 " return from commandline window
3082 call feedkeys("\<cr>")
3083 endfunc
3084
3085 let oldlang=v:lang
3086 lang C
3087 set updatetime=20
3088 call timer_start(100, 'DoTimerWork')
3089 try
3090 " throws E23, for whatever reason...
3091 call feedkeys('q:', 'x!')
3092 catch /E23/
3093 " no-op
3094 endtry
3095 " clean up
3096 set updatetime=4000
3097 exe "lang" oldlang
3098 bw!
3099endfunc
3100
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003101func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003102 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003103 " Don't sleep after the warning message.
3104 call test_settime(1)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003105 call writefile(['foo'], 'Xreadonly.log')
3106 new Xreadonly.log
3107 setl ro
3108 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003109 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003110 call assert_equal(['foo'], getline(1,'$'))
3111 call assert_equal('Xreadonly.log', bufname(''))
3112
3113 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003114 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003115 bw!
3116 call delete("Xreadonly.log")
3117endfunc
3118
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003119func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003120 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003121 new
3122 call setline(1, 'abcde fghij klmnopq')
3123 norm! 1gg$
3124 set rl
3125 call assert_equal(19, col('.'))
3126 call feedkeys('l', 'tx')
3127 call assert_equal(18, col('.'))
3128 call feedkeys('h', 'tx')
3129 call assert_equal(19, col('.'))
3130 call feedkeys("\<right>", 'tx')
3131 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003132 call feedkeys("\<left>", 'tx')
3133 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003134 call feedkeys("\<s-right>", 'tx')
3135 call assert_equal(13, col('.'))
3136 call feedkeys("\<c-right>", 'tx')
3137 call assert_equal(7, col('.'))
3138 call feedkeys("\<c-left>", 'tx')
3139 call assert_equal(13, col('.'))
3140 call feedkeys("\<s-left>", 'tx')
3141 call assert_equal(19, col('.'))
3142 call feedkeys("<<", 'tx')
3143 call assert_equal(' abcde fghij klmnopq',getline(1))
3144 call feedkeys(">>", 'tx')
3145 call assert_equal('abcde fghij klmnopq',getline(1))
3146
3147 " cleanup
3148 set norl
3149 bw!
3150endfunc
3151
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003152func Test_normal54_Ctrl_bsl()
3153 new
3154 call setline(1, 'abcdefghijklmn')
3155 exe "norm! df\<c-\>\<c-n>"
3156 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3157 exe "norm! df\<c-\>\<c-g>"
3158 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3159 exe "norm! df\<c-\>m"
3160 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003161
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003162 call setline(2, 'abcdefghijklmnāf')
3163 norm! 2gg0
3164 exe "norm! df\<Char-0x101>"
3165 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3166 norm! 1gg0
3167 exe "norm! df\<esc>"
3168 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003169
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003170 " clean up
3171 bw!
3172endfunc
3173
3174func Test_normal_large_count()
3175 " This may fail with 32bit long, how do we detect that?
3176 new
3177 normal o
3178 normal 6666666666dL
3179 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003180endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003181
3182func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003183 new
3184 normal grádv}
3185 call assert_equal('á', getline(1))
3186 normal grád}
3187 call assert_equal('', getline(1))
3188 bwipe!
3189endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003190
3191" Test for the gr (virtual replace) command
3192" Test for the bug fixed by 7.4.387
3193func Test_gr_command()
3194 enew!
3195 let save_cpo = &cpo
3196 call append(0, ['First line', 'Second line', 'Third line'])
3197 exe "normal i\<C-G>u"
3198 call cursor(2, 1)
3199 set cpo-=X
3200 normal 4gro
3201 call assert_equal('oooond line', getline(2))
3202 undo
3203 set cpo+=X
3204 normal 4gro
3205 call assert_equal('ooooecond line', getline(2))
3206 let &cpo = save_cpo
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003207 normal! ggvegrx
3208 call assert_equal('xxxxx line', getline(1))
3209 exe "normal! gggr\<C-V>122"
3210 call assert_equal('zxxxx line', getline(1))
3211 set virtualedit=all
3212 normal! 15|grl
3213 call assert_equal('zxxxx line l', getline(1))
3214 set virtualedit&
3215 set nomodifiable
3216 call assert_fails('normal! grx', 'E21:')
3217 call assert_fails('normal! gRx', 'E21:')
3218 set modifiable&
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003219 enew!
3220endfunc
3221
3222" When splitting a window the changelist position is wrong.
3223" Test the changelist position after splitting a window.
3224" Test for the bug fixed by 7.4.386
3225func Test_changelist()
3226 let save_ul = &ul
3227 enew!
3228 call append('$', ['1', '2'])
3229 exe "normal i\<C-G>u"
3230 exe "normal Gkylpa\<C-G>u"
3231 set ul=100
3232 exe "normal Gylpa\<C-G>u"
3233 set ul=100
3234 normal gg
3235 vsplit
3236 normal g;
3237 call assert_equal([3, 2], [line('.'), col('.')])
3238 normal g;
3239 call assert_equal([2, 2], [line('.'), col('.')])
3240 call assert_fails('normal g;', 'E662:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003241 new
3242 call assert_fails('normal g;', 'E664:')
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003243 %bwipe!
3244 let &ul = save_ul
3245endfunc
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003246
3247func Test_nv_hat_count()
3248 %bwipeout!
3249 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003250 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003251
3252 edit Xfoo
3253 let l:foo_nr = bufnr('Xfoo')
3254
3255 edit Xbar
3256 let l:bar_nr = bufnr('Xbar')
3257
3258 " Make sure we are not just using the alternate file.
3259 edit Xbaz
3260
3261 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3262 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3263
3264 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3265 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3266
3267 %bwipeout!
3268endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003269
3270func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003271 " Make sure no buffers are changed.
3272 %bwipe!
3273
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003274 exe "normal \<C-C>"
3275 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003276
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003277 new
3278 cal setline(1, 'hi!')
3279 exe "normal \<C-C>"
3280 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003281
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003282 bwipe!
3283endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003284
3285" Test for '[m', ']m', '[M' and ']M'
3286" Jumping to beginning and end of methods in Java-like languages
3287func Test_java_motion()
3288 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003289 call assert_beeps('normal! [m')
3290 call assert_beeps('normal! ]m')
3291 call assert_beeps('normal! [M')
3292 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003293 let lines =<< trim [CODE]
3294 Piece of Java
3295 {
3296 tt m1 {
3297 t1;
3298 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003299
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003300 tt m2 {
3301 t2;
3302 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003303
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003304 tt m3 {
3305 if (x)
3306 {
3307 t3;
3308 }
3309 } e3
3310 }
3311 [CODE]
3312 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003313
3314 normal gg
3315
3316 normal 2]maA
3317 call assert_equal("\ttt m1 {A", getline('.'))
3318 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3319
3320 normal j]maB
3321 call assert_equal("\ttt m2 {B", getline('.'))
3322 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3323
3324 normal ]maC
3325 call assert_equal("\ttt m3 {C", getline('.'))
3326 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3327
3328 normal [maD
3329 call assert_equal("\ttt m3 {DC", getline('.'))
3330 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3331
3332 normal k2[maE
3333 call assert_equal("\ttt m1 {EA", getline('.'))
3334 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3335
3336 normal 3[maF
3337 call assert_equal("{F", getline('.'))
3338 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3339
3340 normal ]MaG
3341 call assert_equal("\t}G e1", getline('.'))
3342 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3343
3344 normal j2]MaH
3345 call assert_equal("\t}H e3", getline('.'))
3346 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3347
3348 normal ]M]M
3349 normal aI
3350 call assert_equal("}I", getline('.'))
3351 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3352
3353 normal 2[MaJ
3354 call assert_equal("\t}JH e3", getline('.'))
3355 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3356
3357 normal k[MaK
3358 call assert_equal("\t}K e2", getline('.'))
3359 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3360
3361 normal 3[MaL
3362 call assert_equal("{LF", getline('.'))
3363 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3364
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003365 call cursor(2, 1)
3366 call assert_beeps('norm! 5]m')
3367
3368 " jumping to a method in a fold should open the fold
3369 6,10fold
3370 call feedkeys("gg3]m", 'xt')
3371 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3372 call assert_equal(-1, foldclosedend(7))
3373
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003374 close!
3375endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003376
Bram Moolenaar004a6782020-04-11 17:09:31 +02003377" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003378func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003379 call Setup_NewWindow()
3380 " Make long lines that will wrap
3381 %s/$/\=repeat(' foobar', 10)/
3382 20vsp
3383 set wrap
3384 " Test for g$ with count
3385 norm! gg
3386 norm! 0vg$y
3387 call assert_equal(20, col("'>"))
3388 call assert_equal('1 foobar foobar foob', getreg(0))
3389 norm! gg
3390 norm! 0v4g$y
3391 call assert_equal(72, col("'>"))
3392 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3393 norm! gg
3394 norm! 0v6g$y
3395 call assert_equal(40, col("'>"))
3396 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3397 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3398 set nowrap
3399 " clean up
3400 norm! gg
3401 norm! 0vg$y
3402 call assert_equal(20, col("'>"))
3403 call assert_equal('1 foobar foobar foob', getreg(0))
3404 norm! gg
3405 norm! 0v4g$y
3406 call assert_equal(20, col("'>"))
3407 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3408 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3409 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3410 \ '4 foobar foobar foob', getreg(0))
3411 norm! gg
3412 norm! 0v6g$y
3413 call assert_equal(20, col("'>"))
3414 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3415 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3416 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3417 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3418 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3419 \ '6 foobar foobar foob', getreg(0))
3420 " Move to last line, also down movement is not possible, should still move
3421 " the cursor to the last visible char
3422 norm! G
3423 norm! 0v6g$y
3424 call assert_equal(20, col("'>"))
3425 call assert_equal('100 foobar foobar fo', getreg(0))
3426 bw!
3427endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003428
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003429func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003430 " needs 80 column new window
3431 new
3432 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003433 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003434 put =[repeat('x',90)..' {{{1', 'x {{{1']
3435 norm! gk
3436 " In a 80 column wide terminal the window will be only 78 char
3437 " (because Vim will leave space for the other window),
3438 " but if the terminal is larger, it will be 80 chars, so verify the
3439 " cursor column correctly.
3440 call assert_equal(winwidth(0)+1, col('.'))
3441 call assert_equal(winwidth(0)+1, virtcol('.'))
3442 norm! j
3443 call assert_equal(6, col('.'))
3444 call assert_equal(6, virtcol('.'))
3445 norm! gk
3446 call assert_equal(95, col('.'))
3447 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003448 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003449
3450 " needs 80 column new window
3451 new
3452 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003453 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003454 set number
3455 set numberwidth=10
3456 set cpoptions+=n
3457 put =[repeat('0',90), repeat('1',90)]
3458 norm! 075l
3459 call assert_equal(76, col('.'))
3460 norm! gk
3461 call assert_equal(1, col('.'))
3462 norm! gk
3463 call assert_equal(76, col('.'))
3464 norm! gk
3465 call assert_equal(1, col('.'))
3466 norm! gj
3467 call assert_equal(76, col('.'))
3468 norm! gj
3469 call assert_equal(1, col('.'))
3470 norm! gj
3471 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003472 " When 'nowrap' is set, gk and gj behave like k and j
3473 set nowrap
3474 normal! gk
3475 call assert_equal([2, 76], [line('.'), col('.')])
3476 normal! gj
3477 call assert_equal([3, 76], [line('.'), col('.')])
3478 %bw!
3479 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003480endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003481
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003482" Test for using : to run a multi-line Ex command in operator pending mode
3483func Test_normal_yank_with_excmd()
3484 new
3485 call setline(1, ['foo', 'bar', 'baz'])
3486 let @a = ''
3487 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3488 call assert_equal('f', @a)
3489 close!
3490endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003491
3492" Test for supplying a count to a normal-mode command across a cursorhold call
3493func Test_normal_cursorhold_with_count()
3494 func s:cHold()
3495 let g:cHold_Called += 1
3496 endfunc
3497 new
3498 augroup normalcHoldTest
3499 au!
3500 au CursorHold <buffer> call s:cHold()
3501 augroup END
3502 let g:cHold_Called = 0
3503 call feedkeys("3\<CursorHold>2ix", 'xt')
3504 call assert_equal(1, g:cHold_Called)
3505 call assert_equal(repeat('x', 32), getline(1))
3506 augroup normalcHoldTest
3507 au!
3508 augroup END
3509 au! normalcHoldTest
3510 close!
3511 delfunc s:cHold
3512endfunc
3513
3514" Test for using a count and a command with CTRL-W
3515func Test_wincmd_with_count()
3516 call feedkeys("\<C-W>12n", 'xt')
3517 call assert_equal(12, winheight(0))
3518endfunc
3519
3520" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003521func Test_horiz_motion()
3522 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003523 normal! gg
3524 call assert_beeps('normal! b')
3525 call assert_beeps('normal! B')
3526 call assert_beeps('normal! gE')
3527 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003528 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3529 call setline(1, 'one ,two ,three')
3530 exe "normal! $\<S-BS>"
3531 call assert_equal(11, col('.'))
3532 exe "normal! $\<C-BS>"
3533 call assert_equal(10, col('.'))
3534 close!
3535endfunc
3536
3537" Test for using a : command in operator pending mode
3538func Test_normal_colon_op()
3539 new
3540 call setline(1, ['one', 'two'])
3541 call assert_beeps("normal! Gc:d\<CR>")
3542 close!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003543endfunc
3544
Bram Moolenaar004a6782020-04-11 17:09:31 +02003545" Test for d and D commands
3546func Test_normal_delete_cmd()
3547 new
3548 " D in an empty line
3549 call setline(1, '')
3550 normal D
3551 call assert_equal('', getline(1))
3552 " D in an empty line in virtualedit mode
3553 set virtualedit=all
3554 normal D
3555 call assert_equal('', getline(1))
3556 set virtualedit&
3557 " delete to a readonly register
3558 call setline(1, ['abcd'])
3559 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003560
3561 " D and d with 'nomodifiable'
3562 call setline(1, ['abcd'])
3563 setlocal nomodifiable
3564 call assert_fails('normal D', 'E21:')
3565 call assert_fails('normal d$', 'E21:')
3566
Bram Moolenaar004a6782020-04-11 17:09:31 +02003567 close!
3568endfunc
3569
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003570" Test for deleting or changing characters across lines with 'whichwrap'
3571" containing 's'. Should count <EOL> as one character.
3572func Test_normal_op_across_lines()
3573 new
3574 set whichwrap&
3575 call setline(1, ['one two', 'three four'])
3576 exe "norm! $3d\<Space>"
3577 call assert_equal(['one twhree four'], getline(1, '$'))
3578
3579 call setline(1, ['one two', 'three four'])
3580 exe "norm! $3c\<Space>x"
3581 call assert_equal(['one twxhree four'], getline(1, '$'))
3582
3583 set whichwrap+=l
3584 call setline(1, ['one two', 'three four'])
3585 exe "norm! $3x"
3586 call assert_equal(['one twhree four'], getline(1, '$'))
3587 close!
3588 set whichwrap&
3589endfunc
3590
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003591" Test for 'w' and 'b' commands
3592func Test_normal_word_move()
3593 new
3594 call setline(1, ['foo bar a', '', 'foo bar b'])
3595 " copy a single character word at the end of a line
3596 normal 1G$yw
3597 call assert_equal('a', @")
3598 " copy a single character word at the end of a file
3599 normal G$yw
3600 call assert_equal('b', @")
3601 " check for a word movement handling an empty line properly
3602 normal 1G$vwy
3603 call assert_equal("a\n\n", @")
3604
3605 " copy using 'b' command
3606 %d
3607 " non-empty blank line at the start of file
3608 call setline(1, [' ', 'foo bar'])
3609 normal 2Gyb
3610 call assert_equal(" \n", @")
3611 " try to copy backwards from the start of the file
3612 call setline(1, ['one two', 'foo bar'])
3613 call assert_beeps('normal ggyb')
3614 " 'b' command should stop at an empty line
3615 call setline(1, ['one two', '', 'foo bar'])
3616 normal 3Gyb
3617 call assert_equal("\n", @")
3618 normal 3Gy2b
3619 call assert_equal("two\n", @")
3620 " 'b' command should not stop at a non-empty blank line
3621 call setline(1, ['one two', ' ', 'foo bar'])
3622 normal 3Gyb
3623 call assert_equal("two\n ", @")
3624
3625 close!
3626endfunc
3627
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003628" Test for 'scrolloff' with a long line that doesn't fit in the screen
3629func Test_normal_scroloff()
3630 10new
3631 80vnew
3632 call setline(1, repeat('a', 1000))
3633 set scrolloff=10
3634 normal gg10gj
3635 call assert_equal(8, winline())
3636 normal 10gj
3637 call assert_equal(10, winline())
3638 normal 10gk
3639 call assert_equal(3, winline())
3640 set scrolloff&
3641 close!
3642endfunc
3643
3644" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3645func Test_normal_vert_scroll_longline()
3646 10new
3647 80vnew
3648 call setline(1, range(1, 10))
3649 call append(5, repeat('a', 1000))
3650 exe "normal gg\<C-F>"
3651 call assert_equal(6, line('.'))
3652 exe "normal \<C-F>\<C-F>"
3653 call assert_equal(11, line('.'))
3654 call assert_equal(1, winline())
3655 exe "normal \<C-B>"
3656 call assert_equal(10, line('.'))
3657 call assert_equal(3, winline())
3658 exe "normal \<C-B>\<C-B>"
3659 call assert_equal(5, line('.'))
3660 call assert_equal(5, winline())
3661 close!
3662endfunc
3663
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003664" Test for jumping in a file using %
3665func Test_normal_percent_jump()
3666 new
3667 call setline(1, range(1, 100))
3668
3669 " jumping to a folded line should open the fold
3670 25,75fold
3671 call feedkeys('50%', 'xt')
3672 call assert_equal(50, line('.'))
3673 call assert_equal(-1, foldclosedend(50))
3674 close!
3675endfunc
3676
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003677" Test for << and >> commands to shift text by 'shiftwidth'
3678func Test_normal_shift_rightleft()
3679 new
3680 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3681 set shiftwidth=2 tabstop=8
3682 normal gg6>>
3683 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3684 \ getline(1, '$'))
3685 normal ggVG2>>
3686 call assert_equal([' one', '', "\t ", "\ttwo",
3687 \ "\t three", "\t four"], getline(1, '$'))
3688 normal gg6<<
3689 call assert_equal([' one', '', "\t ", ' two', "\t three",
3690 \ "\t four"], getline(1, '$'))
3691 normal ggVG2<<
3692 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3693 \ getline(1, '$'))
3694 set shiftwidth& tabstop&
3695 bw!
3696endfunc
3697
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003698" Some commands like yy, cc, dd, >>, << and !! accept a count after
3699" typing the first letter of the command.
3700func Test_normal_count_after_operator()
3701 new
3702 setlocal shiftwidth=4 tabstop=8 autoindent
3703 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3704 let @a = ''
3705 normal! j"ay4y
3706 call assert_equal("two\nthree\nfour\nfive\n", @a)
3707 normal! 3G>2>
3708 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3709 \ getline(1, '$'))
3710 exe "normal! 3G0c2cred\nblue"
3711 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3712 \ getline(1, '$'))
3713 exe "normal! gg<8<"
3714 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3715 \ getline(1, '$'))
3716 exe "normal! ggd3d"
3717 call assert_equal(['blue', 'five'], getline(1, '$'))
3718 call setline(1, range(1, 4))
3719 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3720 call assert_equal('".,.+2!', @:)
3721 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3722 call assert_equal('".!', @:)
3723 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3724 call assert_equal('".,$!', @:)
3725 bw!
3726endfunc
3727
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003728func Test_normal_gj_on_extra_wide_char()
3729 new | 25vsp
3730 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3731 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3732 \ ' dreizehn v ierzehn fünfzehn'
3733 put =text
3734 call cursor(2,1)
3735 norm! gj
3736 call assert_equal([0,2,25,0], getpos('.'))
3737 bw!
3738endfunc
3739
Bram Moolenaar03725c52021-11-24 12:17:53 +00003740func Test_normal_count_out_of_range()
3741 new
3742 call setline(1, 'text')
3743 normal 44444444444|
3744 call assert_equal(999999999, v:count)
3745 normal 444444444444|
3746 call assert_equal(999999999, v:count)
3747 normal 4444444444444|
3748 call assert_equal(999999999, v:count)
3749 normal 4444444444444444444|
3750 call assert_equal(999999999, v:count)
3751
3752 normal 9y99999999|
3753 call assert_equal(899999991, v:count)
3754 normal 10y99999999|
3755 call assert_equal(999999999, v:count)
3756 normal 44444444444y44444444444|
3757 call assert_equal(999999999, v:count)
3758 bwipe!
3759endfunc
3760
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003761" vim: shiftwidth=2 sts=2 expandtab