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