blob: 08539deb050526585a550dd4eb05422c7a186aeb [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
645 " cleanup
646 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000647 delfunc OpFunc1
648 delfunc OpFunc2
649 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000650 %bw!
651endfunc
652
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100653func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200654 " Test for expand()
655 10new
656 call setline(1, ['1', 'ifooar,,cbar'])
657 2
658 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200659 call assert_equal('cbar', expand('<cword>'))
660 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
661
662 call setline(1, ['prx = list[idx];'])
663 1
664 let expected = ['', 'prx', 'prx', 'prx',
665 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
666 \ 'idx', 'idx', 'idx', 'idx',
667 \ 'list[idx]',
668 \ '];',
669 \ ]
670 for i in range(1, 16)
671 exe 'norm ' . i . '|'
672 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
673 endfor
674
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200675 " Test for <cexpr> in state.val and ptr->val
676 call setline(1, 'x = state.val;')
677 call cursor(1, 10)
678 call assert_equal('state.val', expand('<cexpr>'))
679 call setline(1, 'x = ptr->val;')
680 call cursor(1, 9)
681 call assert_equal('ptr->val', expand('<cexpr>'))
682
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100683 if executable('echo')
684 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100685 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100686 endif
687
688 " Test expand(`=...`) i.e. backticks expression expansion
689 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100690 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100691
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200692 " clean up
693 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200694endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200695
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200696" Test for expand() in latin1 encoding
697func Test_normal_expand_latin1()
698 new
699 let save_enc = &encoding
700 set encoding=latin1
701 call setline(1, 'val = item->color;')
702 call cursor(1, 11)
703 call assert_equal('color', expand("<cword>"))
704 call assert_equal('item->color', expand("<cexpr>"))
705 let &encoding = save_enc
706 bw!
707endfunc
708
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100709func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200710 " test for 'showcmd'
711 10new
712 exe "norm! ofoobar\<esc>"
713 call assert_equal(2, line('$'))
714 set showcmd
715 exe "norm! ofoobar2\<esc>"
716 call assert_equal(3, line('$'))
717 exe "norm! VAfoobar3\<esc>"
718 call assert_equal(3, line('$'))
719 exe "norm! 0d3\<del>2l"
720 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200721 " test for the visual block size displayed in the status line
722 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
723 call feedkeys("ggl\<C-V>lljj", 'xt')
724 redraw!
725 call assert_match('3x3$', Screenline(&lines))
726 call feedkeys("\<C-V>", 'xt')
727 " test for visually selecting a multi-byte character
728 call setline(1, ["\U2206"])
729 call feedkeys("ggv", 'xt')
730 redraw!
731 call assert_match('1-3$', Screenline(&lines))
732 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200733 " test for visually selecting the end of line
734 call setline(1, ["foobar"])
735 call feedkeys("$vl", 'xt')
736 redraw!
737 call assert_match('2$', Screenline(&lines))
738 call feedkeys("y", 'xt')
739 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200740 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200741endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200742
Bram Moolenaar1671f442020-03-10 07:48:13 +0100743" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100744func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200745 10new
746 call setline(1, range(1,5))
747 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100748 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200749 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100750 call assert_beeps('normal! G2dd')
751 call assert_beeps("normal! g\<C-A>")
752 call assert_beeps("normal! g\<C-X>")
753 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100754 call assert_beeps("normal! vQ\<Esc>")
755 call assert_beeps("normal! 2[[")
756 call assert_beeps("normal! 2]]")
757 call assert_beeps("normal! 2[]")
758 call assert_beeps("normal! 2][")
759 call assert_beeps("normal! 4[z")
760 call assert_beeps("normal! 4]z")
761 call assert_beeps("normal! 4[c")
762 call assert_beeps("normal! 4]c")
763 call assert_beeps("normal! 200%")
764 call assert_beeps("normal! %")
765 call assert_beeps("normal! 2{")
766 call assert_beeps("normal! 2}")
767 call assert_beeps("normal! r\<Right>")
768 call assert_beeps("normal! 8ry")
769 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200770 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200771endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200772
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100773func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200774 " Test for F1
775 call assert_equal(1, winnr())
776 call feedkeys("\<f1>", 'txi')
777 call assert_match('help\.txt', bufname('%'))
778 call assert_equal(2, winnr('$'))
779 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200780endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200781
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100782func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200783 " basic test for Ctrl-F and Ctrl-B
784 call Setup_NewWindow()
785 exe "norm! \<c-f>"
786 call assert_equal('9', getline('.'))
787 exe "norm! 2\<c-f>"
788 call assert_equal('25', getline('.'))
789 exe "norm! 2\<c-b>"
790 call assert_equal('18', getline('.'))
791 1
792 set scrolloff=5
793 exe "norm! 2\<c-f>"
794 call assert_equal('21', getline('.'))
795 exe "norm! \<c-b>"
796 call assert_equal('13', getline('.'))
797 1
798 set scrolloff=99
799 exe "norm! \<c-f>"
800 call assert_equal('13', getline('.'))
801 set scrolloff=0
802 100
803 exe "norm! $\<c-b>"
804 call assert_equal('92', getline('.'))
805 call assert_equal([0, 92, 1, 0, 1], getcurpos())
806 100
807 set nostartofline
808 exe "norm! $\<c-b>"
809 call assert_equal('92', getline('.'))
810 call assert_equal([0, 92, 2, 0, 2147483647], getcurpos())
811 " cleanup
812 set startofline
813 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200814endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200815
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100816func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200817 10new
818 norm oxxxxxxx
819 exe "norm 2\<c-f>"
820 " check with valgrind that cursor is put back in column 1
821 exe "norm 2\<c-b>"
822 bw!
823endfunc
824
Bram Moolenaar1671f442020-03-10 07:48:13 +0100825" Test for errors with z command
826func Test_normal_z_error()
827 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200828 call assert_beeps('normal! zq')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100829endfunc
830
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100831func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200832 " basic test for z commands that scroll the window
833 call Setup_NewWindow()
834 100
835 norm! >>
836 " Test for z<cr>
837 exe "norm! z\<cr>"
838 call assert_equal(' 100', getline('.'))
839 call assert_equal(100, winsaveview()['topline'])
840 call assert_equal([0, 100, 2, 0, 9], getcurpos())
841
842 " Test for zt
843 21
844 norm! >>0zt
845 call assert_equal(' 21', getline('.'))
846 call assert_equal(21, winsaveview()['topline'])
847 call assert_equal([0, 21, 1, 0, 8], getcurpos())
848
849 " Test for zb
850 30
851 norm! >>$ztzb
852 call assert_equal(' 30', getline('.'))
853 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
854 call assert_equal([0, 30, 3, 0, 2147483647], getcurpos())
855
856 " Test for z-
857 1
858 30
859 norm! 0z-
860 call assert_equal(' 30', getline('.'))
861 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
862 call assert_equal([0, 30, 2, 0, 9], getcurpos())
863
864 " Test for z{height}<cr>
865 call assert_equal(10, winheight(0))
866 exe "norm! z12\<cr>"
867 call assert_equal(12, winheight(0))
868 exe "norm! z10\<cr>"
869 call assert_equal(10, winheight(0))
870
871 " Test for z.
872 1
873 21
874 norm! 0z.
875 call assert_equal(' 21', getline('.'))
876 call assert_equal(17, winsaveview()['topline'])
877 call assert_equal([0, 21, 2, 0, 9], getcurpos())
878
879 " Test for zz
880 1
881 21
882 norm! 0zz
883 call assert_equal(' 21', getline('.'))
884 call assert_equal(17, winsaveview()['topline'])
885 call assert_equal([0, 21, 1, 0, 8], getcurpos())
886
887 " Test for z+
888 11
889 norm! zt
890 norm! z+
891 call assert_equal(' 21', getline('.'))
892 call assert_equal(21, winsaveview()['topline'])
893 call assert_equal([0, 21, 2, 0, 9], getcurpos())
894
895 " Test for [count]z+
896 1
897 norm! 21z+
898 call assert_equal(' 21', getline('.'))
899 call assert_equal(21, winsaveview()['topline'])
900 call assert_equal([0, 21, 2, 0, 9], getcurpos())
901
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200902 " Test for z+ with [count] greater than buffer size
903 1
904 norm! 1000z+
905 call assert_equal(' 100', getline('.'))
906 call assert_equal(100, winsaveview()['topline'])
907 call assert_equal([0, 100, 2, 0, 9], getcurpos())
908
909 " Test for z+ from the last buffer line
910 norm! Gz.z+
911 call assert_equal(' 100', getline('.'))
912 call assert_equal(100, winsaveview()['topline'])
913 call assert_equal([0, 100, 2, 0, 9], getcurpos())
914
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200915 " Test for z^
916 norm! 22z+0
917 norm! z^
918 call assert_equal(' 21', getline('.'))
919 call assert_equal(12, winsaveview()['topline'])
920 call assert_equal([0, 21, 2, 0, 9], getcurpos())
921
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200922 " Test for z^ from first buffer line
923 norm! ggz^
924 call assert_equal('1', getline('.'))
925 call assert_equal(1, winsaveview()['topline'])
926 call assert_equal([0, 1, 1, 0, 1], getcurpos())
927
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200928 " Test for [count]z^
929 1
930 norm! 30z^
931 call assert_equal(' 21', getline('.'))
932 call assert_equal(12, winsaveview()['topline'])
933 call assert_equal([0, 21, 2, 0, 9], getcurpos())
934
935 " cleanup
936 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200937endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200938
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100939func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200940 " basic test for z commands that scroll the window
941 10new
942 15vsp
943 set nowrap listchars=
944 let lineA='abcdefghijklmnopqrstuvwxyz'
945 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
946 $put =lineA
947 $put =lineB
948 1d
949
Bram Moolenaar1671f442020-03-10 07:48:13 +0100950 " Test for zl and zh with a count
951 norm! 0z10l
952 call assert_equal([11, 1], [col('.'), wincol()])
953 norm! z4h
954 call assert_equal([11, 5], [col('.'), wincol()])
955 normal! 2gg
956
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200957 " Test for zl
958 1
959 norm! 5zl
960 call assert_equal(lineA, getline('.'))
961 call assert_equal(6, col('.'))
962 call assert_equal(5, winsaveview()['leftcol'])
963 norm! yl
964 call assert_equal('f', @0)
965
966 " Test for zh
967 norm! 2zh
968 call assert_equal(lineA, getline('.'))
969 call assert_equal(6, col('.'))
970 norm! yl
971 call assert_equal('f', @0)
972 call assert_equal(3, winsaveview()['leftcol'])
973
974 " Test for zL
975 norm! zL
976 call assert_equal(11, col('.'))
977 norm! yl
978 call assert_equal('k', @0)
979 call assert_equal(10, winsaveview()['leftcol'])
980 norm! 2zL
981 call assert_equal(25, col('.'))
982 norm! yl
983 call assert_equal('y', @0)
984 call assert_equal(24, winsaveview()['leftcol'])
985
986 " Test for zH
987 norm! 2zH
988 call assert_equal(25, col('.'))
989 call assert_equal(10, winsaveview()['leftcol'])
990 norm! yl
991 call assert_equal('y', @0)
992
993 " Test for zs
994 norm! $zs
995 call assert_equal(26, col('.'))
996 call assert_equal(25, winsaveview()['leftcol'])
997 norm! yl
998 call assert_equal('z', @0)
999
1000 " Test for ze
1001 norm! ze
1002 call assert_equal(26, col('.'))
1003 call assert_equal(11, winsaveview()['leftcol'])
1004 norm! yl
1005 call assert_equal('z', @0)
1006
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001007 " Test for zs and ze with folds
1008 %fold
1009 norm! $zs
1010 call assert_equal(26, col('.'))
1011 call assert_equal(0, winsaveview()['leftcol'])
1012 norm! yl
1013 call assert_equal('z', @0)
1014 norm! ze
1015 call assert_equal(26, col('.'))
1016 call assert_equal(0, winsaveview()['leftcol'])
1017 norm! yl
1018 call assert_equal('z', @0)
1019
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001020 " cleanup
1021 set wrap listchars=eol:$
1022 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001023endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001024
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001025func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001026 " basic test for z commands that scroll the window
1027 " using 'sidescrolloff' setting
1028 10new
1029 20vsp
1030 set nowrap listchars= sidescrolloff=5
1031 let lineA='abcdefghijklmnopqrstuvwxyz'
1032 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1033 $put =lineA
1034 $put =lineB
1035 1d
1036
1037 " Test for zl
1038 1
1039 norm! 5zl
1040 call assert_equal(lineA, getline('.'))
1041 call assert_equal(11, col('.'))
1042 call assert_equal(5, winsaveview()['leftcol'])
1043 norm! yl
1044 call assert_equal('k', @0)
1045
1046 " Test for zh
1047 norm! 2zh
1048 call assert_equal(lineA, getline('.'))
1049 call assert_equal(11, col('.'))
1050 norm! yl
1051 call assert_equal('k', @0)
1052 call assert_equal(3, winsaveview()['leftcol'])
1053
1054 " Test for zL
1055 norm! 0zL
1056 call assert_equal(16, col('.'))
1057 norm! yl
1058 call assert_equal('p', @0)
1059 call assert_equal(10, winsaveview()['leftcol'])
1060 norm! 2zL
1061 call assert_equal(26, col('.'))
1062 norm! yl
1063 call assert_equal('z', @0)
1064 call assert_equal(15, winsaveview()['leftcol'])
1065
1066 " Test for zH
1067 norm! 2zH
1068 call assert_equal(15, col('.'))
1069 call assert_equal(0, winsaveview()['leftcol'])
1070 norm! yl
1071 call assert_equal('o', @0)
1072
1073 " Test for zs
1074 norm! $zs
1075 call assert_equal(26, col('.'))
1076 call assert_equal(20, winsaveview()['leftcol'])
1077 norm! yl
1078 call assert_equal('z', @0)
1079
1080 " Test for ze
1081 norm! ze
1082 call assert_equal(26, col('.'))
1083 call assert_equal(11, winsaveview()['leftcol'])
1084 norm! yl
1085 call assert_equal('z', @0)
1086
1087 " cleanup
1088 set wrap listchars=eol:$ sidescrolloff=0
1089 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001090endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001091
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001092" Test for commands that scroll the window horizontally. Test with folds.
1093" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1094func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001095 15new
1096 call setline(1, range(1, 100))
1097 exe "normal! 30ggz\<CR>"
1098 set foldenable
1099 33,36fold
1100 40,43fold
1101 46,49fold
1102 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001103
1104 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001105 " Top of the screen = 30
1106 " Folded lines = 9
1107 " Bottom of the screen = 30 + h + 9 - 1
1108 normal! 4L
1109 call assert_equal(35 + h, line('.'))
1110 normal! 4H
1111 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001112
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001113 " Test for using a large count value
1114 %d
1115 call setline(1, range(1, 4))
1116 norm! 6H
1117 call assert_equal(4, line('.'))
1118
1119 " Test for 'M' with folded lines
1120 %d
1121 call setline(1, range(1, 20))
1122 1,5fold
1123 norm! LM
1124 call assert_equal(12, line('.'))
1125
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001126 " Test for the CTRL-E and CTRL-Y commands with folds
1127 %d
1128 call setline(1, range(1, 10))
1129 3,5fold
1130 exe "normal 6G3\<C-E>"
1131 call assert_equal(6, line('w0'))
1132 exe "normal 2\<C-Y>"
1133 call assert_equal(2, line('w0'))
1134
1135 " Test for CTRL-Y on a folded line
1136 %d
1137 call setline(1, range(1, 100))
1138 exe (h + 2) .. "," .. (h + 4) .. "fold"
1139 exe h + 5
1140 normal z-
1141 exe "normal \<C-Y>\<C-Y>"
1142 call assert_equal(h + 1, line('w$'))
1143
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001144 " Test for CTRL-Y from the first line and CTRL-E from the last line
1145 %d
1146 set scrolloff=2
1147 call setline(1, range(1, 4))
1148 exe "normal gg\<C-Y>"
1149 call assert_equal(1, line('w0'))
1150 call assert_equal(1, line('.'))
1151 exe "normal G4\<C-E>\<C-E>"
1152 call assert_equal(4, line('w$'))
1153 call assert_equal(4, line('.'))
1154 set scrolloff&
1155
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001156 " Using <PageUp> and <PageDown> in an empty buffer should beep
1157 %d
1158 call assert_beeps('exe "normal \<PageUp>"')
1159 call assert_beeps('exe "normal \<C-B>"')
1160 call assert_beeps('exe "normal \<PageDown>"')
1161 call assert_beeps('exe "normal \<C-F>"')
1162
1163 " Test for <C-U> and <C-D> with fold
1164 %d
1165 call setline(1, range(1, 100))
1166 10,35fold
1167 set scroll=10
1168 exe "normal \<C-D>"
1169 call assert_equal(36, line('.'))
1170 exe "normal \<C-D>"
1171 call assert_equal(46, line('.'))
1172 exe "normal \<C-U>"
1173 call assert_equal(36, line('.'))
1174 exe "normal \<C-U>"
1175 call assert_equal(10, line('.'))
1176 exe "normal \<C-U>"
1177 call assert_equal(1, line('.'))
1178 set scroll&
1179
1180 " Test for scrolling to the top of the file with <C-U> and a fold
1181 10
1182 normal ztL
1183 exe "normal \<C-U>\<C-U>"
1184 call assert_equal(1, line('w0'))
1185
1186 " Test for CTRL-D on a folded line
1187 %d
1188 call setline(1, range(1, 100))
1189 50,100fold
1190 75
1191 normal z-
1192 exe "normal \<C-D>"
1193 call assert_equal(50, line('.'))
1194 call assert_equal(100, line('w$'))
1195 normal z.
1196 let lnum = winline()
1197 exe "normal \<C-D>"
1198 call assert_equal(lnum, winline())
1199 call assert_equal(50, line('.'))
1200 normal zt
1201 exe "normal \<C-D>"
1202 call assert_equal(50, line('w0'))
1203
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001204 " Test for <S-CR>. Page down.
1205 %d
1206 call setline(1, range(1, 100))
1207 call feedkeys("\<S-CR>", 'xt')
1208 call assert_equal(14, line('w0'))
1209 call assert_equal(28, line('w$'))
1210
1211 " Test for <S-->. Page up.
1212 call feedkeys("\<S-->", 'xt')
1213 call assert_equal(1, line('w0'))
1214 call assert_equal(15, line('w$'))
1215
Bram Moolenaar1671f442020-03-10 07:48:13 +01001216 set foldenable&
1217 close!
1218endfunc
1219
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001220func Test_scroll_in_ex_mode()
1221 " This was using invalid memory because w_botline was invalid.
1222 let lines =<< trim END
1223 diffsplit
1224 norm os00(
1225 call writefile(['done'], 'Xdone')
1226 qa!
1227 END
1228 call writefile(lines, 'Xscript')
1229 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1230 call assert_equal(['done'], readfile('Xdone'))
1231
1232 call delete('Xscript')
1233 call delete('Xdone')
1234endfunc
1235
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001236" Test for the 'sidescroll' option
1237func Test_sidescroll_opt()
1238 new
1239 20vnew
1240
1241 " scroll by 2 characters horizontally
1242 set sidescroll=2 nowrap
1243 call setline(1, repeat('a', 40))
1244 normal g$l
1245 call assert_equal(19, screenpos(0, 1, 21).col)
1246 normal l
1247 call assert_equal(20, screenpos(0, 1, 22).col)
1248 normal g0h
1249 call assert_equal(2, screenpos(0, 1, 2).col)
1250 call assert_equal(20, screenpos(0, 1, 20).col)
1251
1252 " when 'sidescroll' is 0, cursor positioned at the center
1253 set sidescroll=0
1254 normal g$l
1255 call assert_equal(11, screenpos(0, 1, 21).col)
1256 normal g0h
1257 call assert_equal(10, screenpos(0, 1, 10).col)
1258
1259 %bw!
1260 set wrap& sidescroll&
1261endfunc
1262
Bram Moolenaar004a6782020-04-11 17:09:31 +02001263" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001264func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001265 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001266 call Setup_NewWindow()
1267 50
1268 setl foldenable fdm=marker foldlevel=5
1269
Bram Moolenaar1671f442020-03-10 07:48:13 +01001270 call assert_beeps('normal! zj')
1271 call assert_beeps('normal! zk')
1272
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001273 " Test for zF
1274 " First fold
1275 norm! 4zF
1276 " check that folds have been created
1277 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1278
1279 " Test for zd
1280 51
1281 norm! 2zF
1282 call assert_equal(2, foldlevel('.'))
1283 norm! kzd
1284 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1285 norm! j
1286 call assert_equal(1, foldlevel('.'))
1287
1288 " Test for zD
1289 " also deletes partially selected folds recursively
1290 51
1291 norm! zF
1292 call assert_equal(2, foldlevel('.'))
1293 norm! kV2jzD
1294 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1295
1296 " Test for zE
1297 85
1298 norm! 4zF
1299 86
1300 norm! 2zF
1301 90
1302 norm! 4zF
1303 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1304 norm! zE
1305 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1306
1307 " Test for zn
1308 50
1309 set foldlevel=0
1310 norm! 2zF
1311 norm! zn
1312 norm! k
1313 call assert_equal('49', getline('.'))
1314 norm! j
1315 call assert_equal('50/*{{{*/', getline('.'))
1316 norm! j
1317 call assert_equal('51/*}}}*/', getline('.'))
1318 norm! j
1319 call assert_equal('52', getline('.'))
1320 call assert_equal(0, &foldenable)
1321
1322 " Test for zN
1323 49
1324 norm! zN
1325 call assert_equal('49', getline('.'))
1326 norm! j
1327 call assert_equal('50/*{{{*/', getline('.'))
1328 norm! j
1329 call assert_equal('52', getline('.'))
1330 call assert_equal(1, &foldenable)
1331
1332 " Test for zi
1333 norm! zi
1334 call assert_equal(0, &foldenable)
1335 norm! zi
1336 call assert_equal(1, &foldenable)
1337 norm! zi
1338 call assert_equal(0, &foldenable)
1339 norm! zi
1340 call assert_equal(1, &foldenable)
1341
1342 " Test for za
1343 50
1344 norm! za
1345 norm! k
1346 call assert_equal('49', getline('.'))
1347 norm! j
1348 call assert_equal('50/*{{{*/', getline('.'))
1349 norm! j
1350 call assert_equal('51/*}}}*/', getline('.'))
1351 norm! j
1352 call assert_equal('52', getline('.'))
1353 50
1354 norm! za
1355 norm! k
1356 call assert_equal('49', getline('.'))
1357 norm! j
1358 call assert_equal('50/*{{{*/', getline('.'))
1359 norm! j
1360 call assert_equal('52', getline('.'))
1361
1362 49
1363 norm! 5zF
1364 norm! k
1365 call assert_equal('48', getline('.'))
1366 norm! j
1367 call assert_equal('49/*{{{*/', getline('.'))
1368 norm! j
1369 call assert_equal('55', getline('.'))
1370 49
1371 norm! za
1372 call assert_equal('49/*{{{*/', getline('.'))
1373 norm! j
1374 call assert_equal('50/*{{{*/', getline('.'))
1375 norm! j
1376 call assert_equal('52', getline('.'))
1377 set nofoldenable
1378 " close fold and set foldenable
1379 norm! za
1380 call assert_equal(1, &foldenable)
1381
1382 50
1383 " have to use {count}za to open all folds and make the cursor visible
1384 norm! 2za
1385 norm! 2k
1386 call assert_equal('48', getline('.'))
1387 norm! j
1388 call assert_equal('49/*{{{*/', getline('.'))
1389 norm! j
1390 call assert_equal('50/*{{{*/', getline('.'))
1391 norm! j
1392 call assert_equal('51/*}}}*/', getline('.'))
1393 norm! j
1394 call assert_equal('52', getline('.'))
1395
1396 " Test for zA
1397 49
1398 set foldlevel=0
1399 50
1400 norm! zA
1401 norm! 2k
1402 call assert_equal('48', getline('.'))
1403 norm! j
1404 call assert_equal('49/*{{{*/', getline('.'))
1405 norm! j
1406 call assert_equal('50/*{{{*/', getline('.'))
1407 norm! j
1408 call assert_equal('51/*}}}*/', getline('.'))
1409 norm! j
1410 call assert_equal('52', getline('.'))
1411
Dominique Pelle923dce22021-11-21 11:36:04 +00001412 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001413 50
1414 set nofoldenable
1415 norm! zA
1416 call assert_equal(1, &foldenable)
1417 norm! k
1418 call assert_equal('48', getline('.'))
1419 norm! j
1420 call assert_equal('49/*{{{*/', getline('.'))
1421 norm! j
1422 call assert_equal('55', getline('.'))
1423
1424 " Test for zc
1425 norm! zE
1426 50
1427 norm! 2zF
1428 49
1429 norm! 5zF
1430 set nofoldenable
1431 50
1432 " There most likely is a bug somewhere:
1433 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1434 " TODO: Should this only close the inner most fold or both folds?
1435 norm! zc
1436 call assert_equal(1, &foldenable)
1437 norm! k
1438 call assert_equal('48', getline('.'))
1439 norm! j
1440 call assert_equal('49/*{{{*/', getline('.'))
1441 norm! j
1442 call assert_equal('55', getline('.'))
1443 set nofoldenable
1444 50
1445 norm! Vjzc
1446 norm! k
1447 call assert_equal('48', getline('.'))
1448 norm! j
1449 call assert_equal('49/*{{{*/', getline('.'))
1450 norm! j
1451 call assert_equal('55', getline('.'))
1452
1453 " Test for zC
1454 set nofoldenable
1455 50
1456 norm! zCk
1457 call assert_equal('48', getline('.'))
1458 norm! j
1459 call assert_equal('49/*{{{*/', getline('.'))
1460 norm! j
1461 call assert_equal('55', getline('.'))
1462
1463 " Test for zx
1464 " 1) close folds at line 49-54
1465 set nofoldenable
1466 48
1467 norm! zx
1468 call assert_equal(1, &foldenable)
1469 norm! j
1470 call assert_equal('49/*{{{*/', getline('.'))
1471 norm! j
1472 call assert_equal('55', getline('.'))
1473
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001474 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001475 51
1476 set nofoldenable
1477 norm! zx
1478 call assert_equal(1, &foldenable)
1479 norm! 3k
1480 call assert_equal('48', getline('.'))
1481 norm! j
1482 call assert_equal('49/*{{{*/', getline('.'))
1483 norm! j
1484 call assert_equal('50/*{{{*/', getline('.'))
1485 norm! j
1486 call assert_equal('51/*}}}*/', getline('.'))
1487 norm! j
1488 call assert_equal('52', getline('.'))
1489 norm! j
1490 call assert_equal('53', getline('.'))
1491 norm! j
1492 call assert_equal('54/*}}}*/', getline('.'))
1493 norm! j
1494 call assert_equal('55', getline('.'))
1495
1496 " 3) close one level of folds
1497 48
1498 set nofoldenable
1499 set foldlevel=1
1500 norm! zx
1501 call assert_equal(1, &foldenable)
1502 call assert_equal('48', getline('.'))
1503 norm! j
1504 call assert_equal('49/*{{{*/', getline('.'))
1505 norm! j
1506 call assert_equal('50/*{{{*/', getline('.'))
1507 norm! j
1508 call assert_equal('52', getline('.'))
1509 norm! j
1510 call assert_equal('53', getline('.'))
1511 norm! j
1512 call assert_equal('54/*}}}*/', getline('.'))
1513 norm! j
1514 call assert_equal('55', getline('.'))
1515
1516 " Test for zX
1517 " Close all folds
1518 set foldlevel=0 nofoldenable
1519 50
1520 norm! zX
1521 call assert_equal(1, &foldenable)
1522 norm! k
1523 call assert_equal('48', getline('.'))
1524 norm! j
1525 call assert_equal('49/*{{{*/', getline('.'))
1526 norm! j
1527 call assert_equal('55', getline('.'))
1528
1529 " Test for zm
1530 50
1531 set nofoldenable foldlevel=2
1532 norm! zm
1533 call assert_equal(1, &foldenable)
1534 call assert_equal(1, &foldlevel)
1535 norm! zm
1536 call assert_equal(0, &foldlevel)
1537 norm! zm
1538 call assert_equal(0, &foldlevel)
1539 norm! k
1540 call assert_equal('48', getline('.'))
1541 norm! j
1542 call assert_equal('49/*{{{*/', getline('.'))
1543 norm! j
1544 call assert_equal('55', getline('.'))
1545
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001546 " Test for zm with a count
1547 50
1548 set foldlevel=2
1549 norm! 3zm
1550 call assert_equal(0, &foldlevel)
1551 call assert_equal(49, foldclosed(line('.')))
1552
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001553 " Test for zM
1554 48
1555 set nofoldenable foldlevel=99
1556 norm! zM
1557 call assert_equal(1, &foldenable)
1558 call assert_equal(0, &foldlevel)
1559 call assert_equal('48', getline('.'))
1560 norm! j
1561 call assert_equal('49/*{{{*/', getline('.'))
1562 norm! j
1563 call assert_equal('55', getline('.'))
1564
1565 " Test for zr
1566 48
1567 set nofoldenable foldlevel=0
1568 norm! zr
1569 call assert_equal(0, &foldenable)
1570 call assert_equal(1, &foldlevel)
1571 set foldlevel=0 foldenable
1572 norm! zr
1573 call assert_equal(1, &foldenable)
1574 call assert_equal(1, &foldlevel)
1575 norm! zr
1576 call assert_equal(2, &foldlevel)
1577 call assert_equal('48', getline('.'))
1578 norm! j
1579 call assert_equal('49/*{{{*/', getline('.'))
1580 norm! j
1581 call assert_equal('50/*{{{*/', getline('.'))
1582 norm! j
1583 call assert_equal('51/*}}}*/', getline('.'))
1584 norm! j
1585 call assert_equal('52', getline('.'))
1586
1587 " Test for zR
1588 48
1589 set nofoldenable foldlevel=0
1590 norm! zR
1591 call assert_equal(0, &foldenable)
1592 call assert_equal(2, &foldlevel)
1593 set foldenable foldlevel=0
1594 norm! zR
1595 call assert_equal(1, &foldenable)
1596 call assert_equal(2, &foldlevel)
1597 call assert_equal('48', getline('.'))
1598 norm! j
1599 call assert_equal('49/*{{{*/', getline('.'))
1600 norm! j
1601 call assert_equal('50/*{{{*/', getline('.'))
1602 norm! j
1603 call assert_equal('51/*}}}*/', getline('.'))
1604 norm! j
1605 call assert_equal('52', getline('.'))
1606 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1607 48
1608 call assert_equal('48', getline('.'))
1609 norm! j
1610 call assert_equal('49/*{{{*/', getline('.'))
1611 norm! j
1612 call assert_equal('50/*{{{*/', getline('.'))
1613 norm! j
1614 call assert_equal('a /*{{{*/', getline('.'))
1615 norm! j
1616 call assert_equal('51/*}}}*/', getline('.'))
1617 norm! j
1618 call assert_equal('52', getline('.'))
1619 48
1620 norm! zR
1621 call assert_equal(1, &foldenable)
1622 call assert_equal(3, &foldlevel)
1623 call assert_equal('48', getline('.'))
1624 norm! j
1625 call assert_equal('49/*{{{*/', getline('.'))
1626 norm! j
1627 call assert_equal('50/*{{{*/', getline('.'))
1628 norm! j
1629 call assert_equal('a /*{{{*/', getline('.'))
1630 norm! j
1631 call assert_equal('b /*}}}*/', getline('.'))
1632 norm! j
1633 call assert_equal('51/*}}}*/', getline('.'))
1634 norm! j
1635 call assert_equal('52', getline('.'))
1636
1637 " clean up
1638 setl nofoldenable fdm=marker foldlevel=0
1639 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001640endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001641
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001642func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001643 " Reading from redirected file doesn't work on MS-Windows
1644 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001645 call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
1646 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001647 call system(GetVimCommand() .. ' -e -s < Xscript Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001648 let a=readfile('Xfile2')
1649 call assert_equal(['1', 'foo', 'bar', '2'], a)
1650
1651 " clean up
1652 for file in ['Xfile', 'Xfile2', 'Xscript']
1653 call delete(file)
1654 endfor
1655 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001656endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001657
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001658func Test_normal21_nv_hat()
1659
1660 " Edit a fresh file and wipe the buffer list so that there is no alternate
1661 " file present. Next, check for the expected command failures.
1662 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001663 call assert_fails(':buffer #', 'E86:')
1664 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001665 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001666
1667 " Test for the expected behavior when switching between two named buffers.
1668 edit Xfoo | edit Xbar
1669 call feedkeys("\<C-^>", 'tx')
1670 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1671 call feedkeys("\<C-^>", 'tx')
1672 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1673
1674 " Test for the expected behavior when only one buffer is named.
1675 enew | let l:nr = bufnr('%')
1676 call feedkeys("\<C-^>", 'tx')
1677 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1678 call feedkeys("\<C-^>", 'tx')
1679 call assert_equal('', bufname('%'))
1680 call assert_equal(l:nr, bufnr('%'))
1681
1682 " Test that no action is taken by "<C-^>" when an operator is pending.
1683 edit Xfoo
1684 call feedkeys("ci\<C-^>", 'tx')
1685 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1686
1687 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001688endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001689
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001690func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001691 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001692 " let shell = &shell
1693 " let &shell = 'sh'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001694 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001695 let args = ' -N -i NONE --noplugins -X --not-a-term'
1696 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001697 let a = readfile('Xfile')
1698 call assert_equal([], a)
1699 " Test for ZQ
1700 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001701 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001702 let a = readfile('Xfile')
1703 call assert_equal(['1', '2'], a)
1704
Bram Moolenaar1671f442020-03-10 07:48:13 +01001705 " Unsupported Z command
1706 call assert_beeps('normal! ZW')
1707
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001708 " clean up
1709 for file in ['Xfile']
1710 call delete(file)
1711 endfor
Bram Moolenaar0913a102016-09-03 19:11:59 +02001712 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001713endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001714
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001715func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001716 " Test for K command
1717 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001718 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001719 let k = &keywordprg
1720 set keywordprg=:help
1721 1
1722 norm! VK
1723 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1724 call assert_equal('help', &ft)
1725 call assert_match('\*version8.txt\*', getline('.'))
1726 helpclose
1727 norm! 0K
1728 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1729 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001730 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001731 helpclose
1732
Bram Moolenaar426f3752016-11-04 21:22:37 +01001733 set keywordprg=:new
1734 set iskeyword+=%
1735 set iskeyword+=\|
1736 2
1737 norm! K
1738 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1739 bwipe!
1740 3
1741 norm! K
1742 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1743 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001744 if !has('win32')
1745 4
1746 norm! K
1747 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1748 bwipe!
1749 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001750 set iskeyword-=%
1751 set iskeyword-=\|
1752
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001753 " Test for specifying a count to K
1754 1
1755 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1756 set keywordprg=:Kprog
1757 norm! 3K
1758 call assert_equal('3 version8', g:Kprog_Args)
1759 delcom Kprog
1760
Bram Moolenaar0913a102016-09-03 19:11:59 +02001761 " Only expect "man" to work on Unix
1762 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001763 let &keywordprg = k
1764 bw!
1765 return
1766 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001767
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001768 let not_gnu_man = has('mac') || has('bsd')
1769 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001770 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001771 set keywordprg=man\ -P\ cat
1772 else
1773 set keywordprg=man\ --pager=cat
1774 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001775 " Test for using man
1776 2
1777 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001778 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001779 call assert_match("man -P cat 'man'", a)
1780 else
1781 call assert_match("man --pager=cat 'man'", a)
1782 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001783
Bram Moolenaar1671f442020-03-10 07:48:13 +01001784 " Error cases
1785 call setline(1, '#$#')
1786 call assert_fails('normal! ggK', 'E349:')
1787 call setline(1, '---')
1788 call assert_fails('normal! ggv2lK', 'E349:')
1789 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001790 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001791 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001792 norm! V
1793 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001794
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001795 " clean up
1796 let &keywordprg = k
1797 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001798endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001799
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001800func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001801 " Testing for g?? g?g?
1802 new
1803 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1804 1
1805 norm! g??
1806 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1807 norm! g?g?
1808 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1809
1810 " clean up
1811 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001812endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001813
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001814func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001815 CheckFeature quickfix
1816
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001817 " Testing for CTRL-] g CTRL-] g]
1818 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1819 h
1820 " Test for CTRL-]
1821 call search('\<x\>$')
1822 exe "norm! \<c-]>"
1823 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1824 norm! yiW
1825 call assert_equal("*x*", @0)
1826 exe ":norm \<c-o>"
1827
1828 " Test for g_CTRL-]
1829 call search('\<v_u\>$')
1830 exe "norm! g\<c-]>"
1831 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1832 norm! yiW
1833 call assert_equal("*v_u*", @0)
1834 exe ":norm \<c-o>"
1835
1836 " Test for g]
1837 call search('\<i_<Esc>$')
1838 let a = execute(":norm! g]")
1839 call assert_match('i_<Esc>.*insert.txt', a)
1840
1841 if !empty(exepath('cscope')) && has('cscope')
1842 " setting cscopetag changes how g] works
1843 set cst
1844 exe "norm! g]"
1845 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1846 norm! yiW
1847 call assert_equal("*i_<Esc>*", @0)
1848 exe ":norm \<c-o>"
1849 " Test for CTRL-W g]
1850 exe "norm! \<C-W>g]"
1851 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1852 norm! yiW
1853 call assert_equal("*i_<Esc>*", @0)
1854 call assert_equal(3, winnr('$'))
1855 helpclose
1856 set nocst
1857 endif
1858
1859 " Test for CTRL-W g]
1860 let a = execute("norm! \<C-W>g]")
1861 call assert_match('i_<Esc>.*insert.txt', a)
1862
1863 " Test for CTRL-W CTRL-]
1864 exe "norm! \<C-W>\<C-]>"
1865 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1866 norm! yiW
1867 call assert_equal("*i_<Esc>*", @0)
1868 call assert_equal(3, winnr('$'))
1869 helpclose
1870
1871 " Test for CTRL-W g CTRL-]
1872 exe "norm! \<C-W>g\<C-]>"
1873 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1874 norm! yiW
1875 call assert_equal("*i_<Esc>*", @0)
1876 call assert_equal(3, winnr('$'))
1877 helpclose
1878
1879 " clean up
1880 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001881endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001882
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001883func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001884 " Test for ]p ]P [p and [P
1885 new
1886 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1887 1
1888 /Error/y a
1889 2
1890 norm! "a]pj"a[p
1891 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1892 1
1893 /^\s\{4}/
1894 exe "norm! \"a]P3Eldt'"
1895 exe "norm! j\"a[P2Eldt'"
1896 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
1897
1898 " clean up
1899 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001900endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001901
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001902func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001903 " Test for [' [` ]' ]`
1904 call Setup_NewWindow()
1905 1,21s/.\+/ & b/
1906 1
1907 norm! $ma
1908 5
1909 norm! $mb
1910 10
1911 norm! $mc
1912 15
1913 norm! $md
1914 20
1915 norm! $me
1916
1917 " Test for ['
1918 9
1919 norm! 2['
1920 call assert_equal(' 1 b', getline('.'))
1921 call assert_equal(1, line('.'))
1922 call assert_equal(3, col('.'))
1923
1924 " Test for ]'
1925 norm! ]'
1926 call assert_equal(' 5 b', getline('.'))
1927 call assert_equal(5, line('.'))
1928 call assert_equal(3, col('.'))
1929
1930 " No mark after line 21, cursor moves to first non blank on current line
1931 21
1932 norm! $]'
1933 call assert_equal(' 21 b', getline('.'))
1934 call assert_equal(21, line('.'))
1935 call assert_equal(3, col('.'))
1936
1937 " Test for [`
1938 norm! 2[`
1939 call assert_equal(' 15 b', getline('.'))
1940 call assert_equal(15, line('.'))
1941 call assert_equal(8, col('.'))
1942
1943 " Test for ]`
1944 norm! ]`
1945 call assert_equal(' 20 b', getline('.'))
1946 call assert_equal(20, line('.'))
1947 call assert_equal(8, col('.'))
1948
1949 " clean up
1950 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001951endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001952
Bram Moolenaar1671f442020-03-10 07:48:13 +01001953" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001954func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001955 new
1956 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
1957
1958 $
1959 norm! d(
1960 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
1961 norm! 2d(
1962 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
1963 1
1964 norm! 0d)
1965 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
1966
1967 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
1968 $
1969 norm! $d(
1970 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
1971
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001972 " Move to the next sentence from a paragraph macro
1973 %d
1974 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
1975 call cursor(1, 1)
1976 normal )
1977 call assert_equal([2, 1], [line('.'), col('.')])
1978 normal )
1979 call assert_equal([2, 12], [line('.'), col('.')])
1980 normal ((
1981 call assert_equal([1, 1], [line('.'), col('.')])
1982
Bram Moolenaar1671f442020-03-10 07:48:13 +01001983 " It is an error if a next sentence is not found
1984 %d
1985 call setline(1, '.SH')
1986 call assert_beeps('normal )')
1987
Bram Moolenaar224a5f12020-04-28 20:29:07 +02001988 " If only dot is present, don't treat that as a sentence
1989 call setline(1, '. This is a sentence.')
1990 normal $((
1991 call assert_equal(3, col('.'))
1992
Bram Moolenaar1671f442020-03-10 07:48:13 +01001993 " Jumping to a fold should open the fold
1994 call setline(1, ['', '', 'one', 'two', 'three'])
1995 set foldenable
1996 2,$fold
1997 call feedkeys(')', 'xt')
1998 call assert_equal(3, line('.'))
1999 call assert_equal(1, foldlevel('.'))
2000 call assert_equal(-1, foldclosed('.'))
2001 set foldenable&
2002
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002003 " clean up
2004 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002005endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002006
Bram Moolenaar1671f442020-03-10 07:48:13 +01002007" Test for { and } paragraph movements
2008func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002009 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002010 A paragraph begins after each empty line, and also at each of a set of
2011 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2012 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2013 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2014 the first column). A section boundary is also a paragraph boundary.
2015 Note that a blank line (only containing white space) is NOT a paragraph
2016 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002017
2018
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002019 Also note that this does not include a '{' or '}' in the first column. When
2020 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2021 paragraph boundary |posix|.
2022 {
2023 This is no paragraph
2024 unless the '{' is set
2025 in 'cpoptions'
2026 }
2027 .IP
2028 The nroff macros IP separates a paragraph
2029 That means, it must be a '.'
2030 followed by IP
2031 .LPIt does not matter, if afterwards some
2032 more characters follow.
2033 .SHAlso section boundaries from the nroff
2034 macros terminate a paragraph. That means
2035 a character like this:
2036 .NH
2037 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002038 [DATA]
2039
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002040 new
2041 call append(0, text)
2042 1
2043 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002044
2045 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002046 .IP
2047 The nroff macros IP separates a paragraph
2048 That means, it must be a '.'
2049 followed by IP
2050 .LPIt does not matter, if afterwards some
2051 more characters follow.
2052 .SHAlso section boundaries from the nroff
2053 macros terminate a paragraph. That means
2054 a character like this:
2055 .NH
2056 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002057
2058 [DATA]
2059 call assert_equal(expected, getline(1, '$'))
2060
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002061 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002062
2063 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002064 .LPIt does not matter, if afterwards some
2065 more characters follow.
2066 .SHAlso section boundaries from the nroff
2067 macros terminate a paragraph. That means
2068 a character like this:
2069 .NH
2070 End of text here
2071
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002072 [DATA]
2073 call assert_equal(expected, getline(1, '$'))
2074
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002075 $
2076 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002077
2078 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002079 .LPIt does not matter, if afterwards some
2080 more characters follow.
2081 .SHAlso section boundaries from the nroff
2082 macros terminate a paragraph. That means
2083 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002084
2085 [DATA]
2086 call assert_equal(expected, getline(1, '$'))
2087
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002088 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.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002093
2094 [DATA]
2095 call assert_equal(expected, getline(1, '$'))
2096
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002097 " Test with { in cpooptions
2098 %d
2099 call append(0, text)
2100 set cpo+={
2101 1
2102 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002103
2104 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002105 {
2106 This is no paragraph
2107 unless the '{' is set
2108 in 'cpoptions'
2109 }
2110 .IP
2111 The nroff macros IP separates a paragraph
2112 That means, it must be a '.'
2113 followed by IP
2114 .LPIt does not matter, if afterwards some
2115 more characters follow.
2116 .SHAlso section boundaries from the nroff
2117 macros terminate a paragraph. That means
2118 a character like this:
2119 .NH
2120 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002121
2122 [DATA]
2123 call assert_equal(expected, getline(1, '$'))
2124
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002125 $
2126 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002127
2128 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002129 {
2130 This is no paragraph
2131 unless the '{' is set
2132 in 'cpoptions'
2133 }
2134 .IP
2135 The nroff macros IP separates a paragraph
2136 That means, it must be a '.'
2137 followed by IP
2138 .LPIt does not matter, if afterwards some
2139 more characters follow.
2140 .SHAlso section boundaries from the nroff
2141 macros terminate a paragraph. That means
2142 a character like this:
2143 .NH
2144 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002145
2146 [DATA]
2147 call assert_equal(expected, getline(1, '$'))
2148
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002149 norm! gg}
2150 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002151
2152 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002153 {
2154 This is no paragraph
2155 unless the '{' is set
2156 in 'cpoptions'
2157 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002158
2159 [DATA]
2160 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002161
Bram Moolenaar1671f442020-03-10 07:48:13 +01002162 " Jumping to a fold should open the fold
2163 %d
2164 call setline(1, ['', 'one', 'two', ''])
2165 set foldenable
2166 2,$fold
2167 call feedkeys('}', 'xt')
2168 call assert_equal(4, line('.'))
2169 call assert_equal(1, foldlevel('.'))
2170 call assert_equal(-1, foldclosed('.'))
2171 set foldenable&
2172
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002173 " clean up
2174 set cpo-={
2175 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002176endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002177
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002178" Test for section movements
2179func Test_normal_section()
2180 new
2181 let lines =<< trim [END]
2182 int foo()
2183 {
2184 if (1)
2185 {
2186 a = 1;
2187 }
2188 }
2189 [END]
2190 call setline(1, lines)
2191
2192 " jumping to a folded line using [[ should open the fold
2193 2,3fold
2194 call cursor(5, 1)
2195 call feedkeys("[[", 'xt')
2196 call assert_equal(2, line('.'))
2197 call assert_equal(-1, foldclosedend(line('.')))
2198
2199 close!
2200endfunc
2201
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002202" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002203func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002204 new
2205 call append(0, 'This is a simple test: äüöß')
2206 norm! 1ggVu
2207 call assert_equal('this is a simple test: äüöß', getline('.'))
2208 norm! VU
2209 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2210 norm! guu
2211 call assert_equal('this is a simple test: äüöss', getline('.'))
2212 norm! gUgU
2213 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2214 norm! gugu
2215 call assert_equal('this is a simple test: äüöss', getline('.'))
2216 norm! gUU
2217 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2218 norm! 010~
2219 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
2220 norm! V~
2221 call assert_equal('THIS IS A simple test: äüöss', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002222 call assert_beeps('norm! c~')
2223 %d
2224 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002225
Bram Moolenaar1671f442020-03-10 07:48:13 +01002226 " Test for changing case across lines using 'whichwrap'
2227 call setline(1, ['aaaaaa', 'aaaaaa'])
2228 normal! gg10~
2229 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2230 set whichwrap+=~
2231 normal! gg10~
2232 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2233 set whichwrap&
2234
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002235 " try changing the case with a double byte encoding (DBCS)
2236 %bw!
2237 let enc = &enc
2238 set encoding=cp932
2239 call setline(1, "\u8470")
2240 normal ~
2241 normal gU$gu$gUgUg~g~gugu
2242 call assert_equal("\u8470", getline(1))
2243 let &encoding = enc
2244
Bram Moolenaar1671f442020-03-10 07:48:13 +01002245 " clean up
2246 bw!
2247endfunc
2248
2249" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2250" is available but toupper()/tolower() don't do the right thing.
2251func Test_normal_changecase_turkish()
2252 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002253 try
2254 lang tr_TR.UTF-8
2255 set casemap=
2256 let iupper = toupper('i')
2257 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002258 call setline(1, 'iI')
2259 1normal gUU
2260 call assert_equal("\u0130I", getline(1))
2261 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002262
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002263 call setline(1, 'iI')
2264 1normal guu
2265 call assert_equal("i\u0131", getline(1))
2266 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002267 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002268 call setline(1, 'iI')
2269 1normal gUU
2270 call assert_equal("II", getline(1))
2271 call assert_equal("II", toupper("iI"))
2272
2273 call setline(1, 'iI')
2274 1normal guu
2275 call assert_equal("ii", getline(1))
2276 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002277 else
2278 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2279 endif
2280 set casemap&
2281 call setline(1, 'iI')
2282 1normal gUU
2283 call assert_equal("II", getline(1))
2284 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002285
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002286 call setline(1, 'iI')
2287 1normal guu
2288 call assert_equal("ii", getline(1))
2289 call assert_equal("ii", tolower("iI"))
2290
2291 lang en_US.UTF-8
2292 catch /E197:/
2293 " can't use Turkish locale
2294 throw 'Skipped: Turkish locale not available'
2295 endtry
Bram Moolenaar1671f442020-03-10 07:48:13 +01002296 close!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002297endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002298
Bram Moolenaar1671f442020-03-10 07:48:13 +01002299" Test for r (replace) command
2300func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002301 new
2302 call append(0, 'This is a simple test: abcd')
2303 exe "norm! 1gg$r\<cr>"
2304 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2305 exe "norm! 1gg2wlr\<cr>"
2306 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2307 exe "norm! 2gg0W5r\<cr>"
2308 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2309 set autoindent
2310 call setline(2, ['simple test: abc', ''])
2311 exe "norm! 2gg0W5r\<cr>"
2312 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2313 exe "norm! 1ggVr\<cr>"
2314 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2315 call setline(1, 'This is a')
2316 exe "norm! 1gg05rf"
2317 call assert_equal('fffffis a', getline(1))
2318
Bram Moolenaar1671f442020-03-10 07:48:13 +01002319 " When replacing characters, copy characters from above and below lines
2320 " using CTRL-Y and CTRL-E.
2321 " Different code paths are used for utf-8 and latin1 encodings
2322 set showmatch
2323 for enc in ['latin1', 'utf-8']
2324 enew!
2325 let &encoding = enc
2326 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2327 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2328 call assert_equal(' {a}x [b]x', getline(2))
2329 endfor
2330 set showmatch&
2331
2332 " r command should fail in operator pending mode
2333 call assert_beeps('normal! cr')
2334
Bram Moolenaar004a6782020-04-11 17:09:31 +02002335 " replace a tab character in visual mode
2336 %d
2337 call setline(1, ["a\tb", "c\td", "e\tf"])
2338 normal gglvjjrx
2339 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2340
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002341 " replace with a multibyte character (with multiple composing characters)
2342 %d
2343 new
2344 call setline(1, 'aaa')
2345 exe "normal $ra\u0328\u0301"
2346 call assert_equal("aaa\u0328\u0301", getline(1))
2347
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002348 " clean up
2349 set noautoindent
2350 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002351endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002352
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002353" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002354func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002355 new
2356 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2357 1
2358 norm! $g*
2359 call assert_equal('x_foo', @/)
2360 call assert_equal('x_foobar.abc', getline('.'))
2361 norm! $g#
2362 call assert_equal('abc', @/)
2363 call assert_equal('abc.x_foo', getline('.'))
2364
2365 " clean up
2366 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002367endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002368
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002369" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2370" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002371func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002372 call Setup_NewWindow()
2373 " Test for g`
2374 clearjumps
2375 norm! ma10j
2376 let a=execute(':jumps')
2377 " empty jumplist
2378 call assert_equal('>', a[-1:])
2379 norm! g`a
2380 call assert_equal('>', a[-1:])
2381 call assert_equal(1, line('.'))
2382 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002383 call cursor(10, 1)
2384 norm! g'a
2385 call assert_equal('>', a[-1:])
2386 call assert_equal(1, line('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002387
2388 " Test for g; and g,
2389 norm! g;
2390 " there is only one change in the changelist
2391 " currently, when we setup the window
2392 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002393 call assert_fails(':norm! g;', 'E662:')
2394 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002395 let &ul=&ul
2396 call append('$', ['a', 'b', 'c', 'd'])
2397 let &ul=&ul
2398 call append('$', ['Z', 'Y', 'X', 'W'])
2399 let a = execute(':changes')
2400 call assert_match('2\s\+0\s\+2', a)
2401 call assert_match('101\s\+0\s\+a', a)
2402 call assert_match('105\s\+0\s\+Z', a)
2403 norm! 3g;
2404 call assert_equal(2, line('.'))
2405 norm! 2g,
2406 call assert_equal(105, line('.'))
2407
2408 " Test for g& - global substitute
2409 %d
2410 call setline(1, range(1,10))
2411 call append('$', ['a', 'b', 'c', 'd'])
2412 $s/\w/&&/g
2413 exe "norm! /[1-8]\<cr>"
2414 norm! g&
2415 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2416
Bram Moolenaar1671f442020-03-10 07:48:13 +01002417 " Jumping to a fold using gg should open the fold
2418 set foldenable
2419 set foldopen+=jump
2420 5,8fold
2421 call feedkeys('6gg', 'xt')
2422 call assert_equal(1, foldlevel('.'))
2423 call assert_equal(-1, foldclosed('.'))
2424 set foldopen-=jump
2425 set foldenable&
2426
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002427 " Test for gv
2428 %d
2429 call append('$', repeat(['abcdefgh'], 8))
2430 exe "norm! 2gg02l\<c-v>2j2ly"
2431 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2432 " in visual mode, gv swaps current and last selected region
2433 exe "norm! G0\<c-v>4k4lgvd"
2434 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2435 exe "norm! G0\<c-v>4k4ly"
2436 exe "norm! gvood"
2437 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002438 " gv cannot be used in operator pending mode
2439 call assert_beeps('normal! cgv')
2440 " gv should beep without a previously selected visual area
2441 new
2442 call assert_beeps('normal! gv')
2443 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002444
2445 " Test for gk/gj
2446 %d
2447 15vsp
2448 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002449 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2450 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2451 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002452 $put =lineA
2453 $put =lineB
2454
2455 norm! 3gg0dgk
2456 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2457 set nu
2458 norm! 3gg0gjdgj
2459 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2460
2461 " Test for gJ
2462 norm! 2gggJ
2463 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2464 call assert_equal(16, col('.'))
2465 " shouldn't do anything
2466 norm! 10gJ
2467 call assert_equal(1, col('.'))
2468
2469 " Test for g0 g^ gm g$
2470 exe "norm! 2gg0gji "
2471 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2472 norm! g0yl
2473 call assert_equal(12, col('.'))
2474 call assert_equal(' ', getreg(0))
2475 norm! g$yl
2476 call assert_equal(22, col('.'))
2477 call assert_equal('3', getreg(0))
2478 norm! gmyl
2479 call assert_equal(17, col('.'))
2480 call assert_equal('n', getreg(0))
2481 norm! g^yl
2482 call assert_equal(15, col('.'))
2483 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002484 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002485
Bram Moolenaar74ede802021-05-29 19:18:01 +02002486 " Test for g$ with double-width character half displayed
2487 vsplit
2488 9wincmd |
2489 setlocal nowrap nonumber
2490 call setline(2, 'asdfasdfヨ')
2491 2
2492 normal 0g$
2493 call assert_equal(8, col('.'))
2494 10wincmd |
2495 normal 0g$
2496 call assert_equal(9, col('.'))
2497
2498 setlocal signcolumn=yes
2499 11wincmd |
2500 normal 0g$
2501 call assert_equal(8, col('.'))
2502 12wincmd |
2503 normal 0g$
2504 call assert_equal(9, col('.'))
2505
2506 close
2507
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002508 " Test for g_
2509 call assert_beeps('normal! 100g_')
2510 call setline(2, [' foo ', ' foobar '])
2511 normal! 2ggg_
2512 call assert_equal(5, col('.'))
2513 normal! 2g_
2514 call assert_equal(8, col('.'))
2515
2516 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002517 $put =lineC
2518
2519 " Test for gM
2520 norm! gMyl
2521 call assert_equal(73, col('.'))
2522 call assert_equal('0', getreg(0))
2523 " Test for 20gM
2524 norm! 20gMyl
2525 call assert_equal(29, col('.'))
2526 call assert_equal('S', getreg(0))
2527 " Test for 60gM
2528 norm! 60gMyl
2529 call assert_equal(87, col('.'))
2530 call assert_equal('E', getreg(0))
2531
2532 " Test for g Ctrl-G
2533 set ff=unix
2534 let a=execute(":norm! g\<c-g>")
2535 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2536
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002537 " Test for gI
2538 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002539 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002540
2541 " Test for gi
2542 wincmd c
2543 %d
2544 set tw=0
2545 call setline(1, ['foobar', 'new line'])
2546 norm! A next word
2547 $put ='third line'
2548 norm! gi another word
2549 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002550 call setline(1, 'foobar')
2551 normal! Ggifirst line
2552 call assert_equal('foobarfirst line', getline(1))
2553 " Test gi in 'virtualedit' mode with cursor after the end of the line
2554 set virtualedit=all
2555 call setline(1, 'foo')
2556 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2557 call setline(1, 'foo')
2558 normal! Ggifirst line
2559 call assert_equal('foo first line', getline(1))
2560 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002561
Dominique Pelle923dce22021-11-21 11:36:04 +00002562 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002563 exe "normal! g\<C-\>\<C-G>"
2564 call assert_equal('foo first line', getline('.'))
2565
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002566 " clean up
2567 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002568endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002569
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002570" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002571func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002572 new
2573
2574 let a = execute(":norm! g\<c-g>")
2575 call assert_equal("\n--No lines in buffer--", a)
2576
Bram Moolenaar1671f442020-03-10 07:48:13 +01002577 " Test for CTRL-G (same as :file)
2578 let a = execute(":norm! \<c-g>")
2579 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2580
Bram Moolenaar05295832018-08-24 22:07:58 +02002581 call setline(1, ['first line', 'second line'])
2582
2583 " Test g CTRL-g with dos, mac and unix file type.
2584 norm! gojll
2585 set ff=dos
2586 let a = execute(":norm! g\<c-g>")
2587 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2588
2589 set ff=mac
2590 let a = execute(":norm! g\<c-g>")
2591 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2592
2593 set ff=unix
2594 let a = execute(":norm! g\<c-g>")
2595 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2596
2597 " Test g CTRL-g in visual mode (v)
2598 let a = execute(":norm! gojllvlg\<c-g>")
2599 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2600
2601 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2602 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2603 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2604
2605 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2606 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2607 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2608
2609 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2610 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2611 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2612
2613 " There should be one byte less with noeol
2614 set bin noeol
2615 let a = execute(":norm! \<Esc>gog\<c-g>")
2616 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2617 set bin & eol&
2618
Bram Moolenaar30276f22019-01-24 17:59:39 +01002619 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002620
Bram Moolenaar30276f22019-01-24 17:59:39 +01002621 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2622 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 +02002623
Bram Moolenaar30276f22019-01-24 17:59:39 +01002624 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2625 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 +02002626
Bram Moolenaar30276f22019-01-24 17:59:39 +01002627 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2628 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 +02002629
Bram Moolenaar30276f22019-01-24 17:59:39 +01002630 set fenc=utf8 bomb
2631 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2632 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 +02002633
Bram Moolenaar30276f22019-01-24 17:59:39 +01002634 set fenc=utf16 bomb
2635 let a = execute(":norm! g\<c-g>")
2636 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 +02002637
Bram Moolenaar30276f22019-01-24 17:59:39 +01002638 set fenc=utf32 bomb
2639 let a = execute(":norm! g\<c-g>")
2640 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 +02002641
Bram Moolenaar30276f22019-01-24 17:59:39 +01002642 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002643
2644 set ff&
2645 bwipe!
2646endfunc
2647
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002648" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002649func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002650 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002651 let a=execute(':norm! 1G0g8')
2652 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002653
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002654 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2655 let a=execute(':norm! 1G$g8')
2656 call assert_equal("\nc3 b6 ", a)
2657
2658 call setline(1, "a\u0302")
2659 let a=execute(':norm! 1G0g8')
2660 call assert_equal("\n61 + cc 82 ", a)
2661
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002662 " clean up
2663 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002664endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002665
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002666" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002667func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002668 new
2669
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002670 " With invalid byte.
2671 call setline(1, "___\xff___")
2672 norm! 1G08g8g
2673 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2674
2675 " With invalid byte before the cursor.
2676 call setline(1, "___\xff___")
2677 norm! 1G$h8g8g
2678 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2679
2680 " With truncated sequence.
2681 call setline(1, "___\xE2\x82___")
2682 norm! 1G08g8g
2683 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2684
2685 " With overlong sequence.
2686 call setline(1, "___\xF0\x82\x82\xAC___")
2687 norm! 1G08g8g
2688 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2689
2690 " With valid utf8.
2691 call setline(1, "café")
2692 norm! 1G08g8
2693 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2694
2695 bw!
2696endfunc
2697
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002698" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002699func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002700 " Cannot capture its output,
2701 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002702 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002703 echo "a\nb\nc\nd"
2704 let b=execute(':norm! g<')
2705 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002706endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002707
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002708" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002709func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002710 new
2711 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002712 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002713 " Test for gp gP
2714 call append(1, range(1,10))
2715 1
2716 norm! 1yy
2717 3
2718 norm! gp
2719 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2720 $
2721 norm! gP
2722 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2723
2724 " Test for go
2725 norm! 26go
2726 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2727 norm! 27go
2728 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2729 norm! 28go
2730 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2731 set ff=dos
2732 norm! 29go
2733 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2734 set ff=unix
2735 norm! gg0
2736 norm! 101go
2737 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2738 norm! 103go
2739 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2740 " count > buffer content
2741 norm! 120go
2742 call assert_equal([0, 14, 1, 0, 2147483647], getcurpos())
2743 " clean up
2744 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002745endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002746
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002747" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002748func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002749 tabnew 1.txt
2750 tabnew 2.txt
2751 tabnew 3.txt
2752 norm! 1gt
2753 call assert_equal(1, tabpagenr())
2754 norm! 3gt
2755 call assert_equal(3, tabpagenr())
2756 norm! 1gT
2757 " count gT goes not to the absolute tabpagenumber
2758 " but, but goes to the count previous tabpagenumber
2759 call assert_equal(2, tabpagenr())
2760 " wrap around
2761 norm! 3gT
2762 call assert_equal(3, tabpagenr())
2763 " gt does not wrap around
2764 norm! 5gt
2765 call assert_equal(3, tabpagenr())
2766
2767 for i in range(3)
2768 tabclose
2769 endfor
2770 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002771 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002772endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002773
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002774" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002775func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002776 new
2777 call setline(1, range(10))
2778 $
2779 setl et sw=2
2780 norm! V10>$
2781 " count is ignored
2782 exe "norm! 10\<home>"
2783 call assert_equal(1, col('.'))
2784 exe "norm! \<home>"
2785 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2786 exe "norm! 5\<c-home>"
2787 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2788 exe "norm! \<c-home>"
2789 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002790 exe "norm! G\<c-kHome>"
2791 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002792
2793 " clean up
2794 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002795endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002796
Bram Moolenaar1671f442020-03-10 07:48:13 +01002797" Test for <End> and <C-End> keys
2798func Test_normal_nvend()
2799 new
2800 call setline(1, map(range(1, 10), '"line" .. v:val'))
2801 exe "normal! \<End>"
2802 call assert_equal(5, col('.'))
2803 exe "normal! 4\<End>"
2804 call assert_equal([4, 5], [line('.'), col('.')])
2805 exe "normal! \<C-End>"
2806 call assert_equal([10, 6], [line('.'), col('.')])
2807 close!
2808endfunc
2809
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002810" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002811func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002812 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002813 new
2814 set tw=0
2815 call append(0, 'here are some words')
2816 norm! 1gg0elcwZZZ
2817 call assert_equal('hereZZZare some words', getline('.'))
2818 norm! 1gg0elcWYYY
2819 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002820 norm! 2gg0cwfoo
2821 call assert_equal('foo', getline('.'))
2822
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002823 call setline(1, 'one; two')
2824 call cursor(1, 1)
2825 call feedkeys('cwvim', 'xt')
2826 call assert_equal('vim; two', getline(1))
2827 call feedkeys('0cWone', 'xt')
2828 call assert_equal('one two', getline(1))
2829 "When cursor is at the end of a word 'ce' will change until the end of the
2830 "next word, but 'cw' will change only one character
2831 call setline(1, 'one two')
2832 call feedkeys('0ecwce', 'xt')
2833 call assert_equal('once two', getline(1))
2834 call setline(1, 'one two')
2835 call feedkeys('0ecely', 'xt')
2836 call assert_equal('only', getline(1))
2837
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002838 " clean up
2839 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002840endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002841
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002842" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002843func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002844 new
2845 call append(0, 'here are some words')
2846 exe "norm! 1gg0a\<C-\>\<C-N>"
2847 call assert_equal('n', mode())
2848 call assert_equal(1, col('.'))
2849 call assert_equal('', visualmode())
2850 exe "norm! 1gg0viw\<C-\>\<C-N>"
2851 call assert_equal('n', mode())
2852 call assert_equal(4, col('.'))
2853 exe "norm! 1gg0a\<C-\>\<C-G>"
2854 call assert_equal('n', mode())
2855 call assert_equal(1, col('.'))
2856 "imap <buffer> , <c-\><c-n>
2857 set im
2858 exe ":norm! \<c-\>\<c-n>dw"
2859 set noim
2860 call assert_equal('are some words', getline(1))
2861 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02002862 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01002863
Bram Moolenaar21829c52021-01-26 22:42:21 +01002864 if has('cmdwin')
2865 " Using CTRL-\ CTRL-N in cmd window should close the window
2866 call feedkeys("q:\<C-\>\<C-N>", 'xt')
2867 call assert_equal('', getcmdwintype())
2868 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002869
2870 " clean up
2871 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002872endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002873
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002874" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01002875func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002876 new
2877 set sts=2 sw=2 ts=8 tw=0
2878 call append(0, ["aaa\tbbb\tccc", '', '', ''])
2879 let a=getline(1)
2880 norm! 2gg0
2881 exe "norm! a\<c-r>=a\<cr>"
2882 norm! 3gg0
2883 exe "norm! a\<c-r>\<c-r>=a\<cr>"
2884 norm! 4gg0
2885 exe "norm! a\<c-r>\<c-o>=a\<cr>"
2886 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
2887
2888 " clean up
2889 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02002890 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002891endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002892
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002893" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002894func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002895 call Setup_NewWindow()
2896 call assert_equal(5, &scroll)
2897 exe "norm! \<c-d>"
2898 call assert_equal('6', getline('.'))
2899 exe "norm! 2\<c-d>"
2900 call assert_equal('8', getline('.'))
2901 call assert_equal(2, &scroll)
2902 set scroll=5
2903 exe "norm! \<c-u>"
2904 call assert_equal('3', getline('.'))
2905 1
2906 set scrolloff=5
2907 exe "norm! \<c-d>"
2908 call assert_equal('10', getline('.'))
2909 exe "norm! \<c-u>"
2910 call assert_equal('5', getline('.'))
2911 1
2912 set scrolloff=99
2913 exe "norm! \<c-d>"
2914 call assert_equal('10', getline('.'))
2915 set scrolloff=0
2916 100
2917 exe "norm! $\<c-u>"
2918 call assert_equal('95', getline('.'))
2919 call assert_equal([0, 95, 1, 0, 1], getcurpos())
2920 100
2921 set nostartofline
2922 exe "norm! $\<c-u>"
2923 call assert_equal('95', getline('.'))
2924 call assert_equal([0, 95, 2, 0, 2147483647], getcurpos())
2925 " cleanup
2926 set startofline
2927 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002928endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002929
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002930func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01002931 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01002932 " The ~ register does not exist
2933 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01002934 return
2935 endif
2936
2937 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002938 " unfortunately, without a gui, we can't really test much here,
2939 " so simply test that ~p fails (which uses the drop register)
2940 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02002941 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002942 call assert_equal([], getreg('~', 1, 1))
2943 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02002944 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002945 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002946endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002947
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002948func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002949 new
2950 " How to test this?
2951 " let's just for now test, that the buffer
2952 " does not change
2953 call feedkeys("\<c-s>", 't')
2954 call assert_equal([''], getline(1,'$'))
2955
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002956 " no valid commands
2957 exe "norm! \<char-0x100>"
2958 call assert_equal([''], getline(1,'$'))
2959
2960 exe "norm! ä"
2961 call assert_equal([''], getline(1,'$'))
2962
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002963 " clean up
2964 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002965endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02002966
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002967func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02002968 " This was causing a crash or ml_get error.
2969 enew!
2970 call setline(1,'xxx')
2971 normal $
2972 new
2973 call setline(1, range(1,2))
2974 2
2975 exe "norm \<C-V>$"
2976 bw!
2977 norm yp
2978 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002979endfunc
2980
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002981func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002982 new
2983 exe "norm! \<c-w>c"
2984 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002985 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002986endfunc
2987
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002988func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002989 new
2990 call setline(1, 'one two three four five six seven eight nine ten')
2991 1
2992 norm! 3d2w
2993 call assert_equal('seven eight nine ten', getline(1))
2994 bw!
2995endfunc
2996
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002997func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02002998 CheckFeature timers
2999 CheckFeature cmdline_hist
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003000 func! DoTimerWork(id)
3001 call assert_equal('[Command Line]', bufname(''))
3002 " should fail, with E11, but does fail with E23?
3003 "call feedkeys("\<c-^>", 'tm')
3004
3005 " should also fail with E11
Bram Moolenaare2e40752020-09-04 21:18:46 +02003006 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003007 " return from commandline window
3008 call feedkeys("\<cr>")
3009 endfunc
3010
3011 let oldlang=v:lang
3012 lang C
3013 set updatetime=20
3014 call timer_start(100, 'DoTimerWork')
3015 try
3016 " throws E23, for whatever reason...
3017 call feedkeys('q:', 'x!')
3018 catch /E23/
3019 " no-op
3020 endtry
3021 " clean up
3022 set updatetime=4000
3023 exe "lang" oldlang
3024 bw!
3025endfunc
3026
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003027func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003028 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003029 " Don't sleep after the warning message.
3030 call test_settime(1)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003031 call writefile(['foo'], 'Xreadonly.log')
3032 new Xreadonly.log
3033 setl ro
3034 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003035 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003036 call assert_equal(['foo'], getline(1,'$'))
3037 call assert_equal('Xreadonly.log', bufname(''))
3038
3039 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003040 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003041 bw!
3042 call delete("Xreadonly.log")
3043endfunc
3044
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003045func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003046 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003047 new
3048 call setline(1, 'abcde fghij klmnopq')
3049 norm! 1gg$
3050 set rl
3051 call assert_equal(19, col('.'))
3052 call feedkeys('l', 'tx')
3053 call assert_equal(18, col('.'))
3054 call feedkeys('h', 'tx')
3055 call assert_equal(19, col('.'))
3056 call feedkeys("\<right>", 'tx')
3057 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003058 call feedkeys("\<left>", 'tx')
3059 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003060 call feedkeys("\<s-right>", 'tx')
3061 call assert_equal(13, col('.'))
3062 call feedkeys("\<c-right>", 'tx')
3063 call assert_equal(7, col('.'))
3064 call feedkeys("\<c-left>", 'tx')
3065 call assert_equal(13, col('.'))
3066 call feedkeys("\<s-left>", 'tx')
3067 call assert_equal(19, col('.'))
3068 call feedkeys("<<", 'tx')
3069 call assert_equal(' abcde fghij klmnopq',getline(1))
3070 call feedkeys(">>", 'tx')
3071 call assert_equal('abcde fghij klmnopq',getline(1))
3072
3073 " cleanup
3074 set norl
3075 bw!
3076endfunc
3077
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003078func Test_normal54_Ctrl_bsl()
3079 new
3080 call setline(1, 'abcdefghijklmn')
3081 exe "norm! df\<c-\>\<c-n>"
3082 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3083 exe "norm! df\<c-\>\<c-g>"
3084 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3085 exe "norm! df\<c-\>m"
3086 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003087
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003088 call setline(2, 'abcdefghijklmnāf')
3089 norm! 2gg0
3090 exe "norm! df\<Char-0x101>"
3091 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3092 norm! 1gg0
3093 exe "norm! df\<esc>"
3094 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003095
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003096 " clean up
3097 bw!
3098endfunc
3099
3100func Test_normal_large_count()
3101 " This may fail with 32bit long, how do we detect that?
3102 new
3103 normal o
3104 normal 6666666666dL
3105 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003106endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003107
3108func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003109 new
3110 normal grádv}
3111 call assert_equal('á', getline(1))
3112 normal grád}
3113 call assert_equal('', getline(1))
3114 bwipe!
3115endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003116
3117" Test for the gr (virtual replace) command
3118" Test for the bug fixed by 7.4.387
3119func Test_gr_command()
3120 enew!
3121 let save_cpo = &cpo
3122 call append(0, ['First line', 'Second line', 'Third line'])
3123 exe "normal i\<C-G>u"
3124 call cursor(2, 1)
3125 set cpo-=X
3126 normal 4gro
3127 call assert_equal('oooond line', getline(2))
3128 undo
3129 set cpo+=X
3130 normal 4gro
3131 call assert_equal('ooooecond line', getline(2))
3132 let &cpo = save_cpo
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003133 normal! ggvegrx
3134 call assert_equal('xxxxx line', getline(1))
3135 exe "normal! gggr\<C-V>122"
3136 call assert_equal('zxxxx line', getline(1))
3137 set virtualedit=all
3138 normal! 15|grl
3139 call assert_equal('zxxxx line l', getline(1))
3140 set virtualedit&
3141 set nomodifiable
3142 call assert_fails('normal! grx', 'E21:')
3143 call assert_fails('normal! gRx', 'E21:')
3144 set modifiable&
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003145 enew!
3146endfunc
3147
3148" When splitting a window the changelist position is wrong.
3149" Test the changelist position after splitting a window.
3150" Test for the bug fixed by 7.4.386
3151func Test_changelist()
3152 let save_ul = &ul
3153 enew!
3154 call append('$', ['1', '2'])
3155 exe "normal i\<C-G>u"
3156 exe "normal Gkylpa\<C-G>u"
3157 set ul=100
3158 exe "normal Gylpa\<C-G>u"
3159 set ul=100
3160 normal gg
3161 vsplit
3162 normal g;
3163 call assert_equal([3, 2], [line('.'), col('.')])
3164 normal g;
3165 call assert_equal([2, 2], [line('.'), col('.')])
3166 call assert_fails('normal g;', 'E662:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003167 new
3168 call assert_fails('normal g;', 'E664:')
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003169 %bwipe!
3170 let &ul = save_ul
3171endfunc
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003172
3173func Test_nv_hat_count()
3174 %bwipeout!
3175 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003176 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003177
3178 edit Xfoo
3179 let l:foo_nr = bufnr('Xfoo')
3180
3181 edit Xbar
3182 let l:bar_nr = bufnr('Xbar')
3183
3184 " Make sure we are not just using the alternate file.
3185 edit Xbaz
3186
3187 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3188 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3189
3190 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3191 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3192
3193 %bwipeout!
3194endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003195
3196func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003197 " Make sure no buffers are changed.
3198 %bwipe!
3199
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003200 exe "normal \<C-C>"
3201 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003202
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003203 new
3204 cal setline(1, 'hi!')
3205 exe "normal \<C-C>"
3206 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003207
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003208 bwipe!
3209endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003210
3211" Test for '[m', ']m', '[M' and ']M'
3212" Jumping to beginning and end of methods in Java-like languages
3213func Test_java_motion()
3214 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003215 call assert_beeps('normal! [m')
3216 call assert_beeps('normal! ]m')
3217 call assert_beeps('normal! [M')
3218 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003219 let lines =<< trim [CODE]
3220 Piece of Java
3221 {
3222 tt m1 {
3223 t1;
3224 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003225
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003226 tt m2 {
3227 t2;
3228 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003229
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003230 tt m3 {
3231 if (x)
3232 {
3233 t3;
3234 }
3235 } e3
3236 }
3237 [CODE]
3238 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003239
3240 normal gg
3241
3242 normal 2]maA
3243 call assert_equal("\ttt m1 {A", getline('.'))
3244 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3245
3246 normal j]maB
3247 call assert_equal("\ttt m2 {B", getline('.'))
3248 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3249
3250 normal ]maC
3251 call assert_equal("\ttt m3 {C", getline('.'))
3252 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3253
3254 normal [maD
3255 call assert_equal("\ttt m3 {DC", getline('.'))
3256 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3257
3258 normal k2[maE
3259 call assert_equal("\ttt m1 {EA", getline('.'))
3260 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3261
3262 normal 3[maF
3263 call assert_equal("{F", getline('.'))
3264 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3265
3266 normal ]MaG
3267 call assert_equal("\t}G e1", getline('.'))
3268 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3269
3270 normal j2]MaH
3271 call assert_equal("\t}H e3", getline('.'))
3272 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3273
3274 normal ]M]M
3275 normal aI
3276 call assert_equal("}I", getline('.'))
3277 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3278
3279 normal 2[MaJ
3280 call assert_equal("\t}JH e3", getline('.'))
3281 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3282
3283 normal k[MaK
3284 call assert_equal("\t}K e2", getline('.'))
3285 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3286
3287 normal 3[MaL
3288 call assert_equal("{LF", getline('.'))
3289 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3290
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003291 call cursor(2, 1)
3292 call assert_beeps('norm! 5]m')
3293
3294 " jumping to a method in a fold should open the fold
3295 6,10fold
3296 call feedkeys("gg3]m", 'xt')
3297 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3298 call assert_equal(-1, foldclosedend(7))
3299
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003300 close!
3301endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003302
Bram Moolenaar004a6782020-04-11 17:09:31 +02003303" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003304func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003305 call Setup_NewWindow()
3306 " Make long lines that will wrap
3307 %s/$/\=repeat(' foobar', 10)/
3308 20vsp
3309 set wrap
3310 " Test for g$ with count
3311 norm! gg
3312 norm! 0vg$y
3313 call assert_equal(20, col("'>"))
3314 call assert_equal('1 foobar foobar foob', getreg(0))
3315 norm! gg
3316 norm! 0v4g$y
3317 call assert_equal(72, col("'>"))
3318 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3319 norm! gg
3320 norm! 0v6g$y
3321 call assert_equal(40, col("'>"))
3322 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3323 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3324 set nowrap
3325 " clean up
3326 norm! gg
3327 norm! 0vg$y
3328 call assert_equal(20, col("'>"))
3329 call assert_equal('1 foobar foobar foob', getreg(0))
3330 norm! gg
3331 norm! 0v4g$y
3332 call assert_equal(20, col("'>"))
3333 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3334 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3335 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3336 \ '4 foobar foobar foob', getreg(0))
3337 norm! gg
3338 norm! 0v6g$y
3339 call assert_equal(20, col("'>"))
3340 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3341 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3342 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3343 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3344 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3345 \ '6 foobar foobar foob', getreg(0))
3346 " Move to last line, also down movement is not possible, should still move
3347 " the cursor to the last visible char
3348 norm! G
3349 norm! 0v6g$y
3350 call assert_equal(20, col("'>"))
3351 call assert_equal('100 foobar foobar fo', getreg(0))
3352 bw!
3353endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003354
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003355func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003356 " needs 80 column new window
3357 new
3358 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003359 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003360 put =[repeat('x',90)..' {{{1', 'x {{{1']
3361 norm! gk
3362 " In a 80 column wide terminal the window will be only 78 char
3363 " (because Vim will leave space for the other window),
3364 " but if the terminal is larger, it will be 80 chars, so verify the
3365 " cursor column correctly.
3366 call assert_equal(winwidth(0)+1, col('.'))
3367 call assert_equal(winwidth(0)+1, virtcol('.'))
3368 norm! j
3369 call assert_equal(6, col('.'))
3370 call assert_equal(6, virtcol('.'))
3371 norm! gk
3372 call assert_equal(95, col('.'))
3373 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003374 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003375
3376 " needs 80 column new window
3377 new
3378 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003379 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003380 set number
3381 set numberwidth=10
3382 set cpoptions+=n
3383 put =[repeat('0',90), repeat('1',90)]
3384 norm! 075l
3385 call assert_equal(76, col('.'))
3386 norm! gk
3387 call assert_equal(1, col('.'))
3388 norm! gk
3389 call assert_equal(76, col('.'))
3390 norm! gk
3391 call assert_equal(1, col('.'))
3392 norm! gj
3393 call assert_equal(76, col('.'))
3394 norm! gj
3395 call assert_equal(1, col('.'))
3396 norm! gj
3397 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003398 " When 'nowrap' is set, gk and gj behave like k and j
3399 set nowrap
3400 normal! gk
3401 call assert_equal([2, 76], [line('.'), col('.')])
3402 normal! gj
3403 call assert_equal([3, 76], [line('.'), col('.')])
3404 %bw!
3405 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003406endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003407
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003408" Test for using : to run a multi-line Ex command in operator pending mode
3409func Test_normal_yank_with_excmd()
3410 new
3411 call setline(1, ['foo', 'bar', 'baz'])
3412 let @a = ''
3413 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3414 call assert_equal('f', @a)
3415 close!
3416endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003417
3418" Test for supplying a count to a normal-mode command across a cursorhold call
3419func Test_normal_cursorhold_with_count()
3420 func s:cHold()
3421 let g:cHold_Called += 1
3422 endfunc
3423 new
3424 augroup normalcHoldTest
3425 au!
3426 au CursorHold <buffer> call s:cHold()
3427 augroup END
3428 let g:cHold_Called = 0
3429 call feedkeys("3\<CursorHold>2ix", 'xt')
3430 call assert_equal(1, g:cHold_Called)
3431 call assert_equal(repeat('x', 32), getline(1))
3432 augroup normalcHoldTest
3433 au!
3434 augroup END
3435 au! normalcHoldTest
3436 close!
3437 delfunc s:cHold
3438endfunc
3439
3440" Test for using a count and a command with CTRL-W
3441func Test_wincmd_with_count()
3442 call feedkeys("\<C-W>12n", 'xt')
3443 call assert_equal(12, winheight(0))
3444endfunc
3445
3446" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003447func Test_horiz_motion()
3448 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003449 normal! gg
3450 call assert_beeps('normal! b')
3451 call assert_beeps('normal! B')
3452 call assert_beeps('normal! gE')
3453 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003454 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3455 call setline(1, 'one ,two ,three')
3456 exe "normal! $\<S-BS>"
3457 call assert_equal(11, col('.'))
3458 exe "normal! $\<C-BS>"
3459 call assert_equal(10, col('.'))
3460 close!
3461endfunc
3462
3463" Test for using a : command in operator pending mode
3464func Test_normal_colon_op()
3465 new
3466 call setline(1, ['one', 'two'])
3467 call assert_beeps("normal! Gc:d\<CR>")
3468 close!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003469endfunc
3470
Bram Moolenaar004a6782020-04-11 17:09:31 +02003471" Test for d and D commands
3472func Test_normal_delete_cmd()
3473 new
3474 " D in an empty line
3475 call setline(1, '')
3476 normal D
3477 call assert_equal('', getline(1))
3478 " D in an empty line in virtualedit mode
3479 set virtualedit=all
3480 normal D
3481 call assert_equal('', getline(1))
3482 set virtualedit&
3483 " delete to a readonly register
3484 call setline(1, ['abcd'])
3485 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003486
3487 " D and d with 'nomodifiable'
3488 call setline(1, ['abcd'])
3489 setlocal nomodifiable
3490 call assert_fails('normal D', 'E21:')
3491 call assert_fails('normal d$', 'E21:')
3492
Bram Moolenaar004a6782020-04-11 17:09:31 +02003493 close!
3494endfunc
3495
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003496" Test for deleting or changing characters across lines with 'whichwrap'
3497" containing 's'. Should count <EOL> as one character.
3498func Test_normal_op_across_lines()
3499 new
3500 set whichwrap&
3501 call setline(1, ['one two', 'three four'])
3502 exe "norm! $3d\<Space>"
3503 call assert_equal(['one twhree four'], getline(1, '$'))
3504
3505 call setline(1, ['one two', 'three four'])
3506 exe "norm! $3c\<Space>x"
3507 call assert_equal(['one twxhree four'], getline(1, '$'))
3508
3509 set whichwrap+=l
3510 call setline(1, ['one two', 'three four'])
3511 exe "norm! $3x"
3512 call assert_equal(['one twhree four'], getline(1, '$'))
3513 close!
3514 set whichwrap&
3515endfunc
3516
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003517" Test for 'w' and 'b' commands
3518func Test_normal_word_move()
3519 new
3520 call setline(1, ['foo bar a', '', 'foo bar b'])
3521 " copy a single character word at the end of a line
3522 normal 1G$yw
3523 call assert_equal('a', @")
3524 " copy a single character word at the end of a file
3525 normal G$yw
3526 call assert_equal('b', @")
3527 " check for a word movement handling an empty line properly
3528 normal 1G$vwy
3529 call assert_equal("a\n\n", @")
3530
3531 " copy using 'b' command
3532 %d
3533 " non-empty blank line at the start of file
3534 call setline(1, [' ', 'foo bar'])
3535 normal 2Gyb
3536 call assert_equal(" \n", @")
3537 " try to copy backwards from the start of the file
3538 call setline(1, ['one two', 'foo bar'])
3539 call assert_beeps('normal ggyb')
3540 " 'b' command should stop at an empty line
3541 call setline(1, ['one two', '', 'foo bar'])
3542 normal 3Gyb
3543 call assert_equal("\n", @")
3544 normal 3Gy2b
3545 call assert_equal("two\n", @")
3546 " 'b' command should not stop at a non-empty blank line
3547 call setline(1, ['one two', ' ', 'foo bar'])
3548 normal 3Gyb
3549 call assert_equal("two\n ", @")
3550
3551 close!
3552endfunc
3553
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003554" Test for 'scrolloff' with a long line that doesn't fit in the screen
3555func Test_normal_scroloff()
3556 10new
3557 80vnew
3558 call setline(1, repeat('a', 1000))
3559 set scrolloff=10
3560 normal gg10gj
3561 call assert_equal(8, winline())
3562 normal 10gj
3563 call assert_equal(10, winline())
3564 normal 10gk
3565 call assert_equal(3, winline())
3566 set scrolloff&
3567 close!
3568endfunc
3569
3570" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3571func Test_normal_vert_scroll_longline()
3572 10new
3573 80vnew
3574 call setline(1, range(1, 10))
3575 call append(5, repeat('a', 1000))
3576 exe "normal gg\<C-F>"
3577 call assert_equal(6, line('.'))
3578 exe "normal \<C-F>\<C-F>"
3579 call assert_equal(11, line('.'))
3580 call assert_equal(1, winline())
3581 exe "normal \<C-B>"
3582 call assert_equal(10, line('.'))
3583 call assert_equal(3, winline())
3584 exe "normal \<C-B>\<C-B>"
3585 call assert_equal(5, line('.'))
3586 call assert_equal(5, winline())
3587 close!
3588endfunc
3589
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003590" Test for jumping in a file using %
3591func Test_normal_percent_jump()
3592 new
3593 call setline(1, range(1, 100))
3594
3595 " jumping to a folded line should open the fold
3596 25,75fold
3597 call feedkeys('50%', 'xt')
3598 call assert_equal(50, line('.'))
3599 call assert_equal(-1, foldclosedend(50))
3600 close!
3601endfunc
3602
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003603" Test for << and >> commands to shift text by 'shiftwidth'
3604func Test_normal_shift_rightleft()
3605 new
3606 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3607 set shiftwidth=2 tabstop=8
3608 normal gg6>>
3609 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3610 \ getline(1, '$'))
3611 normal ggVG2>>
3612 call assert_equal([' one', '', "\t ", "\ttwo",
3613 \ "\t three", "\t four"], getline(1, '$'))
3614 normal gg6<<
3615 call assert_equal([' one', '', "\t ", ' two', "\t three",
3616 \ "\t four"], getline(1, '$'))
3617 normal ggVG2<<
3618 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3619 \ getline(1, '$'))
3620 set shiftwidth& tabstop&
3621 bw!
3622endfunc
3623
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003624" Some commands like yy, cc, dd, >>, << and !! accept a count after
3625" typing the first letter of the command.
3626func Test_normal_count_after_operator()
3627 new
3628 setlocal shiftwidth=4 tabstop=8 autoindent
3629 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3630 let @a = ''
3631 normal! j"ay4y
3632 call assert_equal("two\nthree\nfour\nfive\n", @a)
3633 normal! 3G>2>
3634 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3635 \ getline(1, '$'))
3636 exe "normal! 3G0c2cred\nblue"
3637 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3638 \ getline(1, '$'))
3639 exe "normal! gg<8<"
3640 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3641 \ getline(1, '$'))
3642 exe "normal! ggd3d"
3643 call assert_equal(['blue', 'five'], getline(1, '$'))
3644 call setline(1, range(1, 4))
3645 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3646 call assert_equal('".,.+2!', @:)
3647 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3648 call assert_equal('".!', @:)
3649 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3650 call assert_equal('".,$!', @:)
3651 bw!
3652endfunc
3653
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003654func Test_normal_gj_on_extra_wide_char()
3655 new | 25vsp
3656 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3657 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3658 \ ' dreizehn v ierzehn fünfzehn'
3659 put =text
3660 call cursor(2,1)
3661 norm! gj
3662 call assert_equal([0,2,25,0], getpos('.'))
3663 bw!
3664endfunc
3665
Bram Moolenaar03725c52021-11-24 12:17:53 +00003666func Test_normal_count_out_of_range()
3667 new
3668 call setline(1, 'text')
3669 normal 44444444444|
3670 call assert_equal(999999999, v:count)
3671 normal 444444444444|
3672 call assert_equal(999999999, v:count)
3673 normal 4444444444444|
3674 call assert_equal(999999999, v:count)
3675 normal 4444444444444444444|
3676 call assert_equal(999999999, v:count)
3677
3678 normal 9y99999999|
3679 call assert_equal(899999991, v:count)
3680 normal 10y99999999|
3681 call assert_equal(999999999, v:count)
3682 normal 44444444444y44444444444|
3683 call assert_equal(999999999, v:count)
3684 bwipe!
3685endfunc
3686
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003687" vim: shiftwidth=2 sts=2 expandtab