blob: 4a09964e970b61e5e3c84da5e9f5d9a00a77e49b [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
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000467func Underscorize(_)
468 normal! '[V']r_
469endfunc
470
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000471func Test_normal09c_operatorfunc()
472 " Test redoing operatorfunc
473 new
474 call setline(1, 'some text')
475 set operatorfunc=OperatorfuncRedo
476 normal v3g@
477 call assert_equal(3, g:opfunc_count)
478 let g:opfunc_count = 0
479 normal .
480 call assert_equal(3, g:opfunc_count)
481
482 bw!
483 unlet g:opfunc_count
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000484
485 " Test redoing Visual mode
486 set operatorfunc=Underscorize
487 new
488 call setline(1, ['first', 'first', 'third', 'third', 'second'])
naohiro ono5c75eed2022-01-03 11:15:47 +0000489 normal! 1GVjg@
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000490 normal! 5G.
491 normal! 3G.
492 call assert_equal(['_____', '_____', '_____', '_____', '______'], getline(1, '$'))
493 bwipe!
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000494 set operatorfunc=
495endfunc
496
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000497" Test for different ways of setting the 'operatorfunc' option
498func Test_opfunc_callback()
499 new
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000500 func OpFunc1(callnr, type)
501 let g:OpFunc1Args = [a:callnr, a:type]
502 endfunc
503 func OpFunc2(type)
504 let g:OpFunc2Args = [a:type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000505 endfunc
506
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000507 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000508 #" Test for using a function name
509 LET &opfunc = 'g:OpFunc2'
510 LET g:OpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000511 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000512 call assert_equal(['char'], g:OpFunc2Args)
513
514 #" Test for using a function()
515 set opfunc=function('g:OpFunc1',\ [10])
516 LET g:OpFunc1Args = []
517 normal! g@l
518 call assert_equal([10, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000519
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000520 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000521 VAR Fn = function('g:OpFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000522 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000523 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000524 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000525 call assert_equal([11, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000526
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000527 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000528 LET Fn = function('g:OpFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000529 LET &operatorfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000530 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000531 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000532 call assert_equal([12, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000533
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000534 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000535 set operatorfunc=funcref('g:OpFunc1',\ [13])
536 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000537 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000538 call assert_equal([13, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000539
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000540 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000541 LET Fn = funcref('g:OpFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000542 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000543 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000544 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000545 call assert_equal([14, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000546
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000547 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000548 LET Fn = funcref('g:OpFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000549 LET &opfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000550 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000551 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000552 call assert_equal([15, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000553
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000554 #" Test for using a lambda function using set
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000555 VAR optval = "LSTART a LMIDDLE OpFunc1(16, a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000556 LET optval = substitute(optval, ' ', '\\ ', 'g')
557 exe "set opfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000558 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000559 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000560 call assert_equal([16, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000561
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000562 #" Test for using a lambda function using LET
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000563 LET &opfunc = LSTART a LMIDDLE OpFunc1(17, a) LEND
564 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000565 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000566 call assert_equal([17, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000567
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000568 #" Set 'operatorfunc' to a string(lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000569 LET &opfunc = 'LSTART a LMIDDLE OpFunc1(18, a) LEND'
570 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000571 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000572 call assert_equal([18, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000573
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000574 #" Set 'operatorfunc' to a variable with a lambda expression
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000575 VAR Lambda = LSTART a LMIDDLE OpFunc1(19, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000576 LET &opfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000577 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000578 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000579 call assert_equal([19, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000580
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000581 #" Set 'operatorfunc' to a string(variable with a lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000582 LET Lambda = LSTART a LMIDDLE OpFunc1(20, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000583 LET &opfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000584 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000585 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000586 call assert_equal([20, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000587
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000588 #" Try to use 'operatorfunc' after the function is deleted
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000589 func g:TmpOpFunc1(type)
590 let g:TmpOpFunc1Args = [21, a:type]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000591 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000592 LET &opfunc = function('g:TmpOpFunc1')
593 delfunc g:TmpOpFunc1
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000594 call test_garbagecollect_now()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000595 LET g:TmpOpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000596 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000597 call assert_equal([], g:TmpOpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000598
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000599 #" Try to use a function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000600 func g:TmpOpFunc2(x, y)
601 let g:TmpOpFunc2Args = [a:x, a:y]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000602 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000603 set opfunc=TmpOpFunc2
604 LET g:TmpOpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000605 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000606 call assert_equal([], g:TmpOpFunc2Args)
607 delfunc TmpOpFunc2
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000608
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000609 #" Try to use a lambda function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000610 LET &opfunc = LSTART a, b LMIDDLE OpFunc1(22, b) LEND
611 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000612 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000613 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000614
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000615 #" Test for clearing the 'operatorfunc' option
616 set opfunc=''
617 set opfunc&
618 call assert_fails("set opfunc=function('abc')", "E700:")
619 call assert_fails("set opfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000620
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000621 #" set 'operatorfunc' to a non-existing function
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000622 LET &opfunc = function('g:OpFunc1', [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000623 call assert_fails("set opfunc=function('NonExistingFunc')", 'E700:')
624 call assert_fails("LET &opfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000625 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000626 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000627 call assert_equal([23, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000628 END
629 call CheckTransLegacySuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000630
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000631 " Test for using a script-local function name
632 func s:OpFunc3(type)
633 let g:OpFunc3Args = [a:type]
634 endfunc
635 set opfunc=s:OpFunc3
636 let g:OpFunc3Args = []
637 normal! g@l
638 call assert_equal(['char'], g:OpFunc3Args)
639
640 let &opfunc = 's:OpFunc3'
641 let g:OpFunc3Args = []
642 normal! g@l
643 call assert_equal(['char'], g:OpFunc3Args)
644 delfunc s:OpFunc3
645
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000646 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000647 set opfunc=(a)\ =>\ OpFunc1(24,\ a)
648 let g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000649 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000650 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000651
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000652 " set 'operatorfunc' to a partial with dict. This used to cause a crash.
653 func SetOpFunc()
654 let operator = {'execute': function('OperatorExecute')}
655 let &opfunc = operator.execute
656 endfunc
657 func OperatorExecute(_) dict
658 endfunc
659 call SetOpFunc()
660 call test_garbagecollect_now()
661 set operatorfunc=
662 delfunc SetOpFunc
663 delfunc OperatorExecute
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000664
665 " Vim9 tests
666 let lines =<< trim END
667 vim9script
668
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000669 def g:Vim9opFunc(val: number, type: string): void
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000670 g:OpFunc1Args = [val, type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000671 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000672
673 # Test for using a def function with opfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000674 set opfunc=function('g:Vim9opFunc',\ [60])
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000675 g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000676 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000677 assert_equal([60, 'char'], g:OpFunc1Args)
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000678
679 # Test for using a global function name
680 &opfunc = g:OpFunc2
681 g:OpFunc2Args = []
682 normal! g@l
683 assert_equal(['char'], g:OpFunc2Args)
684 bw!
685
686 # Test for using a script-local function name
687 def s:LocalOpFunc(type: string): void
688 g:LocalOpFuncArgs = [type]
689 enddef
690 &opfunc = s:LocalOpFunc
691 g:LocalOpFuncArgs = []
692 normal! g@l
693 assert_equal(['char'], g:LocalOpFuncArgs)
694 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000695 END
696 call CheckScriptSuccess(lines)
697
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000698 " setting 'opfunc' to a script local function outside of a script context
699 " should fail
700 let cleanup =<< trim END
701 call writefile([execute('messages')], 'Xtest.out')
702 qall
703 END
704 call writefile(cleanup, 'Xverify.vim')
705 call RunVim([], [], "-c \"set opfunc=s:abc\" -S Xverify.vim")
706 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
707 call delete('Xtest.out')
708 call delete('Xverify.vim')
709
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000710 " cleanup
711 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000712 delfunc OpFunc1
713 delfunc OpFunc2
714 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000715 %bw!
716endfunc
717
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100718func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200719 " Test for expand()
720 10new
721 call setline(1, ['1', 'ifooar,,cbar'])
722 2
723 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200724 call assert_equal('cbar', expand('<cword>'))
725 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
726
727 call setline(1, ['prx = list[idx];'])
728 1
729 let expected = ['', 'prx', 'prx', 'prx',
730 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
731 \ 'idx', 'idx', 'idx', 'idx',
732 \ 'list[idx]',
733 \ '];',
734 \ ]
735 for i in range(1, 16)
736 exe 'norm ' . i . '|'
737 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
738 endfor
739
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200740 " Test for <cexpr> in state.val and ptr->val
741 call setline(1, 'x = state.val;')
742 call cursor(1, 10)
743 call assert_equal('state.val', expand('<cexpr>'))
744 call setline(1, 'x = ptr->val;')
745 call cursor(1, 9)
746 call assert_equal('ptr->val', expand('<cexpr>'))
747
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100748 if executable('echo')
749 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100750 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100751 endif
752
753 " Test expand(`=...`) i.e. backticks expression expansion
754 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100755 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100756
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200757 " clean up
758 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200759endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200760
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200761" Test for expand() in latin1 encoding
762func Test_normal_expand_latin1()
763 new
764 let save_enc = &encoding
765 set encoding=latin1
766 call setline(1, 'val = item->color;')
767 call cursor(1, 11)
768 call assert_equal('color', expand("<cword>"))
769 call assert_equal('item->color', expand("<cexpr>"))
770 let &encoding = save_enc
771 bw!
772endfunc
773
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100774func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200775 " test for 'showcmd'
776 10new
777 exe "norm! ofoobar\<esc>"
778 call assert_equal(2, line('$'))
779 set showcmd
780 exe "norm! ofoobar2\<esc>"
781 call assert_equal(3, line('$'))
782 exe "norm! VAfoobar3\<esc>"
783 call assert_equal(3, line('$'))
784 exe "norm! 0d3\<del>2l"
785 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200786 " test for the visual block size displayed in the status line
787 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
788 call feedkeys("ggl\<C-V>lljj", 'xt')
789 redraw!
790 call assert_match('3x3$', Screenline(&lines))
791 call feedkeys("\<C-V>", 'xt')
792 " test for visually selecting a multi-byte character
793 call setline(1, ["\U2206"])
794 call feedkeys("ggv", 'xt')
795 redraw!
796 call assert_match('1-3$', Screenline(&lines))
797 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200798 " test for visually selecting the end of line
799 call setline(1, ["foobar"])
800 call feedkeys("$vl", 'xt')
801 redraw!
802 call assert_match('2$', Screenline(&lines))
803 call feedkeys("y", 'xt')
804 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200805 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200806endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200807
Bram Moolenaar1671f442020-03-10 07:48:13 +0100808" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100809func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200810 10new
811 call setline(1, range(1,5))
812 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100813 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200814 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100815 call assert_beeps('normal! G2dd')
816 call assert_beeps("normal! g\<C-A>")
817 call assert_beeps("normal! g\<C-X>")
818 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100819 call assert_beeps("normal! vQ\<Esc>")
820 call assert_beeps("normal! 2[[")
821 call assert_beeps("normal! 2]]")
822 call assert_beeps("normal! 2[]")
823 call assert_beeps("normal! 2][")
824 call assert_beeps("normal! 4[z")
825 call assert_beeps("normal! 4]z")
826 call assert_beeps("normal! 4[c")
827 call assert_beeps("normal! 4]c")
828 call assert_beeps("normal! 200%")
829 call assert_beeps("normal! %")
830 call assert_beeps("normal! 2{")
831 call assert_beeps("normal! 2}")
832 call assert_beeps("normal! r\<Right>")
833 call assert_beeps("normal! 8ry")
834 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200835 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200836endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200837
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100838func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200839 " Test for F1
840 call assert_equal(1, winnr())
841 call feedkeys("\<f1>", 'txi')
842 call assert_match('help\.txt', bufname('%'))
843 call assert_equal(2, winnr('$'))
844 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200845endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200846
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100847func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200848 " basic test for Ctrl-F and Ctrl-B
849 call Setup_NewWindow()
850 exe "norm! \<c-f>"
851 call assert_equal('9', getline('.'))
852 exe "norm! 2\<c-f>"
853 call assert_equal('25', getline('.'))
854 exe "norm! 2\<c-b>"
855 call assert_equal('18', getline('.'))
856 1
857 set scrolloff=5
858 exe "norm! 2\<c-f>"
859 call assert_equal('21', getline('.'))
860 exe "norm! \<c-b>"
861 call assert_equal('13', getline('.'))
862 1
863 set scrolloff=99
864 exe "norm! \<c-f>"
865 call assert_equal('13', getline('.'))
866 set scrolloff=0
867 100
868 exe "norm! $\<c-b>"
869 call assert_equal('92', getline('.'))
870 call assert_equal([0, 92, 1, 0, 1], getcurpos())
871 100
872 set nostartofline
873 exe "norm! $\<c-b>"
874 call assert_equal('92', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +0000875 call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200876 " cleanup
877 set startofline
878 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200879endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200880
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100881func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200882 10new
883 norm oxxxxxxx
884 exe "norm 2\<c-f>"
885 " check with valgrind that cursor is put back in column 1
886 exe "norm 2\<c-b>"
887 bw!
888endfunc
889
Bram Moolenaar1671f442020-03-10 07:48:13 +0100890" Test for errors with z command
891func Test_normal_z_error()
892 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200893 call assert_beeps('normal! zq')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100894endfunc
895
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100896func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200897 " basic test for z commands that scroll the window
898 call Setup_NewWindow()
899 100
900 norm! >>
901 " Test for z<cr>
902 exe "norm! z\<cr>"
903 call assert_equal(' 100', getline('.'))
904 call assert_equal(100, winsaveview()['topline'])
905 call assert_equal([0, 100, 2, 0, 9], getcurpos())
906
907 " Test for zt
908 21
909 norm! >>0zt
910 call assert_equal(' 21', getline('.'))
911 call assert_equal(21, winsaveview()['topline'])
912 call assert_equal([0, 21, 1, 0, 8], getcurpos())
913
914 " Test for zb
915 30
916 norm! >>$ztzb
917 call assert_equal(' 30', getline('.'))
918 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
naohiro ono56200ee2022-01-01 14:59:44 +0000919 call assert_equal([0, 30, 3, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200920
921 " Test for z-
922 1
923 30
924 norm! 0z-
925 call assert_equal(' 30', getline('.'))
926 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
927 call assert_equal([0, 30, 2, 0, 9], getcurpos())
928
929 " Test for z{height}<cr>
930 call assert_equal(10, winheight(0))
931 exe "norm! z12\<cr>"
932 call assert_equal(12, winheight(0))
933 exe "norm! z10\<cr>"
934 call assert_equal(10, winheight(0))
935
936 " Test for z.
937 1
938 21
939 norm! 0z.
940 call assert_equal(' 21', getline('.'))
941 call assert_equal(17, winsaveview()['topline'])
942 call assert_equal([0, 21, 2, 0, 9], getcurpos())
943
944 " Test for zz
945 1
946 21
947 norm! 0zz
948 call assert_equal(' 21', getline('.'))
949 call assert_equal(17, winsaveview()['topline'])
950 call assert_equal([0, 21, 1, 0, 8], getcurpos())
951
952 " Test for z+
953 11
954 norm! zt
955 norm! z+
956 call assert_equal(' 21', getline('.'))
957 call assert_equal(21, winsaveview()['topline'])
958 call assert_equal([0, 21, 2, 0, 9], getcurpos())
959
960 " Test for [count]z+
961 1
962 norm! 21z+
963 call assert_equal(' 21', getline('.'))
964 call assert_equal(21, winsaveview()['topline'])
965 call assert_equal([0, 21, 2, 0, 9], getcurpos())
966
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200967 " Test for z+ with [count] greater than buffer size
968 1
969 norm! 1000z+
970 call assert_equal(' 100', getline('.'))
971 call assert_equal(100, winsaveview()['topline'])
972 call assert_equal([0, 100, 2, 0, 9], getcurpos())
973
974 " Test for z+ from the last buffer line
975 norm! Gz.z+
976 call assert_equal(' 100', getline('.'))
977 call assert_equal(100, winsaveview()['topline'])
978 call assert_equal([0, 100, 2, 0, 9], getcurpos())
979
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200980 " Test for z^
981 norm! 22z+0
982 norm! z^
983 call assert_equal(' 21', getline('.'))
984 call assert_equal(12, winsaveview()['topline'])
985 call assert_equal([0, 21, 2, 0, 9], getcurpos())
986
Bram Moolenaar8a9bc952020-10-02 18:48:07 +0200987 " Test for z^ from first buffer line
988 norm! ggz^
989 call assert_equal('1', getline('.'))
990 call assert_equal(1, winsaveview()['topline'])
991 call assert_equal([0, 1, 1, 0, 1], getcurpos())
992
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200993 " Test for [count]z^
994 1
995 norm! 30z^
996 call assert_equal(' 21', getline('.'))
997 call assert_equal(12, winsaveview()['topline'])
998 call assert_equal([0, 21, 2, 0, 9], getcurpos())
999
1000 " cleanup
1001 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001002endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001003
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001004func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001005 " basic test for z commands that scroll the window
1006 10new
1007 15vsp
1008 set nowrap listchars=
1009 let lineA='abcdefghijklmnopqrstuvwxyz'
1010 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1011 $put =lineA
1012 $put =lineB
1013 1d
1014
Bram Moolenaar1671f442020-03-10 07:48:13 +01001015 " Test for zl and zh with a count
1016 norm! 0z10l
1017 call assert_equal([11, 1], [col('.'), wincol()])
1018 norm! z4h
1019 call assert_equal([11, 5], [col('.'), wincol()])
1020 normal! 2gg
1021
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001022 " Test for zl
1023 1
1024 norm! 5zl
1025 call assert_equal(lineA, getline('.'))
1026 call assert_equal(6, col('.'))
1027 call assert_equal(5, winsaveview()['leftcol'])
1028 norm! yl
1029 call assert_equal('f', @0)
1030
1031 " Test for zh
1032 norm! 2zh
1033 call assert_equal(lineA, getline('.'))
1034 call assert_equal(6, col('.'))
1035 norm! yl
1036 call assert_equal('f', @0)
1037 call assert_equal(3, winsaveview()['leftcol'])
1038
1039 " Test for zL
1040 norm! zL
1041 call assert_equal(11, col('.'))
1042 norm! yl
1043 call assert_equal('k', @0)
1044 call assert_equal(10, winsaveview()['leftcol'])
1045 norm! 2zL
1046 call assert_equal(25, col('.'))
1047 norm! yl
1048 call assert_equal('y', @0)
1049 call assert_equal(24, winsaveview()['leftcol'])
1050
1051 " Test for zH
1052 norm! 2zH
1053 call assert_equal(25, col('.'))
1054 call assert_equal(10, winsaveview()['leftcol'])
1055 norm! yl
1056 call assert_equal('y', @0)
1057
1058 " Test for zs
1059 norm! $zs
1060 call assert_equal(26, col('.'))
1061 call assert_equal(25, winsaveview()['leftcol'])
1062 norm! yl
1063 call assert_equal('z', @0)
1064
1065 " Test for ze
1066 norm! ze
1067 call assert_equal(26, col('.'))
1068 call assert_equal(11, winsaveview()['leftcol'])
1069 norm! yl
1070 call assert_equal('z', @0)
1071
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001072 " Test for zs and ze with folds
1073 %fold
1074 norm! $zs
1075 call assert_equal(26, col('.'))
1076 call assert_equal(0, winsaveview()['leftcol'])
1077 norm! yl
1078 call assert_equal('z', @0)
1079 norm! ze
1080 call assert_equal(26, col('.'))
1081 call assert_equal(0, winsaveview()['leftcol'])
1082 norm! yl
1083 call assert_equal('z', @0)
1084
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001085 " cleanup
1086 set wrap listchars=eol:$
1087 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001088endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001089
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001090func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001091 " basic test for z commands that scroll the window
1092 " using 'sidescrolloff' setting
1093 10new
1094 20vsp
1095 set nowrap listchars= sidescrolloff=5
1096 let lineA='abcdefghijklmnopqrstuvwxyz'
1097 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1098 $put =lineA
1099 $put =lineB
1100 1d
1101
1102 " Test for zl
1103 1
1104 norm! 5zl
1105 call assert_equal(lineA, getline('.'))
1106 call assert_equal(11, col('.'))
1107 call assert_equal(5, winsaveview()['leftcol'])
1108 norm! yl
1109 call assert_equal('k', @0)
1110
1111 " Test for zh
1112 norm! 2zh
1113 call assert_equal(lineA, getline('.'))
1114 call assert_equal(11, col('.'))
1115 norm! yl
1116 call assert_equal('k', @0)
1117 call assert_equal(3, winsaveview()['leftcol'])
1118
1119 " Test for zL
1120 norm! 0zL
1121 call assert_equal(16, col('.'))
1122 norm! yl
1123 call assert_equal('p', @0)
1124 call assert_equal(10, winsaveview()['leftcol'])
1125 norm! 2zL
1126 call assert_equal(26, col('.'))
1127 norm! yl
1128 call assert_equal('z', @0)
1129 call assert_equal(15, winsaveview()['leftcol'])
1130
1131 " Test for zH
1132 norm! 2zH
1133 call assert_equal(15, col('.'))
1134 call assert_equal(0, winsaveview()['leftcol'])
1135 norm! yl
1136 call assert_equal('o', @0)
1137
1138 " Test for zs
1139 norm! $zs
1140 call assert_equal(26, col('.'))
1141 call assert_equal(20, winsaveview()['leftcol'])
1142 norm! yl
1143 call assert_equal('z', @0)
1144
1145 " Test for ze
1146 norm! ze
1147 call assert_equal(26, col('.'))
1148 call assert_equal(11, winsaveview()['leftcol'])
1149 norm! yl
1150 call assert_equal('z', @0)
1151
1152 " cleanup
1153 set wrap listchars=eol:$ sidescrolloff=0
1154 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001155endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001156
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001157" Test for commands that scroll the window horizontally. Test with folds.
1158" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1159func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001160 15new
1161 call setline(1, range(1, 100))
1162 exe "normal! 30ggz\<CR>"
1163 set foldenable
1164 33,36fold
1165 40,43fold
1166 46,49fold
1167 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001168
1169 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001170 " Top of the screen = 30
1171 " Folded lines = 9
1172 " Bottom of the screen = 30 + h + 9 - 1
1173 normal! 4L
1174 call assert_equal(35 + h, line('.'))
1175 normal! 4H
1176 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001177
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001178 " Test for using a large count value
1179 %d
1180 call setline(1, range(1, 4))
1181 norm! 6H
1182 call assert_equal(4, line('.'))
1183
1184 " Test for 'M' with folded lines
1185 %d
1186 call setline(1, range(1, 20))
1187 1,5fold
1188 norm! LM
1189 call assert_equal(12, line('.'))
1190
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001191 " Test for the CTRL-E and CTRL-Y commands with folds
1192 %d
1193 call setline(1, range(1, 10))
1194 3,5fold
1195 exe "normal 6G3\<C-E>"
1196 call assert_equal(6, line('w0'))
1197 exe "normal 2\<C-Y>"
1198 call assert_equal(2, line('w0'))
1199
1200 " Test for CTRL-Y on a folded line
1201 %d
1202 call setline(1, range(1, 100))
1203 exe (h + 2) .. "," .. (h + 4) .. "fold"
1204 exe h + 5
1205 normal z-
1206 exe "normal \<C-Y>\<C-Y>"
1207 call assert_equal(h + 1, line('w$'))
1208
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001209 " Test for CTRL-Y from the first line and CTRL-E from the last line
1210 %d
1211 set scrolloff=2
1212 call setline(1, range(1, 4))
1213 exe "normal gg\<C-Y>"
1214 call assert_equal(1, line('w0'))
1215 call assert_equal(1, line('.'))
1216 exe "normal G4\<C-E>\<C-E>"
1217 call assert_equal(4, line('w$'))
1218 call assert_equal(4, line('.'))
1219 set scrolloff&
1220
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001221 " Using <PageUp> and <PageDown> in an empty buffer should beep
1222 %d
1223 call assert_beeps('exe "normal \<PageUp>"')
1224 call assert_beeps('exe "normal \<C-B>"')
1225 call assert_beeps('exe "normal \<PageDown>"')
1226 call assert_beeps('exe "normal \<C-F>"')
1227
1228 " Test for <C-U> and <C-D> with fold
1229 %d
1230 call setline(1, range(1, 100))
1231 10,35fold
1232 set scroll=10
1233 exe "normal \<C-D>"
1234 call assert_equal(36, line('.'))
1235 exe "normal \<C-D>"
1236 call assert_equal(46, line('.'))
1237 exe "normal \<C-U>"
1238 call assert_equal(36, line('.'))
1239 exe "normal \<C-U>"
1240 call assert_equal(10, line('.'))
1241 exe "normal \<C-U>"
1242 call assert_equal(1, line('.'))
1243 set scroll&
1244
1245 " Test for scrolling to the top of the file with <C-U> and a fold
1246 10
1247 normal ztL
1248 exe "normal \<C-U>\<C-U>"
1249 call assert_equal(1, line('w0'))
1250
1251 " Test for CTRL-D on a folded line
1252 %d
1253 call setline(1, range(1, 100))
1254 50,100fold
1255 75
1256 normal z-
1257 exe "normal \<C-D>"
1258 call assert_equal(50, line('.'))
1259 call assert_equal(100, line('w$'))
1260 normal z.
1261 let lnum = winline()
1262 exe "normal \<C-D>"
1263 call assert_equal(lnum, winline())
1264 call assert_equal(50, line('.'))
1265 normal zt
1266 exe "normal \<C-D>"
1267 call assert_equal(50, line('w0'))
1268
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001269 " Test for <S-CR>. Page down.
1270 %d
1271 call setline(1, range(1, 100))
1272 call feedkeys("\<S-CR>", 'xt')
1273 call assert_equal(14, line('w0'))
1274 call assert_equal(28, line('w$'))
1275
1276 " Test for <S-->. Page up.
1277 call feedkeys("\<S-->", 'xt')
1278 call assert_equal(1, line('w0'))
1279 call assert_equal(15, line('w$'))
1280
Bram Moolenaar1671f442020-03-10 07:48:13 +01001281 set foldenable&
1282 close!
1283endfunc
1284
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001285func Test_scroll_in_ex_mode()
1286 " This was using invalid memory because w_botline was invalid.
1287 let lines =<< trim END
1288 diffsplit
1289 norm os00(
1290 call writefile(['done'], 'Xdone')
1291 qa!
1292 END
1293 call writefile(lines, 'Xscript')
1294 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1295 call assert_equal(['done'], readfile('Xdone'))
1296
1297 call delete('Xscript')
1298 call delete('Xdone')
1299endfunc
1300
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001301" Test for the 'sidescroll' option
1302func Test_sidescroll_opt()
1303 new
1304 20vnew
1305
1306 " scroll by 2 characters horizontally
1307 set sidescroll=2 nowrap
1308 call setline(1, repeat('a', 40))
1309 normal g$l
1310 call assert_equal(19, screenpos(0, 1, 21).col)
1311 normal l
1312 call assert_equal(20, screenpos(0, 1, 22).col)
1313 normal g0h
1314 call assert_equal(2, screenpos(0, 1, 2).col)
1315 call assert_equal(20, screenpos(0, 1, 20).col)
1316
1317 " when 'sidescroll' is 0, cursor positioned at the center
1318 set sidescroll=0
1319 normal g$l
1320 call assert_equal(11, screenpos(0, 1, 21).col)
1321 normal g0h
1322 call assert_equal(10, screenpos(0, 1, 10).col)
1323
1324 %bw!
1325 set wrap& sidescroll&
1326endfunc
1327
Bram Moolenaar004a6782020-04-11 17:09:31 +02001328" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001329func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001330 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001331 call Setup_NewWindow()
1332 50
1333 setl foldenable fdm=marker foldlevel=5
1334
Bram Moolenaar1671f442020-03-10 07:48:13 +01001335 call assert_beeps('normal! zj')
1336 call assert_beeps('normal! zk')
1337
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001338 " Test for zF
1339 " First fold
1340 norm! 4zF
1341 " check that folds have been created
1342 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1343
1344 " Test for zd
1345 51
1346 norm! 2zF
1347 call assert_equal(2, foldlevel('.'))
1348 norm! kzd
1349 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1350 norm! j
1351 call assert_equal(1, foldlevel('.'))
1352
1353 " Test for zD
1354 " also deletes partially selected folds recursively
1355 51
1356 norm! zF
1357 call assert_equal(2, foldlevel('.'))
1358 norm! kV2jzD
1359 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1360
1361 " Test for zE
1362 85
1363 norm! 4zF
1364 86
1365 norm! 2zF
1366 90
1367 norm! 4zF
1368 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1369 norm! zE
1370 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1371
1372 " Test for zn
1373 50
1374 set foldlevel=0
1375 norm! 2zF
1376 norm! zn
1377 norm! k
1378 call assert_equal('49', getline('.'))
1379 norm! j
1380 call assert_equal('50/*{{{*/', getline('.'))
1381 norm! j
1382 call assert_equal('51/*}}}*/', getline('.'))
1383 norm! j
1384 call assert_equal('52', getline('.'))
1385 call assert_equal(0, &foldenable)
1386
1387 " Test for zN
1388 49
1389 norm! zN
1390 call assert_equal('49', getline('.'))
1391 norm! j
1392 call assert_equal('50/*{{{*/', getline('.'))
1393 norm! j
1394 call assert_equal('52', getline('.'))
1395 call assert_equal(1, &foldenable)
1396
1397 " Test for zi
1398 norm! zi
1399 call assert_equal(0, &foldenable)
1400 norm! zi
1401 call assert_equal(1, &foldenable)
1402 norm! zi
1403 call assert_equal(0, &foldenable)
1404 norm! zi
1405 call assert_equal(1, &foldenable)
1406
1407 " Test for za
1408 50
1409 norm! za
1410 norm! k
1411 call assert_equal('49', getline('.'))
1412 norm! j
1413 call assert_equal('50/*{{{*/', getline('.'))
1414 norm! j
1415 call assert_equal('51/*}}}*/', getline('.'))
1416 norm! j
1417 call assert_equal('52', getline('.'))
1418 50
1419 norm! za
1420 norm! k
1421 call assert_equal('49', getline('.'))
1422 norm! j
1423 call assert_equal('50/*{{{*/', getline('.'))
1424 norm! j
1425 call assert_equal('52', getline('.'))
1426
1427 49
1428 norm! 5zF
1429 norm! k
1430 call assert_equal('48', getline('.'))
1431 norm! j
1432 call assert_equal('49/*{{{*/', getline('.'))
1433 norm! j
1434 call assert_equal('55', getline('.'))
1435 49
1436 norm! za
1437 call assert_equal('49/*{{{*/', getline('.'))
1438 norm! j
1439 call assert_equal('50/*{{{*/', getline('.'))
1440 norm! j
1441 call assert_equal('52', getline('.'))
1442 set nofoldenable
1443 " close fold and set foldenable
1444 norm! za
1445 call assert_equal(1, &foldenable)
1446
1447 50
1448 " have to use {count}za to open all folds and make the cursor visible
1449 norm! 2za
1450 norm! 2k
1451 call assert_equal('48', getline('.'))
1452 norm! j
1453 call assert_equal('49/*{{{*/', getline('.'))
1454 norm! j
1455 call assert_equal('50/*{{{*/', getline('.'))
1456 norm! j
1457 call assert_equal('51/*}}}*/', getline('.'))
1458 norm! j
1459 call assert_equal('52', getline('.'))
1460
1461 " Test for zA
1462 49
1463 set foldlevel=0
1464 50
1465 norm! zA
1466 norm! 2k
1467 call assert_equal('48', getline('.'))
1468 norm! j
1469 call assert_equal('49/*{{{*/', getline('.'))
1470 norm! j
1471 call assert_equal('50/*{{{*/', getline('.'))
1472 norm! j
1473 call assert_equal('51/*}}}*/', getline('.'))
1474 norm! j
1475 call assert_equal('52', getline('.'))
1476
Dominique Pelle923dce22021-11-21 11:36:04 +00001477 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001478 50
1479 set nofoldenable
1480 norm! zA
1481 call assert_equal(1, &foldenable)
1482 norm! k
1483 call assert_equal('48', getline('.'))
1484 norm! j
1485 call assert_equal('49/*{{{*/', getline('.'))
1486 norm! j
1487 call assert_equal('55', getline('.'))
1488
1489 " Test for zc
1490 norm! zE
1491 50
1492 norm! 2zF
1493 49
1494 norm! 5zF
1495 set nofoldenable
1496 50
1497 " There most likely is a bug somewhere:
1498 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1499 " TODO: Should this only close the inner most fold or both folds?
1500 norm! zc
1501 call assert_equal(1, &foldenable)
1502 norm! k
1503 call assert_equal('48', getline('.'))
1504 norm! j
1505 call assert_equal('49/*{{{*/', getline('.'))
1506 norm! j
1507 call assert_equal('55', getline('.'))
1508 set nofoldenable
1509 50
1510 norm! Vjzc
1511 norm! k
1512 call assert_equal('48', getline('.'))
1513 norm! j
1514 call assert_equal('49/*{{{*/', getline('.'))
1515 norm! j
1516 call assert_equal('55', getline('.'))
1517
1518 " Test for zC
1519 set nofoldenable
1520 50
1521 norm! zCk
1522 call assert_equal('48', getline('.'))
1523 norm! j
1524 call assert_equal('49/*{{{*/', getline('.'))
1525 norm! j
1526 call assert_equal('55', getline('.'))
1527
1528 " Test for zx
1529 " 1) close folds at line 49-54
1530 set nofoldenable
1531 48
1532 norm! zx
1533 call assert_equal(1, &foldenable)
1534 norm! j
1535 call assert_equal('49/*{{{*/', getline('.'))
1536 norm! j
1537 call assert_equal('55', getline('.'))
1538
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001539 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001540 51
1541 set nofoldenable
1542 norm! zx
1543 call assert_equal(1, &foldenable)
1544 norm! 3k
1545 call assert_equal('48', getline('.'))
1546 norm! j
1547 call assert_equal('49/*{{{*/', getline('.'))
1548 norm! j
1549 call assert_equal('50/*{{{*/', getline('.'))
1550 norm! j
1551 call assert_equal('51/*}}}*/', getline('.'))
1552 norm! j
1553 call assert_equal('52', getline('.'))
1554 norm! j
1555 call assert_equal('53', getline('.'))
1556 norm! j
1557 call assert_equal('54/*}}}*/', getline('.'))
1558 norm! j
1559 call assert_equal('55', getline('.'))
1560
1561 " 3) close one level of folds
1562 48
1563 set nofoldenable
1564 set foldlevel=1
1565 norm! zx
1566 call assert_equal(1, &foldenable)
1567 call assert_equal('48', getline('.'))
1568 norm! j
1569 call assert_equal('49/*{{{*/', getline('.'))
1570 norm! j
1571 call assert_equal('50/*{{{*/', getline('.'))
1572 norm! j
1573 call assert_equal('52', getline('.'))
1574 norm! j
1575 call assert_equal('53', getline('.'))
1576 norm! j
1577 call assert_equal('54/*}}}*/', getline('.'))
1578 norm! j
1579 call assert_equal('55', getline('.'))
1580
1581 " Test for zX
1582 " Close all folds
1583 set foldlevel=0 nofoldenable
1584 50
1585 norm! zX
1586 call assert_equal(1, &foldenable)
1587 norm! k
1588 call assert_equal('48', getline('.'))
1589 norm! j
1590 call assert_equal('49/*{{{*/', getline('.'))
1591 norm! j
1592 call assert_equal('55', getline('.'))
1593
1594 " Test for zm
1595 50
1596 set nofoldenable foldlevel=2
1597 norm! zm
1598 call assert_equal(1, &foldenable)
1599 call assert_equal(1, &foldlevel)
1600 norm! zm
1601 call assert_equal(0, &foldlevel)
1602 norm! zm
1603 call assert_equal(0, &foldlevel)
1604 norm! k
1605 call assert_equal('48', getline('.'))
1606 norm! j
1607 call assert_equal('49/*{{{*/', getline('.'))
1608 norm! j
1609 call assert_equal('55', getline('.'))
1610
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001611 " Test for zm with a count
1612 50
1613 set foldlevel=2
1614 norm! 3zm
1615 call assert_equal(0, &foldlevel)
1616 call assert_equal(49, foldclosed(line('.')))
1617
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001618 " Test for zM
1619 48
1620 set nofoldenable foldlevel=99
1621 norm! zM
1622 call assert_equal(1, &foldenable)
1623 call assert_equal(0, &foldlevel)
1624 call assert_equal('48', getline('.'))
1625 norm! j
1626 call assert_equal('49/*{{{*/', getline('.'))
1627 norm! j
1628 call assert_equal('55', getline('.'))
1629
1630 " Test for zr
1631 48
1632 set nofoldenable foldlevel=0
1633 norm! zr
1634 call assert_equal(0, &foldenable)
1635 call assert_equal(1, &foldlevel)
1636 set foldlevel=0 foldenable
1637 norm! zr
1638 call assert_equal(1, &foldenable)
1639 call assert_equal(1, &foldlevel)
1640 norm! zr
1641 call assert_equal(2, &foldlevel)
1642 call assert_equal('48', getline('.'))
1643 norm! j
1644 call assert_equal('49/*{{{*/', getline('.'))
1645 norm! j
1646 call assert_equal('50/*{{{*/', getline('.'))
1647 norm! j
1648 call assert_equal('51/*}}}*/', getline('.'))
1649 norm! j
1650 call assert_equal('52', getline('.'))
1651
1652 " Test for zR
1653 48
1654 set nofoldenable foldlevel=0
1655 norm! zR
1656 call assert_equal(0, &foldenable)
1657 call assert_equal(2, &foldlevel)
1658 set foldenable foldlevel=0
1659 norm! zR
1660 call assert_equal(1, &foldenable)
1661 call assert_equal(2, &foldlevel)
1662 call assert_equal('48', getline('.'))
1663 norm! j
1664 call assert_equal('49/*{{{*/', getline('.'))
1665 norm! j
1666 call assert_equal('50/*{{{*/', getline('.'))
1667 norm! j
1668 call assert_equal('51/*}}}*/', getline('.'))
1669 norm! j
1670 call assert_equal('52', getline('.'))
1671 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1672 48
1673 call assert_equal('48', getline('.'))
1674 norm! j
1675 call assert_equal('49/*{{{*/', getline('.'))
1676 norm! j
1677 call assert_equal('50/*{{{*/', getline('.'))
1678 norm! j
1679 call assert_equal('a /*{{{*/', getline('.'))
1680 norm! j
1681 call assert_equal('51/*}}}*/', getline('.'))
1682 norm! j
1683 call assert_equal('52', getline('.'))
1684 48
1685 norm! zR
1686 call assert_equal(1, &foldenable)
1687 call assert_equal(3, &foldlevel)
1688 call assert_equal('48', getline('.'))
1689 norm! j
1690 call assert_equal('49/*{{{*/', getline('.'))
1691 norm! j
1692 call assert_equal('50/*{{{*/', getline('.'))
1693 norm! j
1694 call assert_equal('a /*{{{*/', getline('.'))
1695 norm! j
1696 call assert_equal('b /*}}}*/', getline('.'))
1697 norm! j
1698 call assert_equal('51/*}}}*/', getline('.'))
1699 norm! j
1700 call assert_equal('52', getline('.'))
1701
1702 " clean up
1703 setl nofoldenable fdm=marker foldlevel=0
1704 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001705endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001706
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001707func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001708 " Reading from redirected file doesn't work on MS-Windows
1709 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001710 call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
1711 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001712 call system(GetVimCommand() .. ' -e -s < Xscript Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001713 let a=readfile('Xfile2')
1714 call assert_equal(['1', 'foo', 'bar', '2'], a)
1715
1716 " clean up
1717 for file in ['Xfile', 'Xfile2', 'Xscript']
1718 call delete(file)
1719 endfor
1720 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001721endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001722
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001723func Test_normal21_nv_hat()
1724
1725 " Edit a fresh file and wipe the buffer list so that there is no alternate
1726 " file present. Next, check for the expected command failures.
1727 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001728 call assert_fails(':buffer #', 'E86:')
1729 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001730 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001731
1732 " Test for the expected behavior when switching between two named buffers.
1733 edit Xfoo | edit Xbar
1734 call feedkeys("\<C-^>", 'tx')
1735 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1736 call feedkeys("\<C-^>", 'tx')
1737 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1738
1739 " Test for the expected behavior when only one buffer is named.
1740 enew | let l:nr = bufnr('%')
1741 call feedkeys("\<C-^>", 'tx')
1742 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1743 call feedkeys("\<C-^>", 'tx')
1744 call assert_equal('', bufname('%'))
1745 call assert_equal(l:nr, bufnr('%'))
1746
1747 " Test that no action is taken by "<C-^>" when an operator is pending.
1748 edit Xfoo
1749 call feedkeys("ci\<C-^>", 'tx')
1750 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1751
1752 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001753endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001754
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001755func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001756 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001757 " let shell = &shell
1758 " let &shell = 'sh'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001759 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001760 let args = ' -N -i NONE --noplugins -X --not-a-term'
1761 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001762 let a = readfile('Xfile')
1763 call assert_equal([], a)
1764 " Test for ZQ
1765 call writefile(['1', '2'], 'Xfile')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001766 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xfile')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001767 let a = readfile('Xfile')
1768 call assert_equal(['1', '2'], a)
1769
Bram Moolenaar1671f442020-03-10 07:48:13 +01001770 " Unsupported Z command
1771 call assert_beeps('normal! ZW')
1772
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001773 " clean up
1774 for file in ['Xfile']
1775 call delete(file)
1776 endfor
Bram Moolenaar0913a102016-09-03 19:11:59 +02001777 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001778endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001779
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001780func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001781 " Test for K command
1782 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001783 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001784 let k = &keywordprg
1785 set keywordprg=:help
1786 1
1787 norm! VK
1788 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1789 call assert_equal('help', &ft)
1790 call assert_match('\*version8.txt\*', getline('.'))
1791 helpclose
1792 norm! 0K
1793 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1794 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001795 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001796 helpclose
1797
Bram Moolenaar426f3752016-11-04 21:22:37 +01001798 set keywordprg=:new
1799 set iskeyword+=%
1800 set iskeyword+=\|
1801 2
1802 norm! K
1803 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1804 bwipe!
1805 3
1806 norm! K
1807 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1808 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001809 if !has('win32')
1810 4
1811 norm! K
1812 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1813 bwipe!
1814 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001815 set iskeyword-=%
1816 set iskeyword-=\|
1817
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001818 " Test for specifying a count to K
1819 1
1820 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1821 set keywordprg=:Kprog
1822 norm! 3K
1823 call assert_equal('3 version8', g:Kprog_Args)
1824 delcom Kprog
1825
Bram Moolenaar0913a102016-09-03 19:11:59 +02001826 " Only expect "man" to work on Unix
1827 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001828 let &keywordprg = k
1829 bw!
1830 return
1831 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001832
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001833 let not_gnu_man = has('mac') || has('bsd')
1834 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001835 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001836 set keywordprg=man\ -P\ cat
1837 else
1838 set keywordprg=man\ --pager=cat
1839 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001840 " Test for using man
1841 2
1842 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001843 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001844 call assert_match("man -P cat 'man'", a)
1845 else
1846 call assert_match("man --pager=cat 'man'", a)
1847 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001848
Bram Moolenaar1671f442020-03-10 07:48:13 +01001849 " Error cases
1850 call setline(1, '#$#')
1851 call assert_fails('normal! ggK', 'E349:')
1852 call setline(1, '---')
1853 call assert_fails('normal! ggv2lK', 'E349:')
1854 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001855 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001856 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001857 norm! V
1858 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001859
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001860 " clean up
1861 let &keywordprg = k
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_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001866 " Testing for g?? g?g?
1867 new
1868 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1869 1
1870 norm! g??
1871 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1872 norm! g?g?
1873 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1874
1875 " clean up
1876 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001877endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001878
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001879func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001880 CheckFeature quickfix
1881
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001882 " Testing for CTRL-] g CTRL-] g]
1883 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1884 h
1885 " Test for CTRL-]
1886 call search('\<x\>$')
1887 exe "norm! \<c-]>"
1888 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1889 norm! yiW
1890 call assert_equal("*x*", @0)
1891 exe ":norm \<c-o>"
1892
1893 " Test for g_CTRL-]
1894 call search('\<v_u\>$')
1895 exe "norm! g\<c-]>"
1896 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1897 norm! yiW
1898 call assert_equal("*v_u*", @0)
1899 exe ":norm \<c-o>"
1900
1901 " Test for g]
1902 call search('\<i_<Esc>$')
1903 let a = execute(":norm! g]")
1904 call assert_match('i_<Esc>.*insert.txt', a)
1905
1906 if !empty(exepath('cscope')) && has('cscope')
1907 " setting cscopetag changes how g] works
1908 set cst
1909 exe "norm! g]"
1910 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1911 norm! yiW
1912 call assert_equal("*i_<Esc>*", @0)
1913 exe ":norm \<c-o>"
1914 " Test for CTRL-W g]
1915 exe "norm! \<C-W>g]"
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 set nocst
1922 endif
1923
1924 " Test for CTRL-W g]
1925 let a = execute("norm! \<C-W>g]")
1926 call assert_match('i_<Esc>.*insert.txt', a)
1927
1928 " Test for CTRL-W CTRL-]
1929 exe "norm! \<C-W>\<C-]>"
1930 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1931 norm! yiW
1932 call assert_equal("*i_<Esc>*", @0)
1933 call assert_equal(3, winnr('$'))
1934 helpclose
1935
1936 " Test for CTRL-W g CTRL-]
1937 exe "norm! \<C-W>g\<C-]>"
1938 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1939 norm! yiW
1940 call assert_equal("*i_<Esc>*", @0)
1941 call assert_equal(3, winnr('$'))
1942 helpclose
1943
1944 " clean up
1945 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001946endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001947
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001948func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001949 " Test for ]p ]P [p and [P
1950 new
1951 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1952 1
1953 /Error/y a
1954 2
1955 norm! "a]pj"a[p
1956 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1957 1
1958 /^\s\{4}/
1959 exe "norm! \"a]P3Eldt'"
1960 exe "norm! j\"a[P2Eldt'"
1961 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
1962
1963 " clean up
1964 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001965endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001966
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001967func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001968 " Test for [' [` ]' ]`
1969 call Setup_NewWindow()
1970 1,21s/.\+/ & b/
1971 1
1972 norm! $ma
1973 5
1974 norm! $mb
1975 10
1976 norm! $mc
1977 15
1978 norm! $md
1979 20
1980 norm! $me
1981
1982 " Test for ['
1983 9
1984 norm! 2['
1985 call assert_equal(' 1 b', getline('.'))
1986 call assert_equal(1, line('.'))
1987 call assert_equal(3, col('.'))
1988
1989 " Test for ]'
1990 norm! ]'
1991 call assert_equal(' 5 b', getline('.'))
1992 call assert_equal(5, line('.'))
1993 call assert_equal(3, col('.'))
1994
1995 " No mark after line 21, cursor moves to first non blank on current line
1996 21
1997 norm! $]'
1998 call assert_equal(' 21 b', getline('.'))
1999 call assert_equal(21, line('.'))
2000 call assert_equal(3, col('.'))
2001
2002 " Test for [`
2003 norm! 2[`
2004 call assert_equal(' 15 b', getline('.'))
2005 call assert_equal(15, line('.'))
2006 call assert_equal(8, col('.'))
2007
2008 " Test for ]`
2009 norm! ]`
2010 call assert_equal(' 20 b', getline('.'))
2011 call assert_equal(20, line('.'))
2012 call assert_equal(8, col('.'))
2013
2014 " clean up
2015 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002016endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002017
Bram Moolenaar1671f442020-03-10 07:48:13 +01002018" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002019func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002020 new
2021 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2022
2023 $
2024 norm! d(
2025 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2026 norm! 2d(
2027 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2028 1
2029 norm! 0d)
2030 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2031
2032 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2033 $
2034 norm! $d(
2035 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2036
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002037 " Move to the next sentence from a paragraph macro
2038 %d
2039 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2040 call cursor(1, 1)
2041 normal )
2042 call assert_equal([2, 1], [line('.'), col('.')])
2043 normal )
2044 call assert_equal([2, 12], [line('.'), col('.')])
2045 normal ((
2046 call assert_equal([1, 1], [line('.'), col('.')])
2047
Bram Moolenaar1671f442020-03-10 07:48:13 +01002048 " It is an error if a next sentence is not found
2049 %d
2050 call setline(1, '.SH')
2051 call assert_beeps('normal )')
2052
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002053 " If only dot is present, don't treat that as a sentence
2054 call setline(1, '. This is a sentence.')
2055 normal $((
2056 call assert_equal(3, col('.'))
2057
Bram Moolenaar1671f442020-03-10 07:48:13 +01002058 " Jumping to a fold should open the fold
2059 call setline(1, ['', '', 'one', 'two', 'three'])
2060 set foldenable
2061 2,$fold
2062 call feedkeys(')', 'xt')
2063 call assert_equal(3, line('.'))
2064 call assert_equal(1, foldlevel('.'))
2065 call assert_equal(-1, foldclosed('.'))
2066 set foldenable&
2067
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002068 " clean up
2069 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002070endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002071
Bram Moolenaar1671f442020-03-10 07:48:13 +01002072" Test for { and } paragraph movements
2073func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002074 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002075 A paragraph begins after each empty line, and also at each of a set of
2076 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2077 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2078 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2079 the first column). A section boundary is also a paragraph boundary.
2080 Note that a blank line (only containing white space) is NOT a paragraph
2081 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002082
2083
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002084 Also note that this does not include a '{' or '}' in the first column. When
2085 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2086 paragraph boundary |posix|.
2087 {
2088 This is no paragraph
2089 unless the '{' is set
2090 in 'cpoptions'
2091 }
2092 .IP
2093 The nroff macros IP separates a paragraph
2094 That means, it must be a '.'
2095 followed by IP
2096 .LPIt does not matter, if afterwards some
2097 more characters follow.
2098 .SHAlso section boundaries from the nroff
2099 macros terminate a paragraph. That means
2100 a character like this:
2101 .NH
2102 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002103 [DATA]
2104
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002105 new
2106 call append(0, text)
2107 1
2108 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002109
2110 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002111 .IP
2112 The nroff macros IP separates a paragraph
2113 That means, it must be a '.'
2114 followed by IP
2115 .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
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002122
2123 [DATA]
2124 call assert_equal(expected, getline(1, '$'))
2125
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002126 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002127
2128 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002129 .LPIt does not matter, if afterwards some
2130 more characters follow.
2131 .SHAlso section boundaries from the nroff
2132 macros terminate a paragraph. That means
2133 a character like this:
2134 .NH
2135 End of text here
2136
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002137 [DATA]
2138 call assert_equal(expected, getline(1, '$'))
2139
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002140 $
2141 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002142
2143 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002144 .LPIt does not matter, if afterwards some
2145 more characters follow.
2146 .SHAlso section boundaries from the nroff
2147 macros terminate a paragraph. That means
2148 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002149
2150 [DATA]
2151 call assert_equal(expected, getline(1, '$'))
2152
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002153 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002154
2155 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002156 .LPIt does not matter, if afterwards some
2157 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002158
2159 [DATA]
2160 call assert_equal(expected, getline(1, '$'))
2161
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002162 " Test with { in cpooptions
2163 %d
2164 call append(0, text)
2165 set cpo+={
2166 1
2167 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002168
2169 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002170 {
2171 This is no paragraph
2172 unless the '{' is set
2173 in 'cpoptions'
2174 }
2175 .IP
2176 The nroff macros IP separates a paragraph
2177 That means, it must be a '.'
2178 followed by IP
2179 .LPIt does not matter, if afterwards some
2180 more characters follow.
2181 .SHAlso section boundaries from the nroff
2182 macros terminate a paragraph. That means
2183 a character like this:
2184 .NH
2185 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002186
2187 [DATA]
2188 call assert_equal(expected, getline(1, '$'))
2189
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002190 $
2191 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002192
2193 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002194 {
2195 This is no paragraph
2196 unless the '{' is set
2197 in 'cpoptions'
2198 }
2199 .IP
2200 The nroff macros IP separates a paragraph
2201 That means, it must be a '.'
2202 followed by IP
2203 .LPIt does not matter, if afterwards some
2204 more characters follow.
2205 .SHAlso section boundaries from the nroff
2206 macros terminate a paragraph. That means
2207 a character like this:
2208 .NH
2209 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002210
2211 [DATA]
2212 call assert_equal(expected, getline(1, '$'))
2213
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002214 norm! gg}
2215 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002216
2217 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002218 {
2219 This is no paragraph
2220 unless the '{' is set
2221 in 'cpoptions'
2222 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002223
2224 [DATA]
2225 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002226
Bram Moolenaar1671f442020-03-10 07:48:13 +01002227 " Jumping to a fold should open the fold
2228 %d
2229 call setline(1, ['', 'one', 'two', ''])
2230 set foldenable
2231 2,$fold
2232 call feedkeys('}', 'xt')
2233 call assert_equal(4, line('.'))
2234 call assert_equal(1, foldlevel('.'))
2235 call assert_equal(-1, foldclosed('.'))
2236 set foldenable&
2237
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002238 " clean up
2239 set cpo-={
2240 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002241endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002242
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002243" Test for section movements
2244func Test_normal_section()
2245 new
2246 let lines =<< trim [END]
2247 int foo()
2248 {
2249 if (1)
2250 {
2251 a = 1;
2252 }
2253 }
2254 [END]
2255 call setline(1, lines)
2256
2257 " jumping to a folded line using [[ should open the fold
2258 2,3fold
2259 call cursor(5, 1)
2260 call feedkeys("[[", 'xt')
2261 call assert_equal(2, line('.'))
2262 call assert_equal(-1, foldclosedend(line('.')))
2263
2264 close!
2265endfunc
2266
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002267" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002268func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002269 new
2270 call append(0, 'This is a simple test: äüöß')
2271 norm! 1ggVu
2272 call assert_equal('this is a simple test: äüöß', getline('.'))
2273 norm! VU
2274 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2275 norm! guu
2276 call assert_equal('this is a simple test: äüöss', getline('.'))
2277 norm! gUgU
2278 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2279 norm! gugu
2280 call assert_equal('this is a simple test: äüöss', getline('.'))
2281 norm! gUU
2282 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2283 norm! 010~
2284 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
2285 norm! V~
2286 call assert_equal('THIS IS A simple test: äüöss', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002287 call assert_beeps('norm! c~')
2288 %d
2289 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002290
Bram Moolenaar1671f442020-03-10 07:48:13 +01002291 " Test for changing case across lines using 'whichwrap'
2292 call setline(1, ['aaaaaa', 'aaaaaa'])
2293 normal! gg10~
2294 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2295 set whichwrap+=~
2296 normal! gg10~
2297 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2298 set whichwrap&
2299
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002300 " try changing the case with a double byte encoding (DBCS)
2301 %bw!
2302 let enc = &enc
2303 set encoding=cp932
2304 call setline(1, "\u8470")
2305 normal ~
2306 normal gU$gu$gUgUg~g~gugu
2307 call assert_equal("\u8470", getline(1))
2308 let &encoding = enc
2309
Bram Moolenaar1671f442020-03-10 07:48:13 +01002310 " clean up
2311 bw!
2312endfunc
2313
2314" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2315" is available but toupper()/tolower() don't do the right thing.
2316func Test_normal_changecase_turkish()
2317 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002318 try
2319 lang tr_TR.UTF-8
2320 set casemap=
2321 let iupper = toupper('i')
2322 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002323 call setline(1, 'iI')
2324 1normal gUU
2325 call assert_equal("\u0130I", getline(1))
2326 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002327
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002328 call setline(1, 'iI')
2329 1normal guu
2330 call assert_equal("i\u0131", getline(1))
2331 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002332 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002333 call setline(1, 'iI')
2334 1normal gUU
2335 call assert_equal("II", getline(1))
2336 call assert_equal("II", toupper("iI"))
2337
2338 call setline(1, 'iI')
2339 1normal guu
2340 call assert_equal("ii", getline(1))
2341 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002342 else
2343 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2344 endif
2345 set casemap&
2346 call setline(1, 'iI')
2347 1normal gUU
2348 call assert_equal("II", getline(1))
2349 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002350
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002351 call setline(1, 'iI')
2352 1normal guu
2353 call assert_equal("ii", getline(1))
2354 call assert_equal("ii", tolower("iI"))
2355
2356 lang en_US.UTF-8
2357 catch /E197:/
2358 " can't use Turkish locale
2359 throw 'Skipped: Turkish locale not available'
2360 endtry
Bram Moolenaar1671f442020-03-10 07:48:13 +01002361 close!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002362endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002363
Bram Moolenaar1671f442020-03-10 07:48:13 +01002364" Test for r (replace) command
2365func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002366 new
2367 call append(0, 'This is a simple test: abcd')
2368 exe "norm! 1gg$r\<cr>"
2369 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2370 exe "norm! 1gg2wlr\<cr>"
2371 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2372 exe "norm! 2gg0W5r\<cr>"
2373 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2374 set autoindent
2375 call setline(2, ['simple test: abc', ''])
2376 exe "norm! 2gg0W5r\<cr>"
2377 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2378 exe "norm! 1ggVr\<cr>"
2379 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2380 call setline(1, 'This is a')
2381 exe "norm! 1gg05rf"
2382 call assert_equal('fffffis a', getline(1))
2383
Bram Moolenaar1671f442020-03-10 07:48:13 +01002384 " When replacing characters, copy characters from above and below lines
2385 " using CTRL-Y and CTRL-E.
2386 " Different code paths are used for utf-8 and latin1 encodings
2387 set showmatch
2388 for enc in ['latin1', 'utf-8']
2389 enew!
2390 let &encoding = enc
2391 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2392 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2393 call assert_equal(' {a}x [b]x', getline(2))
2394 endfor
2395 set showmatch&
2396
2397 " r command should fail in operator pending mode
2398 call assert_beeps('normal! cr')
2399
Bram Moolenaar004a6782020-04-11 17:09:31 +02002400 " replace a tab character in visual mode
2401 %d
2402 call setline(1, ["a\tb", "c\td", "e\tf"])
2403 normal gglvjjrx
2404 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2405
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002406 " replace with a multibyte character (with multiple composing characters)
2407 %d
2408 new
2409 call setline(1, 'aaa')
2410 exe "normal $ra\u0328\u0301"
2411 call assert_equal("aaa\u0328\u0301", getline(1))
2412
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002413 " clean up
2414 set noautoindent
2415 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002416endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002417
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002418" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002419func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002420 new
2421 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2422 1
2423 norm! $g*
2424 call assert_equal('x_foo', @/)
2425 call assert_equal('x_foobar.abc', getline('.'))
2426 norm! $g#
2427 call assert_equal('abc', @/)
2428 call assert_equal('abc.x_foo', getline('.'))
2429
2430 " clean up
2431 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002432endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002433
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002434" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2435" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002436func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002437 call Setup_NewWindow()
2438 " Test for g`
2439 clearjumps
2440 norm! ma10j
2441 let a=execute(':jumps')
2442 " empty jumplist
2443 call assert_equal('>', a[-1:])
2444 norm! g`a
2445 call assert_equal('>', a[-1:])
2446 call assert_equal(1, line('.'))
2447 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002448 call cursor(10, 1)
2449 norm! g'a
2450 call assert_equal('>', a[-1:])
2451 call assert_equal(1, line('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002452
2453 " Test for g; and g,
2454 norm! g;
2455 " there is only one change in the changelist
2456 " currently, when we setup the window
2457 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002458 call assert_fails(':norm! g;', 'E662:')
2459 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002460 let &ul=&ul
2461 call append('$', ['a', 'b', 'c', 'd'])
2462 let &ul=&ul
2463 call append('$', ['Z', 'Y', 'X', 'W'])
2464 let a = execute(':changes')
2465 call assert_match('2\s\+0\s\+2', a)
2466 call assert_match('101\s\+0\s\+a', a)
2467 call assert_match('105\s\+0\s\+Z', a)
2468 norm! 3g;
2469 call assert_equal(2, line('.'))
2470 norm! 2g,
2471 call assert_equal(105, line('.'))
2472
2473 " Test for g& - global substitute
2474 %d
2475 call setline(1, range(1,10))
2476 call append('$', ['a', 'b', 'c', 'd'])
2477 $s/\w/&&/g
2478 exe "norm! /[1-8]\<cr>"
2479 norm! g&
2480 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2481
Bram Moolenaar1671f442020-03-10 07:48:13 +01002482 " Jumping to a fold using gg should open the fold
2483 set foldenable
2484 set foldopen+=jump
2485 5,8fold
2486 call feedkeys('6gg', 'xt')
2487 call assert_equal(1, foldlevel('.'))
2488 call assert_equal(-1, foldclosed('.'))
2489 set foldopen-=jump
2490 set foldenable&
2491
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002492 " Test for gv
2493 %d
2494 call append('$', repeat(['abcdefgh'], 8))
2495 exe "norm! 2gg02l\<c-v>2j2ly"
2496 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2497 " in visual mode, gv swaps current and last selected region
2498 exe "norm! G0\<c-v>4k4lgvd"
2499 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2500 exe "norm! G0\<c-v>4k4ly"
2501 exe "norm! gvood"
2502 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002503 " gv cannot be used in operator pending mode
2504 call assert_beeps('normal! cgv')
2505 " gv should beep without a previously selected visual area
2506 new
2507 call assert_beeps('normal! gv')
2508 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002509
2510 " Test for gk/gj
2511 %d
2512 15vsp
2513 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002514 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2515 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2516 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002517 $put =lineA
2518 $put =lineB
2519
2520 norm! 3gg0dgk
2521 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2522 set nu
2523 norm! 3gg0gjdgj
2524 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2525
2526 " Test for gJ
2527 norm! 2gggJ
2528 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2529 call assert_equal(16, col('.'))
2530 " shouldn't do anything
2531 norm! 10gJ
2532 call assert_equal(1, col('.'))
2533
2534 " Test for g0 g^ gm g$
2535 exe "norm! 2gg0gji "
2536 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2537 norm! g0yl
2538 call assert_equal(12, col('.'))
2539 call assert_equal(' ', getreg(0))
2540 norm! g$yl
2541 call assert_equal(22, col('.'))
2542 call assert_equal('3', getreg(0))
2543 norm! gmyl
2544 call assert_equal(17, col('.'))
2545 call assert_equal('n', getreg(0))
2546 norm! g^yl
2547 call assert_equal(15, col('.'))
2548 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002549 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002550
Bram Moolenaar74ede802021-05-29 19:18:01 +02002551 " Test for g$ with double-width character half displayed
2552 vsplit
2553 9wincmd |
2554 setlocal nowrap nonumber
2555 call setline(2, 'asdfasdfヨ')
2556 2
2557 normal 0g$
2558 call assert_equal(8, col('.'))
2559 10wincmd |
2560 normal 0g$
2561 call assert_equal(9, col('.'))
2562
2563 setlocal signcolumn=yes
2564 11wincmd |
2565 normal 0g$
2566 call assert_equal(8, col('.'))
2567 12wincmd |
2568 normal 0g$
2569 call assert_equal(9, col('.'))
2570
2571 close
2572
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002573 " Test for g_
2574 call assert_beeps('normal! 100g_')
2575 call setline(2, [' foo ', ' foobar '])
2576 normal! 2ggg_
2577 call assert_equal(5, col('.'))
2578 normal! 2g_
2579 call assert_equal(8, col('.'))
2580
2581 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002582 $put =lineC
2583
2584 " Test for gM
2585 norm! gMyl
2586 call assert_equal(73, col('.'))
2587 call assert_equal('0', getreg(0))
2588 " Test for 20gM
2589 norm! 20gMyl
2590 call assert_equal(29, col('.'))
2591 call assert_equal('S', getreg(0))
2592 " Test for 60gM
2593 norm! 60gMyl
2594 call assert_equal(87, col('.'))
2595 call assert_equal('E', getreg(0))
2596
Bram Moolenaar71c41252021-12-26 15:00:07 +00002597 " Test for gM with Tab characters
2598 call setline('.', "\ta\tb\tc\td\te\tf")
2599 norm! gMyl
2600 call assert_equal(6, col('.'))
2601 call assert_equal("c", getreg(0))
2602
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002603 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002604 call setline('.', lineC)
2605 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002606 set ff=unix
2607 let a=execute(":norm! g\<c-g>")
2608 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2609
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002610 " Test for gI
2611 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002612 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002613
2614 " Test for gi
2615 wincmd c
2616 %d
2617 set tw=0
2618 call setline(1, ['foobar', 'new line'])
2619 norm! A next word
2620 $put ='third line'
2621 norm! gi another word
2622 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002623 call setline(1, 'foobar')
2624 normal! Ggifirst line
2625 call assert_equal('foobarfirst line', getline(1))
2626 " Test gi in 'virtualedit' mode with cursor after the end of the line
2627 set virtualedit=all
2628 call setline(1, 'foo')
2629 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2630 call setline(1, 'foo')
2631 normal! Ggifirst line
2632 call assert_equal('foo first line', getline(1))
2633 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002634
Dominique Pelle923dce22021-11-21 11:36:04 +00002635 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002636 exe "normal! g\<C-\>\<C-G>"
2637 call assert_equal('foo first line', getline('.'))
2638
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002639 " clean up
2640 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002641endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002642
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002643" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002644func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002645 new
2646
2647 let a = execute(":norm! g\<c-g>")
2648 call assert_equal("\n--No lines in buffer--", a)
2649
Bram Moolenaar1671f442020-03-10 07:48:13 +01002650 " Test for CTRL-G (same as :file)
2651 let a = execute(":norm! \<c-g>")
2652 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2653
Bram Moolenaar05295832018-08-24 22:07:58 +02002654 call setline(1, ['first line', 'second line'])
2655
2656 " Test g CTRL-g with dos, mac and unix file type.
2657 norm! gojll
2658 set ff=dos
2659 let a = execute(":norm! g\<c-g>")
2660 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2661
2662 set ff=mac
2663 let a = execute(":norm! g\<c-g>")
2664 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2665
2666 set ff=unix
2667 let a = execute(":norm! g\<c-g>")
2668 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2669
2670 " Test g CTRL-g in visual mode (v)
2671 let a = execute(":norm! gojllvlg\<c-g>")
2672 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2673
2674 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2675 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2676 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2677
2678 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2679 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2680 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2681
2682 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2683 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2684 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2685
2686 " There should be one byte less with noeol
2687 set bin noeol
2688 let a = execute(":norm! \<Esc>gog\<c-g>")
2689 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2690 set bin & eol&
2691
Bram Moolenaar30276f22019-01-24 17:59:39 +01002692 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002693
Bram Moolenaar30276f22019-01-24 17:59:39 +01002694 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2695 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 +02002696
Bram Moolenaar30276f22019-01-24 17:59:39 +01002697 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2698 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 +02002699
Bram Moolenaar30276f22019-01-24 17:59:39 +01002700 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2701 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 +02002702
Bram Moolenaar30276f22019-01-24 17:59:39 +01002703 set fenc=utf8 bomb
2704 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2705 call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+3 for BOM)", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002706
Bram Moolenaar30276f22019-01-24 17:59:39 +01002707 set fenc=utf16 bomb
2708 let a = execute(":norm! g\<c-g>")
2709 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 +02002710
Bram Moolenaar30276f22019-01-24 17:59:39 +01002711 set fenc=utf32 bomb
2712 let a = execute(":norm! g\<c-g>")
2713 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 +02002714
Bram Moolenaar30276f22019-01-24 17:59:39 +01002715 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002716
2717 set ff&
2718 bwipe!
2719endfunc
2720
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002721" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002722func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002723 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002724 let a=execute(':norm! 1G0g8')
2725 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002726
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002727 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2728 let a=execute(':norm! 1G$g8')
2729 call assert_equal("\nc3 b6 ", a)
2730
2731 call setline(1, "a\u0302")
2732 let a=execute(':norm! 1G0g8')
2733 call assert_equal("\n61 + cc 82 ", a)
2734
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002735 " clean up
2736 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002737endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002738
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002739" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002740func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002741 new
2742
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002743 " With invalid byte.
2744 call setline(1, "___\xff___")
2745 norm! 1G08g8g
2746 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2747
2748 " With invalid byte before the cursor.
2749 call setline(1, "___\xff___")
2750 norm! 1G$h8g8g
2751 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2752
2753 " With truncated sequence.
2754 call setline(1, "___\xE2\x82___")
2755 norm! 1G08g8g
2756 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2757
2758 " With overlong sequence.
2759 call setline(1, "___\xF0\x82\x82\xAC___")
2760 norm! 1G08g8g
2761 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2762
2763 " With valid utf8.
2764 call setline(1, "café")
2765 norm! 1G08g8
2766 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2767
2768 bw!
2769endfunc
2770
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002771" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002772func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002773 " Cannot capture its output,
2774 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002775 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002776 echo "a\nb\nc\nd"
2777 let b=execute(':norm! g<')
2778 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002779endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002780
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002781" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002782func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002783 new
2784 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002785 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002786 " Test for gp gP
2787 call append(1, range(1,10))
2788 1
2789 norm! 1yy
2790 3
2791 norm! gp
2792 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2793 $
2794 norm! gP
2795 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2796
2797 " Test for go
2798 norm! 26go
2799 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2800 norm! 27go
2801 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2802 norm! 28go
2803 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2804 set ff=dos
2805 norm! 29go
2806 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2807 set ff=unix
2808 norm! gg0
2809 norm! 101go
2810 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2811 norm! 103go
2812 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2813 " count > buffer content
2814 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002815 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002816 " clean up
2817 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002818endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002819
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002820" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002821func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002822 tabnew 1.txt
2823 tabnew 2.txt
2824 tabnew 3.txt
2825 norm! 1gt
2826 call assert_equal(1, tabpagenr())
2827 norm! 3gt
2828 call assert_equal(3, tabpagenr())
2829 norm! 1gT
2830 " count gT goes not to the absolute tabpagenumber
2831 " but, but goes to the count previous tabpagenumber
2832 call assert_equal(2, tabpagenr())
2833 " wrap around
2834 norm! 3gT
2835 call assert_equal(3, tabpagenr())
2836 " gt does not wrap around
2837 norm! 5gt
2838 call assert_equal(3, tabpagenr())
2839
2840 for i in range(3)
2841 tabclose
2842 endfor
2843 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002844 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002845endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002846
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002847" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002848func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002849 new
2850 call setline(1, range(10))
2851 $
2852 setl et sw=2
2853 norm! V10>$
2854 " count is ignored
2855 exe "norm! 10\<home>"
2856 call assert_equal(1, col('.'))
2857 exe "norm! \<home>"
2858 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2859 exe "norm! 5\<c-home>"
2860 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2861 exe "norm! \<c-home>"
2862 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002863 exe "norm! G\<c-kHome>"
2864 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002865
2866 " clean up
2867 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002868endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002869
Bram Moolenaar1671f442020-03-10 07:48:13 +01002870" Test for <End> and <C-End> keys
2871func Test_normal_nvend()
2872 new
2873 call setline(1, map(range(1, 10), '"line" .. v:val'))
2874 exe "normal! \<End>"
2875 call assert_equal(5, col('.'))
2876 exe "normal! 4\<End>"
2877 call assert_equal([4, 5], [line('.'), col('.')])
2878 exe "normal! \<C-End>"
2879 call assert_equal([10, 6], [line('.'), col('.')])
2880 close!
2881endfunc
2882
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002883" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002884func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002885 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002886 new
2887 set tw=0
2888 call append(0, 'here are some words')
2889 norm! 1gg0elcwZZZ
2890 call assert_equal('hereZZZare some words', getline('.'))
2891 norm! 1gg0elcWYYY
2892 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002893 norm! 2gg0cwfoo
2894 call assert_equal('foo', getline('.'))
2895
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002896 call setline(1, 'one; two')
2897 call cursor(1, 1)
2898 call feedkeys('cwvim', 'xt')
2899 call assert_equal('vim; two', getline(1))
2900 call feedkeys('0cWone', 'xt')
2901 call assert_equal('one two', getline(1))
2902 "When cursor is at the end of a word 'ce' will change until the end of the
2903 "next word, but 'cw' will change only one character
2904 call setline(1, 'one two')
2905 call feedkeys('0ecwce', 'xt')
2906 call assert_equal('once two', getline(1))
2907 call setline(1, 'one two')
2908 call feedkeys('0ecely', 'xt')
2909 call assert_equal('only', getline(1))
2910
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002911 " clean up
2912 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002913endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002914
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002915" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002916func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002917 new
2918 call append(0, 'here are some words')
2919 exe "norm! 1gg0a\<C-\>\<C-N>"
2920 call assert_equal('n', mode())
2921 call assert_equal(1, col('.'))
2922 call assert_equal('', visualmode())
2923 exe "norm! 1gg0viw\<C-\>\<C-N>"
2924 call assert_equal('n', mode())
2925 call assert_equal(4, col('.'))
2926 exe "norm! 1gg0a\<C-\>\<C-G>"
2927 call assert_equal('n', mode())
2928 call assert_equal(1, col('.'))
2929 "imap <buffer> , <c-\><c-n>
2930 set im
2931 exe ":norm! \<c-\>\<c-n>dw"
2932 set noim
2933 call assert_equal('are some words', getline(1))
2934 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02002935 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01002936
Bram Moolenaar21829c52021-01-26 22:42:21 +01002937 if has('cmdwin')
2938 " Using CTRL-\ CTRL-N in cmd window should close the window
2939 call feedkeys("q:\<C-\>\<C-N>", 'xt')
2940 call assert_equal('', getcmdwintype())
2941 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002942
2943 " clean up
2944 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002945endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002946
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002947" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01002948func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002949 new
2950 set sts=2 sw=2 ts=8 tw=0
2951 call append(0, ["aaa\tbbb\tccc", '', '', ''])
2952 let a=getline(1)
2953 norm! 2gg0
2954 exe "norm! a\<c-r>=a\<cr>"
2955 norm! 3gg0
2956 exe "norm! a\<c-r>\<c-r>=a\<cr>"
2957 norm! 4gg0
2958 exe "norm! a\<c-r>\<c-o>=a\<cr>"
2959 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
2960
2961 " clean up
2962 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02002963 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002964endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002965
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002966" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002967func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002968 call Setup_NewWindow()
2969 call assert_equal(5, &scroll)
2970 exe "norm! \<c-d>"
2971 call assert_equal('6', getline('.'))
2972 exe "norm! 2\<c-d>"
2973 call assert_equal('8', getline('.'))
2974 call assert_equal(2, &scroll)
2975 set scroll=5
2976 exe "norm! \<c-u>"
2977 call assert_equal('3', getline('.'))
2978 1
2979 set scrolloff=5
2980 exe "norm! \<c-d>"
2981 call assert_equal('10', getline('.'))
2982 exe "norm! \<c-u>"
2983 call assert_equal('5', getline('.'))
2984 1
2985 set scrolloff=99
2986 exe "norm! \<c-d>"
2987 call assert_equal('10', getline('.'))
2988 set scrolloff=0
2989 100
2990 exe "norm! $\<c-u>"
2991 call assert_equal('95', getline('.'))
2992 call assert_equal([0, 95, 1, 0, 1], getcurpos())
2993 100
2994 set nostartofline
2995 exe "norm! $\<c-u>"
2996 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00002997 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002998 " cleanup
2999 set startofline
3000 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003001endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003002
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003003func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003004 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003005 " The ~ register does not exist
3006 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003007 return
3008 endif
3009
3010 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003011 " unfortunately, without a gui, we can't really test much here,
3012 " so simply test that ~p fails (which uses the drop register)
3013 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003014 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003015 call assert_equal([], getreg('~', 1, 1))
3016 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003017 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003018 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003019endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003020
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003021func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003022 new
3023 " How to test this?
3024 " let's just for now test, that the buffer
3025 " does not change
3026 call feedkeys("\<c-s>", 't')
3027 call assert_equal([''], getline(1,'$'))
3028
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003029 " no valid commands
3030 exe "norm! \<char-0x100>"
3031 call assert_equal([''], getline(1,'$'))
3032
3033 exe "norm! ä"
3034 call assert_equal([''], getline(1,'$'))
3035
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003036 " clean up
3037 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003038endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003039
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003040func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003041 " This was causing a crash or ml_get error.
3042 enew!
3043 call setline(1,'xxx')
3044 normal $
3045 new
3046 call setline(1, range(1,2))
3047 2
3048 exe "norm \<C-V>$"
3049 bw!
3050 norm yp
3051 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003052endfunc
3053
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003054func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003055 new
3056 exe "norm! \<c-w>c"
3057 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003058 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003059endfunc
3060
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003061func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003062 new
3063 call setline(1, 'one two three four five six seven eight nine ten')
3064 1
3065 norm! 3d2w
3066 call assert_equal('seven eight nine ten', getline(1))
3067 bw!
3068endfunc
3069
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003070func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003071 CheckFeature timers
3072 CheckFeature cmdline_hist
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003073 func! DoTimerWork(id)
3074 call assert_equal('[Command Line]', bufname(''))
3075 " should fail, with E11, but does fail with E23?
3076 "call feedkeys("\<c-^>", 'tm')
3077
3078 " should also fail with E11
Bram Moolenaare2e40752020-09-04 21:18:46 +02003079 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003080 " return from commandline window
3081 call feedkeys("\<cr>")
3082 endfunc
3083
3084 let oldlang=v:lang
3085 lang C
3086 set updatetime=20
3087 call timer_start(100, 'DoTimerWork')
3088 try
3089 " throws E23, for whatever reason...
3090 call feedkeys('q:', 'x!')
3091 catch /E23/
3092 " no-op
3093 endtry
3094 " clean up
3095 set updatetime=4000
3096 exe "lang" oldlang
3097 bw!
3098endfunc
3099
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003100func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003101 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003102 " Don't sleep after the warning message.
3103 call test_settime(1)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003104 call writefile(['foo'], 'Xreadonly.log')
3105 new Xreadonly.log
3106 setl ro
3107 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003108 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003109 call assert_equal(['foo'], getline(1,'$'))
3110 call assert_equal('Xreadonly.log', bufname(''))
3111
3112 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003113 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003114 bw!
3115 call delete("Xreadonly.log")
3116endfunc
3117
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003118func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003119 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003120 new
3121 call setline(1, 'abcde fghij klmnopq')
3122 norm! 1gg$
3123 set rl
3124 call assert_equal(19, col('.'))
3125 call feedkeys('l', 'tx')
3126 call assert_equal(18, col('.'))
3127 call feedkeys('h', 'tx')
3128 call assert_equal(19, col('.'))
3129 call feedkeys("\<right>", 'tx')
3130 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003131 call feedkeys("\<left>", 'tx')
3132 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003133 call feedkeys("\<s-right>", 'tx')
3134 call assert_equal(13, col('.'))
3135 call feedkeys("\<c-right>", 'tx')
3136 call assert_equal(7, col('.'))
3137 call feedkeys("\<c-left>", 'tx')
3138 call assert_equal(13, col('.'))
3139 call feedkeys("\<s-left>", 'tx')
3140 call assert_equal(19, col('.'))
3141 call feedkeys("<<", 'tx')
3142 call assert_equal(' abcde fghij klmnopq',getline(1))
3143 call feedkeys(">>", 'tx')
3144 call assert_equal('abcde fghij klmnopq',getline(1))
3145
3146 " cleanup
3147 set norl
3148 bw!
3149endfunc
3150
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003151func Test_normal54_Ctrl_bsl()
3152 new
3153 call setline(1, 'abcdefghijklmn')
3154 exe "norm! df\<c-\>\<c-n>"
3155 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3156 exe "norm! df\<c-\>\<c-g>"
3157 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3158 exe "norm! df\<c-\>m"
3159 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003160
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003161 call setline(2, 'abcdefghijklmnāf')
3162 norm! 2gg0
3163 exe "norm! df\<Char-0x101>"
3164 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3165 norm! 1gg0
3166 exe "norm! df\<esc>"
3167 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003168
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003169 " clean up
3170 bw!
3171endfunc
3172
3173func Test_normal_large_count()
3174 " This may fail with 32bit long, how do we detect that?
3175 new
3176 normal o
3177 normal 6666666666dL
3178 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003179endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003180
3181func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003182 new
3183 normal grádv}
3184 call assert_equal('á', getline(1))
3185 normal grád}
3186 call assert_equal('', getline(1))
3187 bwipe!
3188endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003189
3190" Test for the gr (virtual replace) command
3191" Test for the bug fixed by 7.4.387
3192func Test_gr_command()
3193 enew!
3194 let save_cpo = &cpo
3195 call append(0, ['First line', 'Second line', 'Third line'])
3196 exe "normal i\<C-G>u"
3197 call cursor(2, 1)
3198 set cpo-=X
3199 normal 4gro
3200 call assert_equal('oooond line', getline(2))
3201 undo
3202 set cpo+=X
3203 normal 4gro
3204 call assert_equal('ooooecond line', getline(2))
3205 let &cpo = save_cpo
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003206 normal! ggvegrx
3207 call assert_equal('xxxxx line', getline(1))
3208 exe "normal! gggr\<C-V>122"
3209 call assert_equal('zxxxx line', getline(1))
3210 set virtualedit=all
3211 normal! 15|grl
3212 call assert_equal('zxxxx line l', getline(1))
3213 set virtualedit&
3214 set nomodifiable
3215 call assert_fails('normal! grx', 'E21:')
3216 call assert_fails('normal! gRx', 'E21:')
3217 set modifiable&
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003218 enew!
3219endfunc
3220
3221" When splitting a window the changelist position is wrong.
3222" Test the changelist position after splitting a window.
3223" Test for the bug fixed by 7.4.386
3224func Test_changelist()
3225 let save_ul = &ul
3226 enew!
3227 call append('$', ['1', '2'])
3228 exe "normal i\<C-G>u"
3229 exe "normal Gkylpa\<C-G>u"
3230 set ul=100
3231 exe "normal Gylpa\<C-G>u"
3232 set ul=100
3233 normal gg
3234 vsplit
3235 normal g;
3236 call assert_equal([3, 2], [line('.'), col('.')])
3237 normal g;
3238 call assert_equal([2, 2], [line('.'), col('.')])
3239 call assert_fails('normal g;', 'E662:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003240 new
3241 call assert_fails('normal g;', 'E664:')
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003242 %bwipe!
3243 let &ul = save_ul
3244endfunc
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003245
3246func Test_nv_hat_count()
3247 %bwipeout!
3248 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003249 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003250
3251 edit Xfoo
3252 let l:foo_nr = bufnr('Xfoo')
3253
3254 edit Xbar
3255 let l:bar_nr = bufnr('Xbar')
3256
3257 " Make sure we are not just using the alternate file.
3258 edit Xbaz
3259
3260 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3261 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3262
3263 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3264 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3265
3266 %bwipeout!
3267endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003268
3269func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003270 " Make sure no buffers are changed.
3271 %bwipe!
3272
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003273 exe "normal \<C-C>"
3274 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003275
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003276 new
3277 cal setline(1, 'hi!')
3278 exe "normal \<C-C>"
3279 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003280
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003281 bwipe!
3282endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003283
3284" Test for '[m', ']m', '[M' and ']M'
3285" Jumping to beginning and end of methods in Java-like languages
3286func Test_java_motion()
3287 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003288 call assert_beeps('normal! [m')
3289 call assert_beeps('normal! ]m')
3290 call assert_beeps('normal! [M')
3291 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003292 let lines =<< trim [CODE]
3293 Piece of Java
3294 {
3295 tt m1 {
3296 t1;
3297 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003298
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003299 tt m2 {
3300 t2;
3301 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003302
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003303 tt m3 {
3304 if (x)
3305 {
3306 t3;
3307 }
3308 } e3
3309 }
3310 [CODE]
3311 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003312
3313 normal gg
3314
3315 normal 2]maA
3316 call assert_equal("\ttt m1 {A", getline('.'))
3317 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3318
3319 normal j]maB
3320 call assert_equal("\ttt m2 {B", getline('.'))
3321 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3322
3323 normal ]maC
3324 call assert_equal("\ttt m3 {C", getline('.'))
3325 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3326
3327 normal [maD
3328 call assert_equal("\ttt m3 {DC", getline('.'))
3329 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3330
3331 normal k2[maE
3332 call assert_equal("\ttt m1 {EA", getline('.'))
3333 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3334
3335 normal 3[maF
3336 call assert_equal("{F", getline('.'))
3337 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3338
3339 normal ]MaG
3340 call assert_equal("\t}G e1", getline('.'))
3341 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3342
3343 normal j2]MaH
3344 call assert_equal("\t}H e3", getline('.'))
3345 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3346
3347 normal ]M]M
3348 normal aI
3349 call assert_equal("}I", getline('.'))
3350 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3351
3352 normal 2[MaJ
3353 call assert_equal("\t}JH e3", getline('.'))
3354 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3355
3356 normal k[MaK
3357 call assert_equal("\t}K e2", getline('.'))
3358 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3359
3360 normal 3[MaL
3361 call assert_equal("{LF", getline('.'))
3362 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3363
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003364 call cursor(2, 1)
3365 call assert_beeps('norm! 5]m')
3366
3367 " jumping to a method in a fold should open the fold
3368 6,10fold
3369 call feedkeys("gg3]m", 'xt')
3370 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3371 call assert_equal(-1, foldclosedend(7))
3372
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003373 close!
3374endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003375
Bram Moolenaar004a6782020-04-11 17:09:31 +02003376" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003377func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003378 call Setup_NewWindow()
3379 " Make long lines that will wrap
3380 %s/$/\=repeat(' foobar', 10)/
3381 20vsp
3382 set wrap
3383 " Test for g$ with count
3384 norm! gg
3385 norm! 0vg$y
3386 call assert_equal(20, col("'>"))
3387 call assert_equal('1 foobar foobar foob', getreg(0))
3388 norm! gg
3389 norm! 0v4g$y
3390 call assert_equal(72, col("'>"))
3391 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3392 norm! gg
3393 norm! 0v6g$y
3394 call assert_equal(40, col("'>"))
3395 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3396 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3397 set nowrap
3398 " clean up
3399 norm! gg
3400 norm! 0vg$y
3401 call assert_equal(20, col("'>"))
3402 call assert_equal('1 foobar foobar foob', getreg(0))
3403 norm! gg
3404 norm! 0v4g$y
3405 call assert_equal(20, col("'>"))
3406 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3407 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3408 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3409 \ '4 foobar foobar foob', getreg(0))
3410 norm! gg
3411 norm! 0v6g$y
3412 call assert_equal(20, col("'>"))
3413 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3414 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3415 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3416 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3417 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3418 \ '6 foobar foobar foob', getreg(0))
3419 " Move to last line, also down movement is not possible, should still move
3420 " the cursor to the last visible char
3421 norm! G
3422 norm! 0v6g$y
3423 call assert_equal(20, col("'>"))
3424 call assert_equal('100 foobar foobar fo', getreg(0))
3425 bw!
3426endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003427
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003428func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003429 " needs 80 column new window
3430 new
3431 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003432 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003433 put =[repeat('x',90)..' {{{1', 'x {{{1']
3434 norm! gk
3435 " In a 80 column wide terminal the window will be only 78 char
3436 " (because Vim will leave space for the other window),
3437 " but if the terminal is larger, it will be 80 chars, so verify the
3438 " cursor column correctly.
3439 call assert_equal(winwidth(0)+1, col('.'))
3440 call assert_equal(winwidth(0)+1, virtcol('.'))
3441 norm! j
3442 call assert_equal(6, col('.'))
3443 call assert_equal(6, virtcol('.'))
3444 norm! gk
3445 call assert_equal(95, col('.'))
3446 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003447 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003448
3449 " needs 80 column new window
3450 new
3451 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003452 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003453 set number
3454 set numberwidth=10
3455 set cpoptions+=n
3456 put =[repeat('0',90), repeat('1',90)]
3457 norm! 075l
3458 call assert_equal(76, col('.'))
3459 norm! gk
3460 call assert_equal(1, col('.'))
3461 norm! gk
3462 call assert_equal(76, col('.'))
3463 norm! gk
3464 call assert_equal(1, col('.'))
3465 norm! gj
3466 call assert_equal(76, col('.'))
3467 norm! gj
3468 call assert_equal(1, col('.'))
3469 norm! gj
3470 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003471 " When 'nowrap' is set, gk and gj behave like k and j
3472 set nowrap
3473 normal! gk
3474 call assert_equal([2, 76], [line('.'), col('.')])
3475 normal! gj
3476 call assert_equal([3, 76], [line('.'), col('.')])
3477 %bw!
3478 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003479endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003480
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003481" Test for using : to run a multi-line Ex command in operator pending mode
3482func Test_normal_yank_with_excmd()
3483 new
3484 call setline(1, ['foo', 'bar', 'baz'])
3485 let @a = ''
3486 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3487 call assert_equal('f', @a)
3488 close!
3489endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003490
3491" Test for supplying a count to a normal-mode command across a cursorhold call
3492func Test_normal_cursorhold_with_count()
3493 func s:cHold()
3494 let g:cHold_Called += 1
3495 endfunc
3496 new
3497 augroup normalcHoldTest
3498 au!
3499 au CursorHold <buffer> call s:cHold()
3500 augroup END
3501 let g:cHold_Called = 0
3502 call feedkeys("3\<CursorHold>2ix", 'xt')
3503 call assert_equal(1, g:cHold_Called)
3504 call assert_equal(repeat('x', 32), getline(1))
3505 augroup normalcHoldTest
3506 au!
3507 augroup END
3508 au! normalcHoldTest
3509 close!
3510 delfunc s:cHold
3511endfunc
3512
3513" Test for using a count and a command with CTRL-W
3514func Test_wincmd_with_count()
3515 call feedkeys("\<C-W>12n", 'xt')
3516 call assert_equal(12, winheight(0))
3517endfunc
3518
3519" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003520func Test_horiz_motion()
3521 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003522 normal! gg
3523 call assert_beeps('normal! b')
3524 call assert_beeps('normal! B')
3525 call assert_beeps('normal! gE')
3526 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003527 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3528 call setline(1, 'one ,two ,three')
3529 exe "normal! $\<S-BS>"
3530 call assert_equal(11, col('.'))
3531 exe "normal! $\<C-BS>"
3532 call assert_equal(10, col('.'))
3533 close!
3534endfunc
3535
3536" Test for using a : command in operator pending mode
3537func Test_normal_colon_op()
3538 new
3539 call setline(1, ['one', 'two'])
3540 call assert_beeps("normal! Gc:d\<CR>")
3541 close!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003542endfunc
3543
Bram Moolenaar004a6782020-04-11 17:09:31 +02003544" Test for d and D commands
3545func Test_normal_delete_cmd()
3546 new
3547 " D in an empty line
3548 call setline(1, '')
3549 normal D
3550 call assert_equal('', getline(1))
3551 " D in an empty line in virtualedit mode
3552 set virtualedit=all
3553 normal D
3554 call assert_equal('', getline(1))
3555 set virtualedit&
3556 " delete to a readonly register
3557 call setline(1, ['abcd'])
3558 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003559
3560 " D and d with 'nomodifiable'
3561 call setline(1, ['abcd'])
3562 setlocal nomodifiable
3563 call assert_fails('normal D', 'E21:')
3564 call assert_fails('normal d$', 'E21:')
3565
Bram Moolenaar004a6782020-04-11 17:09:31 +02003566 close!
3567endfunc
3568
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003569" Test for deleting or changing characters across lines with 'whichwrap'
3570" containing 's'. Should count <EOL> as one character.
3571func Test_normal_op_across_lines()
3572 new
3573 set whichwrap&
3574 call setline(1, ['one two', 'three four'])
3575 exe "norm! $3d\<Space>"
3576 call assert_equal(['one twhree four'], getline(1, '$'))
3577
3578 call setline(1, ['one two', 'three four'])
3579 exe "norm! $3c\<Space>x"
3580 call assert_equal(['one twxhree four'], getline(1, '$'))
3581
3582 set whichwrap+=l
3583 call setline(1, ['one two', 'three four'])
3584 exe "norm! $3x"
3585 call assert_equal(['one twhree four'], getline(1, '$'))
3586 close!
3587 set whichwrap&
3588endfunc
3589
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003590" Test for 'w' and 'b' commands
3591func Test_normal_word_move()
3592 new
3593 call setline(1, ['foo bar a', '', 'foo bar b'])
3594 " copy a single character word at the end of a line
3595 normal 1G$yw
3596 call assert_equal('a', @")
3597 " copy a single character word at the end of a file
3598 normal G$yw
3599 call assert_equal('b', @")
3600 " check for a word movement handling an empty line properly
3601 normal 1G$vwy
3602 call assert_equal("a\n\n", @")
3603
3604 " copy using 'b' command
3605 %d
3606 " non-empty blank line at the start of file
3607 call setline(1, [' ', 'foo bar'])
3608 normal 2Gyb
3609 call assert_equal(" \n", @")
3610 " try to copy backwards from the start of the file
3611 call setline(1, ['one two', 'foo bar'])
3612 call assert_beeps('normal ggyb')
3613 " 'b' command should stop at an empty line
3614 call setline(1, ['one two', '', 'foo bar'])
3615 normal 3Gyb
3616 call assert_equal("\n", @")
3617 normal 3Gy2b
3618 call assert_equal("two\n", @")
3619 " 'b' command should not stop at a non-empty blank line
3620 call setline(1, ['one two', ' ', 'foo bar'])
3621 normal 3Gyb
3622 call assert_equal("two\n ", @")
3623
3624 close!
3625endfunc
3626
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003627" Test for 'scrolloff' with a long line that doesn't fit in the screen
3628func Test_normal_scroloff()
3629 10new
3630 80vnew
3631 call setline(1, repeat('a', 1000))
3632 set scrolloff=10
3633 normal gg10gj
3634 call assert_equal(8, winline())
3635 normal 10gj
3636 call assert_equal(10, winline())
3637 normal 10gk
3638 call assert_equal(3, winline())
3639 set scrolloff&
3640 close!
3641endfunc
3642
3643" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3644func Test_normal_vert_scroll_longline()
3645 10new
3646 80vnew
3647 call setline(1, range(1, 10))
3648 call append(5, repeat('a', 1000))
3649 exe "normal gg\<C-F>"
3650 call assert_equal(6, line('.'))
3651 exe "normal \<C-F>\<C-F>"
3652 call assert_equal(11, line('.'))
3653 call assert_equal(1, winline())
3654 exe "normal \<C-B>"
3655 call assert_equal(10, line('.'))
3656 call assert_equal(3, winline())
3657 exe "normal \<C-B>\<C-B>"
3658 call assert_equal(5, line('.'))
3659 call assert_equal(5, winline())
3660 close!
3661endfunc
3662
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003663" Test for jumping in a file using %
3664func Test_normal_percent_jump()
3665 new
3666 call setline(1, range(1, 100))
3667
3668 " jumping to a folded line should open the fold
3669 25,75fold
3670 call feedkeys('50%', 'xt')
3671 call assert_equal(50, line('.'))
3672 call assert_equal(-1, foldclosedend(50))
3673 close!
3674endfunc
3675
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003676" Test for << and >> commands to shift text by 'shiftwidth'
3677func Test_normal_shift_rightleft()
3678 new
3679 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3680 set shiftwidth=2 tabstop=8
3681 normal gg6>>
3682 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3683 \ getline(1, '$'))
3684 normal ggVG2>>
3685 call assert_equal([' one', '', "\t ", "\ttwo",
3686 \ "\t three", "\t four"], getline(1, '$'))
3687 normal gg6<<
3688 call assert_equal([' one', '', "\t ", ' two', "\t three",
3689 \ "\t four"], getline(1, '$'))
3690 normal ggVG2<<
3691 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3692 \ getline(1, '$'))
3693 set shiftwidth& tabstop&
3694 bw!
3695endfunc
3696
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003697" Some commands like yy, cc, dd, >>, << and !! accept a count after
3698" typing the first letter of the command.
3699func Test_normal_count_after_operator()
3700 new
3701 setlocal shiftwidth=4 tabstop=8 autoindent
3702 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3703 let @a = ''
3704 normal! j"ay4y
3705 call assert_equal("two\nthree\nfour\nfive\n", @a)
3706 normal! 3G>2>
3707 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3708 \ getline(1, '$'))
3709 exe "normal! 3G0c2cred\nblue"
3710 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3711 \ getline(1, '$'))
3712 exe "normal! gg<8<"
3713 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3714 \ getline(1, '$'))
3715 exe "normal! ggd3d"
3716 call assert_equal(['blue', 'five'], getline(1, '$'))
3717 call setline(1, range(1, 4))
3718 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3719 call assert_equal('".,.+2!', @:)
3720 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3721 call assert_equal('".!', @:)
3722 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3723 call assert_equal('".,$!', @:)
3724 bw!
3725endfunc
3726
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003727func Test_normal_gj_on_extra_wide_char()
3728 new | 25vsp
3729 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3730 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3731 \ ' dreizehn v ierzehn fünfzehn'
3732 put =text
3733 call cursor(2,1)
3734 norm! gj
3735 call assert_equal([0,2,25,0], getpos('.'))
3736 bw!
3737endfunc
3738
Bram Moolenaar03725c52021-11-24 12:17:53 +00003739func Test_normal_count_out_of_range()
3740 new
3741 call setline(1, 'text')
3742 normal 44444444444|
3743 call assert_equal(999999999, v:count)
3744 normal 444444444444|
3745 call assert_equal(999999999, v:count)
3746 normal 4444444444444|
3747 call assert_equal(999999999, v:count)
3748 normal 4444444444444444444|
3749 call assert_equal(999999999, v:count)
3750
3751 normal 9y99999999|
3752 call assert_equal(899999991, v:count)
3753 normal 10y99999999|
3754 call assert_equal(999999999, v:count)
3755 normal 44444444444y44444444444|
3756 call assert_equal(999999999, v:count)
3757 bwipe!
3758endfunc
3759
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003760" vim: shiftwidth=2 sts=2 expandtab