blob: 6458a1bed4853d8d971917e87397a21e3e3298df [file] [log] [blame]
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001" Test for various Normal mode commands
2
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003source shared.vim
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01004source check.vim
Bram Moolenaarca68ae12020-03-30 19:32:53 +02005source view_util.vim
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +00006source vim9.vim
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01007
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01008func Setup_NewWindow()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02009 10new
10 call setline(1, range(1,100))
11endfunc
12
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010013func MyFormatExpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020014 " Adds '->$' at lines having numbers followed by trailing whitespace
15 for ln in range(v:lnum, v:lnum+v:count-1)
16 let line = getline(ln)
17 if getline(ln) =~# '\d\s\+$'
18 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
19 endif
20 endfor
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020021endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020022
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010023func CountSpaces(type, ...)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020024 " for testing operatorfunc
25 " will count the number of spaces
26 " and return the result in g:a
27 let sel_save = &selection
28 let &selection = "inclusive"
29 let reg_save = @@
30
31 if a:0 " Invoked from Visual mode, use gv command.
32 silent exe "normal! gvy"
33 elseif a:type == 'line'
34 silent exe "normal! '[V']y"
35 else
36 silent exe "normal! `[v`]y"
37 endif
Bram Moolenaar777e7c22021-10-25 17:07:04 +010038 let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020039 let &selection = sel_save
40 let @@ = reg_save
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020041endfunc
42
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010043func OpfuncDummy(type, ...)
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010044 " for testing operatorfunc
Bram Moolenaar777e7c22021-10-25 17:07:04 +010045 let g:opt = &linebreak
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010046
47 if a:0 " Invoked from Visual mode, use gv command.
48 silent exe "normal! gvy"
49 elseif a:type == 'line'
50 silent exe "normal! '[V']y"
51 else
52 silent exe "normal! `[v`]y"
53 endif
54 " Create a new dummy window
55 new
Bram Moolenaar777e7c22021-10-25 17:07:04 +010056 let g:bufnr = bufnr('%')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020057endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020058
Bram Moolenaar1671f442020-03-10 07:48:13 +010059func Test_normal00_optrans()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020060 new
61 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
62 1
63 exe "norm! Sfoobar\<esc>"
64 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
65 2
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020066 exe "norm! $vbsone"
67 call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020068 norm! VS Second line here
69 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
70 %d
71 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
72 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
73
74 1
75 norm! 2D
76 call assert_equal(['3 this is the third line', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
77 set cpo+=#
78 norm! 4D
79 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
80
81 " clean up
82 set cpo-=#
83 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020084endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020085
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010086func Test_normal01_keymodel()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020087 call Setup_NewWindow()
88 " Test 1: depending on 'keymodel' <s-down> does something different
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020089 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020090 call feedkeys("V\<S-Up>y", 'tx')
91 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020092 set keymodel=startsel
93 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020094 call feedkeys("V\<S-Up>y", 'tx')
95 call assert_equal(['49', '50'], getline("'<", "'>"))
96 " Start visual mode when keymodel = startsel
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020097 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020098 call feedkeys("\<S-Up>y", 'tx')
99 call assert_equal(['49', '5'], getreg(0, 0, 1))
Bram Moolenaar1671f442020-03-10 07:48:13 +0100100 " Use the different Shift special keys
101 50
102 call feedkeys("\<S-Right>\<S-Left>\<S-Up>\<S-Down>\<S-Home>\<S-End>y", 'tx')
103 call assert_equal(['50'], getline("'<", "'>"))
104 call assert_equal(['50', ''], getreg(0, 0, 1))
105
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200106 " Do not start visual mode when keymodel=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200107 set keymodel=
108 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200109 call feedkeys("\<S-Up>y$", 'tx')
110 call assert_equal(['42'], getreg(0, 0, 1))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200111 " Stop visual mode when keymodel=stopsel
112 set keymodel=stopsel
113 50
114 call feedkeys("Vkk\<Up>yy", 'tx')
115 call assert_equal(['47'], getreg(0, 0, 1))
116
117 set keymodel=
118 50
119 call feedkeys("Vkk\<Up>yy", 'tx')
120 call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200121
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200122 " Test for using special keys to start visual selection
123 %d
124 call setline(1, ['red fox tail', 'red fox tail', 'red fox tail'])
125 set keymodel=startsel
126 " Test for <S-PageUp> and <S-PageDown>
127 call cursor(1, 1)
128 call feedkeys("\<S-PageDown>y", 'xt')
129 call assert_equal([0, 1, 1, 0], getpos("'<"))
130 call assert_equal([0, 3, 1, 0], getpos("'>"))
131 call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
132 call assert_equal([0, 2, 1, 0], getpos("'<"))
133 call assert_equal([0, 3, 8, 0], getpos("'>"))
134 " Test for <S-C-Home> and <S-C-End>
135 call cursor(2, 12)
136 call feedkeys("\<S-C-Home>y", 'xt')
137 call assert_equal([0, 1, 1, 0], getpos("'<"))
138 call assert_equal([0, 2, 12, 0], getpos("'>"))
139 call cursor(1, 4)
140 call feedkeys("\<S-C-End>y", 'xt')
141 call assert_equal([0, 1, 4, 0], getpos("'<"))
142 call assert_equal([0, 3, 13, 0], getpos("'>"))
143 " Test for <S-C-Left> and <S-C-Right>
144 call cursor(2, 5)
145 call feedkeys("\<S-C-Right>y", 'xt')
146 call assert_equal([0, 2, 5, 0], getpos("'<"))
147 call assert_equal([0, 2, 9, 0], getpos("'>"))
148 call cursor(2, 9)
149 call feedkeys("\<S-C-Left>y", 'xt')
150 call assert_equal([0, 2, 5, 0], getpos("'<"))
151 call assert_equal([0, 2, 9, 0], getpos("'>"))
152
153 set keymodel&
154
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200155 " clean up
156 bw!
157endfunc
158
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100159func Test_normal03_join()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200160 " basic join test
161 call Setup_NewWindow()
162 50
163 norm! VJ
164 call assert_equal('50 51', getline('.'))
165 $
166 norm! J
167 call assert_equal('100', getline('.'))
168 $
169 norm! V9-gJ
170 call assert_equal('919293949596979899100', getline('.'))
171 call setline(1, range(1,100))
172 $
173 :j 10
174 call assert_equal('100', getline('.'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200175 call assert_beeps('normal GVJ')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200176 " clean up
177 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200178endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200179
Bram Moolenaar004a6782020-04-11 17:09:31 +0200180" basic filter test
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100181func Test_normal04_filter()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200182 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200183 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200184 call Setup_NewWindow()
185 1
186 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
187 call assert_equal('| 1', getline('.'))
188 90
189 :sil :!echo one
190 call feedkeys('.', 'tx')
191 call assert_equal('| 90', getline('.'))
192 95
193 set cpo+=!
194 " 2 <CR>, 1: for executing the command,
195 " 2: clear hit-enter-prompt
196 call feedkeys("!!\n", 'tx')
197 call feedkeys(":!echo one\n\n", 'tx')
198 call feedkeys(".", 'tx')
199 call assert_equal('one', getline('.'))
200 set cpo-=!
201 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200202endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200203
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100204func Test_normal05_formatexpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200205 " basic formatexpr test
206 call Setup_NewWindow()
207 %d_
208 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
209 1
210 set formatexpr=MyFormatExpr()
211 norm! gqG
212 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
213 set formatexpr=
214 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200215endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200216
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200217func Test_normal05_formatexpr_newbuf()
218 " Edit another buffer in the 'formatexpr' function
219 new
220 func! Format()
221 edit another
222 endfunc
223 set formatexpr=Format()
224 norm gqG
225 bw!
226 set formatexpr=
227endfunc
228
229func Test_normal05_formatexpr_setopt()
230 " Change the 'formatexpr' value in the function
231 new
232 func! Format()
233 set formatexpr=
234 endfunc
235 set formatexpr=Format()
236 norm gqG
237 bw!
238 set formatexpr=
239endfunc
240
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200241" When 'formatexpr' returns non-zero, internal formatting is used.
242func Test_normal_formatexpr_returns_nonzero()
243 new
244 call setline(1, ['one', 'two'])
245 func! Format()
246 return 1
247 endfunc
248 setlocal formatexpr=Format()
249 normal VGgq
250 call assert_equal(['one two'], getline(1, '$'))
251 setlocal formatexpr=
252 delfunc Format
253 close!
254endfunc
255
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
467func Test_normal09c_operatorfunc()
468 " Test redoing operatorfunc
469 new
470 call setline(1, 'some text')
471 set operatorfunc=OperatorfuncRedo
472 normal v3g@
473 call assert_equal(3, g:opfunc_count)
474 let g:opfunc_count = 0
475 normal .
476 call assert_equal(3, g:opfunc_count)
477
478 bw!
479 unlet g:opfunc_count
480 set operatorfunc=
481endfunc
482
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000483" Test for different ways of setting the 'operatorfunc' option
484func Test_opfunc_callback()
485 new
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000486 func OpFunc1(callnr, type)
487 let g:OpFunc1Args = [a:callnr, a:type]
488 endfunc
489 func OpFunc2(type)
490 let g:OpFunc2Args = [a:type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000491 endfunc
492
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000493 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000494 #" Test for using a function name
495 LET &opfunc = 'g:OpFunc2'
496 LET g:OpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000497 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000498 call assert_equal(['char'], g:OpFunc2Args)
499
500 #" Test for using a function()
501 set opfunc=function('g:OpFunc1',\ [10])
502 LET g:OpFunc1Args = []
503 normal! g@l
504 call assert_equal([10, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000505
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000506 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000507 VAR Fn = function('g:OpFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000508 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000509 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000510 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000511 call assert_equal([11, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000512
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000513 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000514 LET Fn = function('g:OpFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000515 LET &operatorfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000516 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000517 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000518 call assert_equal([12, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000519
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000520 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000521 set operatorfunc=funcref('g:OpFunc1',\ [13])
522 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000523 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000524 call assert_equal([13, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000525
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000526 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000527 LET Fn = funcref('g:OpFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000528 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000529 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000530 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000531 call assert_equal([14, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000532
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000533 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000534 LET Fn = funcref('g:OpFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000535 LET &opfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000536 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([15, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000539
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000540 #" Test for using a lambda function using set
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000541 VAR optval = "LSTART a LMIDDLE OpFunc1(16, a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000542 LET optval = substitute(optval, ' ', '\\ ', 'g')
543 exe "set opfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000544 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000545 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000546 call assert_equal([16, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000547
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000548 #" Test for using a lambda function using LET
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000549 LET &opfunc = LSTART a LMIDDLE OpFunc1(17, a) LEND
550 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([17, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000553
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000554 #" Set 'operatorfunc' to a string(lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000555 LET &opfunc = 'LSTART a LMIDDLE OpFunc1(18, a) LEND'
556 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000557 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000558 call assert_equal([18, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000559
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000560 #" Set 'operatorfunc' to a variable with a lambda expression
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000561 VAR Lambda = LSTART a LMIDDLE OpFunc1(19, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000562 LET &opfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000563 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000564 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000565 call assert_equal([19, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000566
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000567 #" Set 'operatorfunc' to a string(variable with a lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000568 LET Lambda = LSTART a LMIDDLE OpFunc1(20, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000569 LET &opfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000570 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([20, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000573
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000574 #" Try to use 'operatorfunc' after the function is deleted
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000575 func g:TmpOpFunc1(type)
576 let g:TmpOpFunc1Args = [21, a:type]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000577 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000578 LET &opfunc = function('g:TmpOpFunc1')
579 delfunc g:TmpOpFunc1
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000580 call test_garbagecollect_now()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000581 LET g:TmpOpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000582 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000583 call assert_equal([], g:TmpOpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000584
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000585 #" Try to use a function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000586 func g:TmpOpFunc2(x, y)
587 let g:TmpOpFunc2Args = [a:x, a:y]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000588 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000589 set opfunc=TmpOpFunc2
590 LET g:TmpOpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000591 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000592 call assert_equal([], g:TmpOpFunc2Args)
593 delfunc TmpOpFunc2
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000594
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000595 #" Try to use a lambda function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000596 LET &opfunc = LSTART a, b LMIDDLE OpFunc1(22, b) LEND
597 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000598 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000599 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000600
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000601 #" Test for clearing the 'operatorfunc' option
602 set opfunc=''
603 set opfunc&
604 call assert_fails("set opfunc=function('abc')", "E700:")
605 call assert_fails("set opfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000606
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000607 #" set 'operatorfunc' to a non-existing function
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000608 LET &opfunc = function('g:OpFunc1', [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000609 call assert_fails("set opfunc=function('NonExistingFunc')", 'E700:')
610 call assert_fails("LET &opfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000611 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000612 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000613 call assert_equal([23, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000614 END
615 call CheckTransLegacySuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000616
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000617 " Test for using a script-local function name
618 func s:OpFunc3(type)
619 let g:OpFunc3Args = [a:type]
620 endfunc
621 set opfunc=s:OpFunc3
622 let g:OpFunc3Args = []
623 normal! g@l
624 call assert_equal(['char'], g:OpFunc3Args)
625
626 let &opfunc = 's:OpFunc3'
627 let g:OpFunc3Args = []
628 normal! g@l
629 call assert_equal(['char'], g:OpFunc3Args)
630 delfunc s:OpFunc3
631
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000632 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000633 set opfunc=(a)\ =>\ OpFunc1(24,\ a)
634 let g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000635 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000636 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000637
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000638 " set 'operatorfunc' to a partial with dict. This used to cause a crash.
639 func SetOpFunc()
640 let operator = {'execute': function('OperatorExecute')}
641 let &opfunc = operator.execute
642 endfunc
643 func OperatorExecute(_) dict
644 endfunc
645 call SetOpFunc()
646 call test_garbagecollect_now()
647 set operatorfunc=
648 delfunc SetOpFunc
649 delfunc OperatorExecute
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000650
651 " Vim9 tests
652 let lines =<< trim END
653 vim9script
654
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000655 def g:Vim9opFunc(val: number, type: string): void
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000656 g:OpFunc1Args = [val, type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000657 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000658
659 # Test for using a def function with opfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000660 set opfunc=function('g:Vim9opFunc',\ [60])
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000661 g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000662 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000663 assert_equal([60, 'char'], g:OpFunc1Args)
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000664
665 # Test for using a global function name
666 &opfunc = g:OpFunc2
667 g:OpFunc2Args = []
668 normal! g@l
669 assert_equal(['char'], g:OpFunc2Args)
670 bw!
671
672 # Test for using a script-local function name
673 def s:LocalOpFunc(type: string): void
674 g:LocalOpFuncArgs = [type]
675 enddef
676 &opfunc = s:LocalOpFunc
677 g:LocalOpFuncArgs = []
678 normal! g@l
679 assert_equal(['char'], g:LocalOpFuncArgs)
680 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000681 END
682 call CheckScriptSuccess(lines)
683
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000684 " setting 'opfunc' to a script local function outside of a script context
685 " should fail
686 let cleanup =<< trim END
687 call writefile([execute('messages')], 'Xtest.out')
688 qall
689 END
690 call writefile(cleanup, 'Xverify.vim')
691 call RunVim([], [], "-c \"set opfunc=s:abc\" -S Xverify.vim")
692 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
693 call delete('Xtest.out')
694 call delete('Xverify.vim')
695
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000696 " cleanup
697 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000698 delfunc OpFunc1
699 delfunc OpFunc2
700 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000701 %bw!
702endfunc
703
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100704func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200705 " Test for expand()
706 10new
707 call setline(1, ['1', 'ifooar,,cbar'])
708 2
709 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200710 call assert_equal('cbar', expand('<cword>'))
711 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
712
713 call setline(1, ['prx = list[idx];'])
714 1
715 let expected = ['', 'prx', 'prx', 'prx',
716 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
717 \ 'idx', 'idx', 'idx', 'idx',
718 \ 'list[idx]',
719 \ '];',
720 \ ]
721 for i in range(1, 16)
722 exe 'norm ' . i . '|'
723 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
724 endfor
725
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200726 " Test for <cexpr> in state.val and ptr->val
727 call setline(1, 'x = state.val;')
728 call cursor(1, 10)
729 call assert_equal('state.val', expand('<cexpr>'))
730 call setline(1, 'x = ptr->val;')
731 call cursor(1, 9)
732 call assert_equal('ptr->val', expand('<cexpr>'))
733
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100734 if executable('echo')
735 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100736 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100737 endif
738
739 " Test expand(`=...`) i.e. backticks expression expansion
740 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100741 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100742
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200743 " clean up
744 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200745endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200746
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200747" Test for expand() in latin1 encoding
748func Test_normal_expand_latin1()
749 new
750 let save_enc = &encoding
751 set encoding=latin1
752 call setline(1, 'val = item->color;')
753 call cursor(1, 11)
754 call assert_equal('color', expand("<cword>"))
755 call assert_equal('item->color', expand("<cexpr>"))
756 let &encoding = save_enc
757 bw!
758endfunc
759
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100760func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200761 " test for 'showcmd'
762 10new
763 exe "norm! ofoobar\<esc>"
764 call assert_equal(2, line('$'))
765 set showcmd
766 exe "norm! ofoobar2\<esc>"
767 call assert_equal(3, line('$'))
768 exe "norm! VAfoobar3\<esc>"
769 call assert_equal(3, line('$'))
770 exe "norm! 0d3\<del>2l"
771 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200772 " test for the visual block size displayed in the status line
773 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
774 call feedkeys("ggl\<C-V>lljj", 'xt')
775 redraw!
776 call assert_match('3x3$', Screenline(&lines))
777 call feedkeys("\<C-V>", 'xt')
778 " test for visually selecting a multi-byte character
779 call setline(1, ["\U2206"])
780 call feedkeys("ggv", 'xt')
781 redraw!
782 call assert_match('1-3$', Screenline(&lines))
783 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200784 " test for visually selecting the end of line
785 call setline(1, ["foobar"])
786 call feedkeys("$vl", 'xt')
787 redraw!
788 call assert_match('2$', Screenline(&lines))
789 call feedkeys("y", 'xt')
790 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200791 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200792endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200793
Bram Moolenaar1671f442020-03-10 07:48:13 +0100794" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100795func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200796 10new
797 call setline(1, range(1,5))
798 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100799 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200800 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100801 call assert_beeps('normal! G2dd')
802 call assert_beeps("normal! g\<C-A>")
803 call assert_beeps("normal! g\<C-X>")
804 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100805 call assert_beeps("normal! vQ\<Esc>")
806 call assert_beeps("normal! 2[[")
807 call assert_beeps("normal! 2]]")
808 call assert_beeps("normal! 2[]")
809 call assert_beeps("normal! 2][")
810 call assert_beeps("normal! 4[z")
811 call assert_beeps("normal! 4]z")
812 call assert_beeps("normal! 4[c")
813 call assert_beeps("normal! 4]c")
814 call assert_beeps("normal! 200%")
815 call assert_beeps("normal! %")
816 call assert_beeps("normal! 2{")
817 call assert_beeps("normal! 2}")
818 call assert_beeps("normal! r\<Right>")
819 call assert_beeps("normal! 8ry")
820 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200821 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200822endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200823
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100824func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200825 " Test for F1
826 call assert_equal(1, winnr())
827 call feedkeys("\<f1>", 'txi')
828 call assert_match('help\.txt', bufname('%'))
829 call assert_equal(2, winnr('$'))
830 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200831endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200832
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100833func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200834 " basic test for Ctrl-F and Ctrl-B
835 call Setup_NewWindow()
836 exe "norm! \<c-f>"
837 call assert_equal('9', getline('.'))
838 exe "norm! 2\<c-f>"
839 call assert_equal('25', getline('.'))
840 exe "norm! 2\<c-b>"
841 call assert_equal('18', getline('.'))
842 1
843 set scrolloff=5
844 exe "norm! 2\<c-f>"
845 call assert_equal('21', getline('.'))
846 exe "norm! \<c-b>"
847 call assert_equal('13', getline('.'))
848 1
849 set scrolloff=99
850 exe "norm! \<c-f>"
851 call assert_equal('13', getline('.'))
852 set scrolloff=0
853 100
854 exe "norm! $\<c-b>"
855 call assert_equal('92', getline('.'))
856 call assert_equal([0, 92, 1, 0, 1], getcurpos())
857 100
858 set nostartofline
859 exe "norm! $\<c-b>"
860 call assert_equal('92', getline('.'))
861 call assert_equal([0, 92, 2, 0, 2147483647], getcurpos())
862 " cleanup
863 set startofline
864 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200865endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200866
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100867func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200868 10new
869 norm oxxxxxxx
870 exe "norm 2\<c-f>"
871 " check with valgrind that cursor is put back in column 1
872 exe "norm 2\<c-b>"
873 bw!
874endfunc
875
Bram Moolenaar1671f442020-03-10 07:48:13 +0100876" Test for errors with z command
877func Test_normal_z_error()
878 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200879 call assert_beeps('normal! zq')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100880endfunc
881
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100882func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200883 " basic test for z commands that scroll the window
884 call Setup_NewWindow()
885 100
886 norm! >>
887 " Test for z<cr>
888 exe "norm! z\<cr>"
889 call assert_equal(' 100', getline('.'))
890 call assert_equal(100, winsaveview()['topline'])
891 call assert_equal([0, 100, 2, 0, 9], getcurpos())
892
893 " Test for zt
894 21
895 norm! >>0zt
896 call assert_equal(' 21', getline('.'))
897 call assert_equal(21, winsaveview()['topline'])
898 call assert_equal([0, 21, 1, 0, 8], getcurpos())
899
900 " Test for zb
901 30
902 norm! >>$ztzb
903 call assert_equal(' 30', getline('.'))
904 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
905 call assert_equal([0, 30, 3, 0, 2147483647], getcurpos())
906
907 " Test for z-
908 1
909 30
910 norm! 0z-
911 call assert_equal(' 30', getline('.'))
912 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
913 call assert_equal([0, 30, 2, 0, 9], getcurpos())
914
915 " Test for z{height}<cr>
916 call assert_equal(10, winheight(0))
917 exe "norm! z12\<cr>"
918 call assert_equal(12, winheight(0))
919 exe "norm! z10\<cr>"
920 call assert_equal(10, winheight(0))
921
922 " Test for z.
923 1
924 21
925 norm! 0z.
926 call assert_equal(' 21', getline('.'))
927 call assert_equal(17, winsaveview()['topline'])
928 call assert_equal([0, 21, 2, 0, 9], getcurpos())
929
930 " Test for zz
931 1
932 21
933 norm! 0zz
934 call assert_equal(' 21', getline('.'))
935 call assert_equal(17, winsaveview()['topline'])
936 call assert_equal([0, 21, 1, 0, 8], getcurpos())
937
938 " Test for z+
939 11
940 norm! zt
941 norm! z+
942 call assert_equal(' 21', getline('.'))
943 call assert_equal(21, winsaveview()['topline'])
944 call assert_equal([0, 21, 2, 0, 9], getcurpos())
945
946 " Test for [count]z+
947 1
948 norm! 21z+
949 call assert_equal(' 21', getline('.'))
950 call assert_equal(21, winsaveview()['topline'])
951 call assert_equal([0, 21, 2, 0, 9], getcurpos())
952
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200953 " Test for z+ with [count] greater than buffer size
954 1
955 norm! 1000z+
956 call assert_equal(' 100', getline('.'))
957 call assert_equal(100, winsaveview()['topline'])
958 call assert_equal([0, 100, 2, 0, 9], getcurpos())
959
960 " Test for z+ from the last buffer line
961 norm! Gz.z+
962 call assert_equal(' 100', getline('.'))
963 call assert_equal(100, winsaveview()['topline'])
964 call assert_equal([0, 100, 2, 0, 9], getcurpos())
965
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200966 " Test for z^
967 norm! 22z+0
968 norm! z^
969 call assert_equal(' 21', getline('.'))
970 call assert_equal(12, winsaveview()['topline'])
971 call assert_equal([0, 21, 2, 0, 9], getcurpos())
972
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200973 " Test for z^ from first buffer line
974 norm! ggz^
975 call assert_equal('1', getline('.'))
976 call assert_equal(1, winsaveview()['topline'])
977 call assert_equal([0, 1, 1, 0, 1], getcurpos())
978
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200979 " Test for [count]z^
980 1
981 norm! 30z^
982 call assert_equal(' 21', getline('.'))
983 call assert_equal(12, winsaveview()['topline'])
984 call assert_equal([0, 21, 2, 0, 9], getcurpos())
985
986 " cleanup
987 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200988endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200989
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100990func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200991 " basic test for z commands that scroll the window
992 10new
993 15vsp
994 set nowrap listchars=
995 let lineA='abcdefghijklmnopqrstuvwxyz'
996 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
997 $put =lineA
998 $put =lineB
999 1d
1000
Bram Moolenaar1671f442020-03-10 07:48:13 +01001001 " Test for zl and zh with a count
1002 norm! 0z10l
1003 call assert_equal([11, 1], [col('.'), wincol()])
1004 norm! z4h
1005 call assert_equal([11, 5], [col('.'), wincol()])
1006 normal! 2gg
1007
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001008 " Test for zl
1009 1
1010 norm! 5zl
1011 call assert_equal(lineA, getline('.'))
1012 call assert_equal(6, col('.'))
1013 call assert_equal(5, winsaveview()['leftcol'])
1014 norm! yl
1015 call assert_equal('f', @0)
1016
1017 " Test for zh
1018 norm! 2zh
1019 call assert_equal(lineA, getline('.'))
1020 call assert_equal(6, col('.'))
1021 norm! yl
1022 call assert_equal('f', @0)
1023 call assert_equal(3, winsaveview()['leftcol'])
1024
1025 " Test for zL
1026 norm! zL
1027 call assert_equal(11, col('.'))
1028 norm! yl
1029 call assert_equal('k', @0)
1030 call assert_equal(10, winsaveview()['leftcol'])
1031 norm! 2zL
1032 call assert_equal(25, col('.'))
1033 norm! yl
1034 call assert_equal('y', @0)
1035 call assert_equal(24, winsaveview()['leftcol'])
1036
1037 " Test for zH
1038 norm! 2zH
1039 call assert_equal(25, col('.'))
1040 call assert_equal(10, winsaveview()['leftcol'])
1041 norm! yl
1042 call assert_equal('y', @0)
1043
1044 " Test for zs
1045 norm! $zs
1046 call assert_equal(26, col('.'))
1047 call assert_equal(25, winsaveview()['leftcol'])
1048 norm! yl
1049 call assert_equal('z', @0)
1050
1051 " Test for ze
1052 norm! ze
1053 call assert_equal(26, col('.'))
1054 call assert_equal(11, winsaveview()['leftcol'])
1055 norm! yl
1056 call assert_equal('z', @0)
1057
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001058 " Test for zs and ze with folds
1059 %fold
1060 norm! $zs
1061 call assert_equal(26, col('.'))
1062 call assert_equal(0, winsaveview()['leftcol'])
1063 norm! yl
1064 call assert_equal('z', @0)
1065 norm! ze
1066 call assert_equal(26, col('.'))
1067 call assert_equal(0, winsaveview()['leftcol'])
1068 norm! yl
1069 call assert_equal('z', @0)
1070
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001071 " cleanup
1072 set wrap listchars=eol:$
1073 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001074endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001075
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001076func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001077 " basic test for z commands that scroll the window
1078 " using 'sidescrolloff' setting
1079 10new
1080 20vsp
1081 set nowrap listchars= sidescrolloff=5
1082 let lineA='abcdefghijklmnopqrstuvwxyz'
1083 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1084 $put =lineA
1085 $put =lineB
1086 1d
1087
1088 " Test for zl
1089 1
1090 norm! 5zl
1091 call assert_equal(lineA, getline('.'))
1092 call assert_equal(11, col('.'))
1093 call assert_equal(5, winsaveview()['leftcol'])
1094 norm! yl
1095 call assert_equal('k', @0)
1096
1097 " Test for zh
1098 norm! 2zh
1099 call assert_equal(lineA, getline('.'))
1100 call assert_equal(11, col('.'))
1101 norm! yl
1102 call assert_equal('k', @0)
1103 call assert_equal(3, winsaveview()['leftcol'])
1104
1105 " Test for zL
1106 norm! 0zL
1107 call assert_equal(16, col('.'))
1108 norm! yl
1109 call assert_equal('p', @0)
1110 call assert_equal(10, winsaveview()['leftcol'])
1111 norm! 2zL
1112 call assert_equal(26, col('.'))
1113 norm! yl
1114 call assert_equal('z', @0)
1115 call assert_equal(15, winsaveview()['leftcol'])
1116
1117 " Test for zH
1118 norm! 2zH
1119 call assert_equal(15, col('.'))
1120 call assert_equal(0, winsaveview()['leftcol'])
1121 norm! yl
1122 call assert_equal('o', @0)
1123
1124 " Test for zs
1125 norm! $zs
1126 call assert_equal(26, col('.'))
1127 call assert_equal(20, winsaveview()['leftcol'])
1128 norm! yl
1129 call assert_equal('z', @0)
1130
1131 " Test for ze
1132 norm! ze
1133 call assert_equal(26, col('.'))
1134 call assert_equal(11, winsaveview()['leftcol'])
1135 norm! yl
1136 call assert_equal('z', @0)
1137
1138 " cleanup
1139 set wrap listchars=eol:$ sidescrolloff=0
1140 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001141endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001142
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001143" Test for commands that scroll the window horizontally. Test with folds.
1144" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1145func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001146 15new
1147 call setline(1, range(1, 100))
1148 exe "normal! 30ggz\<CR>"
1149 set foldenable
1150 33,36fold
1151 40,43fold
1152 46,49fold
1153 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001154
1155 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001156 " Top of the screen = 30
1157 " Folded lines = 9
1158 " Bottom of the screen = 30 + h + 9 - 1
1159 normal! 4L
1160 call assert_equal(35 + h, line('.'))
1161 normal! 4H
1162 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001163
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001164 " Test for using a large count value
1165 %d
1166 call setline(1, range(1, 4))
1167 norm! 6H
1168 call assert_equal(4, line('.'))
1169
1170 " Test for 'M' with folded lines
1171 %d
1172 call setline(1, range(1, 20))
1173 1,5fold
1174 norm! LM
1175 call assert_equal(12, line('.'))
1176
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001177 " Test for the CTRL-E and CTRL-Y commands with folds
1178 %d
1179 call setline(1, range(1, 10))
1180 3,5fold
1181 exe "normal 6G3\<C-E>"
1182 call assert_equal(6, line('w0'))
1183 exe "normal 2\<C-Y>"
1184 call assert_equal(2, line('w0'))
1185
1186 " Test for CTRL-Y on a folded line
1187 %d
1188 call setline(1, range(1, 100))
1189 exe (h + 2) .. "," .. (h + 4) .. "fold"
1190 exe h + 5
1191 normal z-
1192 exe "normal \<C-Y>\<C-Y>"
1193 call assert_equal(h + 1, line('w$'))
1194
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001195 " Test for CTRL-Y from the first line and CTRL-E from the last line
1196 %d
1197 set scrolloff=2
1198 call setline(1, range(1, 4))
1199 exe "normal gg\<C-Y>"
1200 call assert_equal(1, line('w0'))
1201 call assert_equal(1, line('.'))
1202 exe "normal G4\<C-E>\<C-E>"
1203 call assert_equal(4, line('w$'))
1204 call assert_equal(4, line('.'))
1205 set scrolloff&
1206
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001207 " Using <PageUp> and <PageDown> in an empty buffer should beep
1208 %d
1209 call assert_beeps('exe "normal \<PageUp>"')
1210 call assert_beeps('exe "normal \<C-B>"')
1211 call assert_beeps('exe "normal \<PageDown>"')
1212 call assert_beeps('exe "normal \<C-F>"')
1213
1214 " Test for <C-U> and <C-D> with fold
1215 %d
1216 call setline(1, range(1, 100))
1217 10,35fold
1218 set scroll=10
1219 exe "normal \<C-D>"
1220 call assert_equal(36, line('.'))
1221 exe "normal \<C-D>"
1222 call assert_equal(46, line('.'))
1223 exe "normal \<C-U>"
1224 call assert_equal(36, line('.'))
1225 exe "normal \<C-U>"
1226 call assert_equal(10, line('.'))
1227 exe "normal \<C-U>"
1228 call assert_equal(1, line('.'))
1229 set scroll&
1230
1231 " Test for scrolling to the top of the file with <C-U> and a fold
1232 10
1233 normal ztL
1234 exe "normal \<C-U>\<C-U>"
1235 call assert_equal(1, line('w0'))
1236
1237 " Test for CTRL-D on a folded line
1238 %d
1239 call setline(1, range(1, 100))
1240 50,100fold
1241 75
1242 normal z-
1243 exe "normal \<C-D>"
1244 call assert_equal(50, line('.'))
1245 call assert_equal(100, line('w$'))
1246 normal z.
1247 let lnum = winline()
1248 exe "normal \<C-D>"
1249 call assert_equal(lnum, winline())
1250 call assert_equal(50, line('.'))
1251 normal zt
1252 exe "normal \<C-D>"
1253 call assert_equal(50, line('w0'))
1254
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001255 " Test for <S-CR>. Page down.
1256 %d
1257 call setline(1, range(1, 100))
1258 call feedkeys("\<S-CR>", 'xt')
1259 call assert_equal(14, line('w0'))
1260 call assert_equal(28, line('w$'))
1261
1262 " Test for <S-->. Page up.
1263 call feedkeys("\<S-->", 'xt')
1264 call assert_equal(1, line('w0'))
1265 call assert_equal(15, line('w$'))
1266
Bram Moolenaar1671f442020-03-10 07:48:13 +01001267 set foldenable&
1268 close!
1269endfunc
1270
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001271func Test_scroll_in_ex_mode()
1272 " This was using invalid memory because w_botline was invalid.
1273 let lines =<< trim END
1274 diffsplit
1275 norm os00(
1276 call writefile(['done'], 'Xdone')
1277 qa!
1278 END
1279 call writefile(lines, 'Xscript')
1280 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1281 call assert_equal(['done'], readfile('Xdone'))
1282
1283 call delete('Xscript')
1284 call delete('Xdone')
1285endfunc
1286
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001287" Test for the 'sidescroll' option
1288func Test_sidescroll_opt()
1289 new
1290 20vnew
1291
1292 " scroll by 2 characters horizontally
1293 set sidescroll=2 nowrap
1294 call setline(1, repeat('a', 40))
1295 normal g$l
1296 call assert_equal(19, screenpos(0, 1, 21).col)
1297 normal l
1298 call assert_equal(20, screenpos(0, 1, 22).col)
1299 normal g0h
1300 call assert_equal(2, screenpos(0, 1, 2).col)
1301 call assert_equal(20, screenpos(0, 1, 20).col)
1302
1303 " when 'sidescroll' is 0, cursor positioned at the center
1304 set sidescroll=0
1305 normal g$l
1306 call assert_equal(11, screenpos(0, 1, 21).col)
1307 normal g0h
1308 call assert_equal(10, screenpos(0, 1, 10).col)
1309
1310 %bw!
1311 set wrap& sidescroll&
1312endfunc
1313
Bram Moolenaar004a6782020-04-11 17:09:31 +02001314" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001315func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001316 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001317 call Setup_NewWindow()
1318 50
1319 setl foldenable fdm=marker foldlevel=5
1320
Bram Moolenaar1671f442020-03-10 07:48:13 +01001321 call assert_beeps('normal! zj')
1322 call assert_beeps('normal! zk')
1323
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001324 " Test for zF
1325 " First fold
1326 norm! 4zF
1327 " check that folds have been created
1328 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1329
1330 " Test for zd
1331 51
1332 norm! 2zF
1333 call assert_equal(2, foldlevel('.'))
1334 norm! kzd
1335 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1336 norm! j
1337 call assert_equal(1, foldlevel('.'))
1338
1339 " Test for zD
1340 " also deletes partially selected folds recursively
1341 51
1342 norm! zF
1343 call assert_equal(2, foldlevel('.'))
1344 norm! kV2jzD
1345 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1346
1347 " Test for zE
1348 85
1349 norm! 4zF
1350 86
1351 norm! 2zF
1352 90
1353 norm! 4zF
1354 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1355 norm! zE
1356 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1357
1358 " Test for zn
1359 50
1360 set foldlevel=0
1361 norm! 2zF
1362 norm! zn
1363 norm! k
1364 call assert_equal('49', getline('.'))
1365 norm! j
1366 call assert_equal('50/*{{{*/', getline('.'))
1367 norm! j
1368 call assert_equal('51/*}}}*/', getline('.'))
1369 norm! j
1370 call assert_equal('52', getline('.'))
1371 call assert_equal(0, &foldenable)
1372
1373 " Test for zN
1374 49
1375 norm! zN
1376 call assert_equal('49', getline('.'))
1377 norm! j
1378 call assert_equal('50/*{{{*/', getline('.'))
1379 norm! j
1380 call assert_equal('52', getline('.'))
1381 call assert_equal(1, &foldenable)
1382
1383 " Test for zi
1384 norm! zi
1385 call assert_equal(0, &foldenable)
1386 norm! zi
1387 call assert_equal(1, &foldenable)
1388 norm! zi
1389 call assert_equal(0, &foldenable)
1390 norm! zi
1391 call assert_equal(1, &foldenable)
1392
1393 " Test for za
1394 50
1395 norm! za
1396 norm! k
1397 call assert_equal('49', getline('.'))
1398 norm! j
1399 call assert_equal('50/*{{{*/', getline('.'))
1400 norm! j
1401 call assert_equal('51/*}}}*/', getline('.'))
1402 norm! j
1403 call assert_equal('52', getline('.'))
1404 50
1405 norm! za
1406 norm! k
1407 call assert_equal('49', getline('.'))
1408 norm! j
1409 call assert_equal('50/*{{{*/', getline('.'))
1410 norm! j
1411 call assert_equal('52', getline('.'))
1412
1413 49
1414 norm! 5zF
1415 norm! k
1416 call assert_equal('48', getline('.'))
1417 norm! j
1418 call assert_equal('49/*{{{*/', getline('.'))
1419 norm! j
1420 call assert_equal('55', getline('.'))
1421 49
1422 norm! za
1423 call assert_equal('49/*{{{*/', getline('.'))
1424 norm! j
1425 call assert_equal('50/*{{{*/', getline('.'))
1426 norm! j
1427 call assert_equal('52', getline('.'))
1428 set nofoldenable
1429 " close fold and set foldenable
1430 norm! za
1431 call assert_equal(1, &foldenable)
1432
1433 50
1434 " have to use {count}za to open all folds and make the cursor visible
1435 norm! 2za
1436 norm! 2k
1437 call assert_equal('48', getline('.'))
1438 norm! j
1439 call assert_equal('49/*{{{*/', getline('.'))
1440 norm! j
1441 call assert_equal('50/*{{{*/', getline('.'))
1442 norm! j
1443 call assert_equal('51/*}}}*/', getline('.'))
1444 norm! j
1445 call assert_equal('52', getline('.'))
1446
1447 " Test for zA
1448 49
1449 set foldlevel=0
1450 50
1451 norm! zA
1452 norm! 2k
1453 call assert_equal('48', getline('.'))
1454 norm! j
1455 call assert_equal('49/*{{{*/', getline('.'))
1456 norm! j
1457 call assert_equal('50/*{{{*/', getline('.'))
1458 norm! j
1459 call assert_equal('51/*}}}*/', getline('.'))
1460 norm! j
1461 call assert_equal('52', getline('.'))
1462
Dominique Pelle923dce22021-11-21 11:36:04 +00001463 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001464 50
1465 set nofoldenable
1466 norm! zA
1467 call assert_equal(1, &foldenable)
1468 norm! k
1469 call assert_equal('48', getline('.'))
1470 norm! j
1471 call assert_equal('49/*{{{*/', getline('.'))
1472 norm! j
1473 call assert_equal('55', getline('.'))
1474
1475 " Test for zc
1476 norm! zE
1477 50
1478 norm! 2zF
1479 49
1480 norm! 5zF
1481 set nofoldenable
1482 50
1483 " There most likely is a bug somewhere:
1484 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1485 " TODO: Should this only close the inner most fold or both folds?
1486 norm! zc
1487 call assert_equal(1, &foldenable)
1488 norm! k
1489 call assert_equal('48', getline('.'))
1490 norm! j
1491 call assert_equal('49/*{{{*/', getline('.'))
1492 norm! j
1493 call assert_equal('55', getline('.'))
1494 set nofoldenable
1495 50
1496 norm! Vjzc
1497 norm! k
1498 call assert_equal('48', getline('.'))
1499 norm! j
1500 call assert_equal('49/*{{{*/', getline('.'))
1501 norm! j
1502 call assert_equal('55', getline('.'))
1503
1504 " Test for zC
1505 set nofoldenable
1506 50
1507 norm! zCk
1508 call assert_equal('48', getline('.'))
1509 norm! j
1510 call assert_equal('49/*{{{*/', getline('.'))
1511 norm! j
1512 call assert_equal('55', getline('.'))
1513
1514 " Test for zx
1515 " 1) close folds at line 49-54
1516 set nofoldenable
1517 48
1518 norm! zx
1519 call assert_equal(1, &foldenable)
1520 norm! j
1521 call assert_equal('49/*{{{*/', getline('.'))
1522 norm! j
1523 call assert_equal('55', getline('.'))
1524
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001525 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001526 51
1527 set nofoldenable
1528 norm! zx
1529 call assert_equal(1, &foldenable)
1530 norm! 3k
1531 call assert_equal('48', getline('.'))
1532 norm! j
1533 call assert_equal('49/*{{{*/', getline('.'))
1534 norm! j
1535 call assert_equal('50/*{{{*/', getline('.'))
1536 norm! j
1537 call assert_equal('51/*}}}*/', getline('.'))
1538 norm! j
1539 call assert_equal('52', getline('.'))
1540 norm! j
1541 call assert_equal('53', getline('.'))
1542 norm! j
1543 call assert_equal('54/*}}}*/', getline('.'))
1544 norm! j
1545 call assert_equal('55', getline('.'))
1546
1547 " 3) close one level of folds
1548 48
1549 set nofoldenable
1550 set foldlevel=1
1551 norm! zx
1552 call assert_equal(1, &foldenable)
1553 call assert_equal('48', getline('.'))
1554 norm! j
1555 call assert_equal('49/*{{{*/', getline('.'))
1556 norm! j
1557 call assert_equal('50/*{{{*/', getline('.'))
1558 norm! j
1559 call assert_equal('52', getline('.'))
1560 norm! j
1561 call assert_equal('53', getline('.'))
1562 norm! j
1563 call assert_equal('54/*}}}*/', getline('.'))
1564 norm! j
1565 call assert_equal('55', getline('.'))
1566
1567 " Test for zX
1568 " Close all folds
1569 set foldlevel=0 nofoldenable
1570 50
1571 norm! zX
1572 call assert_equal(1, &foldenable)
1573 norm! k
1574 call assert_equal('48', getline('.'))
1575 norm! j
1576 call assert_equal('49/*{{{*/', getline('.'))
1577 norm! j
1578 call assert_equal('55', getline('.'))
1579
1580 " Test for zm
1581 50
1582 set nofoldenable foldlevel=2
1583 norm! zm
1584 call assert_equal(1, &foldenable)
1585 call assert_equal(1, &foldlevel)
1586 norm! zm
1587 call assert_equal(0, &foldlevel)
1588 norm! zm
1589 call assert_equal(0, &foldlevel)
1590 norm! k
1591 call assert_equal('48', getline('.'))
1592 norm! j
1593 call assert_equal('49/*{{{*/', getline('.'))
1594 norm! j
1595 call assert_equal('55', getline('.'))
1596
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001597 " Test for zm with a count
1598 50
1599 set foldlevel=2
1600 norm! 3zm
1601 call assert_equal(0, &foldlevel)
1602 call assert_equal(49, foldclosed(line('.')))
1603
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001604 " Test for zM
1605 48
1606 set nofoldenable foldlevel=99
1607 norm! zM
1608 call assert_equal(1, &foldenable)
1609 call assert_equal(0, &foldlevel)
1610 call assert_equal('48', getline('.'))
1611 norm! j
1612 call assert_equal('49/*{{{*/', getline('.'))
1613 norm! j
1614 call assert_equal('55', getline('.'))
1615
1616 " Test for zr
1617 48
1618 set nofoldenable foldlevel=0
1619 norm! zr
1620 call assert_equal(0, &foldenable)
1621 call assert_equal(1, &foldlevel)
1622 set foldlevel=0 foldenable
1623 norm! zr
1624 call assert_equal(1, &foldenable)
1625 call assert_equal(1, &foldlevel)
1626 norm! zr
1627 call assert_equal(2, &foldlevel)
1628 call assert_equal('48', getline('.'))
1629 norm! j
1630 call assert_equal('49/*{{{*/', getline('.'))
1631 norm! j
1632 call assert_equal('50/*{{{*/', getline('.'))
1633 norm! j
1634 call assert_equal('51/*}}}*/', getline('.'))
1635 norm! j
1636 call assert_equal('52', getline('.'))
1637
1638 " Test for zR
1639 48
1640 set nofoldenable foldlevel=0
1641 norm! zR
1642 call assert_equal(0, &foldenable)
1643 call assert_equal(2, &foldlevel)
1644 set foldenable foldlevel=0
1645 norm! zR
1646 call assert_equal(1, &foldenable)
1647 call assert_equal(2, &foldlevel)
1648 call assert_equal('48', getline('.'))
1649 norm! j
1650 call assert_equal('49/*{{{*/', getline('.'))
1651 norm! j
1652 call assert_equal('50/*{{{*/', getline('.'))
1653 norm! j
1654 call assert_equal('51/*}}}*/', getline('.'))
1655 norm! j
1656 call assert_equal('52', getline('.'))
1657 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1658 48
1659 call assert_equal('48', getline('.'))
1660 norm! j
1661 call assert_equal('49/*{{{*/', getline('.'))
1662 norm! j
1663 call assert_equal('50/*{{{*/', getline('.'))
1664 norm! j
1665 call assert_equal('a /*{{{*/', getline('.'))
1666 norm! j
1667 call assert_equal('51/*}}}*/', getline('.'))
1668 norm! j
1669 call assert_equal('52', getline('.'))
1670 48
1671 norm! zR
1672 call assert_equal(1, &foldenable)
1673 call assert_equal(3, &foldlevel)
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('b /*}}}*/', getline('.'))
1683 norm! j
1684 call assert_equal('51/*}}}*/', getline('.'))
1685 norm! j
1686 call assert_equal('52', getline('.'))
1687
1688 " clean up
1689 setl nofoldenable fdm=marker foldlevel=0
1690 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001691endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001692
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001693func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001694 " Reading from redirected file doesn't work on MS-Windows
1695 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001696 call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
1697 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001698 call system(GetVimCommand() .. ' -e -s < Xscript Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001699 let a=readfile('Xfile2')
1700 call assert_equal(['1', 'foo', 'bar', '2'], a)
1701
1702 " clean up
1703 for file in ['Xfile', 'Xfile2', 'Xscript']
1704 call delete(file)
1705 endfor
1706 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001707endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001708
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001709func Test_normal21_nv_hat()
1710
1711 " Edit a fresh file and wipe the buffer list so that there is no alternate
1712 " file present. Next, check for the expected command failures.
1713 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001714 call assert_fails(':buffer #', 'E86:')
1715 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001716 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001717
1718 " Test for the expected behavior when switching between two named buffers.
1719 edit Xfoo | edit Xbar
1720 call feedkeys("\<C-^>", 'tx')
1721 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1722 call feedkeys("\<C-^>", 'tx')
1723 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1724
1725 " Test for the expected behavior when only one buffer is named.
1726 enew | let l:nr = bufnr('%')
1727 call feedkeys("\<C-^>", 'tx')
1728 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1729 call feedkeys("\<C-^>", 'tx')
1730 call assert_equal('', bufname('%'))
1731 call assert_equal(l:nr, bufnr('%'))
1732
1733 " Test that no action is taken by "<C-^>" when an operator is pending.
1734 edit Xfoo
1735 call feedkeys("ci\<C-^>", 'tx')
1736 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1737
1738 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001739endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001740
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001741func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001742 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001743 " let shell = &shell
1744 " let &shell = 'sh'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001745 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001746 let args = ' -N -i NONE --noplugins -X --not-a-term'
1747 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001748 let a = readfile('Xfile')
1749 call assert_equal([], a)
1750 " Test for ZQ
1751 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001752 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001753 let a = readfile('Xfile')
1754 call assert_equal(['1', '2'], a)
1755
Bram Moolenaar1671f442020-03-10 07:48:13 +01001756 " Unsupported Z command
1757 call assert_beeps('normal! ZW')
1758
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001759 " clean up
1760 for file in ['Xfile']
1761 call delete(file)
1762 endfor
Bram Moolenaar0913a102016-09-03 19:11:59 +02001763 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001764endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001765
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001766func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001767 " Test for K command
1768 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001769 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001770 let k = &keywordprg
1771 set keywordprg=:help
1772 1
1773 norm! VK
1774 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1775 call assert_equal('help', &ft)
1776 call assert_match('\*version8.txt\*', getline('.'))
1777 helpclose
1778 norm! 0K
1779 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1780 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001781 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001782 helpclose
1783
Bram Moolenaar426f3752016-11-04 21:22:37 +01001784 set keywordprg=:new
1785 set iskeyword+=%
1786 set iskeyword+=\|
1787 2
1788 norm! K
1789 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1790 bwipe!
1791 3
1792 norm! K
1793 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1794 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001795 if !has('win32')
1796 4
1797 norm! K
1798 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1799 bwipe!
1800 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001801 set iskeyword-=%
1802 set iskeyword-=\|
1803
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001804 " Test for specifying a count to K
1805 1
1806 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1807 set keywordprg=:Kprog
1808 norm! 3K
1809 call assert_equal('3 version8', g:Kprog_Args)
1810 delcom Kprog
1811
Bram Moolenaar0913a102016-09-03 19:11:59 +02001812 " Only expect "man" to work on Unix
1813 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001814 let &keywordprg = k
1815 bw!
1816 return
1817 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001818
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001819 let not_gnu_man = has('mac') || has('bsd')
1820 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001821 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001822 set keywordprg=man\ -P\ cat
1823 else
1824 set keywordprg=man\ --pager=cat
1825 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001826 " Test for using man
1827 2
1828 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001829 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001830 call assert_match("man -P cat 'man'", a)
1831 else
1832 call assert_match("man --pager=cat 'man'", a)
1833 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001834
Bram Moolenaar1671f442020-03-10 07:48:13 +01001835 " Error cases
1836 call setline(1, '#$#')
1837 call assert_fails('normal! ggK', 'E349:')
1838 call setline(1, '---')
1839 call assert_fails('normal! ggv2lK', 'E349:')
1840 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001841 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001842 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001843 norm! V
1844 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001845
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001846 " clean up
1847 let &keywordprg = k
1848 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001849endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001850
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001851func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001852 " Testing for g?? g?g?
1853 new
1854 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1855 1
1856 norm! g??
1857 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1858 norm! g?g?
1859 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1860
1861 " clean up
1862 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001863endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001864
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001865func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001866 CheckFeature quickfix
1867
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001868 " Testing for CTRL-] g CTRL-] g]
1869 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1870 h
1871 " Test for CTRL-]
1872 call search('\<x\>$')
1873 exe "norm! \<c-]>"
1874 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1875 norm! yiW
1876 call assert_equal("*x*", @0)
1877 exe ":norm \<c-o>"
1878
1879 " Test for g_CTRL-]
1880 call search('\<v_u\>$')
1881 exe "norm! g\<c-]>"
1882 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1883 norm! yiW
1884 call assert_equal("*v_u*", @0)
1885 exe ":norm \<c-o>"
1886
1887 " Test for g]
1888 call search('\<i_<Esc>$')
1889 let a = execute(":norm! g]")
1890 call assert_match('i_<Esc>.*insert.txt', a)
1891
1892 if !empty(exepath('cscope')) && has('cscope')
1893 " setting cscopetag changes how g] works
1894 set cst
1895 exe "norm! g]"
1896 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1897 norm! yiW
1898 call assert_equal("*i_<Esc>*", @0)
1899 exe ":norm \<c-o>"
1900 " Test for CTRL-W g]
1901 exe "norm! \<C-W>g]"
1902 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1903 norm! yiW
1904 call assert_equal("*i_<Esc>*", @0)
1905 call assert_equal(3, winnr('$'))
1906 helpclose
1907 set nocst
1908 endif
1909
1910 " Test for CTRL-W g]
1911 let a = execute("norm! \<C-W>g]")
1912 call assert_match('i_<Esc>.*insert.txt', a)
1913
1914 " Test for CTRL-W CTRL-]
1915 exe "norm! \<C-W>\<C-]>"
1916 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1917 norm! yiW
1918 call assert_equal("*i_<Esc>*", @0)
1919 call assert_equal(3, winnr('$'))
1920 helpclose
1921
1922 " Test for CTRL-W g CTRL-]
1923 exe "norm! \<C-W>g\<C-]>"
1924 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1925 norm! yiW
1926 call assert_equal("*i_<Esc>*", @0)
1927 call assert_equal(3, winnr('$'))
1928 helpclose
1929
1930 " clean up
1931 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001932endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001933
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001934func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001935 " Test for ]p ]P [p and [P
1936 new
1937 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1938 1
1939 /Error/y a
1940 2
1941 norm! "a]pj"a[p
1942 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1943 1
1944 /^\s\{4}/
1945 exe "norm! \"a]P3Eldt'"
1946 exe "norm! j\"a[P2Eldt'"
1947 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
1948
1949 " clean up
1950 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001951endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001952
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001953func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001954 " Test for [' [` ]' ]`
1955 call Setup_NewWindow()
1956 1,21s/.\+/ & b/
1957 1
1958 norm! $ma
1959 5
1960 norm! $mb
1961 10
1962 norm! $mc
1963 15
1964 norm! $md
1965 20
1966 norm! $me
1967
1968 " Test for ['
1969 9
1970 norm! 2['
1971 call assert_equal(' 1 b', getline('.'))
1972 call assert_equal(1, line('.'))
1973 call assert_equal(3, col('.'))
1974
1975 " Test for ]'
1976 norm! ]'
1977 call assert_equal(' 5 b', getline('.'))
1978 call assert_equal(5, line('.'))
1979 call assert_equal(3, col('.'))
1980
1981 " No mark after line 21, cursor moves to first non blank on current line
1982 21
1983 norm! $]'
1984 call assert_equal(' 21 b', getline('.'))
1985 call assert_equal(21, line('.'))
1986 call assert_equal(3, col('.'))
1987
1988 " Test for [`
1989 norm! 2[`
1990 call assert_equal(' 15 b', getline('.'))
1991 call assert_equal(15, line('.'))
1992 call assert_equal(8, col('.'))
1993
1994 " Test for ]`
1995 norm! ]`
1996 call assert_equal(' 20 b', getline('.'))
1997 call assert_equal(20, line('.'))
1998 call assert_equal(8, col('.'))
1999
2000 " clean up
2001 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002002endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002003
Bram Moolenaar1671f442020-03-10 07:48:13 +01002004" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002005func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002006 new
2007 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2008
2009 $
2010 norm! d(
2011 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2012 norm! 2d(
2013 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2014 1
2015 norm! 0d)
2016 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2017
2018 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2019 $
2020 norm! $d(
2021 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2022
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002023 " Move to the next sentence from a paragraph macro
2024 %d
2025 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2026 call cursor(1, 1)
2027 normal )
2028 call assert_equal([2, 1], [line('.'), col('.')])
2029 normal )
2030 call assert_equal([2, 12], [line('.'), col('.')])
2031 normal ((
2032 call assert_equal([1, 1], [line('.'), col('.')])
2033
Bram Moolenaar1671f442020-03-10 07:48:13 +01002034 " It is an error if a next sentence is not found
2035 %d
2036 call setline(1, '.SH')
2037 call assert_beeps('normal )')
2038
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002039 " If only dot is present, don't treat that as a sentence
2040 call setline(1, '. This is a sentence.')
2041 normal $((
2042 call assert_equal(3, col('.'))
2043
Bram Moolenaar1671f442020-03-10 07:48:13 +01002044 " Jumping to a fold should open the fold
2045 call setline(1, ['', '', 'one', 'two', 'three'])
2046 set foldenable
2047 2,$fold
2048 call feedkeys(')', 'xt')
2049 call assert_equal(3, line('.'))
2050 call assert_equal(1, foldlevel('.'))
2051 call assert_equal(-1, foldclosed('.'))
2052 set foldenable&
2053
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002054 " clean up
2055 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002056endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002057
Bram Moolenaar1671f442020-03-10 07:48:13 +01002058" Test for { and } paragraph movements
2059func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002060 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002061 A paragraph begins after each empty line, and also at each of a set of
2062 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2063 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2064 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2065 the first column). A section boundary is also a paragraph boundary.
2066 Note that a blank line (only containing white space) is NOT a paragraph
2067 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002068
2069
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002070 Also note that this does not include a '{' or '}' in the first column. When
2071 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2072 paragraph boundary |posix|.
2073 {
2074 This is no paragraph
2075 unless the '{' is set
2076 in 'cpoptions'
2077 }
2078 .IP
2079 The nroff macros IP separates a paragraph
2080 That means, it must be a '.'
2081 followed by IP
2082 .LPIt does not matter, if afterwards some
2083 more characters follow.
2084 .SHAlso section boundaries from the nroff
2085 macros terminate a paragraph. That means
2086 a character like this:
2087 .NH
2088 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002089 [DATA]
2090
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002091 new
2092 call append(0, text)
2093 1
2094 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002095
2096 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002097 .IP
2098 The nroff macros IP separates a paragraph
2099 That means, it must be a '.'
2100 followed by IP
2101 .LPIt does not matter, if afterwards some
2102 more characters follow.
2103 .SHAlso section boundaries from the nroff
2104 macros terminate a paragraph. That means
2105 a character like this:
2106 .NH
2107 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002108
2109 [DATA]
2110 call assert_equal(expected, getline(1, '$'))
2111
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002112 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002113
2114 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002115 .LPIt does not matter, if afterwards some
2116 more characters follow.
2117 .SHAlso section boundaries from the nroff
2118 macros terminate a paragraph. That means
2119 a character like this:
2120 .NH
2121 End of text here
2122
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002123 [DATA]
2124 call assert_equal(expected, getline(1, '$'))
2125
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002126 $
2127 norm! d{
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:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002135
2136 [DATA]
2137 call assert_equal(expected, getline(1, '$'))
2138
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002139 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002140
2141 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002142 .LPIt does not matter, if afterwards some
2143 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002144
2145 [DATA]
2146 call assert_equal(expected, getline(1, '$'))
2147
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002148 " Test with { in cpooptions
2149 %d
2150 call append(0, text)
2151 set cpo+={
2152 1
2153 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002154
2155 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002156 {
2157 This is no paragraph
2158 unless the '{' is set
2159 in 'cpoptions'
2160 }
2161 .IP
2162 The nroff macros IP separates a paragraph
2163 That means, it must be a '.'
2164 followed by IP
2165 .LPIt does not matter, if afterwards some
2166 more characters follow.
2167 .SHAlso section boundaries from the nroff
2168 macros terminate a paragraph. That means
2169 a character like this:
2170 .NH
2171 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002172
2173 [DATA]
2174 call assert_equal(expected, getline(1, '$'))
2175
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002176 $
2177 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002178
2179 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002180 {
2181 This is no paragraph
2182 unless the '{' is set
2183 in 'cpoptions'
2184 }
2185 .IP
2186 The nroff macros IP separates a paragraph
2187 That means, it must be a '.'
2188 followed by IP
2189 .LPIt does not matter, if afterwards some
2190 more characters follow.
2191 .SHAlso section boundaries from the nroff
2192 macros terminate a paragraph. That means
2193 a character like this:
2194 .NH
2195 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002196
2197 [DATA]
2198 call assert_equal(expected, getline(1, '$'))
2199
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002200 norm! gg}
2201 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002202
2203 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002204 {
2205 This is no paragraph
2206 unless the '{' is set
2207 in 'cpoptions'
2208 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002209
2210 [DATA]
2211 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002212
Bram Moolenaar1671f442020-03-10 07:48:13 +01002213 " Jumping to a fold should open the fold
2214 %d
2215 call setline(1, ['', 'one', 'two', ''])
2216 set foldenable
2217 2,$fold
2218 call feedkeys('}', 'xt')
2219 call assert_equal(4, line('.'))
2220 call assert_equal(1, foldlevel('.'))
2221 call assert_equal(-1, foldclosed('.'))
2222 set foldenable&
2223
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002224 " clean up
2225 set cpo-={
2226 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002227endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002228
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002229" Test for section movements
2230func Test_normal_section()
2231 new
2232 let lines =<< trim [END]
2233 int foo()
2234 {
2235 if (1)
2236 {
2237 a = 1;
2238 }
2239 }
2240 [END]
2241 call setline(1, lines)
2242
2243 " jumping to a folded line using [[ should open the fold
2244 2,3fold
2245 call cursor(5, 1)
2246 call feedkeys("[[", 'xt')
2247 call assert_equal(2, line('.'))
2248 call assert_equal(-1, foldclosedend(line('.')))
2249
2250 close!
2251endfunc
2252
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002253" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002254func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002255 new
2256 call append(0, 'This is a simple test: äüöß')
2257 norm! 1ggVu
2258 call assert_equal('this is a simple test: äüöß', getline('.'))
2259 norm! VU
2260 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2261 norm! guu
2262 call assert_equal('this is a simple test: äüöss', getline('.'))
2263 norm! gUgU
2264 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2265 norm! gugu
2266 call assert_equal('this is a simple test: äüöss', getline('.'))
2267 norm! gUU
2268 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2269 norm! 010~
2270 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
2271 norm! V~
2272 call assert_equal('THIS IS A simple test: äüöss', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002273 call assert_beeps('norm! c~')
2274 %d
2275 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002276
Bram Moolenaar1671f442020-03-10 07:48:13 +01002277 " Test for changing case across lines using 'whichwrap'
2278 call setline(1, ['aaaaaa', 'aaaaaa'])
2279 normal! gg10~
2280 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2281 set whichwrap+=~
2282 normal! gg10~
2283 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2284 set whichwrap&
2285
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002286 " try changing the case with a double byte encoding (DBCS)
2287 %bw!
2288 let enc = &enc
2289 set encoding=cp932
2290 call setline(1, "\u8470")
2291 normal ~
2292 normal gU$gu$gUgUg~g~gugu
2293 call assert_equal("\u8470", getline(1))
2294 let &encoding = enc
2295
Bram Moolenaar1671f442020-03-10 07:48:13 +01002296 " clean up
2297 bw!
2298endfunc
2299
2300" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2301" is available but toupper()/tolower() don't do the right thing.
2302func Test_normal_changecase_turkish()
2303 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002304 try
2305 lang tr_TR.UTF-8
2306 set casemap=
2307 let iupper = toupper('i')
2308 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002309 call setline(1, 'iI')
2310 1normal gUU
2311 call assert_equal("\u0130I", getline(1))
2312 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002313
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002314 call setline(1, 'iI')
2315 1normal guu
2316 call assert_equal("i\u0131", getline(1))
2317 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002318 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002319 call setline(1, 'iI')
2320 1normal gUU
2321 call assert_equal("II", getline(1))
2322 call assert_equal("II", toupper("iI"))
2323
2324 call setline(1, 'iI')
2325 1normal guu
2326 call assert_equal("ii", getline(1))
2327 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002328 else
2329 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2330 endif
2331 set casemap&
2332 call setline(1, 'iI')
2333 1normal gUU
2334 call assert_equal("II", getline(1))
2335 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002336
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002337 call setline(1, 'iI')
2338 1normal guu
2339 call assert_equal("ii", getline(1))
2340 call assert_equal("ii", tolower("iI"))
2341
2342 lang en_US.UTF-8
2343 catch /E197:/
2344 " can't use Turkish locale
2345 throw 'Skipped: Turkish locale not available'
2346 endtry
Bram Moolenaar1671f442020-03-10 07:48:13 +01002347 close!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002348endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002349
Bram Moolenaar1671f442020-03-10 07:48:13 +01002350" Test for r (replace) command
2351func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002352 new
2353 call append(0, 'This is a simple test: abcd')
2354 exe "norm! 1gg$r\<cr>"
2355 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2356 exe "norm! 1gg2wlr\<cr>"
2357 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2358 exe "norm! 2gg0W5r\<cr>"
2359 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2360 set autoindent
2361 call setline(2, ['simple test: abc', ''])
2362 exe "norm! 2gg0W5r\<cr>"
2363 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2364 exe "norm! 1ggVr\<cr>"
2365 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2366 call setline(1, 'This is a')
2367 exe "norm! 1gg05rf"
2368 call assert_equal('fffffis a', getline(1))
2369
Bram Moolenaar1671f442020-03-10 07:48:13 +01002370 " When replacing characters, copy characters from above and below lines
2371 " using CTRL-Y and CTRL-E.
2372 " Different code paths are used for utf-8 and latin1 encodings
2373 set showmatch
2374 for enc in ['latin1', 'utf-8']
2375 enew!
2376 let &encoding = enc
2377 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2378 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2379 call assert_equal(' {a}x [b]x', getline(2))
2380 endfor
2381 set showmatch&
2382
2383 " r command should fail in operator pending mode
2384 call assert_beeps('normal! cr')
2385
Bram Moolenaar004a6782020-04-11 17:09:31 +02002386 " replace a tab character in visual mode
2387 %d
2388 call setline(1, ["a\tb", "c\td", "e\tf"])
2389 normal gglvjjrx
2390 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2391
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002392 " replace with a multibyte character (with multiple composing characters)
2393 %d
2394 new
2395 call setline(1, 'aaa')
2396 exe "normal $ra\u0328\u0301"
2397 call assert_equal("aaa\u0328\u0301", getline(1))
2398
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002399 " clean up
2400 set noautoindent
2401 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002402endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002403
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002404" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002405func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002406 new
2407 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2408 1
2409 norm! $g*
2410 call assert_equal('x_foo', @/)
2411 call assert_equal('x_foobar.abc', getline('.'))
2412 norm! $g#
2413 call assert_equal('abc', @/)
2414 call assert_equal('abc.x_foo', getline('.'))
2415
2416 " clean up
2417 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002418endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002419
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002420" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2421" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002422func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002423 call Setup_NewWindow()
2424 " Test for g`
2425 clearjumps
2426 norm! ma10j
2427 let a=execute(':jumps')
2428 " empty jumplist
2429 call assert_equal('>', a[-1:])
2430 norm! g`a
2431 call assert_equal('>', a[-1:])
2432 call assert_equal(1, line('.'))
2433 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002434 call cursor(10, 1)
2435 norm! g'a
2436 call assert_equal('>', a[-1:])
2437 call assert_equal(1, line('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002438
2439 " Test for g; and g,
2440 norm! g;
2441 " there is only one change in the changelist
2442 " currently, when we setup the window
2443 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002444 call assert_fails(':norm! g;', 'E662:')
2445 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002446 let &ul=&ul
2447 call append('$', ['a', 'b', 'c', 'd'])
2448 let &ul=&ul
2449 call append('$', ['Z', 'Y', 'X', 'W'])
2450 let a = execute(':changes')
2451 call assert_match('2\s\+0\s\+2', a)
2452 call assert_match('101\s\+0\s\+a', a)
2453 call assert_match('105\s\+0\s\+Z', a)
2454 norm! 3g;
2455 call assert_equal(2, line('.'))
2456 norm! 2g,
2457 call assert_equal(105, line('.'))
2458
2459 " Test for g& - global substitute
2460 %d
2461 call setline(1, range(1,10))
2462 call append('$', ['a', 'b', 'c', 'd'])
2463 $s/\w/&&/g
2464 exe "norm! /[1-8]\<cr>"
2465 norm! g&
2466 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2467
Bram Moolenaar1671f442020-03-10 07:48:13 +01002468 " Jumping to a fold using gg should open the fold
2469 set foldenable
2470 set foldopen+=jump
2471 5,8fold
2472 call feedkeys('6gg', 'xt')
2473 call assert_equal(1, foldlevel('.'))
2474 call assert_equal(-1, foldclosed('.'))
2475 set foldopen-=jump
2476 set foldenable&
2477
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002478 " Test for gv
2479 %d
2480 call append('$', repeat(['abcdefgh'], 8))
2481 exe "norm! 2gg02l\<c-v>2j2ly"
2482 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2483 " in visual mode, gv swaps current and last selected region
2484 exe "norm! G0\<c-v>4k4lgvd"
2485 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2486 exe "norm! G0\<c-v>4k4ly"
2487 exe "norm! gvood"
2488 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002489 " gv cannot be used in operator pending mode
2490 call assert_beeps('normal! cgv')
2491 " gv should beep without a previously selected visual area
2492 new
2493 call assert_beeps('normal! gv')
2494 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002495
2496 " Test for gk/gj
2497 %d
2498 15vsp
2499 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002500 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2501 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2502 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002503 $put =lineA
2504 $put =lineB
2505
2506 norm! 3gg0dgk
2507 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2508 set nu
2509 norm! 3gg0gjdgj
2510 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2511
2512 " Test for gJ
2513 norm! 2gggJ
2514 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2515 call assert_equal(16, col('.'))
2516 " shouldn't do anything
2517 norm! 10gJ
2518 call assert_equal(1, col('.'))
2519
2520 " Test for g0 g^ gm g$
2521 exe "norm! 2gg0gji "
2522 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2523 norm! g0yl
2524 call assert_equal(12, col('.'))
2525 call assert_equal(' ', getreg(0))
2526 norm! g$yl
2527 call assert_equal(22, col('.'))
2528 call assert_equal('3', getreg(0))
2529 norm! gmyl
2530 call assert_equal(17, col('.'))
2531 call assert_equal('n', getreg(0))
2532 norm! g^yl
2533 call assert_equal(15, col('.'))
2534 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002535 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002536
Bram Moolenaar74ede802021-05-29 19:18:01 +02002537 " Test for g$ with double-width character half displayed
2538 vsplit
2539 9wincmd |
2540 setlocal nowrap nonumber
2541 call setline(2, 'asdfasdfヨ')
2542 2
2543 normal 0g$
2544 call assert_equal(8, col('.'))
2545 10wincmd |
2546 normal 0g$
2547 call assert_equal(9, col('.'))
2548
2549 setlocal signcolumn=yes
2550 11wincmd |
2551 normal 0g$
2552 call assert_equal(8, col('.'))
2553 12wincmd |
2554 normal 0g$
2555 call assert_equal(9, col('.'))
2556
2557 close
2558
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002559 " Test for g_
2560 call assert_beeps('normal! 100g_')
2561 call setline(2, [' foo ', ' foobar '])
2562 normal! 2ggg_
2563 call assert_equal(5, col('.'))
2564 normal! 2g_
2565 call assert_equal(8, col('.'))
2566
2567 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002568 $put =lineC
2569
2570 " Test for gM
2571 norm! gMyl
2572 call assert_equal(73, col('.'))
2573 call assert_equal('0', getreg(0))
2574 " Test for 20gM
2575 norm! 20gMyl
2576 call assert_equal(29, col('.'))
2577 call assert_equal('S', getreg(0))
2578 " Test for 60gM
2579 norm! 60gMyl
2580 call assert_equal(87, col('.'))
2581 call assert_equal('E', getreg(0))
2582
2583 " Test for g Ctrl-G
2584 set ff=unix
2585 let a=execute(":norm! g\<c-g>")
2586 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2587
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002588 " Test for gI
2589 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002590 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002591
2592 " Test for gi
2593 wincmd c
2594 %d
2595 set tw=0
2596 call setline(1, ['foobar', 'new line'])
2597 norm! A next word
2598 $put ='third line'
2599 norm! gi another word
2600 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002601 call setline(1, 'foobar')
2602 normal! Ggifirst line
2603 call assert_equal('foobarfirst line', getline(1))
2604 " Test gi in 'virtualedit' mode with cursor after the end of the line
2605 set virtualedit=all
2606 call setline(1, 'foo')
2607 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2608 call setline(1, 'foo')
2609 normal! Ggifirst line
2610 call assert_equal('foo first line', getline(1))
2611 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002612
Dominique Pelle923dce22021-11-21 11:36:04 +00002613 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002614 exe "normal! g\<C-\>\<C-G>"
2615 call assert_equal('foo first line', getline('.'))
2616
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002617 " clean up
2618 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002619endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002620
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002621" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002622func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002623 new
2624
2625 let a = execute(":norm! g\<c-g>")
2626 call assert_equal("\n--No lines in buffer--", a)
2627
Bram Moolenaar1671f442020-03-10 07:48:13 +01002628 " Test for CTRL-G (same as :file)
2629 let a = execute(":norm! \<c-g>")
2630 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2631
Bram Moolenaar05295832018-08-24 22:07:58 +02002632 call setline(1, ['first line', 'second line'])
2633
2634 " Test g CTRL-g with dos, mac and unix file type.
2635 norm! gojll
2636 set ff=dos
2637 let a = execute(":norm! g\<c-g>")
2638 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2639
2640 set ff=mac
2641 let a = execute(":norm! g\<c-g>")
2642 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2643
2644 set ff=unix
2645 let a = execute(":norm! g\<c-g>")
2646 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2647
2648 " Test g CTRL-g in visual mode (v)
2649 let a = execute(":norm! gojllvlg\<c-g>")
2650 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2651
2652 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2653 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2654 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2655
2656 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2657 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2658 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2659
2660 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2661 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2662 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2663
2664 " There should be one byte less with noeol
2665 set bin noeol
2666 let a = execute(":norm! \<Esc>gog\<c-g>")
2667 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2668 set bin & eol&
2669
Bram Moolenaar30276f22019-01-24 17:59:39 +01002670 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002671
Bram Moolenaar30276f22019-01-24 17:59:39 +01002672 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2673 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 +02002674
Bram Moolenaar30276f22019-01-24 17:59:39 +01002675 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2676 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 +02002677
Bram Moolenaar30276f22019-01-24 17:59:39 +01002678 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2679 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 +02002680
Bram Moolenaar30276f22019-01-24 17:59:39 +01002681 set fenc=utf8 bomb
2682 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2683 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 +02002684
Bram Moolenaar30276f22019-01-24 17:59:39 +01002685 set fenc=utf16 bomb
2686 let a = execute(":norm! g\<c-g>")
2687 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 +02002688
Bram Moolenaar30276f22019-01-24 17:59:39 +01002689 set fenc=utf32 bomb
2690 let a = execute(":norm! g\<c-g>")
2691 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 +02002692
Bram Moolenaar30276f22019-01-24 17:59:39 +01002693 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002694
2695 set ff&
2696 bwipe!
2697endfunc
2698
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002699" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002700func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002701 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002702 let a=execute(':norm! 1G0g8')
2703 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002704
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002705 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2706 let a=execute(':norm! 1G$g8')
2707 call assert_equal("\nc3 b6 ", a)
2708
2709 call setline(1, "a\u0302")
2710 let a=execute(':norm! 1G0g8')
2711 call assert_equal("\n61 + cc 82 ", a)
2712
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002713 " clean up
2714 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002715endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002716
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002717" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002718func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002719 new
2720
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002721 " With invalid byte.
2722 call setline(1, "___\xff___")
2723 norm! 1G08g8g
2724 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2725
2726 " With invalid byte before the cursor.
2727 call setline(1, "___\xff___")
2728 norm! 1G$h8g8g
2729 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2730
2731 " With truncated sequence.
2732 call setline(1, "___\xE2\x82___")
2733 norm! 1G08g8g
2734 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2735
2736 " With overlong sequence.
2737 call setline(1, "___\xF0\x82\x82\xAC___")
2738 norm! 1G08g8g
2739 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2740
2741 " With valid utf8.
2742 call setline(1, "café")
2743 norm! 1G08g8
2744 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2745
2746 bw!
2747endfunc
2748
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002749" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002750func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002751 " Cannot capture its output,
2752 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002753 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002754 echo "a\nb\nc\nd"
2755 let b=execute(':norm! g<')
2756 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002757endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002758
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002759" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002760func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002761 new
2762 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002763 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002764 " Test for gp gP
2765 call append(1, range(1,10))
2766 1
2767 norm! 1yy
2768 3
2769 norm! gp
2770 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2771 $
2772 norm! gP
2773 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2774
2775 " Test for go
2776 norm! 26go
2777 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2778 norm! 27go
2779 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2780 norm! 28go
2781 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2782 set ff=dos
2783 norm! 29go
2784 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2785 set ff=unix
2786 norm! gg0
2787 norm! 101go
2788 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2789 norm! 103go
2790 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2791 " count > buffer content
2792 norm! 120go
2793 call assert_equal([0, 14, 1, 0, 2147483647], getcurpos())
2794 " clean up
2795 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002796endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002797
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002798" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002799func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002800 tabnew 1.txt
2801 tabnew 2.txt
2802 tabnew 3.txt
2803 norm! 1gt
2804 call assert_equal(1, tabpagenr())
2805 norm! 3gt
2806 call assert_equal(3, tabpagenr())
2807 norm! 1gT
2808 " count gT goes not to the absolute tabpagenumber
2809 " but, but goes to the count previous tabpagenumber
2810 call assert_equal(2, tabpagenr())
2811 " wrap around
2812 norm! 3gT
2813 call assert_equal(3, tabpagenr())
2814 " gt does not wrap around
2815 norm! 5gt
2816 call assert_equal(3, tabpagenr())
2817
2818 for i in range(3)
2819 tabclose
2820 endfor
2821 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002822 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002823endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002824
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002825" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002826func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002827 new
2828 call setline(1, range(10))
2829 $
2830 setl et sw=2
2831 norm! V10>$
2832 " count is ignored
2833 exe "norm! 10\<home>"
2834 call assert_equal(1, col('.'))
2835 exe "norm! \<home>"
2836 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2837 exe "norm! 5\<c-home>"
2838 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2839 exe "norm! \<c-home>"
2840 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002841 exe "norm! G\<c-kHome>"
2842 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002843
2844 " clean up
2845 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002846endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002847
Bram Moolenaar1671f442020-03-10 07:48:13 +01002848" Test for <End> and <C-End> keys
2849func Test_normal_nvend()
2850 new
2851 call setline(1, map(range(1, 10), '"line" .. v:val'))
2852 exe "normal! \<End>"
2853 call assert_equal(5, col('.'))
2854 exe "normal! 4\<End>"
2855 call assert_equal([4, 5], [line('.'), col('.')])
2856 exe "normal! \<C-End>"
2857 call assert_equal([10, 6], [line('.'), col('.')])
2858 close!
2859endfunc
2860
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002861" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002862func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002863 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002864 new
2865 set tw=0
2866 call append(0, 'here are some words')
2867 norm! 1gg0elcwZZZ
2868 call assert_equal('hereZZZare some words', getline('.'))
2869 norm! 1gg0elcWYYY
2870 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002871 norm! 2gg0cwfoo
2872 call assert_equal('foo', getline('.'))
2873
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002874 call setline(1, 'one; two')
2875 call cursor(1, 1)
2876 call feedkeys('cwvim', 'xt')
2877 call assert_equal('vim; two', getline(1))
2878 call feedkeys('0cWone', 'xt')
2879 call assert_equal('one two', getline(1))
2880 "When cursor is at the end of a word 'ce' will change until the end of the
2881 "next word, but 'cw' will change only one character
2882 call setline(1, 'one two')
2883 call feedkeys('0ecwce', 'xt')
2884 call assert_equal('once two', getline(1))
2885 call setline(1, 'one two')
2886 call feedkeys('0ecely', 'xt')
2887 call assert_equal('only', getline(1))
2888
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002889 " clean up
2890 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002891endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002892
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002893" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002894func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002895 new
2896 call append(0, 'here are some words')
2897 exe "norm! 1gg0a\<C-\>\<C-N>"
2898 call assert_equal('n', mode())
2899 call assert_equal(1, col('.'))
2900 call assert_equal('', visualmode())
2901 exe "norm! 1gg0viw\<C-\>\<C-N>"
2902 call assert_equal('n', mode())
2903 call assert_equal(4, col('.'))
2904 exe "norm! 1gg0a\<C-\>\<C-G>"
2905 call assert_equal('n', mode())
2906 call assert_equal(1, col('.'))
2907 "imap <buffer> , <c-\><c-n>
2908 set im
2909 exe ":norm! \<c-\>\<c-n>dw"
2910 set noim
2911 call assert_equal('are some words', getline(1))
2912 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02002913 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01002914
Bram Moolenaar21829c52021-01-26 22:42:21 +01002915 if has('cmdwin')
2916 " Using CTRL-\ CTRL-N in cmd window should close the window
2917 call feedkeys("q:\<C-\>\<C-N>", 'xt')
2918 call assert_equal('', getcmdwintype())
2919 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002920
2921 " 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 <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01002926func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002927 new
2928 set sts=2 sw=2 ts=8 tw=0
2929 call append(0, ["aaa\tbbb\tccc", '', '', ''])
2930 let a=getline(1)
2931 norm! 2gg0
2932 exe "norm! a\<c-r>=a\<cr>"
2933 norm! 3gg0
2934 exe "norm! a\<c-r>\<c-r>=a\<cr>"
2935 norm! 4gg0
2936 exe "norm! a\<c-r>\<c-o>=a\<cr>"
2937 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
2938
2939 " clean up
2940 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02002941 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002942endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002943
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002944" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002945func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002946 call Setup_NewWindow()
2947 call assert_equal(5, &scroll)
2948 exe "norm! \<c-d>"
2949 call assert_equal('6', getline('.'))
2950 exe "norm! 2\<c-d>"
2951 call assert_equal('8', getline('.'))
2952 call assert_equal(2, &scroll)
2953 set scroll=5
2954 exe "norm! \<c-u>"
2955 call assert_equal('3', getline('.'))
2956 1
2957 set scrolloff=5
2958 exe "norm! \<c-d>"
2959 call assert_equal('10', getline('.'))
2960 exe "norm! \<c-u>"
2961 call assert_equal('5', getline('.'))
2962 1
2963 set scrolloff=99
2964 exe "norm! \<c-d>"
2965 call assert_equal('10', getline('.'))
2966 set scrolloff=0
2967 100
2968 exe "norm! $\<c-u>"
2969 call assert_equal('95', getline('.'))
2970 call assert_equal([0, 95, 1, 0, 1], getcurpos())
2971 100
2972 set nostartofline
2973 exe "norm! $\<c-u>"
2974 call assert_equal('95', getline('.'))
2975 call assert_equal([0, 95, 2, 0, 2147483647], getcurpos())
2976 " cleanup
2977 set startofline
2978 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002979endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002980
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002981func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01002982 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01002983 " The ~ register does not exist
2984 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01002985 return
2986 endif
2987
2988 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002989 " unfortunately, without a gui, we can't really test much here,
2990 " so simply test that ~p fails (which uses the drop register)
2991 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02002992 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002993 call assert_equal([], getreg('~', 1, 1))
2994 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02002995 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002996 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002997endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002998
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002999func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003000 new
3001 " How to test this?
3002 " let's just for now test, that the buffer
3003 " does not change
3004 call feedkeys("\<c-s>", 't')
3005 call assert_equal([''], getline(1,'$'))
3006
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003007 " no valid commands
3008 exe "norm! \<char-0x100>"
3009 call assert_equal([''], getline(1,'$'))
3010
3011 exe "norm! ä"
3012 call assert_equal([''], getline(1,'$'))
3013
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003014 " clean up
3015 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003016endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003017
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003018func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003019 " This was causing a crash or ml_get error.
3020 enew!
3021 call setline(1,'xxx')
3022 normal $
3023 new
3024 call setline(1, range(1,2))
3025 2
3026 exe "norm \<C-V>$"
3027 bw!
3028 norm yp
3029 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003030endfunc
3031
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003032func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003033 new
3034 exe "norm! \<c-w>c"
3035 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003036 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003037endfunc
3038
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003039func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003040 new
3041 call setline(1, 'one two three four five six seven eight nine ten')
3042 1
3043 norm! 3d2w
3044 call assert_equal('seven eight nine ten', getline(1))
3045 bw!
3046endfunc
3047
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003048func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003049 CheckFeature timers
3050 CheckFeature cmdline_hist
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003051 func! DoTimerWork(id)
3052 call assert_equal('[Command Line]', bufname(''))
3053 " should fail, with E11, but does fail with E23?
3054 "call feedkeys("\<c-^>", 'tm')
3055
3056 " should also fail with E11
Bram Moolenaare2e40752020-09-04 21:18:46 +02003057 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003058 " return from commandline window
3059 call feedkeys("\<cr>")
3060 endfunc
3061
3062 let oldlang=v:lang
3063 lang C
3064 set updatetime=20
3065 call timer_start(100, 'DoTimerWork')
3066 try
3067 " throws E23, for whatever reason...
3068 call feedkeys('q:', 'x!')
3069 catch /E23/
3070 " no-op
3071 endtry
3072 " clean up
3073 set updatetime=4000
3074 exe "lang" oldlang
3075 bw!
3076endfunc
3077
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003078func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003079 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003080 " Don't sleep after the warning message.
3081 call test_settime(1)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003082 call writefile(['foo'], 'Xreadonly.log')
3083 new Xreadonly.log
3084 setl ro
3085 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003086 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003087 call assert_equal(['foo'], getline(1,'$'))
3088 call assert_equal('Xreadonly.log', bufname(''))
3089
3090 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003091 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003092 bw!
3093 call delete("Xreadonly.log")
3094endfunc
3095
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003096func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003097 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003098 new
3099 call setline(1, 'abcde fghij klmnopq')
3100 norm! 1gg$
3101 set rl
3102 call assert_equal(19, col('.'))
3103 call feedkeys('l', 'tx')
3104 call assert_equal(18, col('.'))
3105 call feedkeys('h', 'tx')
3106 call assert_equal(19, col('.'))
3107 call feedkeys("\<right>", 'tx')
3108 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003109 call feedkeys("\<left>", 'tx')
3110 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003111 call feedkeys("\<s-right>", 'tx')
3112 call assert_equal(13, col('.'))
3113 call feedkeys("\<c-right>", 'tx')
3114 call assert_equal(7, col('.'))
3115 call feedkeys("\<c-left>", 'tx')
3116 call assert_equal(13, col('.'))
3117 call feedkeys("\<s-left>", 'tx')
3118 call assert_equal(19, col('.'))
3119 call feedkeys("<<", 'tx')
3120 call assert_equal(' abcde fghij klmnopq',getline(1))
3121 call feedkeys(">>", 'tx')
3122 call assert_equal('abcde fghij klmnopq',getline(1))
3123
3124 " cleanup
3125 set norl
3126 bw!
3127endfunc
3128
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003129func Test_normal54_Ctrl_bsl()
3130 new
3131 call setline(1, 'abcdefghijklmn')
3132 exe "norm! df\<c-\>\<c-n>"
3133 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3134 exe "norm! df\<c-\>\<c-g>"
3135 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3136 exe "norm! df\<c-\>m"
3137 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003138
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003139 call setline(2, 'abcdefghijklmnāf')
3140 norm! 2gg0
3141 exe "norm! df\<Char-0x101>"
3142 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3143 norm! 1gg0
3144 exe "norm! df\<esc>"
3145 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003146
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003147 " clean up
3148 bw!
3149endfunc
3150
3151func Test_normal_large_count()
3152 " This may fail with 32bit long, how do we detect that?
3153 new
3154 normal o
3155 normal 6666666666dL
3156 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003157endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003158
3159func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003160 new
3161 normal grádv}
3162 call assert_equal('á', getline(1))
3163 normal grád}
3164 call assert_equal('', getline(1))
3165 bwipe!
3166endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003167
3168" Test for the gr (virtual replace) command
3169" Test for the bug fixed by 7.4.387
3170func Test_gr_command()
3171 enew!
3172 let save_cpo = &cpo
3173 call append(0, ['First line', 'Second line', 'Third line'])
3174 exe "normal i\<C-G>u"
3175 call cursor(2, 1)
3176 set cpo-=X
3177 normal 4gro
3178 call assert_equal('oooond line', getline(2))
3179 undo
3180 set cpo+=X
3181 normal 4gro
3182 call assert_equal('ooooecond line', getline(2))
3183 let &cpo = save_cpo
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003184 normal! ggvegrx
3185 call assert_equal('xxxxx line', getline(1))
3186 exe "normal! gggr\<C-V>122"
3187 call assert_equal('zxxxx line', getline(1))
3188 set virtualedit=all
3189 normal! 15|grl
3190 call assert_equal('zxxxx line l', getline(1))
3191 set virtualedit&
3192 set nomodifiable
3193 call assert_fails('normal! grx', 'E21:')
3194 call assert_fails('normal! gRx', 'E21:')
3195 set modifiable&
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003196 enew!
3197endfunc
3198
3199" When splitting a window the changelist position is wrong.
3200" Test the changelist position after splitting a window.
3201" Test for the bug fixed by 7.4.386
3202func Test_changelist()
3203 let save_ul = &ul
3204 enew!
3205 call append('$', ['1', '2'])
3206 exe "normal i\<C-G>u"
3207 exe "normal Gkylpa\<C-G>u"
3208 set ul=100
3209 exe "normal Gylpa\<C-G>u"
3210 set ul=100
3211 normal gg
3212 vsplit
3213 normal g;
3214 call assert_equal([3, 2], [line('.'), col('.')])
3215 normal g;
3216 call assert_equal([2, 2], [line('.'), col('.')])
3217 call assert_fails('normal g;', 'E662:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003218 new
3219 call assert_fails('normal g;', 'E664:')
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003220 %bwipe!
3221 let &ul = save_ul
3222endfunc
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003223
3224func Test_nv_hat_count()
3225 %bwipeout!
3226 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003227 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003228
3229 edit Xfoo
3230 let l:foo_nr = bufnr('Xfoo')
3231
3232 edit Xbar
3233 let l:bar_nr = bufnr('Xbar')
3234
3235 " Make sure we are not just using the alternate file.
3236 edit Xbaz
3237
3238 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3239 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3240
3241 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3242 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3243
3244 %bwipeout!
3245endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003246
3247func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003248 " Make sure no buffers are changed.
3249 %bwipe!
3250
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003251 exe "normal \<C-C>"
3252 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003253
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003254 new
3255 cal setline(1, 'hi!')
3256 exe "normal \<C-C>"
3257 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003258
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003259 bwipe!
3260endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003261
3262" Test for '[m', ']m', '[M' and ']M'
3263" Jumping to beginning and end of methods in Java-like languages
3264func Test_java_motion()
3265 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003266 call assert_beeps('normal! [m')
3267 call assert_beeps('normal! ]m')
3268 call assert_beeps('normal! [M')
3269 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003270 let lines =<< trim [CODE]
3271 Piece of Java
3272 {
3273 tt m1 {
3274 t1;
3275 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003276
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003277 tt m2 {
3278 t2;
3279 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003280
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003281 tt m3 {
3282 if (x)
3283 {
3284 t3;
3285 }
3286 } e3
3287 }
3288 [CODE]
3289 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003290
3291 normal gg
3292
3293 normal 2]maA
3294 call assert_equal("\ttt m1 {A", getline('.'))
3295 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3296
3297 normal j]maB
3298 call assert_equal("\ttt m2 {B", getline('.'))
3299 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3300
3301 normal ]maC
3302 call assert_equal("\ttt m3 {C", getline('.'))
3303 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3304
3305 normal [maD
3306 call assert_equal("\ttt m3 {DC", getline('.'))
3307 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3308
3309 normal k2[maE
3310 call assert_equal("\ttt m1 {EA", getline('.'))
3311 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3312
3313 normal 3[maF
3314 call assert_equal("{F", getline('.'))
3315 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3316
3317 normal ]MaG
3318 call assert_equal("\t}G e1", getline('.'))
3319 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3320
3321 normal j2]MaH
3322 call assert_equal("\t}H e3", getline('.'))
3323 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3324
3325 normal ]M]M
3326 normal aI
3327 call assert_equal("}I", getline('.'))
3328 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3329
3330 normal 2[MaJ
3331 call assert_equal("\t}JH e3", getline('.'))
3332 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3333
3334 normal k[MaK
3335 call assert_equal("\t}K e2", getline('.'))
3336 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3337
3338 normal 3[MaL
3339 call assert_equal("{LF", getline('.'))
3340 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3341
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003342 call cursor(2, 1)
3343 call assert_beeps('norm! 5]m')
3344
3345 " jumping to a method in a fold should open the fold
3346 6,10fold
3347 call feedkeys("gg3]m", 'xt')
3348 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3349 call assert_equal(-1, foldclosedend(7))
3350
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003351 close!
3352endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003353
Bram Moolenaar004a6782020-04-11 17:09:31 +02003354" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003355func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003356 call Setup_NewWindow()
3357 " Make long lines that will wrap
3358 %s/$/\=repeat(' foobar', 10)/
3359 20vsp
3360 set wrap
3361 " Test for g$ with count
3362 norm! gg
3363 norm! 0vg$y
3364 call assert_equal(20, col("'>"))
3365 call assert_equal('1 foobar foobar foob', getreg(0))
3366 norm! gg
3367 norm! 0v4g$y
3368 call assert_equal(72, col("'>"))
3369 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3370 norm! gg
3371 norm! 0v6g$y
3372 call assert_equal(40, col("'>"))
3373 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3374 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3375 set nowrap
3376 " clean up
3377 norm! gg
3378 norm! 0vg$y
3379 call assert_equal(20, col("'>"))
3380 call assert_equal('1 foobar foobar foob', getreg(0))
3381 norm! gg
3382 norm! 0v4g$y
3383 call assert_equal(20, col("'>"))
3384 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3385 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3386 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3387 \ '4 foobar foobar foob', getreg(0))
3388 norm! gg
3389 norm! 0v6g$y
3390 call assert_equal(20, col("'>"))
3391 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3392 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3393 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3394 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3395 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3396 \ '6 foobar foobar foob', getreg(0))
3397 " Move to last line, also down movement is not possible, should still move
3398 " the cursor to the last visible char
3399 norm! G
3400 norm! 0v6g$y
3401 call assert_equal(20, col("'>"))
3402 call assert_equal('100 foobar foobar fo', getreg(0))
3403 bw!
3404endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003405
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003406func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003407 " needs 80 column new window
3408 new
3409 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003410 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003411 put =[repeat('x',90)..' {{{1', 'x {{{1']
3412 norm! gk
3413 " In a 80 column wide terminal the window will be only 78 char
3414 " (because Vim will leave space for the other window),
3415 " but if the terminal is larger, it will be 80 chars, so verify the
3416 " cursor column correctly.
3417 call assert_equal(winwidth(0)+1, col('.'))
3418 call assert_equal(winwidth(0)+1, virtcol('.'))
3419 norm! j
3420 call assert_equal(6, col('.'))
3421 call assert_equal(6, virtcol('.'))
3422 norm! gk
3423 call assert_equal(95, col('.'))
3424 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003425 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003426
3427 " needs 80 column new window
3428 new
3429 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003430 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003431 set number
3432 set numberwidth=10
3433 set cpoptions+=n
3434 put =[repeat('0',90), repeat('1',90)]
3435 norm! 075l
3436 call assert_equal(76, col('.'))
3437 norm! gk
3438 call assert_equal(1, col('.'))
3439 norm! gk
3440 call assert_equal(76, col('.'))
3441 norm! gk
3442 call assert_equal(1, col('.'))
3443 norm! gj
3444 call assert_equal(76, col('.'))
3445 norm! gj
3446 call assert_equal(1, col('.'))
3447 norm! gj
3448 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003449 " When 'nowrap' is set, gk and gj behave like k and j
3450 set nowrap
3451 normal! gk
3452 call assert_equal([2, 76], [line('.'), col('.')])
3453 normal! gj
3454 call assert_equal([3, 76], [line('.'), col('.')])
3455 %bw!
3456 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003457endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003458
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003459" Test for using : to run a multi-line Ex command in operator pending mode
3460func Test_normal_yank_with_excmd()
3461 new
3462 call setline(1, ['foo', 'bar', 'baz'])
3463 let @a = ''
3464 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3465 call assert_equal('f', @a)
3466 close!
3467endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003468
3469" Test for supplying a count to a normal-mode command across a cursorhold call
3470func Test_normal_cursorhold_with_count()
3471 func s:cHold()
3472 let g:cHold_Called += 1
3473 endfunc
3474 new
3475 augroup normalcHoldTest
3476 au!
3477 au CursorHold <buffer> call s:cHold()
3478 augroup END
3479 let g:cHold_Called = 0
3480 call feedkeys("3\<CursorHold>2ix", 'xt')
3481 call assert_equal(1, g:cHold_Called)
3482 call assert_equal(repeat('x', 32), getline(1))
3483 augroup normalcHoldTest
3484 au!
3485 augroup END
3486 au! normalcHoldTest
3487 close!
3488 delfunc s:cHold
3489endfunc
3490
3491" Test for using a count and a command with CTRL-W
3492func Test_wincmd_with_count()
3493 call feedkeys("\<C-W>12n", 'xt')
3494 call assert_equal(12, winheight(0))
3495endfunc
3496
3497" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003498func Test_horiz_motion()
3499 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003500 normal! gg
3501 call assert_beeps('normal! b')
3502 call assert_beeps('normal! B')
3503 call assert_beeps('normal! gE')
3504 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003505 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3506 call setline(1, 'one ,two ,three')
3507 exe "normal! $\<S-BS>"
3508 call assert_equal(11, col('.'))
3509 exe "normal! $\<C-BS>"
3510 call assert_equal(10, col('.'))
3511 close!
3512endfunc
3513
3514" Test for using a : command in operator pending mode
3515func Test_normal_colon_op()
3516 new
3517 call setline(1, ['one', 'two'])
3518 call assert_beeps("normal! Gc:d\<CR>")
3519 close!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003520endfunc
3521
Bram Moolenaar004a6782020-04-11 17:09:31 +02003522" Test for d and D commands
3523func Test_normal_delete_cmd()
3524 new
3525 " D in an empty line
3526 call setline(1, '')
3527 normal D
3528 call assert_equal('', getline(1))
3529 " D in an empty line in virtualedit mode
3530 set virtualedit=all
3531 normal D
3532 call assert_equal('', getline(1))
3533 set virtualedit&
3534 " delete to a readonly register
3535 call setline(1, ['abcd'])
3536 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003537
3538 " D and d with 'nomodifiable'
3539 call setline(1, ['abcd'])
3540 setlocal nomodifiable
3541 call assert_fails('normal D', 'E21:')
3542 call assert_fails('normal d$', 'E21:')
3543
Bram Moolenaar004a6782020-04-11 17:09:31 +02003544 close!
3545endfunc
3546
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003547" Test for deleting or changing characters across lines with 'whichwrap'
3548" containing 's'. Should count <EOL> as one character.
3549func Test_normal_op_across_lines()
3550 new
3551 set whichwrap&
3552 call setline(1, ['one two', 'three four'])
3553 exe "norm! $3d\<Space>"
3554 call assert_equal(['one twhree four'], getline(1, '$'))
3555
3556 call setline(1, ['one two', 'three four'])
3557 exe "norm! $3c\<Space>x"
3558 call assert_equal(['one twxhree four'], getline(1, '$'))
3559
3560 set whichwrap+=l
3561 call setline(1, ['one two', 'three four'])
3562 exe "norm! $3x"
3563 call assert_equal(['one twhree four'], getline(1, '$'))
3564 close!
3565 set whichwrap&
3566endfunc
3567
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003568" Test for 'w' and 'b' commands
3569func Test_normal_word_move()
3570 new
3571 call setline(1, ['foo bar a', '', 'foo bar b'])
3572 " copy a single character word at the end of a line
3573 normal 1G$yw
3574 call assert_equal('a', @")
3575 " copy a single character word at the end of a file
3576 normal G$yw
3577 call assert_equal('b', @")
3578 " check for a word movement handling an empty line properly
3579 normal 1G$vwy
3580 call assert_equal("a\n\n", @")
3581
3582 " copy using 'b' command
3583 %d
3584 " non-empty blank line at the start of file
3585 call setline(1, [' ', 'foo bar'])
3586 normal 2Gyb
3587 call assert_equal(" \n", @")
3588 " try to copy backwards from the start of the file
3589 call setline(1, ['one two', 'foo bar'])
3590 call assert_beeps('normal ggyb')
3591 " 'b' command should stop at an empty line
3592 call setline(1, ['one two', '', 'foo bar'])
3593 normal 3Gyb
3594 call assert_equal("\n", @")
3595 normal 3Gy2b
3596 call assert_equal("two\n", @")
3597 " 'b' command should not stop at a non-empty blank line
3598 call setline(1, ['one two', ' ', 'foo bar'])
3599 normal 3Gyb
3600 call assert_equal("two\n ", @")
3601
3602 close!
3603endfunc
3604
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003605" Test for 'scrolloff' with a long line that doesn't fit in the screen
3606func Test_normal_scroloff()
3607 10new
3608 80vnew
3609 call setline(1, repeat('a', 1000))
3610 set scrolloff=10
3611 normal gg10gj
3612 call assert_equal(8, winline())
3613 normal 10gj
3614 call assert_equal(10, winline())
3615 normal 10gk
3616 call assert_equal(3, winline())
3617 set scrolloff&
3618 close!
3619endfunc
3620
3621" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3622func Test_normal_vert_scroll_longline()
3623 10new
3624 80vnew
3625 call setline(1, range(1, 10))
3626 call append(5, repeat('a', 1000))
3627 exe "normal gg\<C-F>"
3628 call assert_equal(6, line('.'))
3629 exe "normal \<C-F>\<C-F>"
3630 call assert_equal(11, line('.'))
3631 call assert_equal(1, winline())
3632 exe "normal \<C-B>"
3633 call assert_equal(10, line('.'))
3634 call assert_equal(3, winline())
3635 exe "normal \<C-B>\<C-B>"
3636 call assert_equal(5, line('.'))
3637 call assert_equal(5, winline())
3638 close!
3639endfunc
3640
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003641" Test for jumping in a file using %
3642func Test_normal_percent_jump()
3643 new
3644 call setline(1, range(1, 100))
3645
3646 " jumping to a folded line should open the fold
3647 25,75fold
3648 call feedkeys('50%', 'xt')
3649 call assert_equal(50, line('.'))
3650 call assert_equal(-1, foldclosedend(50))
3651 close!
3652endfunc
3653
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003654" Test for << and >> commands to shift text by 'shiftwidth'
3655func Test_normal_shift_rightleft()
3656 new
3657 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3658 set shiftwidth=2 tabstop=8
3659 normal gg6>>
3660 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3661 \ getline(1, '$'))
3662 normal ggVG2>>
3663 call assert_equal([' one', '', "\t ", "\ttwo",
3664 \ "\t three", "\t four"], getline(1, '$'))
3665 normal gg6<<
3666 call assert_equal([' one', '', "\t ", ' two', "\t three",
3667 \ "\t four"], getline(1, '$'))
3668 normal ggVG2<<
3669 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3670 \ getline(1, '$'))
3671 set shiftwidth& tabstop&
3672 bw!
3673endfunc
3674
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003675" Some commands like yy, cc, dd, >>, << and !! accept a count after
3676" typing the first letter of the command.
3677func Test_normal_count_after_operator()
3678 new
3679 setlocal shiftwidth=4 tabstop=8 autoindent
3680 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3681 let @a = ''
3682 normal! j"ay4y
3683 call assert_equal("two\nthree\nfour\nfive\n", @a)
3684 normal! 3G>2>
3685 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3686 \ getline(1, '$'))
3687 exe "normal! 3G0c2cred\nblue"
3688 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3689 \ getline(1, '$'))
3690 exe "normal! gg<8<"
3691 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3692 \ getline(1, '$'))
3693 exe "normal! ggd3d"
3694 call assert_equal(['blue', 'five'], getline(1, '$'))
3695 call setline(1, range(1, 4))
3696 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3697 call assert_equal('".,.+2!', @:)
3698 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3699 call assert_equal('".!', @:)
3700 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3701 call assert_equal('".,$!', @:)
3702 bw!
3703endfunc
3704
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003705func Test_normal_gj_on_extra_wide_char()
3706 new | 25vsp
3707 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3708 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3709 \ ' dreizehn v ierzehn fünfzehn'
3710 put =text
3711 call cursor(2,1)
3712 norm! gj
3713 call assert_equal([0,2,25,0], getpos('.'))
3714 bw!
3715endfunc
3716
Bram Moolenaar03725c52021-11-24 12:17:53 +00003717func Test_normal_count_out_of_range()
3718 new
3719 call setline(1, 'text')
3720 normal 44444444444|
3721 call assert_equal(999999999, v:count)
3722 normal 444444444444|
3723 call assert_equal(999999999, v:count)
3724 normal 4444444444444|
3725 call assert_equal(999999999, v:count)
3726 normal 4444444444444444444|
3727 call assert_equal(999999999, v:count)
3728
3729 normal 9y99999999|
3730 call assert_equal(899999991, v:count)
3731 normal 10y99999999|
3732 call assert_equal(999999999, v:count)
3733 normal 44444444444y44444444444|
3734 call assert_equal(999999999, v:count)
3735 bwipe!
3736endfunc
3737
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003738" vim: shiftwidth=2 sts=2 expandtab