blob: e17aca4128d733e346ec5ec1f026008185a2ab24 [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 Moolenaara84a3dd2019-03-25 22:21:24 +01006
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01007func Setup_NewWindow()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02008 10new
9 call setline(1, range(1,100))
10endfunc
11
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010012func MyFormatExpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020013 " Adds '->$' at lines having numbers followed by trailing whitespace
14 for ln in range(v:lnum, v:lnum+v:count-1)
15 let line = getline(ln)
16 if getline(ln) =~# '\d\s\+$'
17 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
18 endif
19 endfor
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020020endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020021
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010022func CountSpaces(type, ...)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020023 " for testing operatorfunc
24 " will count the number of spaces
25 " and return the result in g:a
26 let sel_save = &selection
27 let &selection = "inclusive"
28 let reg_save = @@
29
30 if a:0 " Invoked from Visual mode, use gv command.
31 silent exe "normal! gvy"
32 elseif a:type == 'line'
33 silent exe "normal! '[V']y"
34 else
35 silent exe "normal! `[v`]y"
36 endif
Bram Moolenaar777e7c22021-10-25 17:07:04 +010037 let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020038 let &selection = sel_save
39 let @@ = reg_save
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020040endfunc
41
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010042func OpfuncDummy(type, ...)
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010043 " for testing operatorfunc
Bram Moolenaar777e7c22021-10-25 17:07:04 +010044 let g:opt = &linebreak
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010045
46 if a:0 " Invoked from Visual mode, use gv command.
47 silent exe "normal! gvy"
48 elseif a:type == 'line'
49 silent exe "normal! '[V']y"
50 else
51 silent exe "normal! `[v`]y"
52 endif
53 " Create a new dummy window
54 new
Bram Moolenaar777e7c22021-10-25 17:07:04 +010055 let g:bufnr = bufnr('%')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020056endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020057
Bram Moolenaar1671f442020-03-10 07:48:13 +010058func Test_normal00_optrans()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020059 new
60 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
61 1
62 exe "norm! Sfoobar\<esc>"
63 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
64 2
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020065 exe "norm! $vbsone"
66 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 +020067 norm! VS Second line here
68 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
69 %d
70 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
71 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
72
73 1
74 norm! 2D
75 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,'$'))
76 set cpo+=#
77 norm! 4D
78 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
79
80 " clean up
81 set cpo-=#
82 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020083endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020084
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010085func Test_normal01_keymodel()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020086 call Setup_NewWindow()
87 " Test 1: depending on 'keymodel' <s-down> does something different
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020088 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020089 call feedkeys("V\<S-Up>y", 'tx')
90 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020091 set keymodel=startsel
92 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020093 call feedkeys("V\<S-Up>y", 'tx')
94 call assert_equal(['49', '50'], getline("'<", "'>"))
95 " Start visual mode when keymodel = startsel
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020096 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020097 call feedkeys("\<S-Up>y", 'tx')
98 call assert_equal(['49', '5'], getreg(0, 0, 1))
Bram Moolenaar1671f442020-03-10 07:48:13 +010099 " Use the different Shift special keys
100 50
101 call feedkeys("\<S-Right>\<S-Left>\<S-Up>\<S-Down>\<S-Home>\<S-End>y", 'tx')
102 call assert_equal(['50'], getline("'<", "'>"))
103 call assert_equal(['50', ''], getreg(0, 0, 1))
104
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200105 " Do not start visual mode when keymodel=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200106 set keymodel=
107 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200108 call feedkeys("\<S-Up>y$", 'tx')
109 call assert_equal(['42'], getreg(0, 0, 1))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200110 " Stop visual mode when keymodel=stopsel
111 set keymodel=stopsel
112 50
113 call feedkeys("Vkk\<Up>yy", 'tx')
114 call assert_equal(['47'], getreg(0, 0, 1))
115
116 set keymodel=
117 50
118 call feedkeys("Vkk\<Up>yy", 'tx')
119 call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200120
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200121 " Test for using special keys to start visual selection
122 %d
123 call setline(1, ['red fox tail', 'red fox tail', 'red fox tail'])
124 set keymodel=startsel
125 " Test for <S-PageUp> and <S-PageDown>
126 call cursor(1, 1)
127 call feedkeys("\<S-PageDown>y", 'xt')
128 call assert_equal([0, 1, 1, 0], getpos("'<"))
129 call assert_equal([0, 3, 1, 0], getpos("'>"))
130 call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
131 call assert_equal([0, 2, 1, 0], getpos("'<"))
132 call assert_equal([0, 3, 8, 0], getpos("'>"))
133 " Test for <S-C-Home> and <S-C-End>
134 call cursor(2, 12)
135 call feedkeys("\<S-C-Home>y", 'xt')
136 call assert_equal([0, 1, 1, 0], getpos("'<"))
137 call assert_equal([0, 2, 12, 0], getpos("'>"))
138 call cursor(1, 4)
139 call feedkeys("\<S-C-End>y", 'xt')
140 call assert_equal([0, 1, 4, 0], getpos("'<"))
141 call assert_equal([0, 3, 13, 0], getpos("'>"))
142 " Test for <S-C-Left> and <S-C-Right>
143 call cursor(2, 5)
144 call feedkeys("\<S-C-Right>y", 'xt')
145 call assert_equal([0, 2, 5, 0], getpos("'<"))
146 call assert_equal([0, 2, 9, 0], getpos("'>"))
147 call cursor(2, 9)
148 call feedkeys("\<S-C-Left>y", 'xt')
149 call assert_equal([0, 2, 5, 0], getpos("'<"))
150 call assert_equal([0, 2, 9, 0], getpos("'>"))
151
152 set keymodel&
153
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200154 " clean up
155 bw!
156endfunc
157
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100158func Test_normal03_join()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200159 " basic join test
160 call Setup_NewWindow()
161 50
162 norm! VJ
163 call assert_equal('50 51', getline('.'))
164 $
165 norm! J
166 call assert_equal('100', getline('.'))
167 $
168 norm! V9-gJ
169 call assert_equal('919293949596979899100', getline('.'))
170 call setline(1, range(1,100))
171 $
172 :j 10
173 call assert_equal('100', getline('.'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200174 call assert_beeps('normal GVJ')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200175 " clean up
176 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200177endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200178
Bram Moolenaar004a6782020-04-11 17:09:31 +0200179" basic filter test
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100180func Test_normal04_filter()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200181 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200182 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200183 call Setup_NewWindow()
184 1
185 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
186 call assert_equal('| 1', getline('.'))
187 90
188 :sil :!echo one
189 call feedkeys('.', 'tx')
190 call assert_equal('| 90', getline('.'))
191 95
192 set cpo+=!
193 " 2 <CR>, 1: for executing the command,
194 " 2: clear hit-enter-prompt
195 call feedkeys("!!\n", 'tx')
196 call feedkeys(":!echo one\n\n", 'tx')
197 call feedkeys(".", 'tx')
198 call assert_equal('one', getline('.'))
199 set cpo-=!
200 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200201endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200202
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100203func Test_normal05_formatexpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200204 " basic formatexpr test
205 call Setup_NewWindow()
206 %d_
207 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
208 1
209 set formatexpr=MyFormatExpr()
210 norm! gqG
211 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
212 set formatexpr=
213 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200214endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200215
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200216func Test_normal05_formatexpr_newbuf()
217 " Edit another buffer in the 'formatexpr' function
218 new
219 func! Format()
220 edit another
221 endfunc
222 set formatexpr=Format()
223 norm gqG
224 bw!
225 set formatexpr=
226endfunc
227
228func Test_normal05_formatexpr_setopt()
229 " Change the 'formatexpr' value in the function
230 new
231 func! Format()
232 set formatexpr=
233 endfunc
234 set formatexpr=Format()
235 norm gqG
236 bw!
237 set formatexpr=
238endfunc
239
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200240" When 'formatexpr' returns non-zero, internal formatting is used.
241func Test_normal_formatexpr_returns_nonzero()
242 new
243 call setline(1, ['one', 'two'])
244 func! Format()
245 return 1
246 endfunc
247 setlocal formatexpr=Format()
248 normal VGgq
249 call assert_equal(['one two'], getline(1, '$'))
250 setlocal formatexpr=
251 delfunc Format
252 close!
253endfunc
254
Bram Moolenaar004a6782020-04-11 17:09:31 +0200255" basic test for formatprg
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100256func Test_normal06_formatprg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200257 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200258 CheckNotMSWindows
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100259
260 " uses sed to number non-empty lines
261 call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh')
262 call system('chmod +x ./Xsed_format.sh')
263 let text = ['a', '', 'c', '', ' ', 'd', 'e']
264 let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
265
266 10new
267 call setline(1, text)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200268 set formatprg=./Xsed_format.sh
269 norm! gggqG
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100270 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200271 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100272
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100273 call setline(1, text)
274 set formatprg=donothing
275 setlocal formatprg=./Xsed_format.sh
276 norm! gggqG
277 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200278 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100279
Bram Moolenaar004a6782020-04-11 17:09:31 +0200280 " Check for the command-line ranges added to 'formatprg'
281 set formatprg=cat
282 call setline(1, ['one', 'two', 'three', 'four', 'five'])
283 call feedkeys('gggqG', 'xt')
284 call assert_equal('.,$!cat', @:)
285 call feedkeys('2Ggq2j', 'xt')
286 call assert_equal('.,.+2!cat', @:)
287
288 bw!
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200289 " clean up
290 set formatprg=
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100291 setlocal formatprg=
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200292 call delete('Xsed_format.sh')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200293endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200294
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100295func Test_normal07_internalfmt()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200296 " basic test for internal formmatter to textwidth of 12
297 let list=range(1,11)
298 call map(list, 'v:val." "')
299 10new
300 call setline(1, list)
301 set tw=12
Bram Moolenaar004a6782020-04-11 17:09:31 +0200302 norm! ggVGgq
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200303 call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
304 " clean up
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100305 set tw=0
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200306 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200307endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200308
Bram Moolenaar004a6782020-04-11 17:09:31 +0200309" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100310func Test_normal08_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +0200311 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200312 call Setup_NewWindow()
313 50
314 setl foldenable fdm=marker
315 " First fold
316 norm! V4jzf
317 " check that folds have been created
318 call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
319 " Second fold
320 46
321 norm! V10jzf
322 " check that folds have been created
323 call assert_equal('46/*{{{*/', getline(46))
324 call assert_equal('60/*}}}*/', getline(60))
325 norm! k
326 call assert_equal('45', getline('.'))
327 norm! j
328 call assert_equal('46/*{{{*/', getline('.'))
329 norm! j
330 call assert_equal('61', getline('.'))
331 norm! k
332 " open a fold
333 norm! Vzo
334 norm! k
335 call assert_equal('45', getline('.'))
336 norm! j
337 call assert_equal('46/*{{{*/', getline('.'))
338 norm! j
339 call assert_equal('47', getline('.'))
340 norm! k
341 norm! zcVzO
342 call assert_equal('46/*{{{*/', getline('.'))
343 norm! j
344 call assert_equal('47', getline('.'))
345 norm! j
346 call assert_equal('48', getline('.'))
347 norm! j
348 call assert_equal('49', getline('.'))
349 norm! j
350 call assert_equal('50/*{{{*/', getline('.'))
351 norm! j
352 call assert_equal('51', getline('.'))
353 " delete folds
354 :46
355 " collapse fold
356 norm! V14jzC
357 " delete all folds recursively
358 norm! VzD
359 call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
360
361 " clean up
362 setl nofoldenable fdm=marker
363 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200364endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200365
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000366func Test_normal09a_operatorfunc()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200367 " Test operatorfunc
368 call Setup_NewWindow()
369 " Add some spaces for counting
370 50,60s/$/ /
371 unlet! g:a
372 let g:a=0
373 nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
374 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
375 50
376 norm V2j,,
377 call assert_equal(6, g:a)
378 norm V,,
379 call assert_equal(2, g:a)
380 norm ,,l
381 call assert_equal(0, g:a)
382 50
383 exe "norm 0\<c-v>10j2l,,"
384 call assert_equal(11, g:a)
385 50
386 norm V10j,,
387 call assert_equal(22, g:a)
388
Yegappan Lakshmanan777175b2021-11-18 22:08:57 +0000389 " Use a lambda function for 'opfunc'
390 unmap <buffer> ,,
391 call cursor(1, 1)
392 let g:a=0
393 nmap <buffer><silent> ,, :set opfunc={type\ ->\ CountSpaces(type)}<CR>g@
394 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
395 50
396 norm V2j,,
397 call assert_equal(6, g:a)
398 norm V,,
399 call assert_equal(2, g:a)
400 norm ,,l
401 call assert_equal(0, g:a)
402 50
403 exe "norm 0\<c-v>10j2l,,"
404 call assert_equal(11, g:a)
405 50
406 norm V10j,,
407 call assert_equal(22, g:a)
408
409 " use a partial function for 'opfunc'
410 let g:OpVal = 0
411 func! Test_opfunc1(x, y, type)
412 let g:OpVal = a:x + a:y
413 endfunc
414 set opfunc=function('Test_opfunc1',\ [5,\ 7])
415 normal! g@l
416 call assert_equal(12, g:OpVal)
417 " delete the function and try to use g@
418 delfunc Test_opfunc1
419 call test_garbagecollect_now()
420 call assert_fails('normal! g@l', 'E117:')
421 set opfunc=
422
423 " use a funcref for 'opfunc'
424 let g:OpVal = 0
425 func! Test_opfunc2(x, y, type)
426 let g:OpVal = a:x + a:y
427 endfunc
428 set opfunc=funcref('Test_opfunc2',\ [4,\ 3])
429 normal! g@l
430 call assert_equal(7, g:OpVal)
431 " delete the function and try to use g@
432 delfunc Test_opfunc2
433 call test_garbagecollect_now()
434 call assert_fails('normal! g@l', 'E933:')
435 set opfunc=
436
437 " Try to use a function with two arguments for 'operatorfunc'
438 let g:OpVal = 0
439 func! Test_opfunc3(x, y)
440 let g:OpVal = 4
441 endfunc
442 set opfunc=Test_opfunc3
443 call assert_fails('normal! g@l', 'E119:')
444 call assert_equal(0, g:OpVal)
445 set opfunc=
446 delfunc Test_opfunc3
447 unlet g:OpVal
448
449 " Try to use a lambda function with two arguments for 'operatorfunc'
450 set opfunc={x,\ y\ ->\ 'done'}
451 call assert_fails('normal! g@l', 'E119:')
452
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200453 " clean up
454 unmap <buffer> ,,
455 set opfunc=
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100456 unlet! g:a
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200457 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200458endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200459
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000460func Test_normal09b_operatorfunc()
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100461 " Test operatorfunc
462 call Setup_NewWindow()
463 " Add some spaces for counting
464 50,60s/$/ /
465 unlet! g:opt
466 set linebreak
467 nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
468 50
469 norm ,,j
470 exe "bd!" g:bufnr
471 call assert_true(&linebreak)
472 call assert_equal(g:opt, &linebreak)
473 set nolinebreak
474 norm ,,j
475 exe "bd!" g:bufnr
476 call assert_false(&linebreak)
477 call assert_equal(g:opt, &linebreak)
478
479 " clean up
480 unmap <buffer> ,,
481 set opfunc=
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200482 call assert_fails('normal Vg@', 'E774:')
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100483 bw!
484 unlet! g:opt
485endfunc
486
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000487func OperatorfuncRedo(_)
488 let g:opfunc_count = v:count
489endfunc
490
491func Test_normal09c_operatorfunc()
492 " Test redoing operatorfunc
493 new
494 call setline(1, 'some text')
495 set operatorfunc=OperatorfuncRedo
496 normal v3g@
497 call assert_equal(3, g:opfunc_count)
498 let g:opfunc_count = 0
499 normal .
500 call assert_equal(3, g:opfunc_count)
501
502 bw!
503 unlet g:opfunc_count
504 set operatorfunc=
505endfunc
506
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100507func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200508 " Test for expand()
509 10new
510 call setline(1, ['1', 'ifooar,,cbar'])
511 2
512 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200513 call assert_equal('cbar', expand('<cword>'))
514 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
515
516 call setline(1, ['prx = list[idx];'])
517 1
518 let expected = ['', 'prx', 'prx', 'prx',
519 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
520 \ 'idx', 'idx', 'idx', 'idx',
521 \ 'list[idx]',
522 \ '];',
523 \ ]
524 for i in range(1, 16)
525 exe 'norm ' . i . '|'
526 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
527 endfor
528
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200529 " Test for <cexpr> in state.val and ptr->val
530 call setline(1, 'x = state.val;')
531 call cursor(1, 10)
532 call assert_equal('state.val', expand('<cexpr>'))
533 call setline(1, 'x = ptr->val;')
534 call cursor(1, 9)
535 call assert_equal('ptr->val', expand('<cexpr>'))
536
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100537 if executable('echo')
538 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100539 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100540 endif
541
542 " Test expand(`=...`) i.e. backticks expression expansion
543 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100544 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100545
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200546 " clean up
547 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200548endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200549
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200550" Test for expand() in latin1 encoding
551func Test_normal_expand_latin1()
552 new
553 let save_enc = &encoding
554 set encoding=latin1
555 call setline(1, 'val = item->color;')
556 call cursor(1, 11)
557 call assert_equal('color', expand("<cword>"))
558 call assert_equal('item->color', expand("<cexpr>"))
559 let &encoding = save_enc
560 bw!
561endfunc
562
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100563func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200564 " test for 'showcmd'
565 10new
566 exe "norm! ofoobar\<esc>"
567 call assert_equal(2, line('$'))
568 set showcmd
569 exe "norm! ofoobar2\<esc>"
570 call assert_equal(3, line('$'))
571 exe "norm! VAfoobar3\<esc>"
572 call assert_equal(3, line('$'))
573 exe "norm! 0d3\<del>2l"
574 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200575 " test for the visual block size displayed in the status line
576 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
577 call feedkeys("ggl\<C-V>lljj", 'xt')
578 redraw!
579 call assert_match('3x3$', Screenline(&lines))
580 call feedkeys("\<C-V>", 'xt')
581 " test for visually selecting a multi-byte character
582 call setline(1, ["\U2206"])
583 call feedkeys("ggv", 'xt')
584 redraw!
585 call assert_match('1-3$', Screenline(&lines))
586 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200587 " test for visually selecting the end of line
588 call setline(1, ["foobar"])
589 call feedkeys("$vl", 'xt')
590 redraw!
591 call assert_match('2$', Screenline(&lines))
592 call feedkeys("y", 'xt')
593 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200594 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200595endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200596
Bram Moolenaar1671f442020-03-10 07:48:13 +0100597" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100598func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200599 10new
600 call setline(1, range(1,5))
601 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100602 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200603 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100604 call assert_beeps('normal! G2dd')
605 call assert_beeps("normal! g\<C-A>")
606 call assert_beeps("normal! g\<C-X>")
607 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100608 call assert_beeps("normal! vQ\<Esc>")
609 call assert_beeps("normal! 2[[")
610 call assert_beeps("normal! 2]]")
611 call assert_beeps("normal! 2[]")
612 call assert_beeps("normal! 2][")
613 call assert_beeps("normal! 4[z")
614 call assert_beeps("normal! 4]z")
615 call assert_beeps("normal! 4[c")
616 call assert_beeps("normal! 4]c")
617 call assert_beeps("normal! 200%")
618 call assert_beeps("normal! %")
619 call assert_beeps("normal! 2{")
620 call assert_beeps("normal! 2}")
621 call assert_beeps("normal! r\<Right>")
622 call assert_beeps("normal! 8ry")
623 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200624 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200625endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200626
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100627func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200628 " Test for F1
629 call assert_equal(1, winnr())
630 call feedkeys("\<f1>", 'txi')
631 call assert_match('help\.txt', bufname('%'))
632 call assert_equal(2, winnr('$'))
633 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200634endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200635
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100636func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200637 " basic test for Ctrl-F and Ctrl-B
638 call Setup_NewWindow()
639 exe "norm! \<c-f>"
640 call assert_equal('9', getline('.'))
641 exe "norm! 2\<c-f>"
642 call assert_equal('25', getline('.'))
643 exe "norm! 2\<c-b>"
644 call assert_equal('18', getline('.'))
645 1
646 set scrolloff=5
647 exe "norm! 2\<c-f>"
648 call assert_equal('21', getline('.'))
649 exe "norm! \<c-b>"
650 call assert_equal('13', getline('.'))
651 1
652 set scrolloff=99
653 exe "norm! \<c-f>"
654 call assert_equal('13', getline('.'))
655 set scrolloff=0
656 100
657 exe "norm! $\<c-b>"
658 call assert_equal('92', getline('.'))
659 call assert_equal([0, 92, 1, 0, 1], getcurpos())
660 100
661 set nostartofline
662 exe "norm! $\<c-b>"
663 call assert_equal('92', getline('.'))
664 call assert_equal([0, 92, 2, 0, 2147483647], getcurpos())
665 " cleanup
666 set startofline
667 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200668endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200669
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100670func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200671 10new
672 norm oxxxxxxx
673 exe "norm 2\<c-f>"
674 " check with valgrind that cursor is put back in column 1
675 exe "norm 2\<c-b>"
676 bw!
677endfunc
678
Bram Moolenaar1671f442020-03-10 07:48:13 +0100679" Test for errors with z command
680func Test_normal_z_error()
681 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200682 call assert_beeps('normal! zq')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100683endfunc
684
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100685func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200686 " basic test for z commands that scroll the window
687 call Setup_NewWindow()
688 100
689 norm! >>
690 " Test for z<cr>
691 exe "norm! z\<cr>"
692 call assert_equal(' 100', getline('.'))
693 call assert_equal(100, winsaveview()['topline'])
694 call assert_equal([0, 100, 2, 0, 9], getcurpos())
695
696 " Test for zt
697 21
698 norm! >>0zt
699 call assert_equal(' 21', getline('.'))
700 call assert_equal(21, winsaveview()['topline'])
701 call assert_equal([0, 21, 1, 0, 8], getcurpos())
702
703 " Test for zb
704 30
705 norm! >>$ztzb
706 call assert_equal(' 30', getline('.'))
707 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
708 call assert_equal([0, 30, 3, 0, 2147483647], getcurpos())
709
710 " Test for z-
711 1
712 30
713 norm! 0z-
714 call assert_equal(' 30', getline('.'))
715 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
716 call assert_equal([0, 30, 2, 0, 9], getcurpos())
717
718 " Test for z{height}<cr>
719 call assert_equal(10, winheight(0))
720 exe "norm! z12\<cr>"
721 call assert_equal(12, winheight(0))
722 exe "norm! z10\<cr>"
723 call assert_equal(10, winheight(0))
724
725 " Test for z.
726 1
727 21
728 norm! 0z.
729 call assert_equal(' 21', getline('.'))
730 call assert_equal(17, winsaveview()['topline'])
731 call assert_equal([0, 21, 2, 0, 9], getcurpos())
732
733 " Test for zz
734 1
735 21
736 norm! 0zz
737 call assert_equal(' 21', getline('.'))
738 call assert_equal(17, winsaveview()['topline'])
739 call assert_equal([0, 21, 1, 0, 8], getcurpos())
740
741 " Test for z+
742 11
743 norm! zt
744 norm! z+
745 call assert_equal(' 21', getline('.'))
746 call assert_equal(21, winsaveview()['topline'])
747 call assert_equal([0, 21, 2, 0, 9], getcurpos())
748
749 " Test for [count]z+
750 1
751 norm! 21z+
752 call assert_equal(' 21', getline('.'))
753 call assert_equal(21, winsaveview()['topline'])
754 call assert_equal([0, 21, 2, 0, 9], getcurpos())
755
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200756 " Test for z+ with [count] greater than buffer size
757 1
758 norm! 1000z+
759 call assert_equal(' 100', getline('.'))
760 call assert_equal(100, winsaveview()['topline'])
761 call assert_equal([0, 100, 2, 0, 9], getcurpos())
762
763 " Test for z+ from the last buffer line
764 norm! Gz.z+
765 call assert_equal(' 100', getline('.'))
766 call assert_equal(100, winsaveview()['topline'])
767 call assert_equal([0, 100, 2, 0, 9], getcurpos())
768
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200769 " Test for z^
770 norm! 22z+0
771 norm! z^
772 call assert_equal(' 21', getline('.'))
773 call assert_equal(12, winsaveview()['topline'])
774 call assert_equal([0, 21, 2, 0, 9], getcurpos())
775
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200776 " Test for z^ from first buffer line
777 norm! ggz^
778 call assert_equal('1', getline('.'))
779 call assert_equal(1, winsaveview()['topline'])
780 call assert_equal([0, 1, 1, 0, 1], getcurpos())
781
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200782 " Test for [count]z^
783 1
784 norm! 30z^
785 call assert_equal(' 21', getline('.'))
786 call assert_equal(12, winsaveview()['topline'])
787 call assert_equal([0, 21, 2, 0, 9], getcurpos())
788
789 " cleanup
790 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200791endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200792
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100793func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200794 " basic test for z commands that scroll the window
795 10new
796 15vsp
797 set nowrap listchars=
798 let lineA='abcdefghijklmnopqrstuvwxyz'
799 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
800 $put =lineA
801 $put =lineB
802 1d
803
Bram Moolenaar1671f442020-03-10 07:48:13 +0100804 " Test for zl and zh with a count
805 norm! 0z10l
806 call assert_equal([11, 1], [col('.'), wincol()])
807 norm! z4h
808 call assert_equal([11, 5], [col('.'), wincol()])
809 normal! 2gg
810
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200811 " Test for zl
812 1
813 norm! 5zl
814 call assert_equal(lineA, getline('.'))
815 call assert_equal(6, col('.'))
816 call assert_equal(5, winsaveview()['leftcol'])
817 norm! yl
818 call assert_equal('f', @0)
819
820 " Test for zh
821 norm! 2zh
822 call assert_equal(lineA, getline('.'))
823 call assert_equal(6, col('.'))
824 norm! yl
825 call assert_equal('f', @0)
826 call assert_equal(3, winsaveview()['leftcol'])
827
828 " Test for zL
829 norm! zL
830 call assert_equal(11, col('.'))
831 norm! yl
832 call assert_equal('k', @0)
833 call assert_equal(10, winsaveview()['leftcol'])
834 norm! 2zL
835 call assert_equal(25, col('.'))
836 norm! yl
837 call assert_equal('y', @0)
838 call assert_equal(24, winsaveview()['leftcol'])
839
840 " Test for zH
841 norm! 2zH
842 call assert_equal(25, col('.'))
843 call assert_equal(10, winsaveview()['leftcol'])
844 norm! yl
845 call assert_equal('y', @0)
846
847 " Test for zs
848 norm! $zs
849 call assert_equal(26, col('.'))
850 call assert_equal(25, winsaveview()['leftcol'])
851 norm! yl
852 call assert_equal('z', @0)
853
854 " Test for ze
855 norm! ze
856 call assert_equal(26, col('.'))
857 call assert_equal(11, winsaveview()['leftcol'])
858 norm! yl
859 call assert_equal('z', @0)
860
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200861 " Test for zs and ze with folds
862 %fold
863 norm! $zs
864 call assert_equal(26, col('.'))
865 call assert_equal(0, winsaveview()['leftcol'])
866 norm! yl
867 call assert_equal('z', @0)
868 norm! ze
869 call assert_equal(26, col('.'))
870 call assert_equal(0, winsaveview()['leftcol'])
871 norm! yl
872 call assert_equal('z', @0)
873
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200874 " cleanup
875 set wrap listchars=eol:$
876 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200877endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200878
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100879func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200880 " basic test for z commands that scroll the window
881 " using 'sidescrolloff' setting
882 10new
883 20vsp
884 set nowrap listchars= sidescrolloff=5
885 let lineA='abcdefghijklmnopqrstuvwxyz'
886 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
887 $put =lineA
888 $put =lineB
889 1d
890
891 " Test for zl
892 1
893 norm! 5zl
894 call assert_equal(lineA, getline('.'))
895 call assert_equal(11, col('.'))
896 call assert_equal(5, winsaveview()['leftcol'])
897 norm! yl
898 call assert_equal('k', @0)
899
900 " Test for zh
901 norm! 2zh
902 call assert_equal(lineA, getline('.'))
903 call assert_equal(11, col('.'))
904 norm! yl
905 call assert_equal('k', @0)
906 call assert_equal(3, winsaveview()['leftcol'])
907
908 " Test for zL
909 norm! 0zL
910 call assert_equal(16, col('.'))
911 norm! yl
912 call assert_equal('p', @0)
913 call assert_equal(10, winsaveview()['leftcol'])
914 norm! 2zL
915 call assert_equal(26, col('.'))
916 norm! yl
917 call assert_equal('z', @0)
918 call assert_equal(15, winsaveview()['leftcol'])
919
920 " Test for zH
921 norm! 2zH
922 call assert_equal(15, col('.'))
923 call assert_equal(0, winsaveview()['leftcol'])
924 norm! yl
925 call assert_equal('o', @0)
926
927 " Test for zs
928 norm! $zs
929 call assert_equal(26, col('.'))
930 call assert_equal(20, winsaveview()['leftcol'])
931 norm! yl
932 call assert_equal('z', @0)
933
934 " Test for ze
935 norm! ze
936 call assert_equal(26, col('.'))
937 call assert_equal(11, winsaveview()['leftcol'])
938 norm! yl
939 call assert_equal('z', @0)
940
941 " cleanup
942 set wrap listchars=eol:$ sidescrolloff=0
943 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200944endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200945
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200946" Test for commands that scroll the window horizontally. Test with folds.
947" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
948func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +0100949 15new
950 call setline(1, range(1, 100))
951 exe "normal! 30ggz\<CR>"
952 set foldenable
953 33,36fold
954 40,43fold
955 46,49fold
956 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200957
958 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +0100959 " Top of the screen = 30
960 " Folded lines = 9
961 " Bottom of the screen = 30 + h + 9 - 1
962 normal! 4L
963 call assert_equal(35 + h, line('.'))
964 normal! 4H
965 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200966
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200967 " Test for using a large count value
968 %d
969 call setline(1, range(1, 4))
970 norm! 6H
971 call assert_equal(4, line('.'))
972
973 " Test for 'M' with folded lines
974 %d
975 call setline(1, range(1, 20))
976 1,5fold
977 norm! LM
978 call assert_equal(12, line('.'))
979
Bram Moolenaarbdd2c292020-06-22 21:34:30 +0200980 " Test for the CTRL-E and CTRL-Y commands with folds
981 %d
982 call setline(1, range(1, 10))
983 3,5fold
984 exe "normal 6G3\<C-E>"
985 call assert_equal(6, line('w0'))
986 exe "normal 2\<C-Y>"
987 call assert_equal(2, line('w0'))
988
989 " Test for CTRL-Y on a folded line
990 %d
991 call setline(1, range(1, 100))
992 exe (h + 2) .. "," .. (h + 4) .. "fold"
993 exe h + 5
994 normal z-
995 exe "normal \<C-Y>\<C-Y>"
996 call assert_equal(h + 1, line('w$'))
997
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200998 " Test for CTRL-Y from the first line and CTRL-E from the last line
999 %d
1000 set scrolloff=2
1001 call setline(1, range(1, 4))
1002 exe "normal gg\<C-Y>"
1003 call assert_equal(1, line('w0'))
1004 call assert_equal(1, line('.'))
1005 exe "normal G4\<C-E>\<C-E>"
1006 call assert_equal(4, line('w$'))
1007 call assert_equal(4, line('.'))
1008 set scrolloff&
1009
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001010 " Using <PageUp> and <PageDown> in an empty buffer should beep
1011 %d
1012 call assert_beeps('exe "normal \<PageUp>"')
1013 call assert_beeps('exe "normal \<C-B>"')
1014 call assert_beeps('exe "normal \<PageDown>"')
1015 call assert_beeps('exe "normal \<C-F>"')
1016
1017 " Test for <C-U> and <C-D> with fold
1018 %d
1019 call setline(1, range(1, 100))
1020 10,35fold
1021 set scroll=10
1022 exe "normal \<C-D>"
1023 call assert_equal(36, line('.'))
1024 exe "normal \<C-D>"
1025 call assert_equal(46, line('.'))
1026 exe "normal \<C-U>"
1027 call assert_equal(36, line('.'))
1028 exe "normal \<C-U>"
1029 call assert_equal(10, line('.'))
1030 exe "normal \<C-U>"
1031 call assert_equal(1, line('.'))
1032 set scroll&
1033
1034 " Test for scrolling to the top of the file with <C-U> and a fold
1035 10
1036 normal ztL
1037 exe "normal \<C-U>\<C-U>"
1038 call assert_equal(1, line('w0'))
1039
1040 " Test for CTRL-D on a folded line
1041 %d
1042 call setline(1, range(1, 100))
1043 50,100fold
1044 75
1045 normal z-
1046 exe "normal \<C-D>"
1047 call assert_equal(50, line('.'))
1048 call assert_equal(100, line('w$'))
1049 normal z.
1050 let lnum = winline()
1051 exe "normal \<C-D>"
1052 call assert_equal(lnum, winline())
1053 call assert_equal(50, line('.'))
1054 normal zt
1055 exe "normal \<C-D>"
1056 call assert_equal(50, line('w0'))
1057
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001058 " Test for <S-CR>. Page down.
1059 %d
1060 call setline(1, range(1, 100))
1061 call feedkeys("\<S-CR>", 'xt')
1062 call assert_equal(14, line('w0'))
1063 call assert_equal(28, line('w$'))
1064
1065 " Test for <S-->. Page up.
1066 call feedkeys("\<S-->", 'xt')
1067 call assert_equal(1, line('w0'))
1068 call assert_equal(15, line('w$'))
1069
Bram Moolenaar1671f442020-03-10 07:48:13 +01001070 set foldenable&
1071 close!
1072endfunc
1073
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001074func Test_scroll_in_ex_mode()
1075 " This was using invalid memory because w_botline was invalid.
1076 let lines =<< trim END
1077 diffsplit
1078 norm os00(
1079 call writefile(['done'], 'Xdone')
1080 qa!
1081 END
1082 call writefile(lines, 'Xscript')
1083 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1084 call assert_equal(['done'], readfile('Xdone'))
1085
1086 call delete('Xscript')
1087 call delete('Xdone')
1088endfunc
1089
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001090" Test for the 'sidescroll' option
1091func Test_sidescroll_opt()
1092 new
1093 20vnew
1094
1095 " scroll by 2 characters horizontally
1096 set sidescroll=2 nowrap
1097 call setline(1, repeat('a', 40))
1098 normal g$l
1099 call assert_equal(19, screenpos(0, 1, 21).col)
1100 normal l
1101 call assert_equal(20, screenpos(0, 1, 22).col)
1102 normal g0h
1103 call assert_equal(2, screenpos(0, 1, 2).col)
1104 call assert_equal(20, screenpos(0, 1, 20).col)
1105
1106 " when 'sidescroll' is 0, cursor positioned at the center
1107 set sidescroll=0
1108 normal g$l
1109 call assert_equal(11, screenpos(0, 1, 21).col)
1110 normal g0h
1111 call assert_equal(10, screenpos(0, 1, 10).col)
1112
1113 %bw!
1114 set wrap& sidescroll&
1115endfunc
1116
Bram Moolenaar004a6782020-04-11 17:09:31 +02001117" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001118func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001119 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001120 call Setup_NewWindow()
1121 50
1122 setl foldenable fdm=marker foldlevel=5
1123
Bram Moolenaar1671f442020-03-10 07:48:13 +01001124 call assert_beeps('normal! zj')
1125 call assert_beeps('normal! zk')
1126
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001127 " Test for zF
1128 " First fold
1129 norm! 4zF
1130 " check that folds have been created
1131 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1132
1133 " Test for zd
1134 51
1135 norm! 2zF
1136 call assert_equal(2, foldlevel('.'))
1137 norm! kzd
1138 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1139 norm! j
1140 call assert_equal(1, foldlevel('.'))
1141
1142 " Test for zD
1143 " also deletes partially selected folds recursively
1144 51
1145 norm! zF
1146 call assert_equal(2, foldlevel('.'))
1147 norm! kV2jzD
1148 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1149
1150 " Test for zE
1151 85
1152 norm! 4zF
1153 86
1154 norm! 2zF
1155 90
1156 norm! 4zF
1157 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1158 norm! zE
1159 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1160
1161 " Test for zn
1162 50
1163 set foldlevel=0
1164 norm! 2zF
1165 norm! zn
1166 norm! k
1167 call assert_equal('49', getline('.'))
1168 norm! j
1169 call assert_equal('50/*{{{*/', getline('.'))
1170 norm! j
1171 call assert_equal('51/*}}}*/', getline('.'))
1172 norm! j
1173 call assert_equal('52', getline('.'))
1174 call assert_equal(0, &foldenable)
1175
1176 " Test for zN
1177 49
1178 norm! zN
1179 call assert_equal('49', getline('.'))
1180 norm! j
1181 call assert_equal('50/*{{{*/', getline('.'))
1182 norm! j
1183 call assert_equal('52', getline('.'))
1184 call assert_equal(1, &foldenable)
1185
1186 " Test for zi
1187 norm! zi
1188 call assert_equal(0, &foldenable)
1189 norm! zi
1190 call assert_equal(1, &foldenable)
1191 norm! zi
1192 call assert_equal(0, &foldenable)
1193 norm! zi
1194 call assert_equal(1, &foldenable)
1195
1196 " Test for za
1197 50
1198 norm! za
1199 norm! k
1200 call assert_equal('49', getline('.'))
1201 norm! j
1202 call assert_equal('50/*{{{*/', getline('.'))
1203 norm! j
1204 call assert_equal('51/*}}}*/', getline('.'))
1205 norm! j
1206 call assert_equal('52', getline('.'))
1207 50
1208 norm! za
1209 norm! k
1210 call assert_equal('49', getline('.'))
1211 norm! j
1212 call assert_equal('50/*{{{*/', getline('.'))
1213 norm! j
1214 call assert_equal('52', getline('.'))
1215
1216 49
1217 norm! 5zF
1218 norm! k
1219 call assert_equal('48', getline('.'))
1220 norm! j
1221 call assert_equal('49/*{{{*/', getline('.'))
1222 norm! j
1223 call assert_equal('55', getline('.'))
1224 49
1225 norm! za
1226 call assert_equal('49/*{{{*/', getline('.'))
1227 norm! j
1228 call assert_equal('50/*{{{*/', getline('.'))
1229 norm! j
1230 call assert_equal('52', getline('.'))
1231 set nofoldenable
1232 " close fold and set foldenable
1233 norm! za
1234 call assert_equal(1, &foldenable)
1235
1236 50
1237 " have to use {count}za to open all folds and make the cursor visible
1238 norm! 2za
1239 norm! 2k
1240 call assert_equal('48', getline('.'))
1241 norm! j
1242 call assert_equal('49/*{{{*/', getline('.'))
1243 norm! j
1244 call assert_equal('50/*{{{*/', getline('.'))
1245 norm! j
1246 call assert_equal('51/*}}}*/', getline('.'))
1247 norm! j
1248 call assert_equal('52', getline('.'))
1249
1250 " Test for zA
1251 49
1252 set foldlevel=0
1253 50
1254 norm! zA
1255 norm! 2k
1256 call assert_equal('48', getline('.'))
1257 norm! j
1258 call assert_equal('49/*{{{*/', getline('.'))
1259 norm! j
1260 call assert_equal('50/*{{{*/', getline('.'))
1261 norm! j
1262 call assert_equal('51/*}}}*/', getline('.'))
1263 norm! j
1264 call assert_equal('52', getline('.'))
1265
Dominique Pelle923dce22021-11-21 11:36:04 +00001266 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001267 50
1268 set nofoldenable
1269 norm! zA
1270 call assert_equal(1, &foldenable)
1271 norm! k
1272 call assert_equal('48', getline('.'))
1273 norm! j
1274 call assert_equal('49/*{{{*/', getline('.'))
1275 norm! j
1276 call assert_equal('55', getline('.'))
1277
1278 " Test for zc
1279 norm! zE
1280 50
1281 norm! 2zF
1282 49
1283 norm! 5zF
1284 set nofoldenable
1285 50
1286 " There most likely is a bug somewhere:
1287 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1288 " TODO: Should this only close the inner most fold or both folds?
1289 norm! zc
1290 call assert_equal(1, &foldenable)
1291 norm! k
1292 call assert_equal('48', getline('.'))
1293 norm! j
1294 call assert_equal('49/*{{{*/', getline('.'))
1295 norm! j
1296 call assert_equal('55', getline('.'))
1297 set nofoldenable
1298 50
1299 norm! Vjzc
1300 norm! k
1301 call assert_equal('48', getline('.'))
1302 norm! j
1303 call assert_equal('49/*{{{*/', getline('.'))
1304 norm! j
1305 call assert_equal('55', getline('.'))
1306
1307 " Test for zC
1308 set nofoldenable
1309 50
1310 norm! zCk
1311 call assert_equal('48', getline('.'))
1312 norm! j
1313 call assert_equal('49/*{{{*/', getline('.'))
1314 norm! j
1315 call assert_equal('55', getline('.'))
1316
1317 " Test for zx
1318 " 1) close folds at line 49-54
1319 set nofoldenable
1320 48
1321 norm! zx
1322 call assert_equal(1, &foldenable)
1323 norm! j
1324 call assert_equal('49/*{{{*/', getline('.'))
1325 norm! j
1326 call assert_equal('55', getline('.'))
1327
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001328 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001329 51
1330 set nofoldenable
1331 norm! zx
1332 call assert_equal(1, &foldenable)
1333 norm! 3k
1334 call assert_equal('48', getline('.'))
1335 norm! j
1336 call assert_equal('49/*{{{*/', getline('.'))
1337 norm! j
1338 call assert_equal('50/*{{{*/', getline('.'))
1339 norm! j
1340 call assert_equal('51/*}}}*/', getline('.'))
1341 norm! j
1342 call assert_equal('52', getline('.'))
1343 norm! j
1344 call assert_equal('53', getline('.'))
1345 norm! j
1346 call assert_equal('54/*}}}*/', getline('.'))
1347 norm! j
1348 call assert_equal('55', getline('.'))
1349
1350 " 3) close one level of folds
1351 48
1352 set nofoldenable
1353 set foldlevel=1
1354 norm! zx
1355 call assert_equal(1, &foldenable)
1356 call assert_equal('48', getline('.'))
1357 norm! j
1358 call assert_equal('49/*{{{*/', getline('.'))
1359 norm! j
1360 call assert_equal('50/*{{{*/', getline('.'))
1361 norm! j
1362 call assert_equal('52', getline('.'))
1363 norm! j
1364 call assert_equal('53', getline('.'))
1365 norm! j
1366 call assert_equal('54/*}}}*/', getline('.'))
1367 norm! j
1368 call assert_equal('55', getline('.'))
1369
1370 " Test for zX
1371 " Close all folds
1372 set foldlevel=0 nofoldenable
1373 50
1374 norm! zX
1375 call assert_equal(1, &foldenable)
1376 norm! k
1377 call assert_equal('48', getline('.'))
1378 norm! j
1379 call assert_equal('49/*{{{*/', getline('.'))
1380 norm! j
1381 call assert_equal('55', getline('.'))
1382
1383 " Test for zm
1384 50
1385 set nofoldenable foldlevel=2
1386 norm! zm
1387 call assert_equal(1, &foldenable)
1388 call assert_equal(1, &foldlevel)
1389 norm! zm
1390 call assert_equal(0, &foldlevel)
1391 norm! zm
1392 call assert_equal(0, &foldlevel)
1393 norm! k
1394 call assert_equal('48', getline('.'))
1395 norm! j
1396 call assert_equal('49/*{{{*/', getline('.'))
1397 norm! j
1398 call assert_equal('55', getline('.'))
1399
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001400 " Test for zm with a count
1401 50
1402 set foldlevel=2
1403 norm! 3zm
1404 call assert_equal(0, &foldlevel)
1405 call assert_equal(49, foldclosed(line('.')))
1406
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001407 " Test for zM
1408 48
1409 set nofoldenable foldlevel=99
1410 norm! zM
1411 call assert_equal(1, &foldenable)
1412 call assert_equal(0, &foldlevel)
1413 call assert_equal('48', getline('.'))
1414 norm! j
1415 call assert_equal('49/*{{{*/', getline('.'))
1416 norm! j
1417 call assert_equal('55', getline('.'))
1418
1419 " Test for zr
1420 48
1421 set nofoldenable foldlevel=0
1422 norm! zr
1423 call assert_equal(0, &foldenable)
1424 call assert_equal(1, &foldlevel)
1425 set foldlevel=0 foldenable
1426 norm! zr
1427 call assert_equal(1, &foldenable)
1428 call assert_equal(1, &foldlevel)
1429 norm! zr
1430 call assert_equal(2, &foldlevel)
1431 call assert_equal('48', getline('.'))
1432 norm! j
1433 call assert_equal('49/*{{{*/', getline('.'))
1434 norm! j
1435 call assert_equal('50/*{{{*/', getline('.'))
1436 norm! j
1437 call assert_equal('51/*}}}*/', getline('.'))
1438 norm! j
1439 call assert_equal('52', getline('.'))
1440
1441 " Test for zR
1442 48
1443 set nofoldenable foldlevel=0
1444 norm! zR
1445 call assert_equal(0, &foldenable)
1446 call assert_equal(2, &foldlevel)
1447 set foldenable foldlevel=0
1448 norm! zR
1449 call assert_equal(1, &foldenable)
1450 call assert_equal(2, &foldlevel)
1451 call assert_equal('48', getline('.'))
1452 norm! j
1453 call assert_equal('49/*{{{*/', getline('.'))
1454 norm! j
1455 call assert_equal('50/*{{{*/', getline('.'))
1456 norm! j
1457 call assert_equal('51/*}}}*/', getline('.'))
1458 norm! j
1459 call assert_equal('52', getline('.'))
1460 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1461 48
1462 call assert_equal('48', getline('.'))
1463 norm! j
1464 call assert_equal('49/*{{{*/', getline('.'))
1465 norm! j
1466 call assert_equal('50/*{{{*/', getline('.'))
1467 norm! j
1468 call assert_equal('a /*{{{*/', getline('.'))
1469 norm! j
1470 call assert_equal('51/*}}}*/', getline('.'))
1471 norm! j
1472 call assert_equal('52', getline('.'))
1473 48
1474 norm! zR
1475 call assert_equal(1, &foldenable)
1476 call assert_equal(3, &foldlevel)
1477 call assert_equal('48', getline('.'))
1478 norm! j
1479 call assert_equal('49/*{{{*/', getline('.'))
1480 norm! j
1481 call assert_equal('50/*{{{*/', getline('.'))
1482 norm! j
1483 call assert_equal('a /*{{{*/', getline('.'))
1484 norm! j
1485 call assert_equal('b /*}}}*/', getline('.'))
1486 norm! j
1487 call assert_equal('51/*}}}*/', getline('.'))
1488 norm! j
1489 call assert_equal('52', getline('.'))
1490
1491 " clean up
1492 setl nofoldenable fdm=marker foldlevel=0
1493 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001494endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001495
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001496func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001497 " Reading from redirected file doesn't work on MS-Windows
1498 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001499 call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
1500 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001501 call system(GetVimCommand() .. ' -e -s < Xscript Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001502 let a=readfile('Xfile2')
1503 call assert_equal(['1', 'foo', 'bar', '2'], a)
1504
1505 " clean up
1506 for file in ['Xfile', 'Xfile2', 'Xscript']
1507 call delete(file)
1508 endfor
1509 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001510endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001511
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001512func Test_normal21_nv_hat()
1513
1514 " Edit a fresh file and wipe the buffer list so that there is no alternate
1515 " file present. Next, check for the expected command failures.
1516 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001517 call assert_fails(':buffer #', 'E86:')
1518 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001519 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001520
1521 " Test for the expected behavior when switching between two named buffers.
1522 edit Xfoo | edit Xbar
1523 call feedkeys("\<C-^>", 'tx')
1524 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1525 call feedkeys("\<C-^>", 'tx')
1526 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1527
1528 " Test for the expected behavior when only one buffer is named.
1529 enew | let l:nr = bufnr('%')
1530 call feedkeys("\<C-^>", 'tx')
1531 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1532 call feedkeys("\<C-^>", 'tx')
1533 call assert_equal('', bufname('%'))
1534 call assert_equal(l:nr, bufnr('%'))
1535
1536 " Test that no action is taken by "<C-^>" when an operator is pending.
1537 edit Xfoo
1538 call feedkeys("ci\<C-^>", 'tx')
1539 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1540
1541 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001542endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001543
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001544func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001545 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001546 " let shell = &shell
1547 " let &shell = 'sh'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001548 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001549 let args = ' -N -i NONE --noplugins -X --not-a-term'
1550 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001551 let a = readfile('Xfile')
1552 call assert_equal([], a)
1553 " Test for ZQ
1554 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001555 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001556 let a = readfile('Xfile')
1557 call assert_equal(['1', '2'], a)
1558
Bram Moolenaar1671f442020-03-10 07:48:13 +01001559 " Unsupported Z command
1560 call assert_beeps('normal! ZW')
1561
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001562 " clean up
1563 for file in ['Xfile']
1564 call delete(file)
1565 endfor
Bram Moolenaar0913a102016-09-03 19:11:59 +02001566 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001567endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001568
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001569func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001570 " Test for K command
1571 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001572 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001573 let k = &keywordprg
1574 set keywordprg=:help
1575 1
1576 norm! VK
1577 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1578 call assert_equal('help', &ft)
1579 call assert_match('\*version8.txt\*', getline('.'))
1580 helpclose
1581 norm! 0K
1582 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1583 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001584 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001585 helpclose
1586
Bram Moolenaar426f3752016-11-04 21:22:37 +01001587 set keywordprg=:new
1588 set iskeyword+=%
1589 set iskeyword+=\|
1590 2
1591 norm! K
1592 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1593 bwipe!
1594 3
1595 norm! K
1596 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1597 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001598 if !has('win32')
1599 4
1600 norm! K
1601 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1602 bwipe!
1603 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001604 set iskeyword-=%
1605 set iskeyword-=\|
1606
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001607 " Test for specifying a count to K
1608 1
1609 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1610 set keywordprg=:Kprog
1611 norm! 3K
1612 call assert_equal('3 version8', g:Kprog_Args)
1613 delcom Kprog
1614
Bram Moolenaar0913a102016-09-03 19:11:59 +02001615 " Only expect "man" to work on Unix
1616 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001617 let &keywordprg = k
1618 bw!
1619 return
1620 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001621
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001622 let not_gnu_man = has('mac') || has('bsd')
1623 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001624 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001625 set keywordprg=man\ -P\ cat
1626 else
1627 set keywordprg=man\ --pager=cat
1628 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001629 " Test for using man
1630 2
1631 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001632 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001633 call assert_match("man -P cat 'man'", a)
1634 else
1635 call assert_match("man --pager=cat 'man'", a)
1636 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001637
Bram Moolenaar1671f442020-03-10 07:48:13 +01001638 " Error cases
1639 call setline(1, '#$#')
1640 call assert_fails('normal! ggK', 'E349:')
1641 call setline(1, '---')
1642 call assert_fails('normal! ggv2lK', 'E349:')
1643 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001644 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001645 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001646 norm! V
1647 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001648
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001649 " clean up
1650 let &keywordprg = k
1651 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001652endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001653
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001654func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001655 " Testing for g?? g?g?
1656 new
1657 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1658 1
1659 norm! g??
1660 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1661 norm! g?g?
1662 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1663
1664 " clean up
1665 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001666endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001667
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001668func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001669 CheckFeature quickfix
1670
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001671 " Testing for CTRL-] g CTRL-] g]
1672 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1673 h
1674 " Test for CTRL-]
1675 call search('\<x\>$')
1676 exe "norm! \<c-]>"
1677 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1678 norm! yiW
1679 call assert_equal("*x*", @0)
1680 exe ":norm \<c-o>"
1681
1682 " Test for g_CTRL-]
1683 call search('\<v_u\>$')
1684 exe "norm! g\<c-]>"
1685 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1686 norm! yiW
1687 call assert_equal("*v_u*", @0)
1688 exe ":norm \<c-o>"
1689
1690 " Test for g]
1691 call search('\<i_<Esc>$')
1692 let a = execute(":norm! g]")
1693 call assert_match('i_<Esc>.*insert.txt', a)
1694
1695 if !empty(exepath('cscope')) && has('cscope')
1696 " setting cscopetag changes how g] works
1697 set cst
1698 exe "norm! g]"
1699 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1700 norm! yiW
1701 call assert_equal("*i_<Esc>*", @0)
1702 exe ":norm \<c-o>"
1703 " Test for CTRL-W g]
1704 exe "norm! \<C-W>g]"
1705 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1706 norm! yiW
1707 call assert_equal("*i_<Esc>*", @0)
1708 call assert_equal(3, winnr('$'))
1709 helpclose
1710 set nocst
1711 endif
1712
1713 " Test for CTRL-W g]
1714 let a = execute("norm! \<C-W>g]")
1715 call assert_match('i_<Esc>.*insert.txt', a)
1716
1717 " Test for CTRL-W CTRL-]
1718 exe "norm! \<C-W>\<C-]>"
1719 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1720 norm! yiW
1721 call assert_equal("*i_<Esc>*", @0)
1722 call assert_equal(3, winnr('$'))
1723 helpclose
1724
1725 " Test for CTRL-W g CTRL-]
1726 exe "norm! \<C-W>g\<C-]>"
1727 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1728 norm! yiW
1729 call assert_equal("*i_<Esc>*", @0)
1730 call assert_equal(3, winnr('$'))
1731 helpclose
1732
1733 " clean up
1734 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001735endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001736
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001737func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001738 " Test for ]p ]P [p and [P
1739 new
1740 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1741 1
1742 /Error/y a
1743 2
1744 norm! "a]pj"a[p
1745 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1746 1
1747 /^\s\{4}/
1748 exe "norm! \"a]P3Eldt'"
1749 exe "norm! j\"a[P2Eldt'"
1750 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
1751
1752 " clean up
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_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001757 " Test for [' [` ]' ]`
1758 call Setup_NewWindow()
1759 1,21s/.\+/ & b/
1760 1
1761 norm! $ma
1762 5
1763 norm! $mb
1764 10
1765 norm! $mc
1766 15
1767 norm! $md
1768 20
1769 norm! $me
1770
1771 " Test for ['
1772 9
1773 norm! 2['
1774 call assert_equal(' 1 b', getline('.'))
1775 call assert_equal(1, line('.'))
1776 call assert_equal(3, col('.'))
1777
1778 " Test for ]'
1779 norm! ]'
1780 call assert_equal(' 5 b', getline('.'))
1781 call assert_equal(5, line('.'))
1782 call assert_equal(3, col('.'))
1783
1784 " No mark after line 21, cursor moves to first non blank on current line
1785 21
1786 norm! $]'
1787 call assert_equal(' 21 b', getline('.'))
1788 call assert_equal(21, line('.'))
1789 call assert_equal(3, col('.'))
1790
1791 " Test for [`
1792 norm! 2[`
1793 call assert_equal(' 15 b', getline('.'))
1794 call assert_equal(15, line('.'))
1795 call assert_equal(8, col('.'))
1796
1797 " Test for ]`
1798 norm! ]`
1799 call assert_equal(' 20 b', getline('.'))
1800 call assert_equal(20, line('.'))
1801 call assert_equal(8, col('.'))
1802
1803 " clean up
1804 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001805endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001806
Bram Moolenaar1671f442020-03-10 07:48:13 +01001807" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001808func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001809 new
1810 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
1811
1812 $
1813 norm! d(
1814 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
1815 norm! 2d(
1816 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
1817 1
1818 norm! 0d)
1819 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
1820
1821 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
1822 $
1823 norm! $d(
1824 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
1825
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001826 " Move to the next sentence from a paragraph macro
1827 %d
1828 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
1829 call cursor(1, 1)
1830 normal )
1831 call assert_equal([2, 1], [line('.'), col('.')])
1832 normal )
1833 call assert_equal([2, 12], [line('.'), col('.')])
1834 normal ((
1835 call assert_equal([1, 1], [line('.'), col('.')])
1836
Bram Moolenaar1671f442020-03-10 07:48:13 +01001837 " It is an error if a next sentence is not found
1838 %d
1839 call setline(1, '.SH')
1840 call assert_beeps('normal )')
1841
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001842 " If only dot is present, don't treat that as a sentence
1843 call setline(1, '. This is a sentence.')
1844 normal $((
1845 call assert_equal(3, col('.'))
1846
Bram Moolenaar1671f442020-03-10 07:48:13 +01001847 " Jumping to a fold should open the fold
1848 call setline(1, ['', '', 'one', 'two', 'three'])
1849 set foldenable
1850 2,$fold
1851 call feedkeys(')', 'xt')
1852 call assert_equal(3, line('.'))
1853 call assert_equal(1, foldlevel('.'))
1854 call assert_equal(-1, foldclosed('.'))
1855 set foldenable&
1856
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001857 " clean up
1858 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001859endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001860
Bram Moolenaar1671f442020-03-10 07:48:13 +01001861" Test for { and } paragraph movements
1862func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001863 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001864 A paragraph begins after each empty line, and also at each of a set of
1865 paragraph macros, specified by the pairs of characters in the 'paragraphs'
1866 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
1867 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
1868 the first column). A section boundary is also a paragraph boundary.
1869 Note that a blank line (only containing white space) is NOT a paragraph
1870 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001871
1872
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001873 Also note that this does not include a '{' or '}' in the first column. When
1874 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
1875 paragraph boundary |posix|.
1876 {
1877 This is no paragraph
1878 unless the '{' is set
1879 in 'cpoptions'
1880 }
1881 .IP
1882 The nroff macros IP separates a paragraph
1883 That means, it must be a '.'
1884 followed by IP
1885 .LPIt does not matter, if afterwards some
1886 more characters follow.
1887 .SHAlso section boundaries from the nroff
1888 macros terminate a paragraph. That means
1889 a character like this:
1890 .NH
1891 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001892 [DATA]
1893
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001894 new
1895 call append(0, text)
1896 1
1897 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001898
1899 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001900 .IP
1901 The nroff macros IP separates a paragraph
1902 That means, it must be a '.'
1903 followed by IP
1904 .LPIt does not matter, if afterwards some
1905 more characters follow.
1906 .SHAlso section boundaries from the nroff
1907 macros terminate a paragraph. That means
1908 a character like this:
1909 .NH
1910 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001911
1912 [DATA]
1913 call assert_equal(expected, getline(1, '$'))
1914
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001915 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001916
1917 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001918 .LPIt does not matter, if afterwards some
1919 more characters follow.
1920 .SHAlso section boundaries from the nroff
1921 macros terminate a paragraph. That means
1922 a character like this:
1923 .NH
1924 End of text here
1925
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001926 [DATA]
1927 call assert_equal(expected, getline(1, '$'))
1928
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001929 $
1930 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001931
1932 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001933 .LPIt does not matter, if afterwards some
1934 more characters follow.
1935 .SHAlso section boundaries from the nroff
1936 macros terminate a paragraph. That means
1937 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001938
1939 [DATA]
1940 call assert_equal(expected, getline(1, '$'))
1941
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001942 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001943
1944 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001945 .LPIt does not matter, if afterwards some
1946 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001947
1948 [DATA]
1949 call assert_equal(expected, getline(1, '$'))
1950
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001951 " Test with { in cpooptions
1952 %d
1953 call append(0, text)
1954 set cpo+={
1955 1
1956 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001957
1958 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001959 {
1960 This is no paragraph
1961 unless the '{' is set
1962 in 'cpoptions'
1963 }
1964 .IP
1965 The nroff macros IP separates a paragraph
1966 That means, it must be a '.'
1967 followed by IP
1968 .LPIt does not matter, if afterwards some
1969 more characters follow.
1970 .SHAlso section boundaries from the nroff
1971 macros terminate a paragraph. That means
1972 a character like this:
1973 .NH
1974 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001975
1976 [DATA]
1977 call assert_equal(expected, getline(1, '$'))
1978
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001979 $
1980 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001981
1982 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001983 {
1984 This is no paragraph
1985 unless the '{' is set
1986 in 'cpoptions'
1987 }
1988 .IP
1989 The nroff macros IP separates a paragraph
1990 That means, it must be a '.'
1991 followed by IP
1992 .LPIt does not matter, if afterwards some
1993 more characters follow.
1994 .SHAlso section boundaries from the nroff
1995 macros terminate a paragraph. That means
1996 a character like this:
1997 .NH
1998 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001999
2000 [DATA]
2001 call assert_equal(expected, getline(1, '$'))
2002
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002003 norm! gg}
2004 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002005
2006 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002007 {
2008 This is no paragraph
2009 unless the '{' is set
2010 in 'cpoptions'
2011 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002012
2013 [DATA]
2014 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002015
Bram Moolenaar1671f442020-03-10 07:48:13 +01002016 " Jumping to a fold should open the fold
2017 %d
2018 call setline(1, ['', 'one', 'two', ''])
2019 set foldenable
2020 2,$fold
2021 call feedkeys('}', 'xt')
2022 call assert_equal(4, line('.'))
2023 call assert_equal(1, foldlevel('.'))
2024 call assert_equal(-1, foldclosed('.'))
2025 set foldenable&
2026
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002027 " clean up
2028 set cpo-={
2029 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002030endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002031
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002032" Test for section movements
2033func Test_normal_section()
2034 new
2035 let lines =<< trim [END]
2036 int foo()
2037 {
2038 if (1)
2039 {
2040 a = 1;
2041 }
2042 }
2043 [END]
2044 call setline(1, lines)
2045
2046 " jumping to a folded line using [[ should open the fold
2047 2,3fold
2048 call cursor(5, 1)
2049 call feedkeys("[[", 'xt')
2050 call assert_equal(2, line('.'))
2051 call assert_equal(-1, foldclosedend(line('.')))
2052
2053 close!
2054endfunc
2055
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002056" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002057func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002058 new
2059 call append(0, 'This is a simple test: äüöß')
2060 norm! 1ggVu
2061 call assert_equal('this is a simple test: äüöß', getline('.'))
2062 norm! VU
2063 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2064 norm! guu
2065 call assert_equal('this is a simple test: äüöss', getline('.'))
2066 norm! gUgU
2067 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2068 norm! gugu
2069 call assert_equal('this is a simple test: äüöss', getline('.'))
2070 norm! gUU
2071 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2072 norm! 010~
2073 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
2074 norm! V~
2075 call assert_equal('THIS IS A simple test: äüöss', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002076 call assert_beeps('norm! c~')
2077 %d
2078 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002079
Bram Moolenaar1671f442020-03-10 07:48:13 +01002080 " Test for changing case across lines using 'whichwrap'
2081 call setline(1, ['aaaaaa', 'aaaaaa'])
2082 normal! gg10~
2083 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2084 set whichwrap+=~
2085 normal! gg10~
2086 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2087 set whichwrap&
2088
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002089 " try changing the case with a double byte encoding (DBCS)
2090 %bw!
2091 let enc = &enc
2092 set encoding=cp932
2093 call setline(1, "\u8470")
2094 normal ~
2095 normal gU$gu$gUgUg~g~gugu
2096 call assert_equal("\u8470", getline(1))
2097 let &encoding = enc
2098
Bram Moolenaar1671f442020-03-10 07:48:13 +01002099 " clean up
2100 bw!
2101endfunc
2102
2103" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2104" is available but toupper()/tolower() don't do the right thing.
2105func Test_normal_changecase_turkish()
2106 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002107 try
2108 lang tr_TR.UTF-8
2109 set casemap=
2110 let iupper = toupper('i')
2111 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002112 call setline(1, 'iI')
2113 1normal gUU
2114 call assert_equal("\u0130I", getline(1))
2115 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002116
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002117 call setline(1, 'iI')
2118 1normal guu
2119 call assert_equal("i\u0131", getline(1))
2120 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002121 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002122 call setline(1, 'iI')
2123 1normal gUU
2124 call assert_equal("II", getline(1))
2125 call assert_equal("II", toupper("iI"))
2126
2127 call setline(1, 'iI')
2128 1normal guu
2129 call assert_equal("ii", getline(1))
2130 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002131 else
2132 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2133 endif
2134 set casemap&
2135 call setline(1, 'iI')
2136 1normal gUU
2137 call assert_equal("II", getline(1))
2138 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002139
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002140 call setline(1, 'iI')
2141 1normal guu
2142 call assert_equal("ii", getline(1))
2143 call assert_equal("ii", tolower("iI"))
2144
2145 lang en_US.UTF-8
2146 catch /E197:/
2147 " can't use Turkish locale
2148 throw 'Skipped: Turkish locale not available'
2149 endtry
Bram Moolenaar1671f442020-03-10 07:48:13 +01002150 close!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002151endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002152
Bram Moolenaar1671f442020-03-10 07:48:13 +01002153" Test for r (replace) command
2154func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002155 new
2156 call append(0, 'This is a simple test: abcd')
2157 exe "norm! 1gg$r\<cr>"
2158 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2159 exe "norm! 1gg2wlr\<cr>"
2160 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2161 exe "norm! 2gg0W5r\<cr>"
2162 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2163 set autoindent
2164 call setline(2, ['simple test: abc', ''])
2165 exe "norm! 2gg0W5r\<cr>"
2166 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2167 exe "norm! 1ggVr\<cr>"
2168 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2169 call setline(1, 'This is a')
2170 exe "norm! 1gg05rf"
2171 call assert_equal('fffffis a', getline(1))
2172
Bram Moolenaar1671f442020-03-10 07:48:13 +01002173 " When replacing characters, copy characters from above and below lines
2174 " using CTRL-Y and CTRL-E.
2175 " Different code paths are used for utf-8 and latin1 encodings
2176 set showmatch
2177 for enc in ['latin1', 'utf-8']
2178 enew!
2179 let &encoding = enc
2180 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2181 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2182 call assert_equal(' {a}x [b]x', getline(2))
2183 endfor
2184 set showmatch&
2185
2186 " r command should fail in operator pending mode
2187 call assert_beeps('normal! cr')
2188
Bram Moolenaar004a6782020-04-11 17:09:31 +02002189 " replace a tab character in visual mode
2190 %d
2191 call setline(1, ["a\tb", "c\td", "e\tf"])
2192 normal gglvjjrx
2193 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2194
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002195 " replace with a multibyte character (with multiple composing characters)
2196 %d
2197 new
2198 call setline(1, 'aaa')
2199 exe "normal $ra\u0328\u0301"
2200 call assert_equal("aaa\u0328\u0301", getline(1))
2201
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002202 " clean up
2203 set noautoindent
2204 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002205endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002206
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002207" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002208func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002209 new
2210 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2211 1
2212 norm! $g*
2213 call assert_equal('x_foo', @/)
2214 call assert_equal('x_foobar.abc', getline('.'))
2215 norm! $g#
2216 call assert_equal('abc', @/)
2217 call assert_equal('abc.x_foo', getline('.'))
2218
2219 " clean up
2220 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002221endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002222
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002223" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2224" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002225func Test_normal33_g_cmd2()
Bram Moolenaar004a6782020-04-11 17:09:31 +02002226 CheckFeature jumplist
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002227 call Setup_NewWindow()
2228 " Test for g`
2229 clearjumps
2230 norm! ma10j
2231 let a=execute(':jumps')
2232 " empty jumplist
2233 call assert_equal('>', a[-1:])
2234 norm! g`a
2235 call assert_equal('>', a[-1:])
2236 call assert_equal(1, line('.'))
2237 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002238 call cursor(10, 1)
2239 norm! g'a
2240 call assert_equal('>', a[-1:])
2241 call assert_equal(1, line('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002242
2243 " Test for g; and g,
2244 norm! g;
2245 " there is only one change in the changelist
2246 " currently, when we setup the window
2247 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002248 call assert_fails(':norm! g;', 'E662:')
2249 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002250 let &ul=&ul
2251 call append('$', ['a', 'b', 'c', 'd'])
2252 let &ul=&ul
2253 call append('$', ['Z', 'Y', 'X', 'W'])
2254 let a = execute(':changes')
2255 call assert_match('2\s\+0\s\+2', a)
2256 call assert_match('101\s\+0\s\+a', a)
2257 call assert_match('105\s\+0\s\+Z', a)
2258 norm! 3g;
2259 call assert_equal(2, line('.'))
2260 norm! 2g,
2261 call assert_equal(105, line('.'))
2262
2263 " Test for g& - global substitute
2264 %d
2265 call setline(1, range(1,10))
2266 call append('$', ['a', 'b', 'c', 'd'])
2267 $s/\w/&&/g
2268 exe "norm! /[1-8]\<cr>"
2269 norm! g&
2270 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2271
Bram Moolenaar1671f442020-03-10 07:48:13 +01002272 " Jumping to a fold using gg should open the fold
2273 set foldenable
2274 set foldopen+=jump
2275 5,8fold
2276 call feedkeys('6gg', 'xt')
2277 call assert_equal(1, foldlevel('.'))
2278 call assert_equal(-1, foldclosed('.'))
2279 set foldopen-=jump
2280 set foldenable&
2281
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002282 " Test for gv
2283 %d
2284 call append('$', repeat(['abcdefgh'], 8))
2285 exe "norm! 2gg02l\<c-v>2j2ly"
2286 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2287 " in visual mode, gv swaps current and last selected region
2288 exe "norm! G0\<c-v>4k4lgvd"
2289 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2290 exe "norm! G0\<c-v>4k4ly"
2291 exe "norm! gvood"
2292 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002293 " gv cannot be used in operator pending mode
2294 call assert_beeps('normal! cgv')
2295 " gv should beep without a previously selected visual area
2296 new
2297 call assert_beeps('normal! gv')
2298 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002299
2300 " Test for gk/gj
2301 %d
2302 15vsp
2303 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002304 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2305 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2306 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002307 $put =lineA
2308 $put =lineB
2309
2310 norm! 3gg0dgk
2311 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2312 set nu
2313 norm! 3gg0gjdgj
2314 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2315
2316 " Test for gJ
2317 norm! 2gggJ
2318 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2319 call assert_equal(16, col('.'))
2320 " shouldn't do anything
2321 norm! 10gJ
2322 call assert_equal(1, col('.'))
2323
2324 " Test for g0 g^ gm g$
2325 exe "norm! 2gg0gji "
2326 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2327 norm! g0yl
2328 call assert_equal(12, col('.'))
2329 call assert_equal(' ', getreg(0))
2330 norm! g$yl
2331 call assert_equal(22, col('.'))
2332 call assert_equal('3', getreg(0))
2333 norm! gmyl
2334 call assert_equal(17, col('.'))
2335 call assert_equal('n', getreg(0))
2336 norm! g^yl
2337 call assert_equal(15, col('.'))
2338 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002339 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002340
Bram Moolenaar74ede802021-05-29 19:18:01 +02002341 " Test for g$ with double-width character half displayed
2342 vsplit
2343 9wincmd |
2344 setlocal nowrap nonumber
2345 call setline(2, 'asdfasdfヨ')
2346 2
2347 normal 0g$
2348 call assert_equal(8, col('.'))
2349 10wincmd |
2350 normal 0g$
2351 call assert_equal(9, col('.'))
2352
2353 setlocal signcolumn=yes
2354 11wincmd |
2355 normal 0g$
2356 call assert_equal(8, col('.'))
2357 12wincmd |
2358 normal 0g$
2359 call assert_equal(9, col('.'))
2360
2361 close
2362
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002363 " Test for g_
2364 call assert_beeps('normal! 100g_')
2365 call setline(2, [' foo ', ' foobar '])
2366 normal! 2ggg_
2367 call assert_equal(5, col('.'))
2368 normal! 2g_
2369 call assert_equal(8, col('.'))
2370
2371 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002372 $put =lineC
2373
2374 " Test for gM
2375 norm! gMyl
2376 call assert_equal(73, col('.'))
2377 call assert_equal('0', getreg(0))
2378 " Test for 20gM
2379 norm! 20gMyl
2380 call assert_equal(29, col('.'))
2381 call assert_equal('S', getreg(0))
2382 " Test for 60gM
2383 norm! 60gMyl
2384 call assert_equal(87, col('.'))
2385 call assert_equal('E', getreg(0))
2386
2387 " Test for g Ctrl-G
2388 set ff=unix
2389 let a=execute(":norm! g\<c-g>")
2390 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2391
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002392 " Test for gI
2393 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002394 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002395
2396 " Test for gi
2397 wincmd c
2398 %d
2399 set tw=0
2400 call setline(1, ['foobar', 'new line'])
2401 norm! A next word
2402 $put ='third line'
2403 norm! gi another word
2404 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002405 call setline(1, 'foobar')
2406 normal! Ggifirst line
2407 call assert_equal('foobarfirst line', getline(1))
2408 " Test gi in 'virtualedit' mode with cursor after the end of the line
2409 set virtualedit=all
2410 call setline(1, 'foo')
2411 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2412 call setline(1, 'foo')
2413 normal! Ggifirst line
2414 call assert_equal('foo first line', getline(1))
2415 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002416
Dominique Pelle923dce22021-11-21 11:36:04 +00002417 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002418 exe "normal! g\<C-\>\<C-G>"
2419 call assert_equal('foo first line', getline('.'))
2420
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002421 " clean up
2422 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002423endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002424
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002425" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002426func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002427 new
2428
2429 let a = execute(":norm! g\<c-g>")
2430 call assert_equal("\n--No lines in buffer--", a)
2431
Bram Moolenaar1671f442020-03-10 07:48:13 +01002432 " Test for CTRL-G (same as :file)
2433 let a = execute(":norm! \<c-g>")
2434 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2435
Bram Moolenaar05295832018-08-24 22:07:58 +02002436 call setline(1, ['first line', 'second line'])
2437
2438 " Test g CTRL-g with dos, mac and unix file type.
2439 norm! gojll
2440 set ff=dos
2441 let a = execute(":norm! g\<c-g>")
2442 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2443
2444 set ff=mac
2445 let a = execute(":norm! g\<c-g>")
2446 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2447
2448 set ff=unix
2449 let a = execute(":norm! g\<c-g>")
2450 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2451
2452 " Test g CTRL-g in visual mode (v)
2453 let a = execute(":norm! gojllvlg\<c-g>")
2454 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2455
2456 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2457 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2458 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2459
2460 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2461 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2462 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2463
2464 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2465 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2466 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2467
2468 " There should be one byte less with noeol
2469 set bin noeol
2470 let a = execute(":norm! \<Esc>gog\<c-g>")
2471 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2472 set bin & eol&
2473
Bram Moolenaar30276f22019-01-24 17:59:39 +01002474 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002475
Bram Moolenaar30276f22019-01-24 17:59:39 +01002476 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2477 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 +02002478
Bram Moolenaar30276f22019-01-24 17:59:39 +01002479 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2480 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 +02002481
Bram Moolenaar30276f22019-01-24 17:59:39 +01002482 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2483 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 +02002484
Bram Moolenaar30276f22019-01-24 17:59:39 +01002485 set fenc=utf8 bomb
2486 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2487 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 +02002488
Bram Moolenaar30276f22019-01-24 17:59:39 +01002489 set fenc=utf16 bomb
2490 let a = execute(":norm! g\<c-g>")
2491 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 +02002492
Bram Moolenaar30276f22019-01-24 17:59:39 +01002493 set fenc=utf32 bomb
2494 let a = execute(":norm! g\<c-g>")
2495 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 +02002496
Bram Moolenaar30276f22019-01-24 17:59:39 +01002497 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002498
2499 set ff&
2500 bwipe!
2501endfunc
2502
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002503" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002504func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002505 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002506 let a=execute(':norm! 1G0g8')
2507 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002508
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002509 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2510 let a=execute(':norm! 1G$g8')
2511 call assert_equal("\nc3 b6 ", a)
2512
2513 call setline(1, "a\u0302")
2514 let a=execute(':norm! 1G0g8')
2515 call assert_equal("\n61 + cc 82 ", a)
2516
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002517 " clean up
2518 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002519endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002520
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002521" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002522func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002523 new
2524
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002525 " With invalid byte.
2526 call setline(1, "___\xff___")
2527 norm! 1G08g8g
2528 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2529
2530 " With invalid byte before the cursor.
2531 call setline(1, "___\xff___")
2532 norm! 1G$h8g8g
2533 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2534
2535 " With truncated sequence.
2536 call setline(1, "___\xE2\x82___")
2537 norm! 1G08g8g
2538 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2539
2540 " With overlong sequence.
2541 call setline(1, "___\xF0\x82\x82\xAC___")
2542 norm! 1G08g8g
2543 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2544
2545 " With valid utf8.
2546 call setline(1, "café")
2547 norm! 1G08g8
2548 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2549
2550 bw!
2551endfunc
2552
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002553" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002554func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002555 " Cannot capture its output,
2556 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002557 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002558 echo "a\nb\nc\nd"
2559 let b=execute(':norm! g<')
2560 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002561endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002562
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002563" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002564func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002565 new
2566 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002567 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002568 " Test for gp gP
2569 call append(1, range(1,10))
2570 1
2571 norm! 1yy
2572 3
2573 norm! gp
2574 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2575 $
2576 norm! gP
2577 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2578
2579 " Test for go
2580 norm! 26go
2581 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2582 norm! 27go
2583 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2584 norm! 28go
2585 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2586 set ff=dos
2587 norm! 29go
2588 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2589 set ff=unix
2590 norm! gg0
2591 norm! 101go
2592 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2593 norm! 103go
2594 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2595 " count > buffer content
2596 norm! 120go
2597 call assert_equal([0, 14, 1, 0, 2147483647], getcurpos())
2598 " clean up
2599 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002600endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002601
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002602" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002603func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002604 tabnew 1.txt
2605 tabnew 2.txt
2606 tabnew 3.txt
2607 norm! 1gt
2608 call assert_equal(1, tabpagenr())
2609 norm! 3gt
2610 call assert_equal(3, tabpagenr())
2611 norm! 1gT
2612 " count gT goes not to the absolute tabpagenumber
2613 " but, but goes to the count previous tabpagenumber
2614 call assert_equal(2, tabpagenr())
2615 " wrap around
2616 norm! 3gT
2617 call assert_equal(3, tabpagenr())
2618 " gt does not wrap around
2619 norm! 5gt
2620 call assert_equal(3, tabpagenr())
2621
2622 for i in range(3)
2623 tabclose
2624 endfor
2625 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002626 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002627endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002628
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002629" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002630func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002631 new
2632 call setline(1, range(10))
2633 $
2634 setl et sw=2
2635 norm! V10>$
2636 " count is ignored
2637 exe "norm! 10\<home>"
2638 call assert_equal(1, col('.'))
2639 exe "norm! \<home>"
2640 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2641 exe "norm! 5\<c-home>"
2642 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2643 exe "norm! \<c-home>"
2644 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002645 exe "norm! G\<c-kHome>"
2646 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002647
2648 " clean up
2649 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002650endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002651
Bram Moolenaar1671f442020-03-10 07:48:13 +01002652" Test for <End> and <C-End> keys
2653func Test_normal_nvend()
2654 new
2655 call setline(1, map(range(1, 10), '"line" .. v:val'))
2656 exe "normal! \<End>"
2657 call assert_equal(5, col('.'))
2658 exe "normal! 4\<End>"
2659 call assert_equal([4, 5], [line('.'), col('.')])
2660 exe "normal! \<C-End>"
2661 call assert_equal([10, 6], [line('.'), col('.')])
2662 close!
2663endfunc
2664
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002665" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002666func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002667 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002668 new
2669 set tw=0
2670 call append(0, 'here are some words')
2671 norm! 1gg0elcwZZZ
2672 call assert_equal('hereZZZare some words', getline('.'))
2673 norm! 1gg0elcWYYY
2674 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002675 norm! 2gg0cwfoo
2676 call assert_equal('foo', getline('.'))
2677
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002678 call setline(1, 'one; two')
2679 call cursor(1, 1)
2680 call feedkeys('cwvim', 'xt')
2681 call assert_equal('vim; two', getline(1))
2682 call feedkeys('0cWone', 'xt')
2683 call assert_equal('one two', getline(1))
2684 "When cursor is at the end of a word 'ce' will change until the end of the
2685 "next word, but 'cw' will change only one character
2686 call setline(1, 'one two')
2687 call feedkeys('0ecwce', 'xt')
2688 call assert_equal('once two', getline(1))
2689 call setline(1, 'one two')
2690 call feedkeys('0ecely', 'xt')
2691 call assert_equal('only', getline(1))
2692
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002693 " clean up
2694 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002695endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002696
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002697" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002698func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002699 new
2700 call append(0, 'here are some words')
2701 exe "norm! 1gg0a\<C-\>\<C-N>"
2702 call assert_equal('n', mode())
2703 call assert_equal(1, col('.'))
2704 call assert_equal('', visualmode())
2705 exe "norm! 1gg0viw\<C-\>\<C-N>"
2706 call assert_equal('n', mode())
2707 call assert_equal(4, col('.'))
2708 exe "norm! 1gg0a\<C-\>\<C-G>"
2709 call assert_equal('n', mode())
2710 call assert_equal(1, col('.'))
2711 "imap <buffer> , <c-\><c-n>
2712 set im
2713 exe ":norm! \<c-\>\<c-n>dw"
2714 set noim
2715 call assert_equal('are some words', getline(1))
2716 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02002717 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01002718
Bram Moolenaar21829c52021-01-26 22:42:21 +01002719 if has('cmdwin')
2720 " Using CTRL-\ CTRL-N in cmd window should close the window
2721 call feedkeys("q:\<C-\>\<C-N>", 'xt')
2722 call assert_equal('', getcmdwintype())
2723 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002724
2725 " clean up
2726 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002727endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002728
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002729" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01002730func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002731 new
2732 set sts=2 sw=2 ts=8 tw=0
2733 call append(0, ["aaa\tbbb\tccc", '', '', ''])
2734 let a=getline(1)
2735 norm! 2gg0
2736 exe "norm! a\<c-r>=a\<cr>"
2737 norm! 3gg0
2738 exe "norm! a\<c-r>\<c-r>=a\<cr>"
2739 norm! 4gg0
2740 exe "norm! a\<c-r>\<c-o>=a\<cr>"
2741 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
2742
2743 " clean up
2744 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02002745 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002746endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002747
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002748" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002749func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002750 call Setup_NewWindow()
2751 call assert_equal(5, &scroll)
2752 exe "norm! \<c-d>"
2753 call assert_equal('6', getline('.'))
2754 exe "norm! 2\<c-d>"
2755 call assert_equal('8', getline('.'))
2756 call assert_equal(2, &scroll)
2757 set scroll=5
2758 exe "norm! \<c-u>"
2759 call assert_equal('3', getline('.'))
2760 1
2761 set scrolloff=5
2762 exe "norm! \<c-d>"
2763 call assert_equal('10', getline('.'))
2764 exe "norm! \<c-u>"
2765 call assert_equal('5', getline('.'))
2766 1
2767 set scrolloff=99
2768 exe "norm! \<c-d>"
2769 call assert_equal('10', getline('.'))
2770 set scrolloff=0
2771 100
2772 exe "norm! $\<c-u>"
2773 call assert_equal('95', getline('.'))
2774 call assert_equal([0, 95, 1, 0, 1], getcurpos())
2775 100
2776 set nostartofline
2777 exe "norm! $\<c-u>"
2778 call assert_equal('95', getline('.'))
2779 call assert_equal([0, 95, 2, 0, 2147483647], getcurpos())
2780 " cleanup
2781 set startofline
2782 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002783endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002784
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002785func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01002786 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01002787 " The ~ register does not exist
2788 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01002789 return
2790 endif
2791
2792 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002793 " unfortunately, without a gui, we can't really test much here,
2794 " so simply test that ~p fails (which uses the drop register)
2795 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02002796 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002797 call assert_equal([], getreg('~', 1, 1))
2798 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02002799 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002800 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002801endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002802
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002803func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002804 new
2805 " How to test this?
2806 " let's just for now test, that the buffer
2807 " does not change
2808 call feedkeys("\<c-s>", 't')
2809 call assert_equal([''], getline(1,'$'))
2810
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002811 " no valid commands
2812 exe "norm! \<char-0x100>"
2813 call assert_equal([''], getline(1,'$'))
2814
2815 exe "norm! ä"
2816 call assert_equal([''], getline(1,'$'))
2817
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002818 " clean up
2819 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002820endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02002821
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002822func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02002823 " This was causing a crash or ml_get error.
2824 enew!
2825 call setline(1,'xxx')
2826 normal $
2827 new
2828 call setline(1, range(1,2))
2829 2
2830 exe "norm \<C-V>$"
2831 bw!
2832 norm yp
2833 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002834endfunc
2835
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002836func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002837 new
2838 exe "norm! \<c-w>c"
2839 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002840 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002841endfunc
2842
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002843func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002844 new
2845 call setline(1, 'one two three four five six seven eight nine ten')
2846 1
2847 norm! 3d2w
2848 call assert_equal('seven eight nine ten', getline(1))
2849 bw!
2850endfunc
2851
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002852func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02002853 CheckFeature timers
2854 CheckFeature cmdline_hist
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002855 func! DoTimerWork(id)
2856 call assert_equal('[Command Line]', bufname(''))
2857 " should fail, with E11, but does fail with E23?
2858 "call feedkeys("\<c-^>", 'tm')
2859
2860 " should also fail with E11
Bram Moolenaare2e40752020-09-04 21:18:46 +02002861 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002862 " return from commandline window
2863 call feedkeys("\<cr>")
2864 endfunc
2865
2866 let oldlang=v:lang
2867 lang C
2868 set updatetime=20
2869 call timer_start(100, 'DoTimerWork')
2870 try
2871 " throws E23, for whatever reason...
2872 call feedkeys('q:', 'x!')
2873 catch /E23/
2874 " no-op
2875 endtry
2876 " clean up
2877 set updatetime=4000
2878 exe "lang" oldlang
2879 bw!
2880endfunc
2881
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002882func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02002883 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01002884 " Don't sleep after the warning message.
2885 call test_settime(1)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002886 call writefile(['foo'], 'Xreadonly.log')
2887 new Xreadonly.log
2888 setl ro
2889 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02002890 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002891 call assert_equal(['foo'], getline(1,'$'))
2892 call assert_equal('Xreadonly.log', bufname(''))
2893
2894 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01002895 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002896 bw!
2897 call delete("Xreadonly.log")
2898endfunc
2899
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002900func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02002901 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002902 new
2903 call setline(1, 'abcde fghij klmnopq')
2904 norm! 1gg$
2905 set rl
2906 call assert_equal(19, col('.'))
2907 call feedkeys('l', 'tx')
2908 call assert_equal(18, col('.'))
2909 call feedkeys('h', 'tx')
2910 call assert_equal(19, col('.'))
2911 call feedkeys("\<right>", 'tx')
2912 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01002913 call feedkeys("\<left>", 'tx')
2914 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002915 call feedkeys("\<s-right>", 'tx')
2916 call assert_equal(13, col('.'))
2917 call feedkeys("\<c-right>", 'tx')
2918 call assert_equal(7, col('.'))
2919 call feedkeys("\<c-left>", 'tx')
2920 call assert_equal(13, col('.'))
2921 call feedkeys("\<s-left>", 'tx')
2922 call assert_equal(19, col('.'))
2923 call feedkeys("<<", 'tx')
2924 call assert_equal(' abcde fghij klmnopq',getline(1))
2925 call feedkeys(">>", 'tx')
2926 call assert_equal('abcde fghij klmnopq',getline(1))
2927
2928 " cleanup
2929 set norl
2930 bw!
2931endfunc
2932
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02002933func Test_normal54_Ctrl_bsl()
2934 new
2935 call setline(1, 'abcdefghijklmn')
2936 exe "norm! df\<c-\>\<c-n>"
2937 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
2938 exe "norm! df\<c-\>\<c-g>"
2939 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
2940 exe "norm! df\<c-\>m"
2941 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01002942
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02002943 call setline(2, 'abcdefghijklmnāf')
2944 norm! 2gg0
2945 exe "norm! df\<Char-0x101>"
2946 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
2947 norm! 1gg0
2948 exe "norm! df\<esc>"
2949 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002950
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02002951 " clean up
2952 bw!
2953endfunc
2954
2955func Test_normal_large_count()
2956 " This may fail with 32bit long, how do we detect that?
2957 new
2958 normal o
2959 normal 6666666666dL
2960 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002961endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02002962
2963func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02002964 new
2965 normal grádv}
2966 call assert_equal('á', getline(1))
2967 normal grád}
2968 call assert_equal('', getline(1))
2969 bwipe!
2970endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01002971
2972" Test for the gr (virtual replace) command
2973" Test for the bug fixed by 7.4.387
2974func Test_gr_command()
2975 enew!
2976 let save_cpo = &cpo
2977 call append(0, ['First line', 'Second line', 'Third line'])
2978 exe "normal i\<C-G>u"
2979 call cursor(2, 1)
2980 set cpo-=X
2981 normal 4gro
2982 call assert_equal('oooond line', getline(2))
2983 undo
2984 set cpo+=X
2985 normal 4gro
2986 call assert_equal('ooooecond line', getline(2))
2987 let &cpo = save_cpo
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002988 normal! ggvegrx
2989 call assert_equal('xxxxx line', getline(1))
2990 exe "normal! gggr\<C-V>122"
2991 call assert_equal('zxxxx line', getline(1))
2992 set virtualedit=all
2993 normal! 15|grl
2994 call assert_equal('zxxxx line l', getline(1))
2995 set virtualedit&
2996 set nomodifiable
2997 call assert_fails('normal! grx', 'E21:')
2998 call assert_fails('normal! gRx', 'E21:')
2999 set modifiable&
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003000 enew!
3001endfunc
3002
3003" When splitting a window the changelist position is wrong.
3004" Test the changelist position after splitting a window.
3005" Test for the bug fixed by 7.4.386
3006func Test_changelist()
3007 let save_ul = &ul
3008 enew!
3009 call append('$', ['1', '2'])
3010 exe "normal i\<C-G>u"
3011 exe "normal Gkylpa\<C-G>u"
3012 set ul=100
3013 exe "normal Gylpa\<C-G>u"
3014 set ul=100
3015 normal gg
3016 vsplit
3017 normal g;
3018 call assert_equal([3, 2], [line('.'), col('.')])
3019 normal g;
3020 call assert_equal([2, 2], [line('.'), col('.')])
3021 call assert_fails('normal g;', 'E662:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003022 new
3023 call assert_fails('normal g;', 'E664:')
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003024 %bwipe!
3025 let &ul = save_ul
3026endfunc
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003027
3028func Test_nv_hat_count()
3029 %bwipeout!
3030 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003031 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003032
3033 edit Xfoo
3034 let l:foo_nr = bufnr('Xfoo')
3035
3036 edit Xbar
3037 let l:bar_nr = bufnr('Xbar')
3038
3039 " Make sure we are not just using the alternate file.
3040 edit Xbaz
3041
3042 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3043 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3044
3045 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3046 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3047
3048 %bwipeout!
3049endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003050
3051func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003052 " Make sure no buffers are changed.
3053 %bwipe!
3054
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003055 exe "normal \<C-C>"
3056 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003057
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003058 new
3059 cal setline(1, 'hi!')
3060 exe "normal \<C-C>"
3061 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003062
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003063 bwipe!
3064endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003065
3066" Test for '[m', ']m', '[M' and ']M'
3067" Jumping to beginning and end of methods in Java-like languages
3068func Test_java_motion()
3069 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003070 call assert_beeps('normal! [m')
3071 call assert_beeps('normal! ]m')
3072 call assert_beeps('normal! [M')
3073 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003074 let lines =<< trim [CODE]
3075 Piece of Java
3076 {
3077 tt m1 {
3078 t1;
3079 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003080
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003081 tt m2 {
3082 t2;
3083 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003084
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003085 tt m3 {
3086 if (x)
3087 {
3088 t3;
3089 }
3090 } e3
3091 }
3092 [CODE]
3093 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003094
3095 normal gg
3096
3097 normal 2]maA
3098 call assert_equal("\ttt m1 {A", getline('.'))
3099 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3100
3101 normal j]maB
3102 call assert_equal("\ttt m2 {B", getline('.'))
3103 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3104
3105 normal ]maC
3106 call assert_equal("\ttt m3 {C", getline('.'))
3107 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3108
3109 normal [maD
3110 call assert_equal("\ttt m3 {DC", getline('.'))
3111 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3112
3113 normal k2[maE
3114 call assert_equal("\ttt m1 {EA", getline('.'))
3115 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3116
3117 normal 3[maF
3118 call assert_equal("{F", getline('.'))
3119 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3120
3121 normal ]MaG
3122 call assert_equal("\t}G e1", getline('.'))
3123 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3124
3125 normal j2]MaH
3126 call assert_equal("\t}H e3", getline('.'))
3127 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3128
3129 normal ]M]M
3130 normal aI
3131 call assert_equal("}I", getline('.'))
3132 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3133
3134 normal 2[MaJ
3135 call assert_equal("\t}JH e3", getline('.'))
3136 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3137
3138 normal k[MaK
3139 call assert_equal("\t}K e2", getline('.'))
3140 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3141
3142 normal 3[MaL
3143 call assert_equal("{LF", getline('.'))
3144 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3145
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003146 call cursor(2, 1)
3147 call assert_beeps('norm! 5]m')
3148
3149 " jumping to a method in a fold should open the fold
3150 6,10fold
3151 call feedkeys("gg3]m", 'xt')
3152 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3153 call assert_equal(-1, foldclosedend(7))
3154
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003155 close!
3156endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003157
Bram Moolenaar004a6782020-04-11 17:09:31 +02003158" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003159func Test_normal_gdollar_cmd()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003160 CheckFeature jumplist
Bram Moolenaard5c82342019-07-27 18:44:57 +02003161 call Setup_NewWindow()
3162 " Make long lines that will wrap
3163 %s/$/\=repeat(' foobar', 10)/
3164 20vsp
3165 set wrap
3166 " Test for g$ with count
3167 norm! gg
3168 norm! 0vg$y
3169 call assert_equal(20, col("'>"))
3170 call assert_equal('1 foobar foobar foob', getreg(0))
3171 norm! gg
3172 norm! 0v4g$y
3173 call assert_equal(72, col("'>"))
3174 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3175 norm! gg
3176 norm! 0v6g$y
3177 call assert_equal(40, col("'>"))
3178 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3179 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3180 set nowrap
3181 " clean up
3182 norm! gg
3183 norm! 0vg$y
3184 call assert_equal(20, col("'>"))
3185 call assert_equal('1 foobar foobar foob', getreg(0))
3186 norm! gg
3187 norm! 0v4g$y
3188 call assert_equal(20, col("'>"))
3189 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3190 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3191 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3192 \ '4 foobar foobar foob', getreg(0))
3193 norm! gg
3194 norm! 0v6g$y
3195 call assert_equal(20, col("'>"))
3196 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3197 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3198 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3199 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3200 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3201 \ '6 foobar foobar foob', getreg(0))
3202 " Move to last line, also down movement is not possible, should still move
3203 " the cursor to the last visible char
3204 norm! G
3205 norm! 0v6g$y
3206 call assert_equal(20, col("'>"))
3207 call assert_equal('100 foobar foobar fo', getreg(0))
3208 bw!
3209endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003210
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003211func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003212 " needs 80 column new window
3213 new
3214 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003215 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003216 put =[repeat('x',90)..' {{{1', 'x {{{1']
3217 norm! gk
3218 " In a 80 column wide terminal the window will be only 78 char
3219 " (because Vim will leave space for the other window),
3220 " but if the terminal is larger, it will be 80 chars, so verify the
3221 " cursor column correctly.
3222 call assert_equal(winwidth(0)+1, col('.'))
3223 call assert_equal(winwidth(0)+1, virtcol('.'))
3224 norm! j
3225 call assert_equal(6, col('.'))
3226 call assert_equal(6, virtcol('.'))
3227 norm! gk
3228 call assert_equal(95, col('.'))
3229 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003230 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003231
3232 " needs 80 column new window
3233 new
3234 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003235 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003236 set number
3237 set numberwidth=10
3238 set cpoptions+=n
3239 put =[repeat('0',90), repeat('1',90)]
3240 norm! 075l
3241 call assert_equal(76, col('.'))
3242 norm! gk
3243 call assert_equal(1, col('.'))
3244 norm! gk
3245 call assert_equal(76, col('.'))
3246 norm! gk
3247 call assert_equal(1, col('.'))
3248 norm! gj
3249 call assert_equal(76, col('.'))
3250 norm! gj
3251 call assert_equal(1, col('.'))
3252 norm! gj
3253 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003254 " When 'nowrap' is set, gk and gj behave like k and j
3255 set nowrap
3256 normal! gk
3257 call assert_equal([2, 76], [line('.'), col('.')])
3258 normal! gj
3259 call assert_equal([3, 76], [line('.'), col('.')])
3260 %bw!
3261 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003262endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003263
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003264" Test for using : to run a multi-line Ex command in operator pending mode
3265func Test_normal_yank_with_excmd()
3266 new
3267 call setline(1, ['foo', 'bar', 'baz'])
3268 let @a = ''
3269 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3270 call assert_equal('f', @a)
3271 close!
3272endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003273
3274" Test for supplying a count to a normal-mode command across a cursorhold call
3275func Test_normal_cursorhold_with_count()
3276 func s:cHold()
3277 let g:cHold_Called += 1
3278 endfunc
3279 new
3280 augroup normalcHoldTest
3281 au!
3282 au CursorHold <buffer> call s:cHold()
3283 augroup END
3284 let g:cHold_Called = 0
3285 call feedkeys("3\<CursorHold>2ix", 'xt')
3286 call assert_equal(1, g:cHold_Called)
3287 call assert_equal(repeat('x', 32), getline(1))
3288 augroup normalcHoldTest
3289 au!
3290 augroup END
3291 au! normalcHoldTest
3292 close!
3293 delfunc s:cHold
3294endfunc
3295
3296" Test for using a count and a command with CTRL-W
3297func Test_wincmd_with_count()
3298 call feedkeys("\<C-W>12n", 'xt')
3299 call assert_equal(12, winheight(0))
3300endfunc
3301
3302" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003303func Test_horiz_motion()
3304 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003305 normal! gg
3306 call assert_beeps('normal! b')
3307 call assert_beeps('normal! B')
3308 call assert_beeps('normal! gE')
3309 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003310 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3311 call setline(1, 'one ,two ,three')
3312 exe "normal! $\<S-BS>"
3313 call assert_equal(11, col('.'))
3314 exe "normal! $\<C-BS>"
3315 call assert_equal(10, col('.'))
3316 close!
3317endfunc
3318
3319" Test for using a : command in operator pending mode
3320func Test_normal_colon_op()
3321 new
3322 call setline(1, ['one', 'two'])
3323 call assert_beeps("normal! Gc:d\<CR>")
3324 close!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003325endfunc
3326
Bram Moolenaar004a6782020-04-11 17:09:31 +02003327" Test for d and D commands
3328func Test_normal_delete_cmd()
3329 new
3330 " D in an empty line
3331 call setline(1, '')
3332 normal D
3333 call assert_equal('', getline(1))
3334 " D in an empty line in virtualedit mode
3335 set virtualedit=all
3336 normal D
3337 call assert_equal('', getline(1))
3338 set virtualedit&
3339 " delete to a readonly register
3340 call setline(1, ['abcd'])
3341 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003342
3343 " D and d with 'nomodifiable'
3344 call setline(1, ['abcd'])
3345 setlocal nomodifiable
3346 call assert_fails('normal D', 'E21:')
3347 call assert_fails('normal d$', 'E21:')
3348
Bram Moolenaar004a6782020-04-11 17:09:31 +02003349 close!
3350endfunc
3351
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003352" Test for deleting or changing characters across lines with 'whichwrap'
3353" containing 's'. Should count <EOL> as one character.
3354func Test_normal_op_across_lines()
3355 new
3356 set whichwrap&
3357 call setline(1, ['one two', 'three four'])
3358 exe "norm! $3d\<Space>"
3359 call assert_equal(['one twhree four'], getline(1, '$'))
3360
3361 call setline(1, ['one two', 'three four'])
3362 exe "norm! $3c\<Space>x"
3363 call assert_equal(['one twxhree four'], getline(1, '$'))
3364
3365 set whichwrap+=l
3366 call setline(1, ['one two', 'three four'])
3367 exe "norm! $3x"
3368 call assert_equal(['one twhree four'], getline(1, '$'))
3369 close!
3370 set whichwrap&
3371endfunc
3372
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003373" Test for 'w' and 'b' commands
3374func Test_normal_word_move()
3375 new
3376 call setline(1, ['foo bar a', '', 'foo bar b'])
3377 " copy a single character word at the end of a line
3378 normal 1G$yw
3379 call assert_equal('a', @")
3380 " copy a single character word at the end of a file
3381 normal G$yw
3382 call assert_equal('b', @")
3383 " check for a word movement handling an empty line properly
3384 normal 1G$vwy
3385 call assert_equal("a\n\n", @")
3386
3387 " copy using 'b' command
3388 %d
3389 " non-empty blank line at the start of file
3390 call setline(1, [' ', 'foo bar'])
3391 normal 2Gyb
3392 call assert_equal(" \n", @")
3393 " try to copy backwards from the start of the file
3394 call setline(1, ['one two', 'foo bar'])
3395 call assert_beeps('normal ggyb')
3396 " 'b' command should stop at an empty line
3397 call setline(1, ['one two', '', 'foo bar'])
3398 normal 3Gyb
3399 call assert_equal("\n", @")
3400 normal 3Gy2b
3401 call assert_equal("two\n", @")
3402 " 'b' command should not stop at a non-empty blank line
3403 call setline(1, ['one two', ' ', 'foo bar'])
3404 normal 3Gyb
3405 call assert_equal("two\n ", @")
3406
3407 close!
3408endfunc
3409
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003410" Test for 'scrolloff' with a long line that doesn't fit in the screen
3411func Test_normal_scroloff()
3412 10new
3413 80vnew
3414 call setline(1, repeat('a', 1000))
3415 set scrolloff=10
3416 normal gg10gj
3417 call assert_equal(8, winline())
3418 normal 10gj
3419 call assert_equal(10, winline())
3420 normal 10gk
3421 call assert_equal(3, winline())
3422 set scrolloff&
3423 close!
3424endfunc
3425
3426" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3427func Test_normal_vert_scroll_longline()
3428 10new
3429 80vnew
3430 call setline(1, range(1, 10))
3431 call append(5, repeat('a', 1000))
3432 exe "normal gg\<C-F>"
3433 call assert_equal(6, line('.'))
3434 exe "normal \<C-F>\<C-F>"
3435 call assert_equal(11, line('.'))
3436 call assert_equal(1, winline())
3437 exe "normal \<C-B>"
3438 call assert_equal(10, line('.'))
3439 call assert_equal(3, winline())
3440 exe "normal \<C-B>\<C-B>"
3441 call assert_equal(5, line('.'))
3442 call assert_equal(5, winline())
3443 close!
3444endfunc
3445
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003446" Test for jumping in a file using %
3447func Test_normal_percent_jump()
3448 new
3449 call setline(1, range(1, 100))
3450
3451 " jumping to a folded line should open the fold
3452 25,75fold
3453 call feedkeys('50%', 'xt')
3454 call assert_equal(50, line('.'))
3455 call assert_equal(-1, foldclosedend(50))
3456 close!
3457endfunc
3458
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003459" Test for << and >> commands to shift text by 'shiftwidth'
3460func Test_normal_shift_rightleft()
3461 new
3462 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3463 set shiftwidth=2 tabstop=8
3464 normal gg6>>
3465 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3466 \ getline(1, '$'))
3467 normal ggVG2>>
3468 call assert_equal([' one', '', "\t ", "\ttwo",
3469 \ "\t three", "\t four"], getline(1, '$'))
3470 normal gg6<<
3471 call assert_equal([' one', '', "\t ", ' two', "\t three",
3472 \ "\t four"], getline(1, '$'))
3473 normal ggVG2<<
3474 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3475 \ getline(1, '$'))
3476 set shiftwidth& tabstop&
3477 bw!
3478endfunc
3479
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003480" Some commands like yy, cc, dd, >>, << and !! accept a count after
3481" typing the first letter of the command.
3482func Test_normal_count_after_operator()
3483 new
3484 setlocal shiftwidth=4 tabstop=8 autoindent
3485 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3486 let @a = ''
3487 normal! j"ay4y
3488 call assert_equal("two\nthree\nfour\nfive\n", @a)
3489 normal! 3G>2>
3490 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3491 \ getline(1, '$'))
3492 exe "normal! 3G0c2cred\nblue"
3493 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3494 \ getline(1, '$'))
3495 exe "normal! gg<8<"
3496 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3497 \ getline(1, '$'))
3498 exe "normal! ggd3d"
3499 call assert_equal(['blue', 'five'], getline(1, '$'))
3500 call setline(1, range(1, 4))
3501 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3502 call assert_equal('".,.+2!', @:)
3503 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3504 call assert_equal('".!', @:)
3505 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3506 call assert_equal('".,$!', @:)
3507 bw!
3508endfunc
3509
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003510func Test_normal_gj_on_extra_wide_char()
3511 new | 25vsp
3512 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3513 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3514 \ ' dreizehn v ierzehn fünfzehn'
3515 put =text
3516 call cursor(2,1)
3517 norm! gj
3518 call assert_equal([0,2,25,0], getpos('.'))
3519 bw!
3520endfunc
3521
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003522" vim: shiftwidth=2 sts=2 expandtab