blob: 57ea6d3ecce9d642e95830083ca725440282696e [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
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00006source vim9.vim
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01007
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01008func Setup_NewWindow()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02009 10new
10 call setline(1, range(1,100))
11endfunc
12
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010013func MyFormatExpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020014 " Adds '->$' at lines having numbers followed by trailing whitespace
15 for ln in range(v:lnum, v:lnum+v:count-1)
16 let line = getline(ln)
17 if getline(ln) =~# '\d\s\+$'
18 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
19 endif
20 endfor
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020021endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020022
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010023func CountSpaces(type, ...)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020024 " for testing operatorfunc
25 " will count the number of spaces
26 " and return the result in g:a
27 let sel_save = &selection
28 let &selection = "inclusive"
29 let reg_save = @@
30
31 if a:0 " Invoked from Visual mode, use gv command.
32 silent exe "normal! gvy"
33 elseif a:type == 'line'
34 silent exe "normal! '[V']y"
35 else
36 silent exe "normal! `[v`]y"
37 endif
Bram Moolenaar777e7c22021-10-25 17:07:04 +010038 let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020039 let &selection = sel_save
40 let @@ = reg_save
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020041endfunc
42
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010043func OpfuncDummy(type, ...)
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010044 " for testing operatorfunc
Bram Moolenaar777e7c22021-10-25 17:07:04 +010045 let g:opt = &linebreak
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010046
47 if a:0 " Invoked from Visual mode, use gv command.
48 silent exe "normal! gvy"
49 elseif a:type == 'line'
50 silent exe "normal! '[V']y"
51 else
52 silent exe "normal! `[v`]y"
53 endif
54 " Create a new dummy window
55 new
Bram Moolenaar777e7c22021-10-25 17:07:04 +010056 let g:bufnr = bufnr('%')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020057endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020058
Bram Moolenaar1671f442020-03-10 07:48:13 +010059func Test_normal00_optrans()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020060 new
61 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
62 1
63 exe "norm! Sfoobar\<esc>"
64 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
65 2
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020066 exe "norm! $vbsone"
67 call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020068 norm! VS Second line here
69 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
70 %d
71 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
72 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
73
74 1
75 norm! 2D
76 call assert_equal(['3 this is the third line', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
77 set cpo+=#
78 norm! 4D
79 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
80
81 " clean up
82 set cpo-=#
83 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020084endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020085
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010086func Test_normal01_keymodel()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020087 call Setup_NewWindow()
88 " Test 1: depending on 'keymodel' <s-down> does something different
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020089 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020090 call feedkeys("V\<S-Up>y", 'tx')
91 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020092 set keymodel=startsel
93 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020094 call feedkeys("V\<S-Up>y", 'tx')
95 call assert_equal(['49', '50'], getline("'<", "'>"))
96 " Start visual mode when keymodel = startsel
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020097 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020098 call feedkeys("\<S-Up>y", 'tx')
99 call assert_equal(['49', '5'], getreg(0, 0, 1))
Bram Moolenaar1671f442020-03-10 07:48:13 +0100100 " Use the different Shift special keys
101 50
102 call feedkeys("\<S-Right>\<S-Left>\<S-Up>\<S-Down>\<S-Home>\<S-End>y", 'tx')
103 call assert_equal(['50'], getline("'<", "'>"))
104 call assert_equal(['50', ''], getreg(0, 0, 1))
105
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200106 " Do not start visual mode when keymodel=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200107 set keymodel=
108 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200109 call feedkeys("\<S-Up>y$", 'tx')
110 call assert_equal(['42'], getreg(0, 0, 1))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200111 " Stop visual mode when keymodel=stopsel
112 set keymodel=stopsel
113 50
114 call feedkeys("Vkk\<Up>yy", 'tx')
115 call assert_equal(['47'], getreg(0, 0, 1))
116
117 set keymodel=
118 50
119 call feedkeys("Vkk\<Up>yy", 'tx')
120 call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200121
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200122 " Test for using special keys to start visual selection
123 %d
124 call setline(1, ['red fox tail', 'red fox tail', 'red fox tail'])
125 set keymodel=startsel
126 " Test for <S-PageUp> and <S-PageDown>
127 call cursor(1, 1)
128 call feedkeys("\<S-PageDown>y", 'xt')
129 call assert_equal([0, 1, 1, 0], getpos("'<"))
130 call assert_equal([0, 3, 1, 0], getpos("'>"))
131 call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
132 call assert_equal([0, 2, 1, 0], getpos("'<"))
133 call assert_equal([0, 3, 8, 0], getpos("'>"))
134 " Test for <S-C-Home> and <S-C-End>
135 call cursor(2, 12)
136 call feedkeys("\<S-C-Home>y", 'xt')
137 call assert_equal([0, 1, 1, 0], getpos("'<"))
138 call assert_equal([0, 2, 12, 0], getpos("'>"))
139 call cursor(1, 4)
140 call feedkeys("\<S-C-End>y", 'xt')
141 call assert_equal([0, 1, 4, 0], getpos("'<"))
142 call assert_equal([0, 3, 13, 0], getpos("'>"))
143 " Test for <S-C-Left> and <S-C-Right>
144 call cursor(2, 5)
145 call feedkeys("\<S-C-Right>y", 'xt')
146 call assert_equal([0, 2, 5, 0], getpos("'<"))
147 call assert_equal([0, 2, 9, 0], getpos("'>"))
148 call cursor(2, 9)
149 call feedkeys("\<S-C-Left>y", 'xt')
150 call assert_equal([0, 2, 5, 0], getpos("'<"))
151 call assert_equal([0, 2, 9, 0], getpos("'>"))
152
153 set keymodel&
154
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200155 " clean up
156 bw!
157endfunc
158
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100159func Test_normal03_join()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200160 " basic join test
161 call Setup_NewWindow()
162 50
163 norm! VJ
164 call assert_equal('50 51', getline('.'))
165 $
166 norm! J
167 call assert_equal('100', getline('.'))
168 $
169 norm! V9-gJ
170 call assert_equal('919293949596979899100', getline('.'))
171 call setline(1, range(1,100))
172 $
173 :j 10
174 call assert_equal('100', getline('.'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200175 call assert_beeps('normal GVJ')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200176 " clean up
177 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200178endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200179
Bram Moolenaar004a6782020-04-11 17:09:31 +0200180" basic filter test
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100181func Test_normal04_filter()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200182 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200183 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200184 call Setup_NewWindow()
185 1
186 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
187 call assert_equal('| 1', getline('.'))
188 90
189 :sil :!echo one
190 call feedkeys('.', 'tx')
191 call assert_equal('| 90', getline('.'))
192 95
193 set cpo+=!
194 " 2 <CR>, 1: for executing the command,
195 " 2: clear hit-enter-prompt
196 call feedkeys("!!\n", 'tx')
197 call feedkeys(":!echo one\n\n", 'tx')
198 call feedkeys(".", 'tx')
199 call assert_equal('one', getline('.'))
200 set cpo-=!
201 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200202endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200203
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100204func Test_normal05_formatexpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200205 " basic formatexpr test
206 call Setup_NewWindow()
207 %d_
208 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
209 1
210 set formatexpr=MyFormatExpr()
211 norm! gqG
212 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
213 set formatexpr=
214 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200215endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200216
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200217func Test_normal05_formatexpr_newbuf()
218 " Edit another buffer in the 'formatexpr' function
219 new
220 func! Format()
221 edit another
222 endfunc
223 set formatexpr=Format()
224 norm gqG
225 bw!
226 set formatexpr=
227endfunc
228
229func Test_normal05_formatexpr_setopt()
230 " Change the 'formatexpr' value in the function
231 new
232 func! Format()
233 set formatexpr=
234 endfunc
235 set formatexpr=Format()
236 norm gqG
237 bw!
238 set formatexpr=
239endfunc
240
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200241" When 'formatexpr' returns non-zero, internal formatting is used.
242func Test_normal_formatexpr_returns_nonzero()
243 new
244 call setline(1, ['one', 'two'])
245 func! Format()
246 return 1
247 endfunc
248 setlocal formatexpr=Format()
249 normal VGgq
250 call assert_equal(['one two'], getline(1, '$'))
251 setlocal formatexpr=
252 delfunc Format
253 close!
254endfunc
255
Bram Moolenaar004a6782020-04-11 17:09:31 +0200256" basic test for formatprg
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100257func Test_normal06_formatprg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200258 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200259 CheckNotMSWindows
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100260
261 " uses sed to number non-empty lines
262 call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh')
263 call system('chmod +x ./Xsed_format.sh')
264 let text = ['a', '', 'c', '', ' ', 'd', 'e']
265 let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
266
267 10new
268 call setline(1, text)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200269 set formatprg=./Xsed_format.sh
270 norm! gggqG
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100271 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200272 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100273
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100274 call setline(1, text)
275 set formatprg=donothing
276 setlocal formatprg=./Xsed_format.sh
277 norm! gggqG
278 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200279 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100280
Bram Moolenaar004a6782020-04-11 17:09:31 +0200281 " Check for the command-line ranges added to 'formatprg'
282 set formatprg=cat
283 call setline(1, ['one', 'two', 'three', 'four', 'five'])
284 call feedkeys('gggqG', 'xt')
285 call assert_equal('.,$!cat', @:)
286 call feedkeys('2Ggq2j', 'xt')
287 call assert_equal('.,.+2!cat', @:)
288
289 bw!
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200290 " clean up
291 set formatprg=
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100292 setlocal formatprg=
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200293 call delete('Xsed_format.sh')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200294endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200295
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100296func Test_normal07_internalfmt()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200297 " basic test for internal formmatter to textwidth of 12
298 let list=range(1,11)
299 call map(list, 'v:val." "')
300 10new
301 call setline(1, list)
302 set tw=12
Bram Moolenaar004a6782020-04-11 17:09:31 +0200303 norm! ggVGgq
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200304 call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
305 " clean up
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100306 set tw=0
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200307 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200308endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200309
Bram Moolenaar004a6782020-04-11 17:09:31 +0200310" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100311func Test_normal08_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +0200312 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200313 call Setup_NewWindow()
314 50
315 setl foldenable fdm=marker
316 " First fold
317 norm! V4jzf
318 " check that folds have been created
319 call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
320 " Second fold
321 46
322 norm! V10jzf
323 " check that folds have been created
324 call assert_equal('46/*{{{*/', getline(46))
325 call assert_equal('60/*}}}*/', getline(60))
326 norm! k
327 call assert_equal('45', getline('.'))
328 norm! j
329 call assert_equal('46/*{{{*/', getline('.'))
330 norm! j
331 call assert_equal('61', getline('.'))
332 norm! k
333 " open a fold
334 norm! Vzo
335 norm! k
336 call assert_equal('45', getline('.'))
337 norm! j
338 call assert_equal('46/*{{{*/', getline('.'))
339 norm! j
340 call assert_equal('47', getline('.'))
341 norm! k
342 norm! zcVzO
343 call assert_equal('46/*{{{*/', getline('.'))
344 norm! j
345 call assert_equal('47', getline('.'))
346 norm! j
347 call assert_equal('48', getline('.'))
348 norm! j
349 call assert_equal('49', getline('.'))
350 norm! j
351 call assert_equal('50/*{{{*/', getline('.'))
352 norm! j
353 call assert_equal('51', getline('.'))
354 " delete folds
355 :46
356 " collapse fold
357 norm! V14jzC
358 " delete all folds recursively
359 norm! VzD
360 call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
361
362 " clean up
363 setl nofoldenable fdm=marker
364 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200365endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200366
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000367func Test_normal09a_operatorfunc()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200368 " Test operatorfunc
369 call Setup_NewWindow()
370 " Add some spaces for counting
371 50,60s/$/ /
372 unlet! g:a
373 let g:a=0
374 nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
375 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
376 50
377 norm V2j,,
378 call assert_equal(6, g:a)
379 norm V,,
380 call assert_equal(2, g:a)
381 norm ,,l
382 call assert_equal(0, g:a)
383 50
384 exe "norm 0\<c-v>10j2l,,"
385 call assert_equal(11, g:a)
386 50
387 norm V10j,,
388 call assert_equal(22, g:a)
389
390 " clean up
391 unmap <buffer> ,,
392 set opfunc=
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100393 unlet! g:a
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200394 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200395endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200396
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000397func Test_normal09b_operatorfunc()
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100398 " Test operatorfunc
399 call Setup_NewWindow()
400 " Add some spaces for counting
401 50,60s/$/ /
402 unlet! g:opt
403 set linebreak
404 nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
405 50
406 norm ,,j
407 exe "bd!" g:bufnr
408 call assert_true(&linebreak)
409 call assert_equal(g:opt, &linebreak)
410 set nolinebreak
411 norm ,,j
412 exe "bd!" g:bufnr
413 call assert_false(&linebreak)
414 call assert_equal(g:opt, &linebreak)
415
416 " clean up
417 unmap <buffer> ,,
418 set opfunc=
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200419 call assert_fails('normal Vg@', 'E774:')
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100420 bw!
421 unlet! g:opt
422endfunc
423
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000424func OperatorfuncRedo(_)
425 let g:opfunc_count = v:count
426endfunc
427
428func Test_normal09c_operatorfunc()
429 " Test redoing operatorfunc
430 new
431 call setline(1, 'some text')
432 set operatorfunc=OperatorfuncRedo
433 normal v3g@
434 call assert_equal(3, g:opfunc_count)
435 let g:opfunc_count = 0
436 normal .
437 call assert_equal(3, g:opfunc_count)
438
439 bw!
440 unlet g:opfunc_count
441 set operatorfunc=
442endfunc
443
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000444" Test for different ways of setting the 'operatorfunc' option
445func Test_opfunc_callback()
446 new
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000447 func OpFunc1(callnr, type)
448 let g:OpFunc1Args = [a:callnr, a:type]
449 endfunc
450 func OpFunc2(type)
451 let g:OpFunc2Args = [a:type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000452 endfunc
453
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000454 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000455 #" Test for using a function name
456 LET &opfunc = 'g:OpFunc2'
457 LET g:OpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000458 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000459 call assert_equal(['char'], g:OpFunc2Args)
460
461 #" Test for using a function()
462 set opfunc=function('g:OpFunc1',\ [10])
463 LET g:OpFunc1Args = []
464 normal! g@l
465 call assert_equal([10, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000466
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000467 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000468 VAR Fn = function('g:OpFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000469 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000470 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000471 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000472 call assert_equal([11, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000473
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000474 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000475 LET Fn = function('g:OpFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000476 LET &operatorfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000477 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000478 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000479 call assert_equal([12, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000480
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000481 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000482 set operatorfunc=funcref('g:OpFunc1',\ [13])
483 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000484 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000485 call assert_equal([13, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000486
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000487 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000488 LET Fn = funcref('g:OpFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000489 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000490 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000491 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000492 call assert_equal([14, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000493
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000494 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000495 LET Fn = funcref('g:OpFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000496 LET &opfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000497 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000498 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000499 call assert_equal([15, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000500
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000501 #" Test for using a lambda function using set
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000502 VAR optval = "LSTART a LMIDDLE OpFunc1(16, a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000503 LET optval = substitute(optval, ' ', '\\ ', 'g')
504 exe "set opfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000505 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000506 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000507 call assert_equal([16, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000508
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000509 #" Test for using a lambda function using LET
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000510 LET &opfunc = LSTART a LMIDDLE OpFunc1(17, a) LEND
511 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000512 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000513 call assert_equal([17, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000514
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000515 #" Set 'operatorfunc' to a string(lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000516 LET &opfunc = 'LSTART a LMIDDLE OpFunc1(18, a) LEND'
517 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000518 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000519 call assert_equal([18, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000520
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000521 #" Set 'operatorfunc' to a variable with a lambda expression
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000522 VAR Lambda = LSTART a LMIDDLE OpFunc1(19, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000523 LET &opfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000524 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000525 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000526 call assert_equal([19, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000527
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000528 #" Set 'operatorfunc' to a string(variable with a lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000529 LET Lambda = LSTART a LMIDDLE OpFunc1(20, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000530 LET &opfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000531 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000532 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000533 call assert_equal([20, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000534
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000535 #" Try to use 'operatorfunc' after the function is deleted
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000536 func g:TmpOpFunc1(type)
537 let g:TmpOpFunc1Args = [21, a:type]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000538 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000539 LET &opfunc = function('g:TmpOpFunc1')
540 delfunc g:TmpOpFunc1
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000541 call test_garbagecollect_now()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000542 LET g:TmpOpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000543 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000544 call assert_equal([], g:TmpOpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000545
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000546 #" Try to use a function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000547 func g:TmpOpFunc2(x, y)
548 let g:TmpOpFunc2Args = [a:x, a:y]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000549 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000550 set opfunc=TmpOpFunc2
551 LET g:TmpOpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000552 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000553 call assert_equal([], g:TmpOpFunc2Args)
554 delfunc TmpOpFunc2
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000555
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000556 #" Try to use a lambda function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000557 LET &opfunc = LSTART a, b LMIDDLE OpFunc1(22, b) LEND
558 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000559 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000560 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000561
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000562 #" Test for clearing the 'operatorfunc' option
563 set opfunc=''
564 set opfunc&
565 call assert_fails("set opfunc=function('abc')", "E700:")
566 call assert_fails("set opfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000567
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000568 #" set 'operatorfunc' to a non-existing function
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000569 LET &opfunc = function('g:OpFunc1', [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000570 call assert_fails("set opfunc=function('NonExistingFunc')", 'E700:')
571 call assert_fails("LET &opfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000572 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000573 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000574 call assert_equal([23, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000575 END
576 call CheckTransLegacySuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000577
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000578 " Test for using a script-local function name
579 func s:OpFunc3(type)
580 let g:OpFunc3Args = [a:type]
581 endfunc
582 set opfunc=s:OpFunc3
583 let g:OpFunc3Args = []
584 normal! g@l
585 call assert_equal(['char'], g:OpFunc3Args)
586
587 let &opfunc = 's:OpFunc3'
588 let g:OpFunc3Args = []
589 normal! g@l
590 call assert_equal(['char'], g:OpFunc3Args)
591 delfunc s:OpFunc3
592
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000593 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000594 set opfunc=(a)\ =>\ OpFunc1(24,\ a)
595 let g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000596 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000597 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000598
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000599 " set 'operatorfunc' to a partial with dict. This used to cause a crash.
600 func SetOpFunc()
601 let operator = {'execute': function('OperatorExecute')}
602 let &opfunc = operator.execute
603 endfunc
604 func OperatorExecute(_) dict
605 endfunc
606 call SetOpFunc()
607 call test_garbagecollect_now()
608 set operatorfunc=
609 delfunc SetOpFunc
610 delfunc OperatorExecute
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000611
612 " Vim9 tests
613 let lines =<< trim END
614 vim9script
615
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000616 def g:Vim9opFunc(val: number, type: string): void
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000617 g:OpFunc1Args = [val, type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000618 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000619
620 # Test for using a def function with opfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000621 set opfunc=function('g:Vim9opFunc',\ [60])
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000622 g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000623 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000624 assert_equal([60, 'char'], g:OpFunc1Args)
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000625
626 # Test for using a global function name
627 &opfunc = g:OpFunc2
628 g:OpFunc2Args = []
629 normal! g@l
630 assert_equal(['char'], g:OpFunc2Args)
631 bw!
632
633 # Test for using a script-local function name
634 def s:LocalOpFunc(type: string): void
635 g:LocalOpFuncArgs = [type]
636 enddef
637 &opfunc = s:LocalOpFunc
638 g:LocalOpFuncArgs = []
639 normal! g@l
640 assert_equal(['char'], g:LocalOpFuncArgs)
641 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000642 END
643 call CheckScriptSuccess(lines)
644
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000645 " setting 'opfunc' to a script local function outside of a script context
646 " should fail
647 let cleanup =<< trim END
648 call writefile([execute('messages')], 'Xtest.out')
649 qall
650 END
651 call writefile(cleanup, 'Xverify.vim')
652 call RunVim([], [], "-c \"set opfunc=s:abc\" -S Xverify.vim")
653 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
654 call delete('Xtest.out')
655 call delete('Xverify.vim')
656
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000657 " cleanup
658 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000659 delfunc OpFunc1
660 delfunc OpFunc2
661 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000662 %bw!
663endfunc
664
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100665func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200666 " Test for expand()
667 10new
668 call setline(1, ['1', 'ifooar,,cbar'])
669 2
670 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200671 call assert_equal('cbar', expand('<cword>'))
672 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
673
674 call setline(1, ['prx = list[idx];'])
675 1
676 let expected = ['', 'prx', 'prx', 'prx',
677 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
678 \ 'idx', 'idx', 'idx', 'idx',
679 \ 'list[idx]',
680 \ '];',
681 \ ]
682 for i in range(1, 16)
683 exe 'norm ' . i . '|'
684 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
685 endfor
686
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200687 " Test for <cexpr> in state.val and ptr->val
688 call setline(1, 'x = state.val;')
689 call cursor(1, 10)
690 call assert_equal('state.val', expand('<cexpr>'))
691 call setline(1, 'x = ptr->val;')
692 call cursor(1, 9)
693 call assert_equal('ptr->val', expand('<cexpr>'))
694
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100695 if executable('echo')
696 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100697 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100698 endif
699
700 " Test expand(`=...`) i.e. backticks expression expansion
701 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100702 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100703
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200704 " clean up
705 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200706endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200707
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200708" Test for expand() in latin1 encoding
709func Test_normal_expand_latin1()
710 new
711 let save_enc = &encoding
712 set encoding=latin1
713 call setline(1, 'val = item->color;')
714 call cursor(1, 11)
715 call assert_equal('color', expand("<cword>"))
716 call assert_equal('item->color', expand("<cexpr>"))
717 let &encoding = save_enc
718 bw!
719endfunc
720
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100721func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200722 " test for 'showcmd'
723 10new
724 exe "norm! ofoobar\<esc>"
725 call assert_equal(2, line('$'))
726 set showcmd
727 exe "norm! ofoobar2\<esc>"
728 call assert_equal(3, line('$'))
729 exe "norm! VAfoobar3\<esc>"
730 call assert_equal(3, line('$'))
731 exe "norm! 0d3\<del>2l"
732 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200733 " test for the visual block size displayed in the status line
734 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
735 call feedkeys("ggl\<C-V>lljj", 'xt')
736 redraw!
737 call assert_match('3x3$', Screenline(&lines))
738 call feedkeys("\<C-V>", 'xt')
739 " test for visually selecting a multi-byte character
740 call setline(1, ["\U2206"])
741 call feedkeys("ggv", 'xt')
742 redraw!
743 call assert_match('1-3$', Screenline(&lines))
744 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200745 " test for visually selecting the end of line
746 call setline(1, ["foobar"])
747 call feedkeys("$vl", 'xt')
748 redraw!
749 call assert_match('2$', Screenline(&lines))
750 call feedkeys("y", 'xt')
751 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200752 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200753endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200754
Bram Moolenaar1671f442020-03-10 07:48:13 +0100755" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100756func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200757 10new
758 call setline(1, range(1,5))
759 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100760 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200761 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100762 call assert_beeps('normal! G2dd')
763 call assert_beeps("normal! g\<C-A>")
764 call assert_beeps("normal! g\<C-X>")
765 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100766 call assert_beeps("normal! vQ\<Esc>")
767 call assert_beeps("normal! 2[[")
768 call assert_beeps("normal! 2]]")
769 call assert_beeps("normal! 2[]")
770 call assert_beeps("normal! 2][")
771 call assert_beeps("normal! 4[z")
772 call assert_beeps("normal! 4]z")
773 call assert_beeps("normal! 4[c")
774 call assert_beeps("normal! 4]c")
775 call assert_beeps("normal! 200%")
776 call assert_beeps("normal! %")
777 call assert_beeps("normal! 2{")
778 call assert_beeps("normal! 2}")
779 call assert_beeps("normal! r\<Right>")
780 call assert_beeps("normal! 8ry")
781 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200782 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200783endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200784
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100785func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200786 " Test for F1
787 call assert_equal(1, winnr())
788 call feedkeys("\<f1>", 'txi')
789 call assert_match('help\.txt', bufname('%'))
790 call assert_equal(2, winnr('$'))
791 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200792endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200793
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100794func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200795 " basic test for Ctrl-F and Ctrl-B
796 call Setup_NewWindow()
797 exe "norm! \<c-f>"
798 call assert_equal('9', getline('.'))
799 exe "norm! 2\<c-f>"
800 call assert_equal('25', getline('.'))
801 exe "norm! 2\<c-b>"
802 call assert_equal('18', getline('.'))
803 1
804 set scrolloff=5
805 exe "norm! 2\<c-f>"
806 call assert_equal('21', getline('.'))
807 exe "norm! \<c-b>"
808 call assert_equal('13', getline('.'))
809 1
810 set scrolloff=99
811 exe "norm! \<c-f>"
812 call assert_equal('13', getline('.'))
813 set scrolloff=0
814 100
815 exe "norm! $\<c-b>"
816 call assert_equal('92', getline('.'))
817 call assert_equal([0, 92, 1, 0, 1], getcurpos())
818 100
819 set nostartofline
820 exe "norm! $\<c-b>"
821 call assert_equal('92', getline('.'))
822 call assert_equal([0, 92, 2, 0, 2147483647], getcurpos())
823 " cleanup
824 set startofline
825 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200826endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200827
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100828func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200829 10new
830 norm oxxxxxxx
831 exe "norm 2\<c-f>"
832 " check with valgrind that cursor is put back in column 1
833 exe "norm 2\<c-b>"
834 bw!
835endfunc
836
Bram Moolenaar1671f442020-03-10 07:48:13 +0100837" Test for errors with z command
838func Test_normal_z_error()
839 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200840 call assert_beeps('normal! zq')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100841endfunc
842
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100843func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200844 " basic test for z commands that scroll the window
845 call Setup_NewWindow()
846 100
847 norm! >>
848 " Test for z<cr>
849 exe "norm! z\<cr>"
850 call assert_equal(' 100', getline('.'))
851 call assert_equal(100, winsaveview()['topline'])
852 call assert_equal([0, 100, 2, 0, 9], getcurpos())
853
854 " Test for zt
855 21
856 norm! >>0zt
857 call assert_equal(' 21', getline('.'))
858 call assert_equal(21, winsaveview()['topline'])
859 call assert_equal([0, 21, 1, 0, 8], getcurpos())
860
861 " Test for zb
862 30
863 norm! >>$ztzb
864 call assert_equal(' 30', getline('.'))
865 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
866 call assert_equal([0, 30, 3, 0, 2147483647], getcurpos())
867
868 " Test for z-
869 1
870 30
871 norm! 0z-
872 call assert_equal(' 30', getline('.'))
873 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
874 call assert_equal([0, 30, 2, 0, 9], getcurpos())
875
876 " Test for z{height}<cr>
877 call assert_equal(10, winheight(0))
878 exe "norm! z12\<cr>"
879 call assert_equal(12, winheight(0))
880 exe "norm! z10\<cr>"
881 call assert_equal(10, winheight(0))
882
883 " Test for z.
884 1
885 21
886 norm! 0z.
887 call assert_equal(' 21', getline('.'))
888 call assert_equal(17, winsaveview()['topline'])
889 call assert_equal([0, 21, 2, 0, 9], getcurpos())
890
891 " Test for zz
892 1
893 21
894 norm! 0zz
895 call assert_equal(' 21', getline('.'))
896 call assert_equal(17, winsaveview()['topline'])
897 call assert_equal([0, 21, 1, 0, 8], getcurpos())
898
899 " Test for z+
900 11
901 norm! zt
902 norm! z+
903 call assert_equal(' 21', getline('.'))
904 call assert_equal(21, winsaveview()['topline'])
905 call assert_equal([0, 21, 2, 0, 9], getcurpos())
906
907 " Test for [count]z+
908 1
909 norm! 21z+
910 call assert_equal(' 21', getline('.'))
911 call assert_equal(21, winsaveview()['topline'])
912 call assert_equal([0, 21, 2, 0, 9], getcurpos())
913
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200914 " Test for z+ with [count] greater than buffer size
915 1
916 norm! 1000z+
917 call assert_equal(' 100', getline('.'))
918 call assert_equal(100, winsaveview()['topline'])
919 call assert_equal([0, 100, 2, 0, 9], getcurpos())
920
921 " Test for z+ from the last buffer line
922 norm! Gz.z+
923 call assert_equal(' 100', getline('.'))
924 call assert_equal(100, winsaveview()['topline'])
925 call assert_equal([0, 100, 2, 0, 9], getcurpos())
926
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200927 " Test for z^
928 norm! 22z+0
929 norm! z^
930 call assert_equal(' 21', getline('.'))
931 call assert_equal(12, winsaveview()['topline'])
932 call assert_equal([0, 21, 2, 0, 9], getcurpos())
933
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200934 " Test for z^ from first buffer line
935 norm! ggz^
936 call assert_equal('1', getline('.'))
937 call assert_equal(1, winsaveview()['topline'])
938 call assert_equal([0, 1, 1, 0, 1], getcurpos())
939
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200940 " Test for [count]z^
941 1
942 norm! 30z^
943 call assert_equal(' 21', getline('.'))
944 call assert_equal(12, winsaveview()['topline'])
945 call assert_equal([0, 21, 2, 0, 9], getcurpos())
946
947 " cleanup
948 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200949endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200950
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100951func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200952 " basic test for z commands that scroll the window
953 10new
954 15vsp
955 set nowrap listchars=
956 let lineA='abcdefghijklmnopqrstuvwxyz'
957 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
958 $put =lineA
959 $put =lineB
960 1d
961
Bram Moolenaar1671f442020-03-10 07:48:13 +0100962 " Test for zl and zh with a count
963 norm! 0z10l
964 call assert_equal([11, 1], [col('.'), wincol()])
965 norm! z4h
966 call assert_equal([11, 5], [col('.'), wincol()])
967 normal! 2gg
968
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200969 " Test for zl
970 1
971 norm! 5zl
972 call assert_equal(lineA, getline('.'))
973 call assert_equal(6, col('.'))
974 call assert_equal(5, winsaveview()['leftcol'])
975 norm! yl
976 call assert_equal('f', @0)
977
978 " Test for zh
979 norm! 2zh
980 call assert_equal(lineA, getline('.'))
981 call assert_equal(6, col('.'))
982 norm! yl
983 call assert_equal('f', @0)
984 call assert_equal(3, winsaveview()['leftcol'])
985
986 " Test for zL
987 norm! zL
988 call assert_equal(11, col('.'))
989 norm! yl
990 call assert_equal('k', @0)
991 call assert_equal(10, winsaveview()['leftcol'])
992 norm! 2zL
993 call assert_equal(25, col('.'))
994 norm! yl
995 call assert_equal('y', @0)
996 call assert_equal(24, winsaveview()['leftcol'])
997
998 " Test for zH
999 norm! 2zH
1000 call assert_equal(25, col('.'))
1001 call assert_equal(10, winsaveview()['leftcol'])
1002 norm! yl
1003 call assert_equal('y', @0)
1004
1005 " Test for zs
1006 norm! $zs
1007 call assert_equal(26, col('.'))
1008 call assert_equal(25, winsaveview()['leftcol'])
1009 norm! yl
1010 call assert_equal('z', @0)
1011
1012 " Test for ze
1013 norm! ze
1014 call assert_equal(26, col('.'))
1015 call assert_equal(11, winsaveview()['leftcol'])
1016 norm! yl
1017 call assert_equal('z', @0)
1018
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001019 " Test for zs and ze with folds
1020 %fold
1021 norm! $zs
1022 call assert_equal(26, col('.'))
1023 call assert_equal(0, winsaveview()['leftcol'])
1024 norm! yl
1025 call assert_equal('z', @0)
1026 norm! ze
1027 call assert_equal(26, col('.'))
1028 call assert_equal(0, winsaveview()['leftcol'])
1029 norm! yl
1030 call assert_equal('z', @0)
1031
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001032 " cleanup
1033 set wrap listchars=eol:$
1034 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001035endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001036
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001037func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001038 " basic test for z commands that scroll the window
1039 " using 'sidescrolloff' setting
1040 10new
1041 20vsp
1042 set nowrap listchars= sidescrolloff=5
1043 let lineA='abcdefghijklmnopqrstuvwxyz'
1044 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1045 $put =lineA
1046 $put =lineB
1047 1d
1048
1049 " Test for zl
1050 1
1051 norm! 5zl
1052 call assert_equal(lineA, getline('.'))
1053 call assert_equal(11, col('.'))
1054 call assert_equal(5, winsaveview()['leftcol'])
1055 norm! yl
1056 call assert_equal('k', @0)
1057
1058 " Test for zh
1059 norm! 2zh
1060 call assert_equal(lineA, getline('.'))
1061 call assert_equal(11, col('.'))
1062 norm! yl
1063 call assert_equal('k', @0)
1064 call assert_equal(3, winsaveview()['leftcol'])
1065
1066 " Test for zL
1067 norm! 0zL
1068 call assert_equal(16, col('.'))
1069 norm! yl
1070 call assert_equal('p', @0)
1071 call assert_equal(10, winsaveview()['leftcol'])
1072 norm! 2zL
1073 call assert_equal(26, col('.'))
1074 norm! yl
1075 call assert_equal('z', @0)
1076 call assert_equal(15, winsaveview()['leftcol'])
1077
1078 " Test for zH
1079 norm! 2zH
1080 call assert_equal(15, col('.'))
1081 call assert_equal(0, winsaveview()['leftcol'])
1082 norm! yl
1083 call assert_equal('o', @0)
1084
1085 " Test for zs
1086 norm! $zs
1087 call assert_equal(26, col('.'))
1088 call assert_equal(20, winsaveview()['leftcol'])
1089 norm! yl
1090 call assert_equal('z', @0)
1091
1092 " Test for ze
1093 norm! ze
1094 call assert_equal(26, col('.'))
1095 call assert_equal(11, winsaveview()['leftcol'])
1096 norm! yl
1097 call assert_equal('z', @0)
1098
1099 " cleanup
1100 set wrap listchars=eol:$ sidescrolloff=0
1101 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001102endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001103
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001104" Test for commands that scroll the window horizontally. Test with folds.
1105" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1106func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001107 15new
1108 call setline(1, range(1, 100))
1109 exe "normal! 30ggz\<CR>"
1110 set foldenable
1111 33,36fold
1112 40,43fold
1113 46,49fold
1114 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001115
1116 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001117 " Top of the screen = 30
1118 " Folded lines = 9
1119 " Bottom of the screen = 30 + h + 9 - 1
1120 normal! 4L
1121 call assert_equal(35 + h, line('.'))
1122 normal! 4H
1123 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001124
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001125 " Test for using a large count value
1126 %d
1127 call setline(1, range(1, 4))
1128 norm! 6H
1129 call assert_equal(4, line('.'))
1130
1131 " Test for 'M' with folded lines
1132 %d
1133 call setline(1, range(1, 20))
1134 1,5fold
1135 norm! LM
1136 call assert_equal(12, line('.'))
1137
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001138 " Test for the CTRL-E and CTRL-Y commands with folds
1139 %d
1140 call setline(1, range(1, 10))
1141 3,5fold
1142 exe "normal 6G3\<C-E>"
1143 call assert_equal(6, line('w0'))
1144 exe "normal 2\<C-Y>"
1145 call assert_equal(2, line('w0'))
1146
1147 " Test for CTRL-Y on a folded line
1148 %d
1149 call setline(1, range(1, 100))
1150 exe (h + 2) .. "," .. (h + 4) .. "fold"
1151 exe h + 5
1152 normal z-
1153 exe "normal \<C-Y>\<C-Y>"
1154 call assert_equal(h + 1, line('w$'))
1155
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001156 " Test for CTRL-Y from the first line and CTRL-E from the last line
1157 %d
1158 set scrolloff=2
1159 call setline(1, range(1, 4))
1160 exe "normal gg\<C-Y>"
1161 call assert_equal(1, line('w0'))
1162 call assert_equal(1, line('.'))
1163 exe "normal G4\<C-E>\<C-E>"
1164 call assert_equal(4, line('w$'))
1165 call assert_equal(4, line('.'))
1166 set scrolloff&
1167
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001168 " Using <PageUp> and <PageDown> in an empty buffer should beep
1169 %d
1170 call assert_beeps('exe "normal \<PageUp>"')
1171 call assert_beeps('exe "normal \<C-B>"')
1172 call assert_beeps('exe "normal \<PageDown>"')
1173 call assert_beeps('exe "normal \<C-F>"')
1174
1175 " Test for <C-U> and <C-D> with fold
1176 %d
1177 call setline(1, range(1, 100))
1178 10,35fold
1179 set scroll=10
1180 exe "normal \<C-D>"
1181 call assert_equal(36, line('.'))
1182 exe "normal \<C-D>"
1183 call assert_equal(46, line('.'))
1184 exe "normal \<C-U>"
1185 call assert_equal(36, line('.'))
1186 exe "normal \<C-U>"
1187 call assert_equal(10, line('.'))
1188 exe "normal \<C-U>"
1189 call assert_equal(1, line('.'))
1190 set scroll&
1191
1192 " Test for scrolling to the top of the file with <C-U> and a fold
1193 10
1194 normal ztL
1195 exe "normal \<C-U>\<C-U>"
1196 call assert_equal(1, line('w0'))
1197
1198 " Test for CTRL-D on a folded line
1199 %d
1200 call setline(1, range(1, 100))
1201 50,100fold
1202 75
1203 normal z-
1204 exe "normal \<C-D>"
1205 call assert_equal(50, line('.'))
1206 call assert_equal(100, line('w$'))
1207 normal z.
1208 let lnum = winline()
1209 exe "normal \<C-D>"
1210 call assert_equal(lnum, winline())
1211 call assert_equal(50, line('.'))
1212 normal zt
1213 exe "normal \<C-D>"
1214 call assert_equal(50, line('w0'))
1215
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001216 " Test for <S-CR>. Page down.
1217 %d
1218 call setline(1, range(1, 100))
1219 call feedkeys("\<S-CR>", 'xt')
1220 call assert_equal(14, line('w0'))
1221 call assert_equal(28, line('w$'))
1222
1223 " Test for <S-->. Page up.
1224 call feedkeys("\<S-->", 'xt')
1225 call assert_equal(1, line('w0'))
1226 call assert_equal(15, line('w$'))
1227
Bram Moolenaar1671f442020-03-10 07:48:13 +01001228 set foldenable&
1229 close!
1230endfunc
1231
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001232func Test_scroll_in_ex_mode()
1233 " This was using invalid memory because w_botline was invalid.
1234 let lines =<< trim END
1235 diffsplit
1236 norm os00(
1237 call writefile(['done'], 'Xdone')
1238 qa!
1239 END
1240 call writefile(lines, 'Xscript')
1241 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1242 call assert_equal(['done'], readfile('Xdone'))
1243
1244 call delete('Xscript')
1245 call delete('Xdone')
1246endfunc
1247
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001248" Test for the 'sidescroll' option
1249func Test_sidescroll_opt()
1250 new
1251 20vnew
1252
1253 " scroll by 2 characters horizontally
1254 set sidescroll=2 nowrap
1255 call setline(1, repeat('a', 40))
1256 normal g$l
1257 call assert_equal(19, screenpos(0, 1, 21).col)
1258 normal l
1259 call assert_equal(20, screenpos(0, 1, 22).col)
1260 normal g0h
1261 call assert_equal(2, screenpos(0, 1, 2).col)
1262 call assert_equal(20, screenpos(0, 1, 20).col)
1263
1264 " when 'sidescroll' is 0, cursor positioned at the center
1265 set sidescroll=0
1266 normal g$l
1267 call assert_equal(11, screenpos(0, 1, 21).col)
1268 normal g0h
1269 call assert_equal(10, screenpos(0, 1, 10).col)
1270
1271 %bw!
1272 set wrap& sidescroll&
1273endfunc
1274
Bram Moolenaar004a6782020-04-11 17:09:31 +02001275" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001276func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001277 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001278 call Setup_NewWindow()
1279 50
1280 setl foldenable fdm=marker foldlevel=5
1281
Bram Moolenaar1671f442020-03-10 07:48:13 +01001282 call assert_beeps('normal! zj')
1283 call assert_beeps('normal! zk')
1284
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001285 " Test for zF
1286 " First fold
1287 norm! 4zF
1288 " check that folds have been created
1289 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1290
1291 " Test for zd
1292 51
1293 norm! 2zF
1294 call assert_equal(2, foldlevel('.'))
1295 norm! kzd
1296 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1297 norm! j
1298 call assert_equal(1, foldlevel('.'))
1299
1300 " Test for zD
1301 " also deletes partially selected folds recursively
1302 51
1303 norm! zF
1304 call assert_equal(2, foldlevel('.'))
1305 norm! kV2jzD
1306 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1307
1308 " Test for zE
1309 85
1310 norm! 4zF
1311 86
1312 norm! 2zF
1313 90
1314 norm! 4zF
1315 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1316 norm! zE
1317 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1318
1319 " Test for zn
1320 50
1321 set foldlevel=0
1322 norm! 2zF
1323 norm! zn
1324 norm! k
1325 call assert_equal('49', getline('.'))
1326 norm! j
1327 call assert_equal('50/*{{{*/', getline('.'))
1328 norm! j
1329 call assert_equal('51/*}}}*/', getline('.'))
1330 norm! j
1331 call assert_equal('52', getline('.'))
1332 call assert_equal(0, &foldenable)
1333
1334 " Test for zN
1335 49
1336 norm! zN
1337 call assert_equal('49', getline('.'))
1338 norm! j
1339 call assert_equal('50/*{{{*/', getline('.'))
1340 norm! j
1341 call assert_equal('52', getline('.'))
1342 call assert_equal(1, &foldenable)
1343
1344 " Test for zi
1345 norm! zi
1346 call assert_equal(0, &foldenable)
1347 norm! zi
1348 call assert_equal(1, &foldenable)
1349 norm! zi
1350 call assert_equal(0, &foldenable)
1351 norm! zi
1352 call assert_equal(1, &foldenable)
1353
1354 " Test for za
1355 50
1356 norm! za
1357 norm! k
1358 call assert_equal('49', getline('.'))
1359 norm! j
1360 call assert_equal('50/*{{{*/', getline('.'))
1361 norm! j
1362 call assert_equal('51/*}}}*/', getline('.'))
1363 norm! j
1364 call assert_equal('52', getline('.'))
1365 50
1366 norm! za
1367 norm! k
1368 call assert_equal('49', getline('.'))
1369 norm! j
1370 call assert_equal('50/*{{{*/', getline('.'))
1371 norm! j
1372 call assert_equal('52', getline('.'))
1373
1374 49
1375 norm! 5zF
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 49
1383 norm! za
1384 call assert_equal('49/*{{{*/', getline('.'))
1385 norm! j
1386 call assert_equal('50/*{{{*/', getline('.'))
1387 norm! j
1388 call assert_equal('52', getline('.'))
1389 set nofoldenable
1390 " close fold and set foldenable
1391 norm! za
1392 call assert_equal(1, &foldenable)
1393
1394 50
1395 " have to use {count}za to open all folds and make the cursor visible
1396 norm! 2za
1397 norm! 2k
1398 call assert_equal('48', getline('.'))
1399 norm! j
1400 call assert_equal('49/*{{{*/', getline('.'))
1401 norm! j
1402 call assert_equal('50/*{{{*/', getline('.'))
1403 norm! j
1404 call assert_equal('51/*}}}*/', getline('.'))
1405 norm! j
1406 call assert_equal('52', getline('.'))
1407
1408 " Test for zA
1409 49
1410 set foldlevel=0
1411 50
1412 norm! zA
1413 norm! 2k
1414 call assert_equal('48', getline('.'))
1415 norm! j
1416 call assert_equal('49/*{{{*/', getline('.'))
1417 norm! j
1418 call assert_equal('50/*{{{*/', getline('.'))
1419 norm! j
1420 call assert_equal('51/*}}}*/', getline('.'))
1421 norm! j
1422 call assert_equal('52', getline('.'))
1423
Dominique Pelle923dce22021-11-21 11:36:04 +00001424 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001425 50
1426 set nofoldenable
1427 norm! zA
1428 call assert_equal(1, &foldenable)
1429 norm! k
1430 call assert_equal('48', getline('.'))
1431 norm! j
1432 call assert_equal('49/*{{{*/', getline('.'))
1433 norm! j
1434 call assert_equal('55', getline('.'))
1435
1436 " Test for zc
1437 norm! zE
1438 50
1439 norm! 2zF
1440 49
1441 norm! 5zF
1442 set nofoldenable
1443 50
1444 " There most likely is a bug somewhere:
1445 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1446 " TODO: Should this only close the inner most fold or both folds?
1447 norm! zc
1448 call assert_equal(1, &foldenable)
1449 norm! k
1450 call assert_equal('48', getline('.'))
1451 norm! j
1452 call assert_equal('49/*{{{*/', getline('.'))
1453 norm! j
1454 call assert_equal('55', getline('.'))
1455 set nofoldenable
1456 50
1457 norm! Vjzc
1458 norm! k
1459 call assert_equal('48', getline('.'))
1460 norm! j
1461 call assert_equal('49/*{{{*/', getline('.'))
1462 norm! j
1463 call assert_equal('55', getline('.'))
1464
1465 " Test for zC
1466 set nofoldenable
1467 50
1468 norm! zCk
1469 call assert_equal('48', getline('.'))
1470 norm! j
1471 call assert_equal('49/*{{{*/', getline('.'))
1472 norm! j
1473 call assert_equal('55', getline('.'))
1474
1475 " Test for zx
1476 " 1) close folds at line 49-54
1477 set nofoldenable
1478 48
1479 norm! zx
1480 call assert_equal(1, &foldenable)
1481 norm! j
1482 call assert_equal('49/*{{{*/', getline('.'))
1483 norm! j
1484 call assert_equal('55', getline('.'))
1485
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001486 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001487 51
1488 set nofoldenable
1489 norm! zx
1490 call assert_equal(1, &foldenable)
1491 norm! 3k
1492 call assert_equal('48', getline('.'))
1493 norm! j
1494 call assert_equal('49/*{{{*/', getline('.'))
1495 norm! j
1496 call assert_equal('50/*{{{*/', getline('.'))
1497 norm! j
1498 call assert_equal('51/*}}}*/', getline('.'))
1499 norm! j
1500 call assert_equal('52', getline('.'))
1501 norm! j
1502 call assert_equal('53', getline('.'))
1503 norm! j
1504 call assert_equal('54/*}}}*/', getline('.'))
1505 norm! j
1506 call assert_equal('55', getline('.'))
1507
1508 " 3) close one level of folds
1509 48
1510 set nofoldenable
1511 set foldlevel=1
1512 norm! zx
1513 call assert_equal(1, &foldenable)
1514 call assert_equal('48', getline('.'))
1515 norm! j
1516 call assert_equal('49/*{{{*/', getline('.'))
1517 norm! j
1518 call assert_equal('50/*{{{*/', getline('.'))
1519 norm! j
1520 call assert_equal('52', getline('.'))
1521 norm! j
1522 call assert_equal('53', getline('.'))
1523 norm! j
1524 call assert_equal('54/*}}}*/', getline('.'))
1525 norm! j
1526 call assert_equal('55', getline('.'))
1527
1528 " Test for zX
1529 " Close all folds
1530 set foldlevel=0 nofoldenable
1531 50
1532 norm! zX
1533 call assert_equal(1, &foldenable)
1534 norm! k
1535 call assert_equal('48', getline('.'))
1536 norm! j
1537 call assert_equal('49/*{{{*/', getline('.'))
1538 norm! j
1539 call assert_equal('55', getline('.'))
1540
1541 " Test for zm
1542 50
1543 set nofoldenable foldlevel=2
1544 norm! zm
1545 call assert_equal(1, &foldenable)
1546 call assert_equal(1, &foldlevel)
1547 norm! zm
1548 call assert_equal(0, &foldlevel)
1549 norm! zm
1550 call assert_equal(0, &foldlevel)
1551 norm! k
1552 call assert_equal('48', getline('.'))
1553 norm! j
1554 call assert_equal('49/*{{{*/', getline('.'))
1555 norm! j
1556 call assert_equal('55', getline('.'))
1557
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001558 " Test for zm with a count
1559 50
1560 set foldlevel=2
1561 norm! 3zm
1562 call assert_equal(0, &foldlevel)
1563 call assert_equal(49, foldclosed(line('.')))
1564
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001565 " Test for zM
1566 48
1567 set nofoldenable foldlevel=99
1568 norm! zM
1569 call assert_equal(1, &foldenable)
1570 call assert_equal(0, &foldlevel)
1571 call assert_equal('48', getline('.'))
1572 norm! j
1573 call assert_equal('49/*{{{*/', getline('.'))
1574 norm! j
1575 call assert_equal('55', getline('.'))
1576
1577 " Test for zr
1578 48
1579 set nofoldenable foldlevel=0
1580 norm! zr
1581 call assert_equal(0, &foldenable)
1582 call assert_equal(1, &foldlevel)
1583 set foldlevel=0 foldenable
1584 norm! zr
1585 call assert_equal(1, &foldenable)
1586 call assert_equal(1, &foldlevel)
1587 norm! zr
1588 call assert_equal(2, &foldlevel)
1589 call assert_equal('48', getline('.'))
1590 norm! j
1591 call assert_equal('49/*{{{*/', getline('.'))
1592 norm! j
1593 call assert_equal('50/*{{{*/', getline('.'))
1594 norm! j
1595 call assert_equal('51/*}}}*/', getline('.'))
1596 norm! j
1597 call assert_equal('52', getline('.'))
1598
1599 " Test for zR
1600 48
1601 set nofoldenable foldlevel=0
1602 norm! zR
1603 call assert_equal(0, &foldenable)
1604 call assert_equal(2, &foldlevel)
1605 set foldenable foldlevel=0
1606 norm! zR
1607 call assert_equal(1, &foldenable)
1608 call assert_equal(2, &foldlevel)
1609 call assert_equal('48', getline('.'))
1610 norm! j
1611 call assert_equal('49/*{{{*/', getline('.'))
1612 norm! j
1613 call assert_equal('50/*{{{*/', getline('.'))
1614 norm! j
1615 call assert_equal('51/*}}}*/', getline('.'))
1616 norm! j
1617 call assert_equal('52', getline('.'))
1618 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1619 48
1620 call assert_equal('48', getline('.'))
1621 norm! j
1622 call assert_equal('49/*{{{*/', getline('.'))
1623 norm! j
1624 call assert_equal('50/*{{{*/', getline('.'))
1625 norm! j
1626 call assert_equal('a /*{{{*/', getline('.'))
1627 norm! j
1628 call assert_equal('51/*}}}*/', getline('.'))
1629 norm! j
1630 call assert_equal('52', getline('.'))
1631 48
1632 norm! zR
1633 call assert_equal(1, &foldenable)
1634 call assert_equal(3, &foldlevel)
1635 call assert_equal('48', getline('.'))
1636 norm! j
1637 call assert_equal('49/*{{{*/', getline('.'))
1638 norm! j
1639 call assert_equal('50/*{{{*/', getline('.'))
1640 norm! j
1641 call assert_equal('a /*{{{*/', getline('.'))
1642 norm! j
1643 call assert_equal('b /*}}}*/', getline('.'))
1644 norm! j
1645 call assert_equal('51/*}}}*/', getline('.'))
1646 norm! j
1647 call assert_equal('52', getline('.'))
1648
1649 " clean up
1650 setl nofoldenable fdm=marker foldlevel=0
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_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001655 " Reading from redirected file doesn't work on MS-Windows
1656 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001657 call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
1658 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001659 call system(GetVimCommand() .. ' -e -s < Xscript Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001660 let a=readfile('Xfile2')
1661 call assert_equal(['1', 'foo', 'bar', '2'], a)
1662
1663 " clean up
1664 for file in ['Xfile', 'Xfile2', 'Xscript']
1665 call delete(file)
1666 endfor
1667 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001668endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001669
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001670func Test_normal21_nv_hat()
1671
1672 " Edit a fresh file and wipe the buffer list so that there is no alternate
1673 " file present. Next, check for the expected command failures.
1674 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001675 call assert_fails(':buffer #', 'E86:')
1676 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001677 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001678
1679 " Test for the expected behavior when switching between two named buffers.
1680 edit Xfoo | edit Xbar
1681 call feedkeys("\<C-^>", 'tx')
1682 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1683 call feedkeys("\<C-^>", 'tx')
1684 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1685
1686 " Test for the expected behavior when only one buffer is named.
1687 enew | let l:nr = bufnr('%')
1688 call feedkeys("\<C-^>", 'tx')
1689 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1690 call feedkeys("\<C-^>", 'tx')
1691 call assert_equal('', bufname('%'))
1692 call assert_equal(l:nr, bufnr('%'))
1693
1694 " Test that no action is taken by "<C-^>" when an operator is pending.
1695 edit Xfoo
1696 call feedkeys("ci\<C-^>", 'tx')
1697 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1698
1699 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001700endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001701
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001702func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001703 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001704 " let shell = &shell
1705 " let &shell = 'sh'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001706 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001707 let args = ' -N -i NONE --noplugins -X --not-a-term'
1708 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001709 let a = readfile('Xfile')
1710 call assert_equal([], a)
1711 " Test for ZQ
1712 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001713 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001714 let a = readfile('Xfile')
1715 call assert_equal(['1', '2'], a)
1716
Bram Moolenaar1671f442020-03-10 07:48:13 +01001717 " Unsupported Z command
1718 call assert_beeps('normal! ZW')
1719
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001720 " clean up
1721 for file in ['Xfile']
1722 call delete(file)
1723 endfor
Bram Moolenaar0913a102016-09-03 19:11:59 +02001724 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001725endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001726
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001727func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001728 " Test for K command
1729 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001730 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001731 let k = &keywordprg
1732 set keywordprg=:help
1733 1
1734 norm! VK
1735 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1736 call assert_equal('help', &ft)
1737 call assert_match('\*version8.txt\*', getline('.'))
1738 helpclose
1739 norm! 0K
1740 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1741 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001742 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001743 helpclose
1744
Bram Moolenaar426f3752016-11-04 21:22:37 +01001745 set keywordprg=:new
1746 set iskeyword+=%
1747 set iskeyword+=\|
1748 2
1749 norm! K
1750 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1751 bwipe!
1752 3
1753 norm! K
1754 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1755 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001756 if !has('win32')
1757 4
1758 norm! K
1759 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1760 bwipe!
1761 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001762 set iskeyword-=%
1763 set iskeyword-=\|
1764
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001765 " Test for specifying a count to K
1766 1
1767 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1768 set keywordprg=:Kprog
1769 norm! 3K
1770 call assert_equal('3 version8', g:Kprog_Args)
1771 delcom Kprog
1772
Bram Moolenaar0913a102016-09-03 19:11:59 +02001773 " Only expect "man" to work on Unix
1774 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001775 let &keywordprg = k
1776 bw!
1777 return
1778 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001779
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001780 let not_gnu_man = has('mac') || has('bsd')
1781 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001782 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001783 set keywordprg=man\ -P\ cat
1784 else
1785 set keywordprg=man\ --pager=cat
1786 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001787 " Test for using man
1788 2
1789 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001790 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001791 call assert_match("man -P cat 'man'", a)
1792 else
1793 call assert_match("man --pager=cat 'man'", a)
1794 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001795
Bram Moolenaar1671f442020-03-10 07:48:13 +01001796 " Error cases
1797 call setline(1, '#$#')
1798 call assert_fails('normal! ggK', 'E349:')
1799 call setline(1, '---')
1800 call assert_fails('normal! ggv2lK', 'E349:')
1801 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001802 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001803 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001804 norm! V
1805 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001806
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001807 " clean up
1808 let &keywordprg = k
1809 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001810endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001811
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001812func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001813 " Testing for g?? g?g?
1814 new
1815 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1816 1
1817 norm! g??
1818 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1819 norm! g?g?
1820 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1821
1822 " clean up
1823 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001824endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001825
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001826func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001827 CheckFeature quickfix
1828
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001829 " Testing for CTRL-] g CTRL-] g]
1830 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1831 h
1832 " Test for CTRL-]
1833 call search('\<x\>$')
1834 exe "norm! \<c-]>"
1835 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1836 norm! yiW
1837 call assert_equal("*x*", @0)
1838 exe ":norm \<c-o>"
1839
1840 " Test for g_CTRL-]
1841 call search('\<v_u\>$')
1842 exe "norm! g\<c-]>"
1843 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1844 norm! yiW
1845 call assert_equal("*v_u*", @0)
1846 exe ":norm \<c-o>"
1847
1848 " Test for g]
1849 call search('\<i_<Esc>$')
1850 let a = execute(":norm! g]")
1851 call assert_match('i_<Esc>.*insert.txt', a)
1852
1853 if !empty(exepath('cscope')) && has('cscope')
1854 " setting cscopetag changes how g] works
1855 set cst
1856 exe "norm! g]"
1857 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1858 norm! yiW
1859 call assert_equal("*i_<Esc>*", @0)
1860 exe ":norm \<c-o>"
1861 " Test for CTRL-W g]
1862 exe "norm! \<C-W>g]"
1863 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1864 norm! yiW
1865 call assert_equal("*i_<Esc>*", @0)
1866 call assert_equal(3, winnr('$'))
1867 helpclose
1868 set nocst
1869 endif
1870
1871 " Test for CTRL-W g]
1872 let a = execute("norm! \<C-W>g]")
1873 call assert_match('i_<Esc>.*insert.txt', a)
1874
1875 " Test for CTRL-W CTRL-]
1876 exe "norm! \<C-W>\<C-]>"
1877 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1878 norm! yiW
1879 call assert_equal("*i_<Esc>*", @0)
1880 call assert_equal(3, winnr('$'))
1881 helpclose
1882
1883 " Test for CTRL-W g CTRL-]
1884 exe "norm! \<C-W>g\<C-]>"
1885 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1886 norm! yiW
1887 call assert_equal("*i_<Esc>*", @0)
1888 call assert_equal(3, winnr('$'))
1889 helpclose
1890
1891 " clean up
1892 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001893endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001894
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001895func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001896 " Test for ]p ]P [p and [P
1897 new
1898 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1899 1
1900 /Error/y a
1901 2
1902 norm! "a]pj"a[p
1903 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1904 1
1905 /^\s\{4}/
1906 exe "norm! \"a]P3Eldt'"
1907 exe "norm! j\"a[P2Eldt'"
1908 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
1909
1910 " clean up
1911 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001912endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001913
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001914func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001915 " Test for [' [` ]' ]`
1916 call Setup_NewWindow()
1917 1,21s/.\+/ & b/
1918 1
1919 norm! $ma
1920 5
1921 norm! $mb
1922 10
1923 norm! $mc
1924 15
1925 norm! $md
1926 20
1927 norm! $me
1928
1929 " Test for ['
1930 9
1931 norm! 2['
1932 call assert_equal(' 1 b', getline('.'))
1933 call assert_equal(1, line('.'))
1934 call assert_equal(3, col('.'))
1935
1936 " Test for ]'
1937 norm! ]'
1938 call assert_equal(' 5 b', getline('.'))
1939 call assert_equal(5, line('.'))
1940 call assert_equal(3, col('.'))
1941
1942 " No mark after line 21, cursor moves to first non blank on current line
1943 21
1944 norm! $]'
1945 call assert_equal(' 21 b', getline('.'))
1946 call assert_equal(21, line('.'))
1947 call assert_equal(3, col('.'))
1948
1949 " Test for [`
1950 norm! 2[`
1951 call assert_equal(' 15 b', getline('.'))
1952 call assert_equal(15, line('.'))
1953 call assert_equal(8, col('.'))
1954
1955 " Test for ]`
1956 norm! ]`
1957 call assert_equal(' 20 b', getline('.'))
1958 call assert_equal(20, line('.'))
1959 call assert_equal(8, col('.'))
1960
1961 " clean up
1962 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001963endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001964
Bram Moolenaar1671f442020-03-10 07:48:13 +01001965" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001966func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001967 new
1968 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
1969
1970 $
1971 norm! d(
1972 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
1973 norm! 2d(
1974 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
1975 1
1976 norm! 0d)
1977 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
1978
1979 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
1980 $
1981 norm! $d(
1982 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
1983
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001984 " Move to the next sentence from a paragraph macro
1985 %d
1986 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
1987 call cursor(1, 1)
1988 normal )
1989 call assert_equal([2, 1], [line('.'), col('.')])
1990 normal )
1991 call assert_equal([2, 12], [line('.'), col('.')])
1992 normal ((
1993 call assert_equal([1, 1], [line('.'), col('.')])
1994
Bram Moolenaar1671f442020-03-10 07:48:13 +01001995 " It is an error if a next sentence is not found
1996 %d
1997 call setline(1, '.SH')
1998 call assert_beeps('normal )')
1999
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002000 " If only dot is present, don't treat that as a sentence
2001 call setline(1, '. This is a sentence.')
2002 normal $((
2003 call assert_equal(3, col('.'))
2004
Bram Moolenaar1671f442020-03-10 07:48:13 +01002005 " Jumping to a fold should open the fold
2006 call setline(1, ['', '', 'one', 'two', 'three'])
2007 set foldenable
2008 2,$fold
2009 call feedkeys(')', 'xt')
2010 call assert_equal(3, line('.'))
2011 call assert_equal(1, foldlevel('.'))
2012 call assert_equal(-1, foldclosed('.'))
2013 set foldenable&
2014
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002015 " clean up
2016 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002017endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002018
Bram Moolenaar1671f442020-03-10 07:48:13 +01002019" Test for { and } paragraph movements
2020func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002021 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002022 A paragraph begins after each empty line, and also at each of a set of
2023 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2024 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2025 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2026 the first column). A section boundary is also a paragraph boundary.
2027 Note that a blank line (only containing white space) is NOT a paragraph
2028 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002029
2030
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002031 Also note that this does not include a '{' or '}' in the first column. When
2032 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2033 paragraph boundary |posix|.
2034 {
2035 This is no paragraph
2036 unless the '{' is set
2037 in 'cpoptions'
2038 }
2039 .IP
2040 The nroff macros IP separates a paragraph
2041 That means, it must be a '.'
2042 followed by IP
2043 .LPIt does not matter, if afterwards some
2044 more characters follow.
2045 .SHAlso section boundaries from the nroff
2046 macros terminate a paragraph. That means
2047 a character like this:
2048 .NH
2049 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002050 [DATA]
2051
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002052 new
2053 call append(0, text)
2054 1
2055 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002056
2057 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002058 .IP
2059 The nroff macros IP separates a paragraph
2060 That means, it must be a '.'
2061 followed by IP
2062 .LPIt does not matter, if afterwards some
2063 more characters follow.
2064 .SHAlso section boundaries from the nroff
2065 macros terminate a paragraph. That means
2066 a character like this:
2067 .NH
2068 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002069
2070 [DATA]
2071 call assert_equal(expected, getline(1, '$'))
2072
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002073 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002074
2075 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002076 .LPIt does not matter, if afterwards some
2077 more characters follow.
2078 .SHAlso section boundaries from the nroff
2079 macros terminate a paragraph. That means
2080 a character like this:
2081 .NH
2082 End of text here
2083
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002084 [DATA]
2085 call assert_equal(expected, getline(1, '$'))
2086
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002087 $
2088 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002089
2090 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002091 .LPIt does not matter, if afterwards some
2092 more characters follow.
2093 .SHAlso section boundaries from the nroff
2094 macros terminate a paragraph. That means
2095 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002096
2097 [DATA]
2098 call assert_equal(expected, getline(1, '$'))
2099
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002100 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002101
2102 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002103 .LPIt does not matter, if afterwards some
2104 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002105
2106 [DATA]
2107 call assert_equal(expected, getline(1, '$'))
2108
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002109 " Test with { in cpooptions
2110 %d
2111 call append(0, text)
2112 set cpo+={
2113 1
2114 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002115
2116 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002117 {
2118 This is no paragraph
2119 unless the '{' is set
2120 in 'cpoptions'
2121 }
2122 .IP
2123 The nroff macros IP separates a paragraph
2124 That means, it must be a '.'
2125 followed by IP
2126 .LPIt does not matter, if afterwards some
2127 more characters follow.
2128 .SHAlso section boundaries from the nroff
2129 macros terminate a paragraph. That means
2130 a character like this:
2131 .NH
2132 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002133
2134 [DATA]
2135 call assert_equal(expected, getline(1, '$'))
2136
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002137 $
2138 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002139
2140 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002141 {
2142 This is no paragraph
2143 unless the '{' is set
2144 in 'cpoptions'
2145 }
2146 .IP
2147 The nroff macros IP separates a paragraph
2148 That means, it must be a '.'
2149 followed by IP
2150 .LPIt does not matter, if afterwards some
2151 more characters follow.
2152 .SHAlso section boundaries from the nroff
2153 macros terminate a paragraph. That means
2154 a character like this:
2155 .NH
2156 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002157
2158 [DATA]
2159 call assert_equal(expected, getline(1, '$'))
2160
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002161 norm! gg}
2162 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002163
2164 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002165 {
2166 This is no paragraph
2167 unless the '{' is set
2168 in 'cpoptions'
2169 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002170
2171 [DATA]
2172 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002173
Bram Moolenaar1671f442020-03-10 07:48:13 +01002174 " Jumping to a fold should open the fold
2175 %d
2176 call setline(1, ['', 'one', 'two', ''])
2177 set foldenable
2178 2,$fold
2179 call feedkeys('}', 'xt')
2180 call assert_equal(4, line('.'))
2181 call assert_equal(1, foldlevel('.'))
2182 call assert_equal(-1, foldclosed('.'))
2183 set foldenable&
2184
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002185 " clean up
2186 set cpo-={
2187 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002188endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002189
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002190" Test for section movements
2191func Test_normal_section()
2192 new
2193 let lines =<< trim [END]
2194 int foo()
2195 {
2196 if (1)
2197 {
2198 a = 1;
2199 }
2200 }
2201 [END]
2202 call setline(1, lines)
2203
2204 " jumping to a folded line using [[ should open the fold
2205 2,3fold
2206 call cursor(5, 1)
2207 call feedkeys("[[", 'xt')
2208 call assert_equal(2, line('.'))
2209 call assert_equal(-1, foldclosedend(line('.')))
2210
2211 close!
2212endfunc
2213
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002214" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002215func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002216 new
2217 call append(0, 'This is a simple test: äüöß')
2218 norm! 1ggVu
2219 call assert_equal('this is a simple test: äüöß', getline('.'))
2220 norm! VU
2221 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2222 norm! guu
2223 call assert_equal('this is a simple test: äüöss', getline('.'))
2224 norm! gUgU
2225 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2226 norm! gugu
2227 call assert_equal('this is a simple test: äüöss', getline('.'))
2228 norm! gUU
2229 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2230 norm! 010~
2231 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
2232 norm! V~
2233 call assert_equal('THIS IS A simple test: äüöss', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002234 call assert_beeps('norm! c~')
2235 %d
2236 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002237
Bram Moolenaar1671f442020-03-10 07:48:13 +01002238 " Test for changing case across lines using 'whichwrap'
2239 call setline(1, ['aaaaaa', 'aaaaaa'])
2240 normal! gg10~
2241 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2242 set whichwrap+=~
2243 normal! gg10~
2244 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2245 set whichwrap&
2246
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002247 " try changing the case with a double byte encoding (DBCS)
2248 %bw!
2249 let enc = &enc
2250 set encoding=cp932
2251 call setline(1, "\u8470")
2252 normal ~
2253 normal gU$gu$gUgUg~g~gugu
2254 call assert_equal("\u8470", getline(1))
2255 let &encoding = enc
2256
Bram Moolenaar1671f442020-03-10 07:48:13 +01002257 " clean up
2258 bw!
2259endfunc
2260
2261" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2262" is available but toupper()/tolower() don't do the right thing.
2263func Test_normal_changecase_turkish()
2264 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002265 try
2266 lang tr_TR.UTF-8
2267 set casemap=
2268 let iupper = toupper('i')
2269 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002270 call setline(1, 'iI')
2271 1normal gUU
2272 call assert_equal("\u0130I", getline(1))
2273 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002274
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002275 call setline(1, 'iI')
2276 1normal guu
2277 call assert_equal("i\u0131", getline(1))
2278 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002279 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002280 call setline(1, 'iI')
2281 1normal gUU
2282 call assert_equal("II", getline(1))
2283 call assert_equal("II", toupper("iI"))
2284
2285 call setline(1, 'iI')
2286 1normal guu
2287 call assert_equal("ii", getline(1))
2288 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002289 else
2290 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2291 endif
2292 set casemap&
2293 call setline(1, 'iI')
2294 1normal gUU
2295 call assert_equal("II", getline(1))
2296 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002297
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002298 call setline(1, 'iI')
2299 1normal guu
2300 call assert_equal("ii", getline(1))
2301 call assert_equal("ii", tolower("iI"))
2302
2303 lang en_US.UTF-8
2304 catch /E197:/
2305 " can't use Turkish locale
2306 throw 'Skipped: Turkish locale not available'
2307 endtry
Bram Moolenaar1671f442020-03-10 07:48:13 +01002308 close!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002309endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002310
Bram Moolenaar1671f442020-03-10 07:48:13 +01002311" Test for r (replace) command
2312func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002313 new
2314 call append(0, 'This is a simple test: abcd')
2315 exe "norm! 1gg$r\<cr>"
2316 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2317 exe "norm! 1gg2wlr\<cr>"
2318 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2319 exe "norm! 2gg0W5r\<cr>"
2320 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2321 set autoindent
2322 call setline(2, ['simple test: abc', ''])
2323 exe "norm! 2gg0W5r\<cr>"
2324 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2325 exe "norm! 1ggVr\<cr>"
2326 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2327 call setline(1, 'This is a')
2328 exe "norm! 1gg05rf"
2329 call assert_equal('fffffis a', getline(1))
2330
Bram Moolenaar1671f442020-03-10 07:48:13 +01002331 " When replacing characters, copy characters from above and below lines
2332 " using CTRL-Y and CTRL-E.
2333 " Different code paths are used for utf-8 and latin1 encodings
2334 set showmatch
2335 for enc in ['latin1', 'utf-8']
2336 enew!
2337 let &encoding = enc
2338 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2339 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2340 call assert_equal(' {a}x [b]x', getline(2))
2341 endfor
2342 set showmatch&
2343
2344 " r command should fail in operator pending mode
2345 call assert_beeps('normal! cr')
2346
Bram Moolenaar004a6782020-04-11 17:09:31 +02002347 " replace a tab character in visual mode
2348 %d
2349 call setline(1, ["a\tb", "c\td", "e\tf"])
2350 normal gglvjjrx
2351 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2352
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002353 " replace with a multibyte character (with multiple composing characters)
2354 %d
2355 new
2356 call setline(1, 'aaa')
2357 exe "normal $ra\u0328\u0301"
2358 call assert_equal("aaa\u0328\u0301", getline(1))
2359
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002360 " clean up
2361 set noautoindent
2362 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002363endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002364
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002365" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002366func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002367 new
2368 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2369 1
2370 norm! $g*
2371 call assert_equal('x_foo', @/)
2372 call assert_equal('x_foobar.abc', getline('.'))
2373 norm! $g#
2374 call assert_equal('abc', @/)
2375 call assert_equal('abc.x_foo', getline('.'))
2376
2377 " clean up
2378 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002379endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002380
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002381" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2382" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002383func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002384 call Setup_NewWindow()
2385 " Test for g`
2386 clearjumps
2387 norm! ma10j
2388 let a=execute(':jumps')
2389 " empty jumplist
2390 call assert_equal('>', a[-1:])
2391 norm! g`a
2392 call assert_equal('>', a[-1:])
2393 call assert_equal(1, line('.'))
2394 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002395 call cursor(10, 1)
2396 norm! g'a
2397 call assert_equal('>', a[-1:])
2398 call assert_equal(1, line('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002399
2400 " Test for g; and g,
2401 norm! g;
2402 " there is only one change in the changelist
2403 " currently, when we setup the window
2404 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002405 call assert_fails(':norm! g;', 'E662:')
2406 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002407 let &ul=&ul
2408 call append('$', ['a', 'b', 'c', 'd'])
2409 let &ul=&ul
2410 call append('$', ['Z', 'Y', 'X', 'W'])
2411 let a = execute(':changes')
2412 call assert_match('2\s\+0\s\+2', a)
2413 call assert_match('101\s\+0\s\+a', a)
2414 call assert_match('105\s\+0\s\+Z', a)
2415 norm! 3g;
2416 call assert_equal(2, line('.'))
2417 norm! 2g,
2418 call assert_equal(105, line('.'))
2419
2420 " Test for g& - global substitute
2421 %d
2422 call setline(1, range(1,10))
2423 call append('$', ['a', 'b', 'c', 'd'])
2424 $s/\w/&&/g
2425 exe "norm! /[1-8]\<cr>"
2426 norm! g&
2427 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2428
Bram Moolenaar1671f442020-03-10 07:48:13 +01002429 " Jumping to a fold using gg should open the fold
2430 set foldenable
2431 set foldopen+=jump
2432 5,8fold
2433 call feedkeys('6gg', 'xt')
2434 call assert_equal(1, foldlevel('.'))
2435 call assert_equal(-1, foldclosed('.'))
2436 set foldopen-=jump
2437 set foldenable&
2438
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002439 " Test for gv
2440 %d
2441 call append('$', repeat(['abcdefgh'], 8))
2442 exe "norm! 2gg02l\<c-v>2j2ly"
2443 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2444 " in visual mode, gv swaps current and last selected region
2445 exe "norm! G0\<c-v>4k4lgvd"
2446 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2447 exe "norm! G0\<c-v>4k4ly"
2448 exe "norm! gvood"
2449 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002450 " gv cannot be used in operator pending mode
2451 call assert_beeps('normal! cgv')
2452 " gv should beep without a previously selected visual area
2453 new
2454 call assert_beeps('normal! gv')
2455 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002456
2457 " Test for gk/gj
2458 %d
2459 15vsp
2460 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002461 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2462 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2463 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002464 $put =lineA
2465 $put =lineB
2466
2467 norm! 3gg0dgk
2468 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2469 set nu
2470 norm! 3gg0gjdgj
2471 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2472
2473 " Test for gJ
2474 norm! 2gggJ
2475 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2476 call assert_equal(16, col('.'))
2477 " shouldn't do anything
2478 norm! 10gJ
2479 call assert_equal(1, col('.'))
2480
2481 " Test for g0 g^ gm g$
2482 exe "norm! 2gg0gji "
2483 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2484 norm! g0yl
2485 call assert_equal(12, col('.'))
2486 call assert_equal(' ', getreg(0))
2487 norm! g$yl
2488 call assert_equal(22, col('.'))
2489 call assert_equal('3', getreg(0))
2490 norm! gmyl
2491 call assert_equal(17, col('.'))
2492 call assert_equal('n', getreg(0))
2493 norm! g^yl
2494 call assert_equal(15, col('.'))
2495 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002496 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002497
Bram Moolenaar74ede802021-05-29 19:18:01 +02002498 " Test for g$ with double-width character half displayed
2499 vsplit
2500 9wincmd |
2501 setlocal nowrap nonumber
2502 call setline(2, 'asdfasdfヨ')
2503 2
2504 normal 0g$
2505 call assert_equal(8, col('.'))
2506 10wincmd |
2507 normal 0g$
2508 call assert_equal(9, col('.'))
2509
2510 setlocal signcolumn=yes
2511 11wincmd |
2512 normal 0g$
2513 call assert_equal(8, col('.'))
2514 12wincmd |
2515 normal 0g$
2516 call assert_equal(9, col('.'))
2517
2518 close
2519
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002520 " Test for g_
2521 call assert_beeps('normal! 100g_')
2522 call setline(2, [' foo ', ' foobar '])
2523 normal! 2ggg_
2524 call assert_equal(5, col('.'))
2525 normal! 2g_
2526 call assert_equal(8, col('.'))
2527
2528 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002529 $put =lineC
2530
2531 " Test for gM
2532 norm! gMyl
2533 call assert_equal(73, col('.'))
2534 call assert_equal('0', getreg(0))
2535 " Test for 20gM
2536 norm! 20gMyl
2537 call assert_equal(29, col('.'))
2538 call assert_equal('S', getreg(0))
2539 " Test for 60gM
2540 norm! 60gMyl
2541 call assert_equal(87, col('.'))
2542 call assert_equal('E', getreg(0))
2543
2544 " Test for g Ctrl-G
2545 set ff=unix
2546 let a=execute(":norm! g\<c-g>")
2547 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2548
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002549 " Test for gI
2550 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002551 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002552
2553 " Test for gi
2554 wincmd c
2555 %d
2556 set tw=0
2557 call setline(1, ['foobar', 'new line'])
2558 norm! A next word
2559 $put ='third line'
2560 norm! gi another word
2561 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002562 call setline(1, 'foobar')
2563 normal! Ggifirst line
2564 call assert_equal('foobarfirst line', getline(1))
2565 " Test gi in 'virtualedit' mode with cursor after the end of the line
2566 set virtualedit=all
2567 call setline(1, 'foo')
2568 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2569 call setline(1, 'foo')
2570 normal! Ggifirst line
2571 call assert_equal('foo first line', getline(1))
2572 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002573
Dominique Pelle923dce22021-11-21 11:36:04 +00002574 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002575 exe "normal! g\<C-\>\<C-G>"
2576 call assert_equal('foo first line', getline('.'))
2577
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002578 " clean up
2579 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002580endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002581
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002582" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002583func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002584 new
2585
2586 let a = execute(":norm! g\<c-g>")
2587 call assert_equal("\n--No lines in buffer--", a)
2588
Bram Moolenaar1671f442020-03-10 07:48:13 +01002589 " Test for CTRL-G (same as :file)
2590 let a = execute(":norm! \<c-g>")
2591 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2592
Bram Moolenaar05295832018-08-24 22:07:58 +02002593 call setline(1, ['first line', 'second line'])
2594
2595 " Test g CTRL-g with dos, mac and unix file type.
2596 norm! gojll
2597 set ff=dos
2598 let a = execute(":norm! g\<c-g>")
2599 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2600
2601 set ff=mac
2602 let a = execute(":norm! g\<c-g>")
2603 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2604
2605 set ff=unix
2606 let a = execute(":norm! g\<c-g>")
2607 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2608
2609 " Test g CTRL-g in visual mode (v)
2610 let a = execute(":norm! gojllvlg\<c-g>")
2611 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2612
2613 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2614 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2615 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2616
2617 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2618 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2619 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2620
2621 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2622 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2623 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2624
2625 " There should be one byte less with noeol
2626 set bin noeol
2627 let a = execute(":norm! \<Esc>gog\<c-g>")
2628 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2629 set bin & eol&
2630
Bram Moolenaar30276f22019-01-24 17:59:39 +01002631 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002632
Bram Moolenaar30276f22019-01-24 17:59:39 +01002633 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2634 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 +02002635
Bram Moolenaar30276f22019-01-24 17:59:39 +01002636 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2637 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 +02002638
Bram Moolenaar30276f22019-01-24 17:59:39 +01002639 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2640 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 +02002641
Bram Moolenaar30276f22019-01-24 17:59:39 +01002642 set fenc=utf8 bomb
2643 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2644 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 +02002645
Bram Moolenaar30276f22019-01-24 17:59:39 +01002646 set fenc=utf16 bomb
2647 let a = execute(":norm! g\<c-g>")
2648 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 +02002649
Bram Moolenaar30276f22019-01-24 17:59:39 +01002650 set fenc=utf32 bomb
2651 let a = execute(":norm! g\<c-g>")
2652 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 +02002653
Bram Moolenaar30276f22019-01-24 17:59:39 +01002654 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002655
2656 set ff&
2657 bwipe!
2658endfunc
2659
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002660" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002661func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002662 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002663 let a=execute(':norm! 1G0g8')
2664 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002665
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002666 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2667 let a=execute(':norm! 1G$g8')
2668 call assert_equal("\nc3 b6 ", a)
2669
2670 call setline(1, "a\u0302")
2671 let a=execute(':norm! 1G0g8')
2672 call assert_equal("\n61 + cc 82 ", a)
2673
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002674 " clean up
2675 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002676endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002677
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002678" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002679func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002680 new
2681
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002682 " With invalid byte.
2683 call setline(1, "___\xff___")
2684 norm! 1G08g8g
2685 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2686
2687 " With invalid byte before the cursor.
2688 call setline(1, "___\xff___")
2689 norm! 1G$h8g8g
2690 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2691
2692 " With truncated sequence.
2693 call setline(1, "___\xE2\x82___")
2694 norm! 1G08g8g
2695 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2696
2697 " With overlong sequence.
2698 call setline(1, "___\xF0\x82\x82\xAC___")
2699 norm! 1G08g8g
2700 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2701
2702 " With valid utf8.
2703 call setline(1, "café")
2704 norm! 1G08g8
2705 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2706
2707 bw!
2708endfunc
2709
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002710" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002711func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002712 " Cannot capture its output,
2713 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002714 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002715 echo "a\nb\nc\nd"
2716 let b=execute(':norm! g<')
2717 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002718endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002719
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002720" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002721func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002722 new
2723 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002724 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002725 " Test for gp gP
2726 call append(1, range(1,10))
2727 1
2728 norm! 1yy
2729 3
2730 norm! gp
2731 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2732 $
2733 norm! gP
2734 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2735
2736 " Test for go
2737 norm! 26go
2738 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2739 norm! 27go
2740 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2741 norm! 28go
2742 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2743 set ff=dos
2744 norm! 29go
2745 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2746 set ff=unix
2747 norm! gg0
2748 norm! 101go
2749 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2750 norm! 103go
2751 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2752 " count > buffer content
2753 norm! 120go
2754 call assert_equal([0, 14, 1, 0, 2147483647], getcurpos())
2755 " clean up
2756 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002757endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002758
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002759" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002760func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002761 tabnew 1.txt
2762 tabnew 2.txt
2763 tabnew 3.txt
2764 norm! 1gt
2765 call assert_equal(1, tabpagenr())
2766 norm! 3gt
2767 call assert_equal(3, tabpagenr())
2768 norm! 1gT
2769 " count gT goes not to the absolute tabpagenumber
2770 " but, but goes to the count previous tabpagenumber
2771 call assert_equal(2, tabpagenr())
2772 " wrap around
2773 norm! 3gT
2774 call assert_equal(3, tabpagenr())
2775 " gt does not wrap around
2776 norm! 5gt
2777 call assert_equal(3, tabpagenr())
2778
2779 for i in range(3)
2780 tabclose
2781 endfor
2782 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002783 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002784endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002785
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002786" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002787func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002788 new
2789 call setline(1, range(10))
2790 $
2791 setl et sw=2
2792 norm! V10>$
2793 " count is ignored
2794 exe "norm! 10\<home>"
2795 call assert_equal(1, col('.'))
2796 exe "norm! \<home>"
2797 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2798 exe "norm! 5\<c-home>"
2799 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2800 exe "norm! \<c-home>"
2801 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002802 exe "norm! G\<c-kHome>"
2803 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002804
2805 " clean up
2806 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002807endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002808
Bram Moolenaar1671f442020-03-10 07:48:13 +01002809" Test for <End> and <C-End> keys
2810func Test_normal_nvend()
2811 new
2812 call setline(1, map(range(1, 10), '"line" .. v:val'))
2813 exe "normal! \<End>"
2814 call assert_equal(5, col('.'))
2815 exe "normal! 4\<End>"
2816 call assert_equal([4, 5], [line('.'), col('.')])
2817 exe "normal! \<C-End>"
2818 call assert_equal([10, 6], [line('.'), col('.')])
2819 close!
2820endfunc
2821
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002822" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002823func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002824 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002825 new
2826 set tw=0
2827 call append(0, 'here are some words')
2828 norm! 1gg0elcwZZZ
2829 call assert_equal('hereZZZare some words', getline('.'))
2830 norm! 1gg0elcWYYY
2831 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002832 norm! 2gg0cwfoo
2833 call assert_equal('foo', getline('.'))
2834
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002835 call setline(1, 'one; two')
2836 call cursor(1, 1)
2837 call feedkeys('cwvim', 'xt')
2838 call assert_equal('vim; two', getline(1))
2839 call feedkeys('0cWone', 'xt')
2840 call assert_equal('one two', getline(1))
2841 "When cursor is at the end of a word 'ce' will change until the end of the
2842 "next word, but 'cw' will change only one character
2843 call setline(1, 'one two')
2844 call feedkeys('0ecwce', 'xt')
2845 call assert_equal('once two', getline(1))
2846 call setline(1, 'one two')
2847 call feedkeys('0ecely', 'xt')
2848 call assert_equal('only', getline(1))
2849
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002850 " clean up
2851 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002852endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002853
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002854" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002855func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002856 new
2857 call append(0, 'here are some words')
2858 exe "norm! 1gg0a\<C-\>\<C-N>"
2859 call assert_equal('n', mode())
2860 call assert_equal(1, col('.'))
2861 call assert_equal('', visualmode())
2862 exe "norm! 1gg0viw\<C-\>\<C-N>"
2863 call assert_equal('n', mode())
2864 call assert_equal(4, col('.'))
2865 exe "norm! 1gg0a\<C-\>\<C-G>"
2866 call assert_equal('n', mode())
2867 call assert_equal(1, col('.'))
2868 "imap <buffer> , <c-\><c-n>
2869 set im
2870 exe ":norm! \<c-\>\<c-n>dw"
2871 set noim
2872 call assert_equal('are some words', getline(1))
2873 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02002874 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01002875
Bram Moolenaar21829c52021-01-26 22:42:21 +01002876 if has('cmdwin')
2877 " Using CTRL-\ CTRL-N in cmd window should close the window
2878 call feedkeys("q:\<C-\>\<C-N>", 'xt')
2879 call assert_equal('', getcmdwintype())
2880 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002881
2882 " clean up
2883 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002884endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002885
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002886" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01002887func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002888 new
2889 set sts=2 sw=2 ts=8 tw=0
2890 call append(0, ["aaa\tbbb\tccc", '', '', ''])
2891 let a=getline(1)
2892 norm! 2gg0
2893 exe "norm! a\<c-r>=a\<cr>"
2894 norm! 3gg0
2895 exe "norm! a\<c-r>\<c-r>=a\<cr>"
2896 norm! 4gg0
2897 exe "norm! a\<c-r>\<c-o>=a\<cr>"
2898 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
2899
2900 " clean up
2901 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02002902 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002903endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002904
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002905" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002906func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002907 call Setup_NewWindow()
2908 call assert_equal(5, &scroll)
2909 exe "norm! \<c-d>"
2910 call assert_equal('6', getline('.'))
2911 exe "norm! 2\<c-d>"
2912 call assert_equal('8', getline('.'))
2913 call assert_equal(2, &scroll)
2914 set scroll=5
2915 exe "norm! \<c-u>"
2916 call assert_equal('3', getline('.'))
2917 1
2918 set scrolloff=5
2919 exe "norm! \<c-d>"
2920 call assert_equal('10', getline('.'))
2921 exe "norm! \<c-u>"
2922 call assert_equal('5', getline('.'))
2923 1
2924 set scrolloff=99
2925 exe "norm! \<c-d>"
2926 call assert_equal('10', getline('.'))
2927 set scrolloff=0
2928 100
2929 exe "norm! $\<c-u>"
2930 call assert_equal('95', getline('.'))
2931 call assert_equal([0, 95, 1, 0, 1], getcurpos())
2932 100
2933 set nostartofline
2934 exe "norm! $\<c-u>"
2935 call assert_equal('95', getline('.'))
2936 call assert_equal([0, 95, 2, 0, 2147483647], getcurpos())
2937 " cleanup
2938 set startofline
2939 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002940endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002941
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002942func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01002943 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01002944 " The ~ register does not exist
2945 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01002946 return
2947 endif
2948
2949 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002950 " unfortunately, without a gui, we can't really test much here,
2951 " so simply test that ~p fails (which uses the drop register)
2952 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02002953 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002954 call assert_equal([], getreg('~', 1, 1))
2955 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02002956 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002957 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002958endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002959
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002960func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002961 new
2962 " How to test this?
2963 " let's just for now test, that the buffer
2964 " does not change
2965 call feedkeys("\<c-s>", 't')
2966 call assert_equal([''], getline(1,'$'))
2967
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002968 " no valid commands
2969 exe "norm! \<char-0x100>"
2970 call assert_equal([''], getline(1,'$'))
2971
2972 exe "norm! ä"
2973 call assert_equal([''], getline(1,'$'))
2974
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002975 " clean up
2976 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002977endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02002978
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002979func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02002980 " This was causing a crash or ml_get error.
2981 enew!
2982 call setline(1,'xxx')
2983 normal $
2984 new
2985 call setline(1, range(1,2))
2986 2
2987 exe "norm \<C-V>$"
2988 bw!
2989 norm yp
2990 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002991endfunc
2992
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002993func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002994 new
2995 exe "norm! \<c-w>c"
2996 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002997 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002998endfunc
2999
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003000func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003001 new
3002 call setline(1, 'one two three four five six seven eight nine ten')
3003 1
3004 norm! 3d2w
3005 call assert_equal('seven eight nine ten', getline(1))
3006 bw!
3007endfunc
3008
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003009func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003010 CheckFeature timers
3011 CheckFeature cmdline_hist
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003012 func! DoTimerWork(id)
3013 call assert_equal('[Command Line]', bufname(''))
3014 " should fail, with E11, but does fail with E23?
3015 "call feedkeys("\<c-^>", 'tm')
3016
3017 " should also fail with E11
Bram Moolenaare2e40752020-09-04 21:18:46 +02003018 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003019 " return from commandline window
3020 call feedkeys("\<cr>")
3021 endfunc
3022
3023 let oldlang=v:lang
3024 lang C
3025 set updatetime=20
3026 call timer_start(100, 'DoTimerWork')
3027 try
3028 " throws E23, for whatever reason...
3029 call feedkeys('q:', 'x!')
3030 catch /E23/
3031 " no-op
3032 endtry
3033 " clean up
3034 set updatetime=4000
3035 exe "lang" oldlang
3036 bw!
3037endfunc
3038
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003039func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003040 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003041 " Don't sleep after the warning message.
3042 call test_settime(1)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003043 call writefile(['foo'], 'Xreadonly.log')
3044 new Xreadonly.log
3045 setl ro
3046 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003047 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003048 call assert_equal(['foo'], getline(1,'$'))
3049 call assert_equal('Xreadonly.log', bufname(''))
3050
3051 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003052 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003053 bw!
3054 call delete("Xreadonly.log")
3055endfunc
3056
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003057func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003058 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003059 new
3060 call setline(1, 'abcde fghij klmnopq')
3061 norm! 1gg$
3062 set rl
3063 call assert_equal(19, col('.'))
3064 call feedkeys('l', 'tx')
3065 call assert_equal(18, col('.'))
3066 call feedkeys('h', 'tx')
3067 call assert_equal(19, col('.'))
3068 call feedkeys("\<right>", 'tx')
3069 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003070 call feedkeys("\<left>", 'tx')
3071 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003072 call feedkeys("\<s-right>", 'tx')
3073 call assert_equal(13, col('.'))
3074 call feedkeys("\<c-right>", 'tx')
3075 call assert_equal(7, col('.'))
3076 call feedkeys("\<c-left>", 'tx')
3077 call assert_equal(13, col('.'))
3078 call feedkeys("\<s-left>", 'tx')
3079 call assert_equal(19, col('.'))
3080 call feedkeys("<<", 'tx')
3081 call assert_equal(' abcde fghij klmnopq',getline(1))
3082 call feedkeys(">>", 'tx')
3083 call assert_equal('abcde fghij klmnopq',getline(1))
3084
3085 " cleanup
3086 set norl
3087 bw!
3088endfunc
3089
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003090func Test_normal54_Ctrl_bsl()
3091 new
3092 call setline(1, 'abcdefghijklmn')
3093 exe "norm! df\<c-\>\<c-n>"
3094 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3095 exe "norm! df\<c-\>\<c-g>"
3096 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3097 exe "norm! df\<c-\>m"
3098 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003099
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003100 call setline(2, 'abcdefghijklmnāf')
3101 norm! 2gg0
3102 exe "norm! df\<Char-0x101>"
3103 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3104 norm! 1gg0
3105 exe "norm! df\<esc>"
3106 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003107
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003108 " clean up
3109 bw!
3110endfunc
3111
3112func Test_normal_large_count()
3113 " This may fail with 32bit long, how do we detect that?
3114 new
3115 normal o
3116 normal 6666666666dL
3117 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003118endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003119
3120func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003121 new
3122 normal grádv}
3123 call assert_equal('á', getline(1))
3124 normal grád}
3125 call assert_equal('', getline(1))
3126 bwipe!
3127endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003128
3129" Test for the gr (virtual replace) command
3130" Test for the bug fixed by 7.4.387
3131func Test_gr_command()
3132 enew!
3133 let save_cpo = &cpo
3134 call append(0, ['First line', 'Second line', 'Third line'])
3135 exe "normal i\<C-G>u"
3136 call cursor(2, 1)
3137 set cpo-=X
3138 normal 4gro
3139 call assert_equal('oooond line', getline(2))
3140 undo
3141 set cpo+=X
3142 normal 4gro
3143 call assert_equal('ooooecond line', getline(2))
3144 let &cpo = save_cpo
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003145 normal! ggvegrx
3146 call assert_equal('xxxxx line', getline(1))
3147 exe "normal! gggr\<C-V>122"
3148 call assert_equal('zxxxx line', getline(1))
3149 set virtualedit=all
3150 normal! 15|grl
3151 call assert_equal('zxxxx line l', getline(1))
3152 set virtualedit&
3153 set nomodifiable
3154 call assert_fails('normal! grx', 'E21:')
3155 call assert_fails('normal! gRx', 'E21:')
3156 set modifiable&
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003157 enew!
3158endfunc
3159
3160" When splitting a window the changelist position is wrong.
3161" Test the changelist position after splitting a window.
3162" Test for the bug fixed by 7.4.386
3163func Test_changelist()
3164 let save_ul = &ul
3165 enew!
3166 call append('$', ['1', '2'])
3167 exe "normal i\<C-G>u"
3168 exe "normal Gkylpa\<C-G>u"
3169 set ul=100
3170 exe "normal Gylpa\<C-G>u"
3171 set ul=100
3172 normal gg
3173 vsplit
3174 normal g;
3175 call assert_equal([3, 2], [line('.'), col('.')])
3176 normal g;
3177 call assert_equal([2, 2], [line('.'), col('.')])
3178 call assert_fails('normal g;', 'E662:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003179 new
3180 call assert_fails('normal g;', 'E664:')
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003181 %bwipe!
3182 let &ul = save_ul
3183endfunc
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003184
3185func Test_nv_hat_count()
3186 %bwipeout!
3187 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003188 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003189
3190 edit Xfoo
3191 let l:foo_nr = bufnr('Xfoo')
3192
3193 edit Xbar
3194 let l:bar_nr = bufnr('Xbar')
3195
3196 " Make sure we are not just using the alternate file.
3197 edit Xbaz
3198
3199 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3200 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3201
3202 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3203 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3204
3205 %bwipeout!
3206endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003207
3208func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003209 " Make sure no buffers are changed.
3210 %bwipe!
3211
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003212 exe "normal \<C-C>"
3213 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003214
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003215 new
3216 cal setline(1, 'hi!')
3217 exe "normal \<C-C>"
3218 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003219
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003220 bwipe!
3221endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003222
3223" Test for '[m', ']m', '[M' and ']M'
3224" Jumping to beginning and end of methods in Java-like languages
3225func Test_java_motion()
3226 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003227 call assert_beeps('normal! [m')
3228 call assert_beeps('normal! ]m')
3229 call assert_beeps('normal! [M')
3230 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003231 let lines =<< trim [CODE]
3232 Piece of Java
3233 {
3234 tt m1 {
3235 t1;
3236 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003237
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003238 tt m2 {
3239 t2;
3240 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003241
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003242 tt m3 {
3243 if (x)
3244 {
3245 t3;
3246 }
3247 } e3
3248 }
3249 [CODE]
3250 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003251
3252 normal gg
3253
3254 normal 2]maA
3255 call assert_equal("\ttt m1 {A", getline('.'))
3256 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3257
3258 normal j]maB
3259 call assert_equal("\ttt m2 {B", getline('.'))
3260 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3261
3262 normal ]maC
3263 call assert_equal("\ttt m3 {C", getline('.'))
3264 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3265
3266 normal [maD
3267 call assert_equal("\ttt m3 {DC", getline('.'))
3268 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3269
3270 normal k2[maE
3271 call assert_equal("\ttt m1 {EA", getline('.'))
3272 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3273
3274 normal 3[maF
3275 call assert_equal("{F", getline('.'))
3276 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3277
3278 normal ]MaG
3279 call assert_equal("\t}G e1", getline('.'))
3280 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3281
3282 normal j2]MaH
3283 call assert_equal("\t}H e3", getline('.'))
3284 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3285
3286 normal ]M]M
3287 normal aI
3288 call assert_equal("}I", getline('.'))
3289 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3290
3291 normal 2[MaJ
3292 call assert_equal("\t}JH e3", getline('.'))
3293 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3294
3295 normal k[MaK
3296 call assert_equal("\t}K e2", getline('.'))
3297 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3298
3299 normal 3[MaL
3300 call assert_equal("{LF", getline('.'))
3301 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3302
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003303 call cursor(2, 1)
3304 call assert_beeps('norm! 5]m')
3305
3306 " jumping to a method in a fold should open the fold
3307 6,10fold
3308 call feedkeys("gg3]m", 'xt')
3309 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3310 call assert_equal(-1, foldclosedend(7))
3311
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003312 close!
3313endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003314
Bram Moolenaar004a6782020-04-11 17:09:31 +02003315" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003316func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003317 call Setup_NewWindow()
3318 " Make long lines that will wrap
3319 %s/$/\=repeat(' foobar', 10)/
3320 20vsp
3321 set wrap
3322 " Test for g$ with count
3323 norm! gg
3324 norm! 0vg$y
3325 call assert_equal(20, col("'>"))
3326 call assert_equal('1 foobar foobar foob', getreg(0))
3327 norm! gg
3328 norm! 0v4g$y
3329 call assert_equal(72, col("'>"))
3330 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3331 norm! gg
3332 norm! 0v6g$y
3333 call assert_equal(40, col("'>"))
3334 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3335 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3336 set nowrap
3337 " clean up
3338 norm! gg
3339 norm! 0vg$y
3340 call assert_equal(20, col("'>"))
3341 call assert_equal('1 foobar foobar foob', getreg(0))
3342 norm! gg
3343 norm! 0v4g$y
3344 call assert_equal(20, col("'>"))
3345 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3346 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3347 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3348 \ '4 foobar foobar foob', getreg(0))
3349 norm! gg
3350 norm! 0v6g$y
3351 call assert_equal(20, col("'>"))
3352 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3353 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3354 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3355 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3356 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3357 \ '6 foobar foobar foob', getreg(0))
3358 " Move to last line, also down movement is not possible, should still move
3359 " the cursor to the last visible char
3360 norm! G
3361 norm! 0v6g$y
3362 call assert_equal(20, col("'>"))
3363 call assert_equal('100 foobar foobar fo', getreg(0))
3364 bw!
3365endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003366
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003367func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003368 " needs 80 column new window
3369 new
3370 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003371 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003372 put =[repeat('x',90)..' {{{1', 'x {{{1']
3373 norm! gk
3374 " In a 80 column wide terminal the window will be only 78 char
3375 " (because Vim will leave space for the other window),
3376 " but if the terminal is larger, it will be 80 chars, so verify the
3377 " cursor column correctly.
3378 call assert_equal(winwidth(0)+1, col('.'))
3379 call assert_equal(winwidth(0)+1, virtcol('.'))
3380 norm! j
3381 call assert_equal(6, col('.'))
3382 call assert_equal(6, virtcol('.'))
3383 norm! gk
3384 call assert_equal(95, col('.'))
3385 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003386 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003387
3388 " needs 80 column new window
3389 new
3390 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003391 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003392 set number
3393 set numberwidth=10
3394 set cpoptions+=n
3395 put =[repeat('0',90), repeat('1',90)]
3396 norm! 075l
3397 call assert_equal(76, col('.'))
3398 norm! gk
3399 call assert_equal(1, col('.'))
3400 norm! gk
3401 call assert_equal(76, col('.'))
3402 norm! gk
3403 call assert_equal(1, col('.'))
3404 norm! gj
3405 call assert_equal(76, col('.'))
3406 norm! gj
3407 call assert_equal(1, col('.'))
3408 norm! gj
3409 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003410 " When 'nowrap' is set, gk and gj behave like k and j
3411 set nowrap
3412 normal! gk
3413 call assert_equal([2, 76], [line('.'), col('.')])
3414 normal! gj
3415 call assert_equal([3, 76], [line('.'), col('.')])
3416 %bw!
3417 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003418endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003419
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003420" Test for using : to run a multi-line Ex command in operator pending mode
3421func Test_normal_yank_with_excmd()
3422 new
3423 call setline(1, ['foo', 'bar', 'baz'])
3424 let @a = ''
3425 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3426 call assert_equal('f', @a)
3427 close!
3428endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003429
3430" Test for supplying a count to a normal-mode command across a cursorhold call
3431func Test_normal_cursorhold_with_count()
3432 func s:cHold()
3433 let g:cHold_Called += 1
3434 endfunc
3435 new
3436 augroup normalcHoldTest
3437 au!
3438 au CursorHold <buffer> call s:cHold()
3439 augroup END
3440 let g:cHold_Called = 0
3441 call feedkeys("3\<CursorHold>2ix", 'xt')
3442 call assert_equal(1, g:cHold_Called)
3443 call assert_equal(repeat('x', 32), getline(1))
3444 augroup normalcHoldTest
3445 au!
3446 augroup END
3447 au! normalcHoldTest
3448 close!
3449 delfunc s:cHold
3450endfunc
3451
3452" Test for using a count and a command with CTRL-W
3453func Test_wincmd_with_count()
3454 call feedkeys("\<C-W>12n", 'xt')
3455 call assert_equal(12, winheight(0))
3456endfunc
3457
3458" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003459func Test_horiz_motion()
3460 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003461 normal! gg
3462 call assert_beeps('normal! b')
3463 call assert_beeps('normal! B')
3464 call assert_beeps('normal! gE')
3465 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003466 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3467 call setline(1, 'one ,two ,three')
3468 exe "normal! $\<S-BS>"
3469 call assert_equal(11, col('.'))
3470 exe "normal! $\<C-BS>"
3471 call assert_equal(10, col('.'))
3472 close!
3473endfunc
3474
3475" Test for using a : command in operator pending mode
3476func Test_normal_colon_op()
3477 new
3478 call setline(1, ['one', 'two'])
3479 call assert_beeps("normal! Gc:d\<CR>")
3480 close!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003481endfunc
3482
Bram Moolenaar004a6782020-04-11 17:09:31 +02003483" Test for d and D commands
3484func Test_normal_delete_cmd()
3485 new
3486 " D in an empty line
3487 call setline(1, '')
3488 normal D
3489 call assert_equal('', getline(1))
3490 " D in an empty line in virtualedit mode
3491 set virtualedit=all
3492 normal D
3493 call assert_equal('', getline(1))
3494 set virtualedit&
3495 " delete to a readonly register
3496 call setline(1, ['abcd'])
3497 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003498
3499 " D and d with 'nomodifiable'
3500 call setline(1, ['abcd'])
3501 setlocal nomodifiable
3502 call assert_fails('normal D', 'E21:')
3503 call assert_fails('normal d$', 'E21:')
3504
Bram Moolenaar004a6782020-04-11 17:09:31 +02003505 close!
3506endfunc
3507
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003508" Test for deleting or changing characters across lines with 'whichwrap'
3509" containing 's'. Should count <EOL> as one character.
3510func Test_normal_op_across_lines()
3511 new
3512 set whichwrap&
3513 call setline(1, ['one two', 'three four'])
3514 exe "norm! $3d\<Space>"
3515 call assert_equal(['one twhree four'], getline(1, '$'))
3516
3517 call setline(1, ['one two', 'three four'])
3518 exe "norm! $3c\<Space>x"
3519 call assert_equal(['one twxhree four'], getline(1, '$'))
3520
3521 set whichwrap+=l
3522 call setline(1, ['one two', 'three four'])
3523 exe "norm! $3x"
3524 call assert_equal(['one twhree four'], getline(1, '$'))
3525 close!
3526 set whichwrap&
3527endfunc
3528
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003529" Test for 'w' and 'b' commands
3530func Test_normal_word_move()
3531 new
3532 call setline(1, ['foo bar a', '', 'foo bar b'])
3533 " copy a single character word at the end of a line
3534 normal 1G$yw
3535 call assert_equal('a', @")
3536 " copy a single character word at the end of a file
3537 normal G$yw
3538 call assert_equal('b', @")
3539 " check for a word movement handling an empty line properly
3540 normal 1G$vwy
3541 call assert_equal("a\n\n", @")
3542
3543 " copy using 'b' command
3544 %d
3545 " non-empty blank line at the start of file
3546 call setline(1, [' ', 'foo bar'])
3547 normal 2Gyb
3548 call assert_equal(" \n", @")
3549 " try to copy backwards from the start of the file
3550 call setline(1, ['one two', 'foo bar'])
3551 call assert_beeps('normal ggyb')
3552 " 'b' command should stop at an empty line
3553 call setline(1, ['one two', '', 'foo bar'])
3554 normal 3Gyb
3555 call assert_equal("\n", @")
3556 normal 3Gy2b
3557 call assert_equal("two\n", @")
3558 " 'b' command should not stop at a non-empty blank line
3559 call setline(1, ['one two', ' ', 'foo bar'])
3560 normal 3Gyb
3561 call assert_equal("two\n ", @")
3562
3563 close!
3564endfunc
3565
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003566" Test for 'scrolloff' with a long line that doesn't fit in the screen
3567func Test_normal_scroloff()
3568 10new
3569 80vnew
3570 call setline(1, repeat('a', 1000))
3571 set scrolloff=10
3572 normal gg10gj
3573 call assert_equal(8, winline())
3574 normal 10gj
3575 call assert_equal(10, winline())
3576 normal 10gk
3577 call assert_equal(3, winline())
3578 set scrolloff&
3579 close!
3580endfunc
3581
3582" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3583func Test_normal_vert_scroll_longline()
3584 10new
3585 80vnew
3586 call setline(1, range(1, 10))
3587 call append(5, repeat('a', 1000))
3588 exe "normal gg\<C-F>"
3589 call assert_equal(6, line('.'))
3590 exe "normal \<C-F>\<C-F>"
3591 call assert_equal(11, line('.'))
3592 call assert_equal(1, winline())
3593 exe "normal \<C-B>"
3594 call assert_equal(10, line('.'))
3595 call assert_equal(3, winline())
3596 exe "normal \<C-B>\<C-B>"
3597 call assert_equal(5, line('.'))
3598 call assert_equal(5, winline())
3599 close!
3600endfunc
3601
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003602" Test for jumping in a file using %
3603func Test_normal_percent_jump()
3604 new
3605 call setline(1, range(1, 100))
3606
3607 " jumping to a folded line should open the fold
3608 25,75fold
3609 call feedkeys('50%', 'xt')
3610 call assert_equal(50, line('.'))
3611 call assert_equal(-1, foldclosedend(50))
3612 close!
3613endfunc
3614
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003615" Test for << and >> commands to shift text by 'shiftwidth'
3616func Test_normal_shift_rightleft()
3617 new
3618 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3619 set shiftwidth=2 tabstop=8
3620 normal gg6>>
3621 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3622 \ getline(1, '$'))
3623 normal ggVG2>>
3624 call assert_equal([' one', '', "\t ", "\ttwo",
3625 \ "\t three", "\t four"], getline(1, '$'))
3626 normal gg6<<
3627 call assert_equal([' one', '', "\t ", ' two', "\t three",
3628 \ "\t four"], getline(1, '$'))
3629 normal ggVG2<<
3630 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3631 \ getline(1, '$'))
3632 set shiftwidth& tabstop&
3633 bw!
3634endfunc
3635
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003636" Some commands like yy, cc, dd, >>, << and !! accept a count after
3637" typing the first letter of the command.
3638func Test_normal_count_after_operator()
3639 new
3640 setlocal shiftwidth=4 tabstop=8 autoindent
3641 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3642 let @a = ''
3643 normal! j"ay4y
3644 call assert_equal("two\nthree\nfour\nfive\n", @a)
3645 normal! 3G>2>
3646 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3647 \ getline(1, '$'))
3648 exe "normal! 3G0c2cred\nblue"
3649 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3650 \ getline(1, '$'))
3651 exe "normal! gg<8<"
3652 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3653 \ getline(1, '$'))
3654 exe "normal! ggd3d"
3655 call assert_equal(['blue', 'five'], getline(1, '$'))
3656 call setline(1, range(1, 4))
3657 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3658 call assert_equal('".,.+2!', @:)
3659 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3660 call assert_equal('".!', @:)
3661 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3662 call assert_equal('".,$!', @:)
3663 bw!
3664endfunc
3665
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003666func Test_normal_gj_on_extra_wide_char()
3667 new | 25vsp
3668 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3669 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3670 \ ' dreizehn v ierzehn fünfzehn'
3671 put =text
3672 call cursor(2,1)
3673 norm! gj
3674 call assert_equal([0,2,25,0], getpos('.'))
3675 bw!
3676endfunc
3677
Bram Moolenaar03725c52021-11-24 12:17:53 +00003678func Test_normal_count_out_of_range()
3679 new
3680 call setline(1, 'text')
3681 normal 44444444444|
3682 call assert_equal(999999999, v:count)
3683 normal 444444444444|
3684 call assert_equal(999999999, v:count)
3685 normal 4444444444444|
3686 call assert_equal(999999999, v:count)
3687 normal 4444444444444444444|
3688 call assert_equal(999999999, v:count)
3689
3690 normal 9y99999999|
3691 call assert_equal(899999991, v:count)
3692 normal 10y99999999|
3693 call assert_equal(999999999, v:count)
3694 normal 44444444444y44444444444|
3695 call assert_equal(999999999, v:count)
3696 bwipe!
3697endfunc
3698
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003699" vim: shiftwidth=2 sts=2 expandtab