blob: 069651f6bcbabde322494b611f57ca50f0e40166 [file] [log] [blame]
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001" Test for various Normal mode commands
2
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003source shared.vim
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01004source check.vim
Bram Moolenaarca68ae12020-03-30 19:32:53 +02005source view_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00006import './vim9.vim' as v9
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01007source screendump.vim
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01008
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01009func Setup_NewWindow()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020010 10new
11 call setline(1, range(1,100))
12endfunc
13
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010014func MyFormatExpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020015 " Adds '->$' at lines having numbers followed by trailing whitespace
16 for ln in range(v:lnum, v:lnum+v:count-1)
17 let line = getline(ln)
18 if getline(ln) =~# '\d\s\+$'
19 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
20 endif
21 endfor
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020022endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020023
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010024func CountSpaces(type, ...)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020025 " for testing operatorfunc
26 " will count the number of spaces
27 " and return the result in g:a
28 let sel_save = &selection
29 let &selection = "inclusive"
30 let reg_save = @@
31
32 if a:0 " Invoked from Visual mode, use gv command.
33 silent exe "normal! gvy"
34 elseif a:type == 'line'
35 silent exe "normal! '[V']y"
36 else
37 silent exe "normal! `[v`]y"
38 endif
Bram Moolenaar777e7c22021-10-25 17:07:04 +010039 let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020040 let &selection = sel_save
41 let @@ = reg_save
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020042endfunc
43
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010044func OpfuncDummy(type, ...)
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010045 " for testing operatorfunc
Bram Moolenaar777e7c22021-10-25 17:07:04 +010046 let g:opt = &linebreak
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010047
48 if a:0 " Invoked from Visual mode, use gv command.
49 silent exe "normal! gvy"
50 elseif a:type == 'line'
51 silent exe "normal! '[V']y"
52 else
53 silent exe "normal! `[v`]y"
54 endif
55 " Create a new dummy window
56 new
Bram Moolenaar777e7c22021-10-25 17:07:04 +010057 let g:bufnr = bufnr('%')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020058endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020059
Bram Moolenaar1671f442020-03-10 07:48:13 +010060func Test_normal00_optrans()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020061 new
62 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
63 1
64 exe "norm! Sfoobar\<esc>"
65 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
66 2
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020067 exe "norm! $vbsone"
68 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 +020069 norm! VS Second line here
70 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
71 %d
72 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
73 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
74
75 1
76 norm! 2D
77 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,'$'))
78 set cpo+=#
79 norm! 4D
80 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
81
82 " clean up
83 set cpo-=#
84 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020085endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020086
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010087func Test_normal01_keymodel()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020088 call Setup_NewWindow()
89 " Test 1: depending on 'keymodel' <s-down> does something different
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020090 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020091 call feedkeys("V\<S-Up>y", 'tx')
92 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020093 set keymodel=startsel
94 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020095 call feedkeys("V\<S-Up>y", 'tx')
96 call assert_equal(['49', '50'], getline("'<", "'>"))
97 " Start visual mode when keymodel = startsel
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020098 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020099 call feedkeys("\<S-Up>y", 'tx')
100 call assert_equal(['49', '5'], getreg(0, 0, 1))
Bram Moolenaar1671f442020-03-10 07:48:13 +0100101 " Use the different Shift special keys
102 50
103 call feedkeys("\<S-Right>\<S-Left>\<S-Up>\<S-Down>\<S-Home>\<S-End>y", 'tx')
104 call assert_equal(['50'], getline("'<", "'>"))
105 call assert_equal(['50', ''], getreg(0, 0, 1))
106
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200107 " Do not start visual mode when keymodel=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200108 set keymodel=
109 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200110 call feedkeys("\<S-Up>y$", 'tx')
111 call assert_equal(['42'], getreg(0, 0, 1))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200112 " Stop visual mode when keymodel=stopsel
113 set keymodel=stopsel
114 50
115 call feedkeys("Vkk\<Up>yy", 'tx')
116 call assert_equal(['47'], getreg(0, 0, 1))
117
118 set keymodel=
119 50
120 call feedkeys("Vkk\<Up>yy", 'tx')
121 call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200122
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200123 " Test for using special keys to start visual selection
124 %d
125 call setline(1, ['red fox tail', 'red fox tail', 'red fox tail'])
126 set keymodel=startsel
127 " Test for <S-PageUp> and <S-PageDown>
128 call cursor(1, 1)
129 call feedkeys("\<S-PageDown>y", 'xt')
130 call assert_equal([0, 1, 1, 0], getpos("'<"))
131 call assert_equal([0, 3, 1, 0], getpos("'>"))
132 call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
Luuk van Baalb9f5b952024-03-26 18:46:45 +0100133 call assert_equal([0, 3, 1, 0], getpos("'<"))
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200134 call assert_equal([0, 3, 8, 0], getpos("'>"))
135 " Test for <S-C-Home> and <S-C-End>
136 call cursor(2, 12)
137 call feedkeys("\<S-C-Home>y", 'xt')
138 call assert_equal([0, 1, 1, 0], getpos("'<"))
139 call assert_equal([0, 2, 12, 0], getpos("'>"))
140 call cursor(1, 4)
141 call feedkeys("\<S-C-End>y", 'xt')
142 call assert_equal([0, 1, 4, 0], getpos("'<"))
143 call assert_equal([0, 3, 13, 0], getpos("'>"))
144 " Test for <S-C-Left> and <S-C-Right>
145 call cursor(2, 5)
146 call feedkeys("\<S-C-Right>y", 'xt')
147 call assert_equal([0, 2, 5, 0], getpos("'<"))
148 call assert_equal([0, 2, 9, 0], getpos("'>"))
149 call cursor(2, 9)
150 call feedkeys("\<S-C-Left>y", 'xt')
151 call assert_equal([0, 2, 5, 0], getpos("'<"))
152 call assert_equal([0, 2, 9, 0], getpos("'>"))
153
154 set keymodel&
155
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200156 " clean up
157 bw!
158endfunc
159
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100160func Test_normal03_join()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200161 " basic join test
162 call Setup_NewWindow()
163 50
164 norm! VJ
165 call assert_equal('50 51', getline('.'))
166 $
167 norm! J
168 call assert_equal('100', getline('.'))
169 $
170 norm! V9-gJ
171 call assert_equal('919293949596979899100', getline('.'))
172 call setline(1, range(1,100))
173 $
174 :j 10
175 call assert_equal('100', getline('.'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200176 call assert_beeps('normal GVJ')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200177 " clean up
178 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200179endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200180
Bram Moolenaar004a6782020-04-11 17:09:31 +0200181" basic filter test
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100182func Test_normal04_filter()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200183 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200184 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200185 call Setup_NewWindow()
186 1
187 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
188 call assert_equal('| 1', getline('.'))
189 90
190 :sil :!echo one
191 call feedkeys('.', 'tx')
192 call assert_equal('| 90', getline('.'))
193 95
194 set cpo+=!
195 " 2 <CR>, 1: for executing the command,
196 " 2: clear hit-enter-prompt
197 call feedkeys("!!\n", 'tx')
198 call feedkeys(":!echo one\n\n", 'tx')
199 call feedkeys(".", 'tx')
200 call assert_equal('one', getline('.'))
201 set cpo-=!
202 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200203endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200204
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100205func Test_normal05_formatexpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200206 " basic formatexpr test
207 call Setup_NewWindow()
208 %d_
209 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
210 1
211 set formatexpr=MyFormatExpr()
212 norm! gqG
213 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
214 set formatexpr=
215 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200216endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200217
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200218func Test_normal05_formatexpr_newbuf()
219 " Edit another buffer in the 'formatexpr' function
220 new
221 func! Format()
222 edit another
223 endfunc
224 set formatexpr=Format()
225 norm gqG
226 bw!
227 set formatexpr=
228endfunc
229
230func Test_normal05_formatexpr_setopt()
231 " Change the 'formatexpr' value in the function
232 new
233 func! Format()
234 set formatexpr=
235 endfunc
236 set formatexpr=Format()
237 norm gqG
238 bw!
239 set formatexpr=
240endfunc
241
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200242" When 'formatexpr' returns non-zero, internal formatting is used.
243func Test_normal_formatexpr_returns_nonzero()
244 new
245 call setline(1, ['one', 'two'])
246 func! Format()
247 return 1
248 endfunc
249 setlocal formatexpr=Format()
250 normal VGgq
251 call assert_equal(['one two'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +0000252
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200253 setlocal formatexpr=
254 delfunc Format
Yee Cheng Chin1881abf2022-12-08 09:41:24 +0000255 bwipe!
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200256endfunc
257
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000258" Test for using a script-local function for 'formatexpr'
259func Test_formatexpr_scriptlocal_func()
260 func! s:Format()
261 let g:FormatArgs = [v:lnum, v:count]
262 endfunc
263 set formatexpr=s:Format()
264 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000265 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000266 new | only
267 call setline(1, range(1, 40))
268 let g:FormatArgs = []
269 normal! 2GVjgq
270 call assert_equal([2, 2], g:FormatArgs)
271 bw!
272 set formatexpr=<SID>Format()
273 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000274 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000275 new | only
276 call setline(1, range(1, 40))
277 let g:FormatArgs = []
278 normal! 4GVjgq
279 call assert_equal([4, 2], g:FormatArgs)
280 bw!
281 let &formatexpr = 's:Format()'
zeertzjq01d4efe2023-01-25 15:31:28 +0000282 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000283 new | only
284 call setline(1, range(1, 40))
285 let g:FormatArgs = []
286 normal! 6GVjgq
287 call assert_equal([6, 2], g:FormatArgs)
288 bw!
289 let &formatexpr = '<SID>Format()'
zeertzjq01d4efe2023-01-25 15:31:28 +0000290 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000291 new | only
292 call setline(1, range(1, 40))
293 let g:FormatArgs = []
294 normal! 8GVjgq
295 call assert_equal([8, 2], g:FormatArgs)
zeertzjq01d4efe2023-01-25 15:31:28 +0000296 bw!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000297 setlocal formatexpr=
zeertzjq01d4efe2023-01-25 15:31:28 +0000298 setglobal formatexpr=s:Format()
299 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
300 call assert_equal('', &formatexpr)
301 new
302 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
303 call setline(1, range(1, 40))
304 let g:FormatArgs = []
305 normal! 10GVjgq
306 call assert_equal([10, 2], g:FormatArgs)
307 bw!
308 setglobal formatexpr=<SID>Format()
309 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
310 call assert_equal('', &formatexpr)
311 new
312 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
313 call setline(1, range(1, 40))
314 let g:FormatArgs = []
315 normal! 12GVjgq
316 call assert_equal([12, 2], g:FormatArgs)
317 bw!
318 let &g:formatexpr = 's:Format()'
319 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
320 call assert_equal('', &formatexpr)
321 new
322 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
323 call setline(1, range(1, 40))
324 let g:FormatArgs = []
325 normal! 14GVjgq
326 call assert_equal([14, 2], g:FormatArgs)
327 bw!
328 let &g:formatexpr = '<SID>Format()'
329 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
330 call assert_equal('', &formatexpr)
331 new
332 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
333 call setline(1, range(1, 40))
334 let g:FormatArgs = []
335 normal! 16GVjgq
336 call assert_equal([16, 2], g:FormatArgs)
337 bw!
338 set formatexpr=
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000339 delfunc s:Format
340 bw!
341endfunc
342
Bram Moolenaar004a6782020-04-11 17:09:31 +0200343" basic test for formatprg
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100344func Test_normal06_formatprg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200345 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200346 CheckNotMSWindows
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100347
348 " uses sed to number non-empty lines
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100349 call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh', 'D')
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100350 call system('chmod +x ./Xsed_format.sh')
351 let text = ['a', '', 'c', '', ' ', 'd', 'e']
352 let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
353
354 10new
355 call setline(1, text)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200356 set formatprg=./Xsed_format.sh
357 norm! gggqG
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100358 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200359 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100360
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100361 call setline(1, text)
362 set formatprg=donothing
363 setlocal formatprg=./Xsed_format.sh
364 norm! gggqG
365 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200366 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100367
Bram Moolenaar004a6782020-04-11 17:09:31 +0200368 " Check for the command-line ranges added to 'formatprg'
369 set formatprg=cat
370 call setline(1, ['one', 'two', 'three', 'four', 'five'])
371 call feedkeys('gggqG', 'xt')
372 call assert_equal('.,$!cat', @:)
373 call feedkeys('2Ggq2j', 'xt')
374 call assert_equal('.,.+2!cat', @:)
375
376 bw!
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200377 " clean up
378 set formatprg=
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100379 setlocal formatprg=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200380endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200381
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100382func Test_normal07_internalfmt()
Christian Brabandtee17b6f2023-09-09 11:23:50 +0200383 " basic test for internal formatter to textwidth of 12
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200384 let list=range(1,11)
385 call map(list, 'v:val." "')
386 10new
387 call setline(1, list)
388 set tw=12
Bram Moolenaar004a6782020-04-11 17:09:31 +0200389 norm! ggVGgq
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200390 call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
391 " clean up
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100392 set tw=0
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200393 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200394endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200395
Bram Moolenaar004a6782020-04-11 17:09:31 +0200396" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100397func Test_normal08_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +0200398 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200399 call Setup_NewWindow()
400 50
401 setl foldenable fdm=marker
402 " First fold
403 norm! V4jzf
404 " check that folds have been created
Riley Bruins0a083062024-06-03 20:40:45 +0200405 call assert_equal(['50/* {{{ */', '51', '52', '53', '54/* }}} */'], getline(50,54))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200406 " Second fold
407 46
408 norm! V10jzf
409 " check that folds have been created
Riley Bruins0a083062024-06-03 20:40:45 +0200410 call assert_equal('46/* {{{ */', getline(46))
411 call assert_equal('60/* }}} */', getline(60))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200412 norm! k
413 call assert_equal('45', getline('.'))
414 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +0200415 call assert_equal('46/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200416 norm! j
417 call assert_equal('61', getline('.'))
418 norm! k
419 " open a fold
420 norm! Vzo
421 norm! k
422 call assert_equal('45', getline('.'))
423 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +0200424 call assert_equal('46/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200425 norm! j
426 call assert_equal('47', getline('.'))
427 norm! k
428 norm! zcVzO
Riley Bruins0a083062024-06-03 20:40:45 +0200429 call assert_equal('46/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200430 norm! j
431 call assert_equal('47', getline('.'))
432 norm! j
433 call assert_equal('48', getline('.'))
434 norm! j
435 call assert_equal('49', getline('.'))
436 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +0200437 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200438 norm! j
439 call assert_equal('51', getline('.'))
440 " delete folds
441 :46
442 " collapse fold
443 norm! V14jzC
444 " delete all folds recursively
445 norm! VzD
446 call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
447
448 " clean up
449 setl nofoldenable fdm=marker
450 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200451endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200452
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000453func Test_normal09a_operatorfunc()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200454 " Test operatorfunc
455 call Setup_NewWindow()
456 " Add some spaces for counting
457 50,60s/$/ /
458 unlet! g:a
459 let g:a=0
460 nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
461 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
462 50
463 norm V2j,,
464 call assert_equal(6, g:a)
465 norm V,,
466 call assert_equal(2, g:a)
467 norm ,,l
468 call assert_equal(0, g:a)
469 50
470 exe "norm 0\<c-v>10j2l,,"
471 call assert_equal(11, g:a)
472 50
473 norm V10j,,
474 call assert_equal(22, g:a)
475
476 " clean up
477 unmap <buffer> ,,
478 set opfunc=
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100479 unlet! g:a
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200480 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200481endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200482
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000483func Test_normal09b_operatorfunc()
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100484 " Test operatorfunc
485 call Setup_NewWindow()
486 " Add some spaces for counting
487 50,60s/$/ /
488 unlet! g:opt
489 set linebreak
490 nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
491 50
492 norm ,,j
493 exe "bd!" g:bufnr
494 call assert_true(&linebreak)
495 call assert_equal(g:opt, &linebreak)
496 set nolinebreak
497 norm ,,j
498 exe "bd!" g:bufnr
499 call assert_false(&linebreak)
500 call assert_equal(g:opt, &linebreak)
501
502 " clean up
503 unmap <buffer> ,,
504 set opfunc=
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200505 call assert_fails('normal Vg@', 'E774:')
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100506 bw!
507 unlet! g:opt
508endfunc
509
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000510func OperatorfuncRedo(_)
511 let g:opfunc_count = v:count
512endfunc
513
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000514func Underscorize(_)
515 normal! '[V']r_
516endfunc
517
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000518func Test_normal09c_operatorfunc()
519 " Test redoing operatorfunc
520 new
521 call setline(1, 'some text')
522 set operatorfunc=OperatorfuncRedo
523 normal v3g@
524 call assert_equal(3, g:opfunc_count)
525 let g:opfunc_count = 0
526 normal .
527 call assert_equal(3, g:opfunc_count)
528
529 bw!
530 unlet g:opfunc_count
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000531
532 " Test redoing Visual mode
533 set operatorfunc=Underscorize
534 new
535 call setline(1, ['first', 'first', 'third', 'third', 'second'])
naohiro ono5c75eed2022-01-03 11:15:47 +0000536 normal! 1GVjg@
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000537 normal! 5G.
538 normal! 3G.
539 call assert_equal(['_____', '_____', '_____', '_____', '______'], getline(1, '$'))
540 bwipe!
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000541 set operatorfunc=
542endfunc
543
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000544" Test for different ways of setting the 'operatorfunc' option
545func Test_opfunc_callback()
546 new
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000547 func OpFunc1(callnr, type)
548 let g:OpFunc1Args = [a:callnr, a:type]
549 endfunc
550 func OpFunc2(type)
551 let g:OpFunc2Args = [a:type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000552 endfunc
553
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000554 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000555 #" Test for using a function name
556 LET &opfunc = 'g:OpFunc2'
557 LET g:OpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000558 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000559 call assert_equal(['char'], g:OpFunc2Args)
560
561 #" Test for using a function()
562 set opfunc=function('g:OpFunc1',\ [10])
563 LET g:OpFunc1Args = []
564 normal! g@l
565 call assert_equal([10, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000566
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000567 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000568 VAR Fn = function('g:OpFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000569 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000570 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000571 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000572 call assert_equal([11, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000573
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000574 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000575 LET Fn = function('g:OpFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000576 LET &operatorfunc = string(Fn)
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([12, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000580
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000581 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000582 set operatorfunc=funcref('g:OpFunc1',\ [13])
583 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000584 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000585 call assert_equal([13, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000586
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000587 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000588 LET Fn = funcref('g:OpFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000589 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000590 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000591 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000592 call assert_equal([14, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000593
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000594 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000595 LET Fn = funcref('g:OpFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000596 LET &opfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000597 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000598 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000599 call assert_equal([15, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000600
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000601 #" Test for using a lambda function using set
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000602 VAR optval = "LSTART a LMIDDLE OpFunc1(16, a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000603 LET optval = substitute(optval, ' ', '\\ ', 'g')
604 exe "set opfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000605 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000606 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000607 call assert_equal([16, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000608
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000609 #" Test for using a lambda function using LET
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000610 LET &opfunc = LSTART a LMIDDLE OpFunc1(17, a) LEND
611 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000612 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000613 call assert_equal([17, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000614
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000615 #" Set 'operatorfunc' to a string(lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000616 LET &opfunc = 'LSTART a LMIDDLE OpFunc1(18, a) LEND'
617 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000618 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000619 call assert_equal([18, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000620
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000621 #" Set 'operatorfunc' to a variable with a lambda expression
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000622 VAR Lambda = LSTART a LMIDDLE OpFunc1(19, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000623 LET &opfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000624 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000625 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000626 call assert_equal([19, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000627
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000628 #" Set 'operatorfunc' to a string(variable with a lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000629 LET Lambda = LSTART a LMIDDLE OpFunc1(20, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000630 LET &opfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000631 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000632 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000633 call assert_equal([20, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000634
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000635 #" Try to use 'operatorfunc' after the function is deleted
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000636 func g:TmpOpFunc1(type)
637 let g:TmpOpFunc1Args = [21, a:type]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000638 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000639 LET &opfunc = function('g:TmpOpFunc1')
640 delfunc g:TmpOpFunc1
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000641 call test_garbagecollect_now()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000642 LET g:TmpOpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000643 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000644 call assert_equal([], g:TmpOpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000645
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000646 #" Try to use a function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000647 func g:TmpOpFunc2(x, y)
648 let g:TmpOpFunc2Args = [a:x, a:y]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000649 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000650 set opfunc=TmpOpFunc2
651 LET g:TmpOpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000652 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000653 call assert_equal([], g:TmpOpFunc2Args)
654 delfunc TmpOpFunc2
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000655
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000656 #" Try to use a lambda function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000657 LET &opfunc = LSTART a, b LMIDDLE OpFunc1(22, b) LEND
658 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000659 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000660 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000661
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000662 #" Test for clearing the 'operatorfunc' option
663 set opfunc=''
664 set opfunc&
665 call assert_fails("set opfunc=function('abc')", "E700:")
666 call assert_fails("set opfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000667
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000668 #" set 'operatorfunc' to a non-existing function
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000669 LET &opfunc = function('g:OpFunc1', [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000670 call assert_fails("set opfunc=function('NonExistingFunc')", 'E700:')
671 call assert_fails("LET &opfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000672 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000673 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000674 call assert_equal([23, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000675 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000676 call v9.CheckTransLegacySuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000677
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000678 " Test for using a script-local function name
679 func s:OpFunc3(type)
680 let g:OpFunc3Args = [a:type]
681 endfunc
682 set opfunc=s:OpFunc3
683 let g:OpFunc3Args = []
684 normal! g@l
685 call assert_equal(['char'], g:OpFunc3Args)
686
687 let &opfunc = 's:OpFunc3'
688 let g:OpFunc3Args = []
689 normal! g@l
690 call assert_equal(['char'], g:OpFunc3Args)
691 delfunc s:OpFunc3
692
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000693 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000694 set opfunc=(a)\ =>\ OpFunc1(24,\ a)
695 let g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000696 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000697 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000698
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000699 " set 'operatorfunc' to a partial with dict. This used to cause a crash.
700 func SetOpFunc()
701 let operator = {'execute': function('OperatorExecute')}
702 let &opfunc = operator.execute
703 endfunc
704 func OperatorExecute(_) dict
705 endfunc
706 call SetOpFunc()
707 call test_garbagecollect_now()
708 set operatorfunc=
709 delfunc SetOpFunc
710 delfunc OperatorExecute
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000711
712 " Vim9 tests
713 let lines =<< trim END
714 vim9script
715
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000716 def g:Vim9opFunc(val: number, type: string): void
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000717 g:OpFunc1Args = [val, type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000718 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000719
720 # Test for using a def function with opfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000721 set opfunc=function('g:Vim9opFunc',\ [60])
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000722 g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000723 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000724 assert_equal([60, 'char'], g:OpFunc1Args)
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000725
726 # Test for using a global function name
727 &opfunc = g:OpFunc2
728 g:OpFunc2Args = []
729 normal! g@l
730 assert_equal(['char'], g:OpFunc2Args)
731 bw!
732
733 # Test for using a script-local function name
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000734 def LocalOpFunc(type: string): void
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000735 g:LocalOpFuncArgs = [type]
736 enddef
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000737 &opfunc = LocalOpFunc
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000738 g:LocalOpFuncArgs = []
739 normal! g@l
740 assert_equal(['char'], g:LocalOpFuncArgs)
741 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000742 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000743 call v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000744
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000745 " setting 'opfunc' to a script local function outside of a script context
746 " should fail
747 let cleanup =<< trim END
748 call writefile([execute('messages')], 'Xtest.out')
749 qall
750 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100751 call writefile(cleanup, 'Xverify.vim', 'D')
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000752 call RunVim([], [], "-c \"set opfunc=s:abc\" -S Xverify.vim")
753 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
754 call delete('Xtest.out')
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000755
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000756 " cleanup
757 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000758 delfunc OpFunc1
759 delfunc OpFunc2
760 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000761 %bw!
762endfunc
763
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100764func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200765 " Test for expand()
766 10new
767 call setline(1, ['1', 'ifooar,,cbar'])
768 2
769 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200770 call assert_equal('cbar', expand('<cword>'))
771 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
772
773 call setline(1, ['prx = list[idx];'])
774 1
775 let expected = ['', 'prx', 'prx', 'prx',
776 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
777 \ 'idx', 'idx', 'idx', 'idx',
778 \ 'list[idx]',
779 \ '];',
780 \ ]
781 for i in range(1, 16)
782 exe 'norm ' . i . '|'
783 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
784 endfor
785
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200786 " Test for <cexpr> in state.val and ptr->val
787 call setline(1, 'x = state.val;')
788 call cursor(1, 10)
789 call assert_equal('state.val', expand('<cexpr>'))
790 call setline(1, 'x = ptr->val;')
791 call cursor(1, 9)
792 call assert_equal('ptr->val', expand('<cexpr>'))
793
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100794 if executable('echo')
795 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100796 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100797 endif
798
799 " Test expand(`=...`) i.e. backticks expression expansion
800 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100801 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100802
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200803 " clean up
804 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200805endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200806
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200807" Test for expand() in latin1 encoding
808func Test_normal_expand_latin1()
809 new
810 let save_enc = &encoding
811 set encoding=latin1
812 call setline(1, 'val = item->color;')
813 call cursor(1, 11)
814 call assert_equal('color', expand("<cword>"))
815 call assert_equal('item->color', expand("<cexpr>"))
816 let &encoding = save_enc
817 bw!
818endfunc
819
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100820func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200821 " test for 'showcmd'
822 10new
823 exe "norm! ofoobar\<esc>"
824 call assert_equal(2, line('$'))
825 set showcmd
826 exe "norm! ofoobar2\<esc>"
827 call assert_equal(3, line('$'))
828 exe "norm! VAfoobar3\<esc>"
829 call assert_equal(3, line('$'))
830 exe "norm! 0d3\<del>2l"
831 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200832 " test for the visual block size displayed in the status line
833 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
834 call feedkeys("ggl\<C-V>lljj", 'xt')
835 redraw!
836 call assert_match('3x3$', Screenline(&lines))
837 call feedkeys("\<C-V>", 'xt')
838 " test for visually selecting a multi-byte character
839 call setline(1, ["\U2206"])
840 call feedkeys("ggv", 'xt')
841 redraw!
842 call assert_match('1-3$', Screenline(&lines))
843 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200844 " test for visually selecting the end of line
845 call setline(1, ["foobar"])
846 call feedkeys("$vl", 'xt')
847 redraw!
848 call assert_match('2$', Screenline(&lines))
849 call feedkeys("y", 'xt')
850 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200851 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200852endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200853
Bram Moolenaar1671f442020-03-10 07:48:13 +0100854" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100855func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200856 10new
857 call setline(1, range(1,5))
858 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100859 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200860 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100861 call assert_beeps('normal! G2dd')
862 call assert_beeps("normal! g\<C-A>")
863 call assert_beeps("normal! g\<C-X>")
864 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100865 call assert_beeps("normal! vQ\<Esc>")
866 call assert_beeps("normal! 2[[")
867 call assert_beeps("normal! 2]]")
868 call assert_beeps("normal! 2[]")
869 call assert_beeps("normal! 2][")
870 call assert_beeps("normal! 4[z")
871 call assert_beeps("normal! 4]z")
872 call assert_beeps("normal! 4[c")
873 call assert_beeps("normal! 4]c")
874 call assert_beeps("normal! 200%")
875 call assert_beeps("normal! %")
876 call assert_beeps("normal! 2{")
877 call assert_beeps("normal! 2}")
878 call assert_beeps("normal! r\<Right>")
879 call assert_beeps("normal! 8ry")
880 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200881 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200882endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200883
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100884func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200885 " Test for F1
886 call assert_equal(1, winnr())
887 call feedkeys("\<f1>", 'txi')
888 call assert_match('help\.txt', bufname('%'))
889 call assert_equal(2, winnr('$'))
890 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200891endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200892
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100893func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200894 " basic test for Ctrl-F and Ctrl-B
895 call Setup_NewWindow()
896 exe "norm! \<c-f>"
897 call assert_equal('9', getline('.'))
898 exe "norm! 2\<c-f>"
899 call assert_equal('25', getline('.'))
900 exe "norm! 2\<c-b>"
901 call assert_equal('18', getline('.'))
902 1
903 set scrolloff=5
904 exe "norm! 2\<c-f>"
905 call assert_equal('21', getline('.'))
906 exe "norm! \<c-b>"
907 call assert_equal('13', getline('.'))
908 1
909 set scrolloff=99
910 exe "norm! \<c-f>"
911 call assert_equal('13', getline('.'))
912 set scrolloff=0
913 100
914 exe "norm! $\<c-b>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200915 call assert_equal([0, 92, 1, 0, 1], getcurpos())
916 100
917 set nostartofline
918 exe "norm! $\<c-b>"
naohiro ono56200ee2022-01-01 14:59:44 +0000919 call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200920 " cleanup
921 set startofline
922 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200923endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200924
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100925func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200926 10new
927 norm oxxxxxxx
928 exe "norm 2\<c-f>"
929 " check with valgrind that cursor is put back in column 1
930 exe "norm 2\<c-b>"
931 bw!
932endfunc
933
Bram Moolenaar1671f442020-03-10 07:48:13 +0100934" Test for errors with z command
935func Test_normal_z_error()
936 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200937 call assert_beeps('normal! zq')
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000938 call assert_beeps('normal! cz1')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100939endfunc
940
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100941func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200942 " basic test for z commands that scroll the window
943 call Setup_NewWindow()
944 100
945 norm! >>
946 " Test for z<cr>
947 exe "norm! z\<cr>"
948 call assert_equal(' 100', getline('.'))
949 call assert_equal(100, winsaveview()['topline'])
950 call assert_equal([0, 100, 2, 0, 9], getcurpos())
951
952 " Test for zt
953 21
954 norm! >>0zt
955 call assert_equal(' 21', getline('.'))
956 call assert_equal(21, winsaveview()['topline'])
957 call assert_equal([0, 21, 1, 0, 8], getcurpos())
958
959 " Test for zb
960 30
961 norm! >>$ztzb
962 call assert_equal(' 30', getline('.'))
963 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
naohiro ono56200ee2022-01-01 14:59:44 +0000964 call assert_equal([0, 30, 3, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200965
966 " Test for z-
967 1
968 30
969 norm! 0z-
970 call assert_equal(' 30', getline('.'))
971 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
972 call assert_equal([0, 30, 2, 0, 9], getcurpos())
973
974 " Test for z{height}<cr>
975 call assert_equal(10, winheight(0))
976 exe "norm! z12\<cr>"
977 call assert_equal(12, winheight(0))
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000978 exe "norm! z15\<Del>0\<cr>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200979 call assert_equal(10, winheight(0))
980
981 " Test for z.
982 1
983 21
984 norm! 0z.
985 call assert_equal(' 21', getline('.'))
986 call assert_equal(17, winsaveview()['topline'])
987 call assert_equal([0, 21, 2, 0, 9], getcurpos())
988
989 " Test for zz
990 1
991 21
992 norm! 0zz
993 call assert_equal(' 21', getline('.'))
994 call assert_equal(17, winsaveview()['topline'])
995 call assert_equal([0, 21, 1, 0, 8], getcurpos())
996
997 " Test for z+
998 11
999 norm! zt
1000 norm! z+
1001 call assert_equal(' 21', getline('.'))
1002 call assert_equal(21, winsaveview()['topline'])
1003 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1004
1005 " Test for [count]z+
1006 1
1007 norm! 21z+
1008 call assert_equal(' 21', getline('.'))
1009 call assert_equal(21, winsaveview()['topline'])
1010 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1011
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001012 " Test for z+ with [count] greater than buffer size
1013 1
1014 norm! 1000z+
1015 call assert_equal(' 100', getline('.'))
1016 call assert_equal(100, winsaveview()['topline'])
1017 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1018
1019 " Test for z+ from the last buffer line
1020 norm! Gz.z+
1021 call assert_equal(' 100', getline('.'))
1022 call assert_equal(100, winsaveview()['topline'])
1023 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1024
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001025 " Test for z^
1026 norm! 22z+0
1027 norm! z^
1028 call assert_equal(' 21', getline('.'))
1029 call assert_equal(12, winsaveview()['topline'])
1030 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1031
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001032 " Test for z^ from first buffer line
1033 norm! ggz^
1034 call assert_equal('1', getline('.'))
1035 call assert_equal(1, winsaveview()['topline'])
1036 call assert_equal([0, 1, 1, 0, 1], getcurpos())
1037
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001038 " Test for [count]z^
1039 1
1040 norm! 30z^
1041 call assert_equal(' 21', getline('.'))
1042 call assert_equal(12, winsaveview()['topline'])
1043 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1044
1045 " cleanup
1046 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001047endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001048
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001049func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001050 " basic test for z commands that scroll the window
1051 10new
1052 15vsp
1053 set nowrap listchars=
1054 let lineA='abcdefghijklmnopqrstuvwxyz'
1055 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1056 $put =lineA
1057 $put =lineB
1058 1d
1059
Bram Moolenaar1671f442020-03-10 07:48:13 +01001060 " Test for zl and zh with a count
1061 norm! 0z10l
1062 call assert_equal([11, 1], [col('.'), wincol()])
1063 norm! z4h
1064 call assert_equal([11, 5], [col('.'), wincol()])
1065 normal! 2gg
1066
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001067 " Test for zl
1068 1
1069 norm! 5zl
1070 call assert_equal(lineA, getline('.'))
1071 call assert_equal(6, col('.'))
1072 call assert_equal(5, winsaveview()['leftcol'])
1073 norm! yl
1074 call assert_equal('f', @0)
1075
1076 " Test for zh
1077 norm! 2zh
1078 call assert_equal(lineA, getline('.'))
1079 call assert_equal(6, col('.'))
1080 norm! yl
1081 call assert_equal('f', @0)
1082 call assert_equal(3, winsaveview()['leftcol'])
1083
1084 " Test for zL
1085 norm! zL
1086 call assert_equal(11, col('.'))
1087 norm! yl
1088 call assert_equal('k', @0)
1089 call assert_equal(10, winsaveview()['leftcol'])
1090 norm! 2zL
1091 call assert_equal(25, col('.'))
1092 norm! yl
1093 call assert_equal('y', @0)
1094 call assert_equal(24, winsaveview()['leftcol'])
1095
1096 " Test for zH
1097 norm! 2zH
1098 call assert_equal(25, col('.'))
1099 call assert_equal(10, winsaveview()['leftcol'])
1100 norm! yl
1101 call assert_equal('y', @0)
1102
1103 " Test for zs
1104 norm! $zs
1105 call assert_equal(26, col('.'))
1106 call assert_equal(25, winsaveview()['leftcol'])
1107 norm! yl
1108 call assert_equal('z', @0)
1109
1110 " Test for ze
1111 norm! ze
1112 call assert_equal(26, col('.'))
1113 call assert_equal(11, winsaveview()['leftcol'])
1114 norm! yl
1115 call assert_equal('z', @0)
1116
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001117 " Test for zs and ze with folds
1118 %fold
1119 norm! $zs
1120 call assert_equal(26, col('.'))
1121 call assert_equal(0, winsaveview()['leftcol'])
1122 norm! yl
1123 call assert_equal('z', @0)
1124 norm! ze
1125 call assert_equal(26, col('.'))
1126 call assert_equal(0, winsaveview()['leftcol'])
1127 norm! yl
1128 call assert_equal('z', @0)
1129
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001130 " cleanup
1131 set wrap listchars=eol:$
1132 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001133endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001134
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001135func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001136 " basic test for z commands that scroll the window
1137 " using 'sidescrolloff' setting
1138 10new
1139 20vsp
1140 set nowrap listchars= sidescrolloff=5
1141 let lineA='abcdefghijklmnopqrstuvwxyz'
1142 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1143 $put =lineA
1144 $put =lineB
1145 1d
1146
1147 " Test for zl
1148 1
1149 norm! 5zl
1150 call assert_equal(lineA, getline('.'))
1151 call assert_equal(11, col('.'))
1152 call assert_equal(5, winsaveview()['leftcol'])
1153 norm! yl
1154 call assert_equal('k', @0)
1155
1156 " Test for zh
1157 norm! 2zh
1158 call assert_equal(lineA, getline('.'))
1159 call assert_equal(11, col('.'))
1160 norm! yl
1161 call assert_equal('k', @0)
1162 call assert_equal(3, winsaveview()['leftcol'])
1163
1164 " Test for zL
1165 norm! 0zL
1166 call assert_equal(16, col('.'))
1167 norm! yl
1168 call assert_equal('p', @0)
1169 call assert_equal(10, winsaveview()['leftcol'])
1170 norm! 2zL
1171 call assert_equal(26, col('.'))
1172 norm! yl
1173 call assert_equal('z', @0)
1174 call assert_equal(15, winsaveview()['leftcol'])
1175
1176 " Test for zH
1177 norm! 2zH
1178 call assert_equal(15, col('.'))
1179 call assert_equal(0, winsaveview()['leftcol'])
1180 norm! yl
1181 call assert_equal('o', @0)
1182
1183 " Test for zs
1184 norm! $zs
1185 call assert_equal(26, col('.'))
1186 call assert_equal(20, winsaveview()['leftcol'])
1187 norm! yl
1188 call assert_equal('z', @0)
1189
1190 " Test for ze
1191 norm! ze
1192 call assert_equal(26, col('.'))
1193 call assert_equal(11, winsaveview()['leftcol'])
1194 norm! yl
1195 call assert_equal('z', @0)
1196
1197 " cleanup
1198 set wrap listchars=eol:$ sidescrolloff=0
1199 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001200endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001201
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001202" Test for commands that scroll the window horizontally. Test with folds.
1203" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1204func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001205 15new
1206 call setline(1, range(1, 100))
1207 exe "normal! 30ggz\<CR>"
1208 set foldenable
1209 33,36fold
1210 40,43fold
1211 46,49fold
1212 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001213
1214 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001215 " Top of the screen = 30
1216 " Folded lines = 9
1217 " Bottom of the screen = 30 + h + 9 - 1
1218 normal! 4L
1219 call assert_equal(35 + h, line('.'))
1220 normal! 4H
1221 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001222
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001223 " Test for using a large count value
1224 %d
1225 call setline(1, range(1, 4))
1226 norm! 6H
1227 call assert_equal(4, line('.'))
1228
1229 " Test for 'M' with folded lines
1230 %d
1231 call setline(1, range(1, 20))
1232 1,5fold
1233 norm! LM
1234 call assert_equal(12, line('.'))
1235
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001236 " Test for the CTRL-E and CTRL-Y commands with folds
1237 %d
1238 call setline(1, range(1, 10))
1239 3,5fold
1240 exe "normal 6G3\<C-E>"
1241 call assert_equal(6, line('w0'))
1242 exe "normal 2\<C-Y>"
1243 call assert_equal(2, line('w0'))
1244
1245 " Test for CTRL-Y on a folded line
1246 %d
1247 call setline(1, range(1, 100))
1248 exe (h + 2) .. "," .. (h + 4) .. "fold"
1249 exe h + 5
1250 normal z-
1251 exe "normal \<C-Y>\<C-Y>"
1252 call assert_equal(h + 1, line('w$'))
1253
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001254 " Test for CTRL-Y from the first line and CTRL-E from the last line
1255 %d
1256 set scrolloff=2
1257 call setline(1, range(1, 4))
1258 exe "normal gg\<C-Y>"
1259 call assert_equal(1, line('w0'))
1260 call assert_equal(1, line('.'))
1261 exe "normal G4\<C-E>\<C-E>"
1262 call assert_equal(4, line('w$'))
1263 call assert_equal(4, line('.'))
1264 set scrolloff&
1265
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001266 " Using <PageUp> and <PageDown> in an empty buffer should beep
1267 %d
1268 call assert_beeps('exe "normal \<PageUp>"')
1269 call assert_beeps('exe "normal \<C-B>"')
1270 call assert_beeps('exe "normal \<PageDown>"')
1271 call assert_beeps('exe "normal \<C-F>"')
1272
1273 " Test for <C-U> and <C-D> with fold
1274 %d
1275 call setline(1, range(1, 100))
1276 10,35fold
1277 set scroll=10
1278 exe "normal \<C-D>"
1279 call assert_equal(36, line('.'))
1280 exe "normal \<C-D>"
1281 call assert_equal(46, line('.'))
1282 exe "normal \<C-U>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001283 call assert_equal(36, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001284 exe "normal \<C-U>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001285 call assert_equal(1, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001286 exe "normal \<C-U>"
1287 call assert_equal(1, line('.'))
1288 set scroll&
1289
1290 " Test for scrolling to the top of the file with <C-U> and a fold
1291 10
1292 normal ztL
1293 exe "normal \<C-U>\<C-U>"
1294 call assert_equal(1, line('w0'))
1295
1296 " Test for CTRL-D on a folded line
1297 %d
1298 call setline(1, range(1, 100))
1299 50,100fold
1300 75
1301 normal z-
1302 exe "normal \<C-D>"
1303 call assert_equal(50, line('.'))
1304 call assert_equal(100, line('w$'))
1305 normal z.
Luuk van Baalcb204e62024-04-02 20:49:45 +02001306 let lnum = winline()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001307 exe "normal \<C-D>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001308 call assert_equal(lnum, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001309 call assert_equal(50, line('.'))
1310 normal zt
1311 exe "normal \<C-D>"
1312 call assert_equal(50, line('w0'))
1313
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001314 " Test for <S-CR>. Page down.
1315 %d
1316 call setline(1, range(1, 100))
1317 call feedkeys("\<S-CR>", 'xt')
1318 call assert_equal(14, line('w0'))
1319 call assert_equal(28, line('w$'))
1320
1321 " Test for <S-->. Page up.
1322 call feedkeys("\<S-->", 'xt')
1323 call assert_equal(1, line('w0'))
1324 call assert_equal(15, line('w$'))
1325
Bram Moolenaar1671f442020-03-10 07:48:13 +01001326 set foldenable&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00001327 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01001328endfunc
1329
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001330func Test_scroll_in_ex_mode()
1331 " This was using invalid memory because w_botline was invalid.
1332 let lines =<< trim END
1333 diffsplit
1334 norm os00(
1335 call writefile(['done'], 'Xdone')
1336 qa!
1337 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001338 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001339 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1340 call assert_equal(['done'], readfile('Xdone'))
1341
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001342 call delete('Xdone')
1343endfunc
1344
zeertzjqdf098fe2025-01-22 22:27:30 +01001345func Test_scroll_and_paste_in_ex_mode()
1346 " This used to crash because of moving cursor to line 0.
1347 let lines =<< trim END
1348 v/foo/vi|YY9PYQ
1349 v/bar/vi|YY9PYQ
1350 v/bar/exe line('.') == 1 ? "vi|Y\<C-B>9PYQ" : "vi|YQ"
1351 call writefile(['done'], 'Xdone')
1352 qa!
1353 END
1354 call writefile(lines, 'Xscript', 'D')
1355 call assert_equal(1, RunVim([], [], '-u NONE -i NONE -n -X -Z -e -s -S Xscript'))
1356 call assert_equal(['done'], readfile('Xdone'))
1357
1358 call delete('Xdone')
1359endfunc
1360
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001361" Test for the 'sidescroll' option
1362func Test_sidescroll_opt()
1363 new
1364 20vnew
1365
1366 " scroll by 2 characters horizontally
1367 set sidescroll=2 nowrap
1368 call setline(1, repeat('a', 40))
1369 normal g$l
1370 call assert_equal(19, screenpos(0, 1, 21).col)
1371 normal l
1372 call assert_equal(20, screenpos(0, 1, 22).col)
1373 normal g0h
1374 call assert_equal(2, screenpos(0, 1, 2).col)
1375 call assert_equal(20, screenpos(0, 1, 20).col)
1376
1377 " when 'sidescroll' is 0, cursor positioned at the center
1378 set sidescroll=0
1379 normal g$l
1380 call assert_equal(11, screenpos(0, 1, 21).col)
1381 normal g0h
1382 call assert_equal(10, screenpos(0, 1, 10).col)
1383
1384 %bw!
1385 set wrap& sidescroll&
1386endfunc
1387
Bram Moolenaar004a6782020-04-11 17:09:31 +02001388" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001389func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001390 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001391 call Setup_NewWindow()
1392 50
1393 setl foldenable fdm=marker foldlevel=5
1394
Bram Moolenaar1671f442020-03-10 07:48:13 +01001395 call assert_beeps('normal! zj')
1396 call assert_beeps('normal! zk')
1397
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001398 " Test for zF
1399 " First fold
1400 norm! 4zF
1401 " check that folds have been created
Riley Bruins0a083062024-06-03 20:40:45 +02001402 call assert_equal(['50/* {{{ */', '51', '52', '53/* }}} */'], getline(50,53))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001403
1404 " Test for zd
1405 51
1406 norm! 2zF
1407 call assert_equal(2, foldlevel('.'))
1408 norm! kzd
Riley Bruins0a083062024-06-03 20:40:45 +02001409 call assert_equal(['50', '51/* {{{ */', '52/* }}} */', '53'], getline(50,53))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001410 norm! j
1411 call assert_equal(1, foldlevel('.'))
1412
1413 " Test for zD
1414 " also deletes partially selected folds recursively
1415 51
1416 norm! zF
1417 call assert_equal(2, foldlevel('.'))
1418 norm! kV2jzD
1419 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1420
1421 " Test for zE
1422 85
1423 norm! 4zF
1424 86
1425 norm! 2zF
1426 90
1427 norm! 4zF
Riley Bruins0a083062024-06-03 20:40:45 +02001428 call assert_equal(['85/* {{{ */', '86/* {{{ */', '87/* }}} */', '88/* }}} */', '89', '90/* {{{ */', '91', '92', '93/* }}} */'], getline(85,93))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001429 norm! zE
1430 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1431
1432 " Test for zn
1433 50
1434 set foldlevel=0
1435 norm! 2zF
1436 norm! zn
1437 norm! k
1438 call assert_equal('49', getline('.'))
1439 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001440 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001441 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001442 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001443 norm! j
1444 call assert_equal('52', getline('.'))
1445 call assert_equal(0, &foldenable)
1446
1447 " Test for zN
1448 49
1449 norm! zN
1450 call assert_equal('49', getline('.'))
1451 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001452 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001453 norm! j
1454 call assert_equal('52', getline('.'))
1455 call assert_equal(1, &foldenable)
1456
1457 " Test for zi
1458 norm! zi
1459 call assert_equal(0, &foldenable)
1460 norm! zi
1461 call assert_equal(1, &foldenable)
1462 norm! zi
1463 call assert_equal(0, &foldenable)
1464 norm! zi
1465 call assert_equal(1, &foldenable)
1466
1467 " Test for za
1468 50
1469 norm! za
1470 norm! k
1471 call assert_equal('49', getline('.'))
1472 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001473 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001474 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001475 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001476 norm! j
1477 call assert_equal('52', getline('.'))
1478 50
1479 norm! za
1480 norm! k
1481 call assert_equal('49', getline('.'))
1482 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001483 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001484 norm! j
1485 call assert_equal('52', getline('.'))
1486
1487 49
1488 norm! 5zF
1489 norm! k
1490 call assert_equal('48', getline('.'))
1491 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001492 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001493 norm! j
1494 call assert_equal('55', getline('.'))
1495 49
1496 norm! za
Riley Bruins0a083062024-06-03 20:40:45 +02001497 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001498 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001499 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001500 norm! j
1501 call assert_equal('52', getline('.'))
1502 set nofoldenable
1503 " close fold and set foldenable
1504 norm! za
1505 call assert_equal(1, &foldenable)
1506
1507 50
1508 " have to use {count}za to open all folds and make the cursor visible
1509 norm! 2za
1510 norm! 2k
1511 call assert_equal('48', getline('.'))
1512 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001513 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001514 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001515 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001516 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001517 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001518 norm! j
1519 call assert_equal('52', getline('.'))
1520
1521 " Test for zA
1522 49
1523 set foldlevel=0
1524 50
1525 norm! zA
1526 norm! 2k
1527 call assert_equal('48', getline('.'))
1528 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001529 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001530 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001531 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001532 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001533 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001534 norm! j
1535 call assert_equal('52', getline('.'))
1536
Dominique Pelle923dce22021-11-21 11:36:04 +00001537 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001538 50
1539 set nofoldenable
1540 norm! zA
1541 call assert_equal(1, &foldenable)
1542 norm! k
1543 call assert_equal('48', getline('.'))
1544 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001545 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001546 norm! j
1547 call assert_equal('55', getline('.'))
1548
1549 " Test for zc
1550 norm! zE
1551 50
1552 norm! 2zF
1553 49
1554 norm! 5zF
1555 set nofoldenable
1556 50
1557 " There most likely is a bug somewhere:
1558 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1559 " TODO: Should this only close the inner most fold or both folds?
1560 norm! zc
1561 call assert_equal(1, &foldenable)
1562 norm! k
1563 call assert_equal('48', getline('.'))
1564 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001565 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001566 norm! j
1567 call assert_equal('55', getline('.'))
1568 set nofoldenable
1569 50
1570 norm! Vjzc
1571 norm! k
1572 call assert_equal('48', getline('.'))
1573 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001574 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001575 norm! j
1576 call assert_equal('55', getline('.'))
1577
1578 " Test for zC
1579 set nofoldenable
1580 50
1581 norm! zCk
1582 call assert_equal('48', getline('.'))
1583 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001584 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001585 norm! j
1586 call assert_equal('55', getline('.'))
1587
1588 " Test for zx
1589 " 1) close folds at line 49-54
1590 set nofoldenable
1591 48
1592 norm! zx
1593 call assert_equal(1, &foldenable)
1594 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001595 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001596 norm! j
1597 call assert_equal('55', getline('.'))
1598
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001599 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001600 51
1601 set nofoldenable
1602 norm! zx
1603 call assert_equal(1, &foldenable)
1604 norm! 3k
1605 call assert_equal('48', getline('.'))
1606 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001607 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001608 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001609 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001610 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001611 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001612 norm! j
1613 call assert_equal('52', getline('.'))
1614 norm! j
1615 call assert_equal('53', getline('.'))
1616 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001617 call assert_equal('54/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001618 norm! j
1619 call assert_equal('55', getline('.'))
1620
1621 " 3) close one level of folds
1622 48
1623 set nofoldenable
1624 set foldlevel=1
1625 norm! zx
1626 call assert_equal(1, &foldenable)
1627 call assert_equal('48', getline('.'))
1628 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001629 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001630 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001631 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001632 norm! j
1633 call assert_equal('52', getline('.'))
1634 norm! j
1635 call assert_equal('53', getline('.'))
1636 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001637 call assert_equal('54/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001638 norm! j
1639 call assert_equal('55', getline('.'))
1640
1641 " Test for zX
1642 " Close all folds
1643 set foldlevel=0 nofoldenable
1644 50
1645 norm! zX
1646 call assert_equal(1, &foldenable)
1647 norm! k
1648 call assert_equal('48', getline('.'))
1649 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001650 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001651 norm! j
1652 call assert_equal('55', getline('.'))
1653
1654 " Test for zm
1655 50
1656 set nofoldenable foldlevel=2
1657 norm! zm
1658 call assert_equal(1, &foldenable)
1659 call assert_equal(1, &foldlevel)
1660 norm! zm
1661 call assert_equal(0, &foldlevel)
1662 norm! zm
1663 call assert_equal(0, &foldlevel)
1664 norm! k
1665 call assert_equal('48', getline('.'))
1666 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001667 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001668 norm! j
1669 call assert_equal('55', getline('.'))
1670
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001671 " Test for zm with a count
1672 50
1673 set foldlevel=2
1674 norm! 3zm
1675 call assert_equal(0, &foldlevel)
1676 call assert_equal(49, foldclosed(line('.')))
1677
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001678 " Test for zM
1679 48
1680 set nofoldenable foldlevel=99
1681 norm! zM
1682 call assert_equal(1, &foldenable)
1683 call assert_equal(0, &foldlevel)
1684 call assert_equal('48', getline('.'))
1685 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001686 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001687 norm! j
1688 call assert_equal('55', getline('.'))
1689
1690 " Test for zr
1691 48
1692 set nofoldenable foldlevel=0
1693 norm! zr
1694 call assert_equal(0, &foldenable)
1695 call assert_equal(1, &foldlevel)
1696 set foldlevel=0 foldenable
1697 norm! zr
1698 call assert_equal(1, &foldenable)
1699 call assert_equal(1, &foldlevel)
1700 norm! zr
1701 call assert_equal(2, &foldlevel)
1702 call assert_equal('48', getline('.'))
1703 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001704 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001705 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001706 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001707 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001708 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001709 norm! j
1710 call assert_equal('52', getline('.'))
1711
1712 " Test for zR
1713 48
1714 set nofoldenable foldlevel=0
1715 norm! zR
1716 call assert_equal(0, &foldenable)
1717 call assert_equal(2, &foldlevel)
1718 set foldenable foldlevel=0
1719 norm! zR
1720 call assert_equal(1, &foldenable)
1721 call assert_equal(2, &foldlevel)
1722 call assert_equal('48', getline('.'))
1723 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001724 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001725 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001726 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001727 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001728 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001729 norm! j
1730 call assert_equal('52', getline('.'))
Riley Bruins0a083062024-06-03 20:40:45 +02001731 call append(50, ['a /* {{{ */', 'b /* }}} */'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001732 48
1733 call assert_equal('48', getline('.'))
1734 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001735 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001736 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001737 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001738 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001739 call assert_equal('a /* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001740 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001741 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001742 norm! j
1743 call assert_equal('52', getline('.'))
1744 48
1745 norm! zR
1746 call assert_equal(1, &foldenable)
1747 call assert_equal(3, &foldlevel)
1748 call assert_equal('48', getline('.'))
1749 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001750 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001751 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001752 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001753 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001754 call assert_equal('a /* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001755 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001756 call assert_equal('b /* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001757 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001758 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001759 norm! j
1760 call assert_equal('52', getline('.'))
1761
1762 " clean up
1763 setl nofoldenable fdm=marker foldlevel=0
1764 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001765endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001766
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001767func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001768 " Reading from redirected file doesn't work on MS-Windows
1769 CheckNotMSWindows
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001770 call writefile(['1a', 'foo', 'bar', '.', 'w! Xn20file2', 'q!'], 'Xn20script', 'D')
1771 call writefile(['1', '2'], 'Xn20file', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001772 call system(GetVimCommand() .. ' -e -s < Xn20script Xn20file')
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001773 let a = readfile('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001774 call assert_equal(['1', 'foo', 'bar', '2'], a)
1775
1776 " clean up
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001777 call delete('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001778 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001779endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001780
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001781func Test_normal21_nv_hat()
1782
1783 " Edit a fresh file and wipe the buffer list so that there is no alternate
1784 " file present. Next, check for the expected command failures.
1785 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001786 call assert_fails(':buffer #', 'E86:')
1787 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001788 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001789
1790 " Test for the expected behavior when switching between two named buffers.
1791 edit Xfoo | edit Xbar
1792 call feedkeys("\<C-^>", 'tx')
1793 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1794 call feedkeys("\<C-^>", 'tx')
1795 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1796
1797 " Test for the expected behavior when only one buffer is named.
1798 enew | let l:nr = bufnr('%')
1799 call feedkeys("\<C-^>", 'tx')
1800 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1801 call feedkeys("\<C-^>", 'tx')
1802 call assert_equal('', bufname('%'))
1803 call assert_equal(l:nr, bufnr('%'))
1804
1805 " Test that no action is taken by "<C-^>" when an operator is pending.
1806 edit Xfoo
1807 call feedkeys("ci\<C-^>", 'tx')
1808 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1809
1810 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001811endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001812
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001813func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001814 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001815 " let shell = &shell
1816 " let &shell = 'sh'
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001817 call writefile(['1', '2'], 'Xn22file', 'D')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001818 let args = ' -N -i NONE --noplugins -X --not-a-term'
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001819 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xn22file')
1820 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001821 call assert_equal([], a)
1822 " Test for ZQ
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001823 call writefile(['1', '2'], 'Xn22file')
1824 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xn22file')
1825 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001826 call assert_equal(['1', '2'], a)
1827
Bram Moolenaar1671f442020-03-10 07:48:13 +01001828 " Unsupported Z command
1829 call assert_beeps('normal! ZW')
1830
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001831 " clean up
Bram Moolenaar0913a102016-09-03 19:11:59 +02001832 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001833endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001834
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001835func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001836 " Test for K command
1837 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001838 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001839 let k = &keywordprg
1840 set keywordprg=:help
1841 1
1842 norm! VK
1843 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1844 call assert_equal('help', &ft)
1845 call assert_match('\*version8.txt\*', getline('.'))
1846 helpclose
1847 norm! 0K
1848 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1849 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001850 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001851 helpclose
1852
Bram Moolenaar426f3752016-11-04 21:22:37 +01001853 set keywordprg=:new
1854 set iskeyword+=%
1855 set iskeyword+=\|
1856 2
1857 norm! K
1858 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1859 bwipe!
1860 3
1861 norm! K
1862 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1863 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001864 if !has('win32')
1865 4
1866 norm! K
1867 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1868 bwipe!
1869 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001870 set iskeyword-=%
1871 set iskeyword-=\|
1872
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001873 " Test for specifying a count to K
1874 1
1875 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1876 set keywordprg=:Kprog
1877 norm! 3K
1878 call assert_equal('3 version8', g:Kprog_Args)
1879 delcom Kprog
1880
Bram Moolenaar0913a102016-09-03 19:11:59 +02001881 " Only expect "man" to work on Unix
1882 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001883 let &keywordprg = k
1884 bw!
1885 return
1886 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001887
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001888 let not_gnu_man = has('mac') || has('bsd')
1889 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001890 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001891 set keywordprg=man\ -P\ cat
1892 else
1893 set keywordprg=man\ --pager=cat
1894 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001895 " Test for using man
1896 2
1897 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001898 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001899 call assert_match("man -P cat 'man'", a)
1900 else
1901 call assert_match("man --pager=cat 'man'", a)
1902 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001903
Bram Moolenaar1671f442020-03-10 07:48:13 +01001904 " Error cases
1905 call setline(1, '#$#')
1906 call assert_fails('normal! ggK', 'E349:')
1907 call setline(1, '---')
1908 call assert_fails('normal! ggv2lK', 'E349:')
1909 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001910 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001911 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001912 norm! V
1913 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001914
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001915 " clean up
1916 let &keywordprg = k
1917 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001918endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001919
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001920func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001921 " Testing for g?? g?g?
1922 new
1923 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1924 1
1925 norm! g??
1926 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1927 norm! g?g?
1928 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1929
1930 " clean up
1931 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001932endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001933
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001934func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001935 CheckFeature quickfix
1936
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001937 " Testing for CTRL-] g CTRL-] g]
1938 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1939 h
1940 " Test for CTRL-]
1941 call search('\<x\>$')
1942 exe "norm! \<c-]>"
1943 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1944 norm! yiW
1945 call assert_equal("*x*", @0)
1946 exe ":norm \<c-o>"
1947
1948 " Test for g_CTRL-]
1949 call search('\<v_u\>$')
1950 exe "norm! g\<c-]>"
1951 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1952 norm! yiW
1953 call assert_equal("*v_u*", @0)
1954 exe ":norm \<c-o>"
1955
1956 " Test for g]
1957 call search('\<i_<Esc>$')
1958 let a = execute(":norm! g]")
1959 call assert_match('i_<Esc>.*insert.txt', a)
1960
1961 if !empty(exepath('cscope')) && has('cscope')
1962 " setting cscopetag changes how g] works
1963 set cst
1964 exe "norm! g]"
1965 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1966 norm! yiW
1967 call assert_equal("*i_<Esc>*", @0)
1968 exe ":norm \<c-o>"
1969 " Test for CTRL-W g]
1970 exe "norm! \<C-W>g]"
1971 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1972 norm! yiW
1973 call assert_equal("*i_<Esc>*", @0)
1974 call assert_equal(3, winnr('$'))
1975 helpclose
1976 set nocst
1977 endif
1978
1979 " Test for CTRL-W g]
1980 let a = execute("norm! \<C-W>g]")
1981 call assert_match('i_<Esc>.*insert.txt', a)
1982
1983 " Test for CTRL-W CTRL-]
1984 exe "norm! \<C-W>\<C-]>"
1985 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1986 norm! yiW
1987 call assert_equal("*i_<Esc>*", @0)
1988 call assert_equal(3, winnr('$'))
1989 helpclose
1990
1991 " Test for CTRL-W g CTRL-]
1992 exe "norm! \<C-W>g\<C-]>"
1993 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1994 norm! yiW
1995 call assert_equal("*i_<Esc>*", @0)
1996 call assert_equal(3, winnr('$'))
1997 helpclose
1998
1999 " clean up
2000 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002001endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002002
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002003func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002004 " Test for ]p ]P [p and [P
2005 new
2006 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
2007 1
2008 /Error/y a
2009 2
2010 norm! "a]pj"a[p
2011 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
2012 1
2013 /^\s\{4}/
2014 exe "norm! \"a]P3Eldt'"
2015 exe "norm! j\"a[P2Eldt'"
2016 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
2017
2018 " clean up
2019 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002020endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002021
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002022func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002023 " Test for [' [` ]' ]`
2024 call Setup_NewWindow()
2025 1,21s/.\+/ & b/
2026 1
2027 norm! $ma
2028 5
2029 norm! $mb
2030 10
2031 norm! $mc
2032 15
2033 norm! $md
2034 20
2035 norm! $me
2036
2037 " Test for ['
2038 9
2039 norm! 2['
2040 call assert_equal(' 1 b', getline('.'))
2041 call assert_equal(1, line('.'))
2042 call assert_equal(3, col('.'))
2043
2044 " Test for ]'
2045 norm! ]'
2046 call assert_equal(' 5 b', getline('.'))
2047 call assert_equal(5, line('.'))
2048 call assert_equal(3, col('.'))
2049
zeertzjqcf344342022-07-06 12:57:31 +01002050 " No mark before line 1, cursor moves to first non-blank on current line
2051 1
2052 norm! 5|['
2053 call assert_equal(' 1 b', getline('.'))
2054 call assert_equal(1, line('.'))
2055 call assert_equal(3, col('.'))
2056
2057 " No mark after line 21, cursor moves to first non-blank on current line
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002058 21
zeertzjqcf344342022-07-06 12:57:31 +01002059 norm! 5|]'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002060 call assert_equal(' 21 b', getline('.'))
2061 call assert_equal(21, line('.'))
2062 call assert_equal(3, col('.'))
2063
2064 " Test for [`
2065 norm! 2[`
2066 call assert_equal(' 15 b', getline('.'))
2067 call assert_equal(15, line('.'))
2068 call assert_equal(8, col('.'))
2069
2070 " Test for ]`
2071 norm! ]`
2072 call assert_equal(' 20 b', getline('.'))
2073 call assert_equal(20, line('.'))
2074 call assert_equal(8, col('.'))
2075
zeertzjqcf344342022-07-06 12:57:31 +01002076 " No mark before line 1, cursor does not move
2077 1
2078 norm! 5|[`
2079 call assert_equal(' 1 b', getline('.'))
2080 call assert_equal(1, line('.'))
2081 call assert_equal(5, col('.'))
2082
2083 " No mark after line 21, cursor does not move
2084 21
2085 norm! 5|]`
2086 call assert_equal(' 21 b', getline('.'))
2087 call assert_equal(21, line('.'))
2088 call assert_equal(5, col('.'))
2089
2090 " Count too large for [`
2091 " cursor moves to first lowercase mark
2092 norm! 99[`
2093 call assert_equal(' 1 b', getline('.'))
2094 call assert_equal(1, line('.'))
2095 call assert_equal(7, col('.'))
2096
2097 " Count too large for ]`
2098 " cursor moves to last lowercase mark
2099 norm! 99]`
2100 call assert_equal(' 20 b', getline('.'))
2101 call assert_equal(20, line('.'))
2102 call assert_equal(8, col('.'))
2103
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002104 " clean up
2105 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002106endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002107
Bram Moolenaar1671f442020-03-10 07:48:13 +01002108" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002109func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002110 new
2111 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2112
2113 $
2114 norm! d(
2115 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2116 norm! 2d(
2117 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2118 1
2119 norm! 0d)
2120 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2121
2122 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2123 $
2124 norm! $d(
2125 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2126
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002127 " Move to the next sentence from a paragraph macro
2128 %d
2129 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2130 call cursor(1, 1)
2131 normal )
2132 call assert_equal([2, 1], [line('.'), col('.')])
2133 normal )
2134 call assert_equal([2, 12], [line('.'), col('.')])
2135 normal ((
2136 call assert_equal([1, 1], [line('.'), col('.')])
2137
Bram Moolenaar1671f442020-03-10 07:48:13 +01002138 " It is an error if a next sentence is not found
2139 %d
2140 call setline(1, '.SH')
2141 call assert_beeps('normal )')
2142
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002143 " If only dot is present, don't treat that as a sentence
2144 call setline(1, '. This is a sentence.')
2145 normal $((
2146 call assert_equal(3, col('.'))
2147
Bram Moolenaar1671f442020-03-10 07:48:13 +01002148 " Jumping to a fold should open the fold
2149 call setline(1, ['', '', 'one', 'two', 'three'])
2150 set foldenable
2151 2,$fold
2152 call feedkeys(')', 'xt')
2153 call assert_equal(3, line('.'))
2154 call assert_equal(1, foldlevel('.'))
2155 call assert_equal(-1, foldclosed('.'))
2156 set foldenable&
2157
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002158 " clean up
2159 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002160endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002161
Bram Moolenaar1671f442020-03-10 07:48:13 +01002162" Test for { and } paragraph movements
2163func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002164 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002165 A paragraph begins after each empty line, and also at each of a set of
2166 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2167 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2168 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2169 the first column). A section boundary is also a paragraph boundary.
2170 Note that a blank line (only containing white space) is NOT a paragraph
2171 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002172
2173
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002174 Also note that this does not include a '{' or '}' in the first column. When
2175 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2176 paragraph boundary |posix|.
2177 {
2178 This is no paragraph
2179 unless the '{' is set
2180 in 'cpoptions'
2181 }
2182 .IP
2183 The nroff macros IP separates a paragraph
2184 That means, it must be a '.'
2185 followed by IP
2186 .LPIt does not matter, if afterwards some
2187 more characters follow.
2188 .SHAlso section boundaries from the nroff
2189 macros terminate a paragraph. That means
2190 a character like this:
2191 .NH
2192 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002193 [DATA]
2194
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002195 new
2196 call append(0, text)
2197 1
2198 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002199
2200 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002201 .IP
2202 The nroff macros IP separates a paragraph
2203 That means, it must be a '.'
2204 followed by IP
2205 .LPIt does not matter, if afterwards some
2206 more characters follow.
2207 .SHAlso section boundaries from the nroff
2208 macros terminate a paragraph. That means
2209 a character like this:
2210 .NH
2211 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002212
2213 [DATA]
2214 call assert_equal(expected, getline(1, '$'))
2215
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002216 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002217
2218 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002219 .LPIt does not matter, if afterwards some
2220 more characters follow.
2221 .SHAlso section boundaries from the nroff
2222 macros terminate a paragraph. That means
2223 a character like this:
2224 .NH
2225 End of text here
Bram Moolenaar94722c52023-01-28 19:19:03 +00002226
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002227 [DATA]
2228 call assert_equal(expected, getline(1, '$'))
2229
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002230 $
2231 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002232
2233 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002234 .LPIt does not matter, if afterwards some
2235 more characters follow.
2236 .SHAlso section boundaries from the nroff
2237 macros terminate a paragraph. That means
2238 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002239
2240 [DATA]
2241 call assert_equal(expected, getline(1, '$'))
2242
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002243 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002244
2245 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002246 .LPIt does not matter, if afterwards some
2247 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002248
2249 [DATA]
2250 call assert_equal(expected, getline(1, '$'))
2251
dundargocdc4c37b2024-01-12 18:02:10 +01002252 " Test with { in cpoptions
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002253 %d
2254 call append(0, text)
2255 set cpo+={
2256 1
2257 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002258
2259 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002260 {
2261 This is no paragraph
2262 unless the '{' is set
2263 in 'cpoptions'
2264 }
2265 .IP
2266 The nroff macros IP separates a paragraph
2267 That means, it must be a '.'
2268 followed by IP
2269 .LPIt does not matter, if afterwards some
2270 more characters follow.
2271 .SHAlso section boundaries from the nroff
2272 macros terminate a paragraph. That means
2273 a character like this:
2274 .NH
2275 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002276
2277 [DATA]
2278 call assert_equal(expected, getline(1, '$'))
2279
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002280 $
2281 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002282
2283 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002284 {
2285 This is no paragraph
2286 unless the '{' is set
2287 in 'cpoptions'
2288 }
2289 .IP
2290 The nroff macros IP separates a paragraph
2291 That means, it must be a '.'
2292 followed by IP
2293 .LPIt does not matter, if afterwards some
2294 more characters follow.
2295 .SHAlso section boundaries from the nroff
2296 macros terminate a paragraph. That means
2297 a character like this:
2298 .NH
2299 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002300
2301 [DATA]
2302 call assert_equal(expected, getline(1, '$'))
2303
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002304 norm! gg}
2305 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002306
2307 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002308 {
2309 This is no paragraph
2310 unless the '{' is set
2311 in 'cpoptions'
2312 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002313
2314 [DATA]
2315 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002316
Bram Moolenaar1671f442020-03-10 07:48:13 +01002317 " Jumping to a fold should open the fold
2318 %d
2319 call setline(1, ['', 'one', 'two', ''])
2320 set foldenable
2321 2,$fold
2322 call feedkeys('}', 'xt')
2323 call assert_equal(4, line('.'))
2324 call assert_equal(1, foldlevel('.'))
2325 call assert_equal(-1, foldclosed('.'))
2326 set foldenable&
2327
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002328 " clean up
2329 set cpo-={
2330 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002331endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002332
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002333" Test for section movements
2334func Test_normal_section()
2335 new
2336 let lines =<< trim [END]
2337 int foo()
2338 {
2339 if (1)
2340 {
2341 a = 1;
2342 }
2343 }
2344 [END]
2345 call setline(1, lines)
2346
2347 " jumping to a folded line using [[ should open the fold
2348 2,3fold
2349 call cursor(5, 1)
2350 call feedkeys("[[", 'xt')
2351 call assert_equal(2, line('.'))
2352 call assert_equal(-1, foldclosedend(line('.')))
2353
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002354 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002355endfunc
2356
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002357" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002358func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002359 new
2360 call append(0, 'This is a simple test: äüöß')
2361 norm! 1ggVu
2362 call assert_equal('this is a simple test: äüöß', getline('.'))
2363 norm! VU
glepnirbd1232a2024-02-12 22:14:53 +01002364 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002365 norm! guu
glepnirbd1232a2024-02-12 22:14:53 +01002366 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002367 norm! gUgU
glepnirbd1232a2024-02-12 22:14:53 +01002368 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002369 norm! gugu
glepnirbd1232a2024-02-12 22:14:53 +01002370 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002371 norm! gUU
glepnirbd1232a2024-02-12 22:14:53 +01002372 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002373 norm! 010~
glepnirbd1232a2024-02-12 22:14:53 +01002374 call assert_equal('this is a SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002375 norm! V~
glepnirbd1232a2024-02-12 22:14:53 +01002376 call assert_equal('THIS IS A simple test: äüöß', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002377 call assert_beeps('norm! c~')
2378 %d
2379 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002380
zeertzjq8c55d602024-03-13 20:42:26 +01002381 " Test with multiple lines
2382 call setline(1, ['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'])
2383 norm! ggguG
2384 call assert_equal(['aa', 'bbbb', 'cccccc', 'dddddddd'], getline(1, '$'))
2385 norm! GgUgg
2386 call assert_equal(['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'], getline(1, '$'))
2387 %d
2388
Bram Moolenaar1671f442020-03-10 07:48:13 +01002389 " Test for changing case across lines using 'whichwrap'
2390 call setline(1, ['aaaaaa', 'aaaaaa'])
2391 normal! gg10~
2392 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2393 set whichwrap+=~
2394 normal! gg10~
2395 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2396 set whichwrap&
2397
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002398 " try changing the case with a double byte encoding (DBCS)
2399 %bw!
2400 let enc = &enc
2401 set encoding=cp932
2402 call setline(1, "\u8470")
2403 normal ~
2404 normal gU$gu$gUgUg~g~gugu
2405 call assert_equal("\u8470", getline(1))
2406 let &encoding = enc
2407
Bram Moolenaar1671f442020-03-10 07:48:13 +01002408 " clean up
2409 bw!
2410endfunc
2411
2412" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2413" is available but toupper()/tolower() don't do the right thing.
2414func Test_normal_changecase_turkish()
2415 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002416 try
2417 lang tr_TR.UTF-8
2418 set casemap=
2419 let iupper = toupper('i')
2420 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002421 call setline(1, 'iI')
2422 1normal gUU
2423 call assert_equal("\u0130I", getline(1))
2424 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002425
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002426 call setline(1, 'iI')
2427 1normal guu
2428 call assert_equal("i\u0131", getline(1))
2429 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002430 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002431 call setline(1, 'iI')
2432 1normal gUU
2433 call assert_equal("II", getline(1))
2434 call assert_equal("II", toupper("iI"))
2435
2436 call setline(1, 'iI')
2437 1normal guu
2438 call assert_equal("ii", getline(1))
2439 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002440 else
2441 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2442 endif
2443 set casemap&
2444 call setline(1, 'iI')
2445 1normal gUU
2446 call assert_equal("II", getline(1))
2447 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002448
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002449 call setline(1, 'iI')
2450 1normal guu
2451 call assert_equal("ii", getline(1))
2452 call assert_equal("ii", tolower("iI"))
2453
2454 lang en_US.UTF-8
2455 catch /E197:/
2456 " can't use Turkish locale
2457 throw 'Skipped: Turkish locale not available'
2458 endtry
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002459
2460 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002461endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002462
Bram Moolenaar1671f442020-03-10 07:48:13 +01002463" Test for r (replace) command
2464func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002465 new
2466 call append(0, 'This is a simple test: abcd')
2467 exe "norm! 1gg$r\<cr>"
2468 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2469 exe "norm! 1gg2wlr\<cr>"
2470 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2471 exe "norm! 2gg0W5r\<cr>"
2472 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2473 set autoindent
2474 call setline(2, ['simple test: abc', ''])
2475 exe "norm! 2gg0W5r\<cr>"
2476 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2477 exe "norm! 1ggVr\<cr>"
2478 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2479 call setline(1, 'This is a')
2480 exe "norm! 1gg05rf"
2481 call assert_equal('fffffis a', getline(1))
2482
Bram Moolenaar1671f442020-03-10 07:48:13 +01002483 " When replacing characters, copy characters from above and below lines
2484 " using CTRL-Y and CTRL-E.
2485 " Different code paths are used for utf-8 and latin1 encodings
2486 set showmatch
2487 for enc in ['latin1', 'utf-8']
2488 enew!
2489 let &encoding = enc
2490 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2491 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2492 call assert_equal(' {a}x [b]x', getline(2))
2493 endfor
2494 set showmatch&
2495
2496 " r command should fail in operator pending mode
2497 call assert_beeps('normal! cr')
2498
Bram Moolenaar004a6782020-04-11 17:09:31 +02002499 " replace a tab character in visual mode
2500 %d
2501 call setline(1, ["a\tb", "c\td", "e\tf"])
2502 normal gglvjjrx
2503 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2504
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002505 " replace with a multibyte character (with multiple composing characters)
2506 %d
2507 new
2508 call setline(1, 'aaa')
2509 exe "normal $ra\u0328\u0301"
2510 call assert_equal("aaa\u0328\u0301", getline(1))
2511
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002512 " clean up
2513 set noautoindent
2514 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002515endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002516
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002517" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002518func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002519 new
2520 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2521 1
2522 norm! $g*
2523 call assert_equal('x_foo', @/)
2524 call assert_equal('x_foobar.abc', getline('.'))
2525 norm! $g#
2526 call assert_equal('abc', @/)
2527 call assert_equal('abc.x_foo', getline('.'))
2528
2529 " clean up
2530 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002531endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002532
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002533" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2534" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002535func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002536 call Setup_NewWindow()
2537 " Test for g`
2538 clearjumps
2539 norm! ma10j
2540 let a=execute(':jumps')
2541 " empty jumplist
2542 call assert_equal('>', a[-1:])
2543 norm! g`a
2544 call assert_equal('>', a[-1:])
2545 call assert_equal(1, line('.'))
2546 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002547 call cursor(10, 1)
2548 norm! g'a
2549 call assert_equal('>', a[-1:])
2550 call assert_equal(1, line('.'))
zeertzjq30585e02023-03-06 08:10:04 +00002551 let v:errmsg = ''
zeertzjqf86dea82023-03-05 21:15:06 +00002552 call assert_nobeep("normal! g`\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002553 call assert_equal('', v:errmsg)
zeertzjqf86dea82023-03-05 21:15:06 +00002554 call assert_nobeep("normal! g'\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002555 call assert_equal('', v:errmsg)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002556
2557 " Test for g; and g,
2558 norm! g;
2559 " there is only one change in the changelist
2560 " currently, when we setup the window
2561 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002562 call assert_fails(':norm! g;', 'E662:')
2563 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002564 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002565 call append('$', ['a', 'b', 'c', 'd'])
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002566 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002567 call append('$', ['Z', 'Y', 'X', 'W'])
2568 let a = execute(':changes')
2569 call assert_match('2\s\+0\s\+2', a)
2570 call assert_match('101\s\+0\s\+a', a)
2571 call assert_match('105\s\+0\s\+Z', a)
2572 norm! 3g;
2573 call assert_equal(2, line('.'))
2574 norm! 2g,
2575 call assert_equal(105, line('.'))
2576
2577 " Test for g& - global substitute
2578 %d
2579 call setline(1, range(1,10))
2580 call append('$', ['a', 'b', 'c', 'd'])
2581 $s/\w/&&/g
2582 exe "norm! /[1-8]\<cr>"
2583 norm! g&
2584 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2585
Bram Moolenaar1671f442020-03-10 07:48:13 +01002586 " Jumping to a fold using gg should open the fold
2587 set foldenable
2588 set foldopen+=jump
2589 5,8fold
2590 call feedkeys('6gg', 'xt')
2591 call assert_equal(1, foldlevel('.'))
2592 call assert_equal(-1, foldclosed('.'))
2593 set foldopen-=jump
2594 set foldenable&
2595
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002596 " Test for gv
2597 %d
2598 call append('$', repeat(['abcdefgh'], 8))
2599 exe "norm! 2gg02l\<c-v>2j2ly"
2600 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2601 " in visual mode, gv swaps current and last selected region
2602 exe "norm! G0\<c-v>4k4lgvd"
2603 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2604 exe "norm! G0\<c-v>4k4ly"
2605 exe "norm! gvood"
2606 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Christian Brabandtee17b6f2023-09-09 11:23:50 +02002607 " gv cannot be used in operator pending mode
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002608 call assert_beeps('normal! cgv')
2609 " gv should beep without a previously selected visual area
2610 new
2611 call assert_beeps('normal! gv')
2612 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002613
2614 " Test for gk/gj
2615 %d
2616 15vsp
2617 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002618 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2619 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2620 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002621 $put =lineA
2622 $put =lineB
2623
2624 norm! 3gg0dgk
2625 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2626 set nu
2627 norm! 3gg0gjdgj
2628 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2629
2630 " Test for gJ
2631 norm! 2gggJ
2632 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2633 call assert_equal(16, col('.'))
2634 " shouldn't do anything
2635 norm! 10gJ
2636 call assert_equal(1, col('.'))
2637
2638 " Test for g0 g^ gm g$
2639 exe "norm! 2gg0gji "
2640 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2641 norm! g0yl
2642 call assert_equal(12, col('.'))
2643 call assert_equal(' ', getreg(0))
2644 norm! g$yl
2645 call assert_equal(22, col('.'))
2646 call assert_equal('3', getreg(0))
2647 norm! gmyl
2648 call assert_equal(17, col('.'))
2649 call assert_equal('n', getreg(0))
2650 norm! g^yl
2651 call assert_equal(15, col('.'))
2652 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002653 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002654
Bram Moolenaar74ede802021-05-29 19:18:01 +02002655 " Test for g$ with double-width character half displayed
2656 vsplit
2657 9wincmd |
2658 setlocal nowrap nonumber
2659 call setline(2, 'asdfasdfヨ')
2660 2
2661 normal 0g$
2662 call assert_equal(8, col('.'))
2663 10wincmd |
2664 normal 0g$
2665 call assert_equal(9, col('.'))
2666
2667 setlocal signcolumn=yes
2668 11wincmd |
2669 normal 0g$
2670 call assert_equal(8, col('.'))
2671 12wincmd |
2672 normal 0g$
2673 call assert_equal(9, col('.'))
2674
2675 close
2676
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002677 " Test for g_
2678 call assert_beeps('normal! 100g_')
2679 call setline(2, [' foo ', ' foobar '])
2680 normal! 2ggg_
2681 call assert_equal(5, col('.'))
2682 normal! 2g_
2683 call assert_equal(8, col('.'))
2684
2685 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002686 $put =lineC
2687
2688 " Test for gM
2689 norm! gMyl
2690 call assert_equal(73, col('.'))
2691 call assert_equal('0', getreg(0))
2692 " Test for 20gM
2693 norm! 20gMyl
2694 call assert_equal(29, col('.'))
2695 call assert_equal('S', getreg(0))
2696 " Test for 60gM
2697 norm! 60gMyl
2698 call assert_equal(87, col('.'))
2699 call assert_equal('E', getreg(0))
2700
zeertzjq757c37d2025-03-27 18:21:49 +01002701 " Have an odd number of chars in the line
2702 norm! A.
2703 call assert_equal(145, col('.'))
2704 norm! gMyl
2705 call assert_equal(73, col('.'))
2706 call assert_equal('0', getreg(0))
2707
2708 " 'listchars' "eol" should not affect gM behavior
2709 setlocal list listchars=eol:$
2710 norm! $
2711 call assert_equal(145, col('.'))
2712 norm! gMyl
2713 call assert_equal(73, col('.'))
2714 call assert_equal('0', getreg(0))
2715 setlocal nolist
2716
Bram Moolenaar71c41252021-12-26 15:00:07 +00002717 " Test for gM with Tab characters
2718 call setline('.', "\ta\tb\tc\td\te\tf")
2719 norm! gMyl
2720 call assert_equal(6, col('.'))
2721 call assert_equal("c", getreg(0))
2722
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002723 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002724 call setline('.', lineC)
2725 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002726 set ff=unix
2727 let a=execute(":norm! g\<c-g>")
2728 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2729
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002730 " Test for gI
2731 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002732 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002733
2734 " Test for gi
2735 wincmd c
2736 %d
2737 set tw=0
2738 call setline(1, ['foobar', 'new line'])
2739 norm! A next word
2740 $put ='third line'
2741 norm! gi another word
2742 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002743 call setline(1, 'foobar')
2744 normal! Ggifirst line
2745 call assert_equal('foobarfirst line', getline(1))
2746 " Test gi in 'virtualedit' mode with cursor after the end of the line
2747 set virtualedit=all
2748 call setline(1, 'foo')
2749 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2750 call setline(1, 'foo')
2751 normal! Ggifirst line
2752 call assert_equal('foo first line', getline(1))
2753 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002754
Dominique Pelle923dce22021-11-21 11:36:04 +00002755 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002756 exe "normal! g\<C-\>\<C-G>"
2757 call assert_equal('foo first line', getline('.'))
2758
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002759 " clean up
2760 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002761endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002762
Bram Moolenaarce416b42022-04-03 12:59:34 +01002763func Test_normal_ex_substitute()
2764 " This was hanging on the substitute prompt.
2765 new
2766 call setline(1, 'a')
2767 exe "normal! gggQs/a/b/c\<CR>"
2768 call assert_equal('a', getline(1))
2769 bwipe!
2770endfunc
2771
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002772" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002773func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002774 new
2775
2776 let a = execute(":norm! g\<c-g>")
2777 call assert_equal("\n--No lines in buffer--", a)
2778
Bram Moolenaar1671f442020-03-10 07:48:13 +01002779 " Test for CTRL-G (same as :file)
2780 let a = execute(":norm! \<c-g>")
2781 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2782
Bram Moolenaar05295832018-08-24 22:07:58 +02002783 call setline(1, ['first line', 'second line'])
2784
2785 " Test g CTRL-g with dos, mac and unix file type.
2786 norm! gojll
2787 set ff=dos
2788 let a = execute(":norm! g\<c-g>")
2789 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2790
2791 set ff=mac
2792 let a = execute(":norm! g\<c-g>")
2793 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2794
2795 set ff=unix
2796 let a = execute(":norm! g\<c-g>")
2797 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2798
2799 " Test g CTRL-g in visual mode (v)
2800 let a = execute(":norm! gojllvlg\<c-g>")
2801 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2802
2803 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2804 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2805 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2806
2807 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2808 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2809 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2810
2811 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2812 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2813 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2814
2815 " There should be one byte less with noeol
2816 set bin noeol
2817 let a = execute(":norm! \<Esc>gog\<c-g>")
2818 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2819 set bin & eol&
2820
Bram Moolenaar30276f22019-01-24 17:59:39 +01002821 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002822
Bram Moolenaar30276f22019-01-24 17:59:39 +01002823 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2824 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 +02002825
Bram Moolenaar30276f22019-01-24 17:59:39 +01002826 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2827 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 +02002828
Bram Moolenaar30276f22019-01-24 17:59:39 +01002829 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2830 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 +02002831
Bram Moolenaar30276f22019-01-24 17:59:39 +01002832 set fenc=utf8 bomb
2833 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2834 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 +02002835
Bram Moolenaar30276f22019-01-24 17:59:39 +01002836 set fenc=utf16 bomb
2837 let a = execute(":norm! g\<c-g>")
2838 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 +02002839
Bram Moolenaar30276f22019-01-24 17:59:39 +01002840 set fenc=utf32 bomb
2841 let a = execute(":norm! g\<c-g>")
2842 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 +02002843
Bram Moolenaar30276f22019-01-24 17:59:39 +01002844 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002845
2846 set ff&
2847 bwipe!
2848endfunc
2849
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002850" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002851func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002852 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002853 let a=execute(':norm! 1G0g8')
2854 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002855
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002856 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2857 let a=execute(':norm! 1G$g8')
2858 call assert_equal("\nc3 b6 ", a)
2859
2860 call setline(1, "a\u0302")
2861 let a=execute(':norm! 1G0g8')
2862 call assert_equal("\n61 + cc 82 ", a)
2863
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002864 " clean up
2865 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002866endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002867
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002868" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002869func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002870 new
2871
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002872 " With invalid byte.
2873 call setline(1, "___\xff___")
2874 norm! 1G08g8g
2875 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2876
2877 " With invalid byte before the cursor.
2878 call setline(1, "___\xff___")
2879 norm! 1G$h8g8g
2880 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2881
2882 " With truncated sequence.
2883 call setline(1, "___\xE2\x82___")
2884 norm! 1G08g8g
2885 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2886
2887 " With overlong sequence.
2888 call setline(1, "___\xF0\x82\x82\xAC___")
2889 norm! 1G08g8g
2890 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2891
2892 " With valid utf8.
2893 call setline(1, "café")
2894 norm! 1G08g8
2895 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2896
2897 bw!
2898endfunc
2899
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002900" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002901func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002902 " Cannot capture its output,
2903 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002904 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002905 echo "a\nb\nc\nd"
2906 let b=execute(':norm! g<')
2907 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002908endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002909
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002910" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002911func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002912 new
2913 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002914 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002915 " Test for gp gP
2916 call append(1, range(1,10))
2917 1
2918 norm! 1yy
2919 3
2920 norm! gp
2921 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2922 $
2923 norm! gP
2924 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2925
2926 " Test for go
2927 norm! 26go
2928 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2929 norm! 27go
2930 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2931 norm! 28go
2932 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2933 set ff=dos
2934 norm! 29go
2935 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2936 set ff=unix
2937 norm! gg0
2938 norm! 101go
2939 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2940 norm! 103go
2941 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2942 " count > buffer content
2943 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002944 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002945 " clean up
2946 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002947endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002948
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002949" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002950func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002951 tabnew 1.txt
2952 tabnew 2.txt
2953 tabnew 3.txt
2954 norm! 1gt
2955 call assert_equal(1, tabpagenr())
2956 norm! 3gt
2957 call assert_equal(3, tabpagenr())
2958 norm! 1gT
2959 " count gT goes not to the absolute tabpagenumber
2960 " but, but goes to the count previous tabpagenumber
2961 call assert_equal(2, tabpagenr())
2962 " wrap around
2963 norm! 3gT
2964 call assert_equal(3, tabpagenr())
2965 " gt does not wrap around
2966 norm! 5gt
2967 call assert_equal(3, tabpagenr())
2968
2969 for i in range(3)
2970 tabclose
2971 endfor
2972 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002973 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002974endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002975
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002976" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002977func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002978 new
2979 call setline(1, range(10))
2980 $
2981 setl et sw=2
2982 norm! V10>$
2983 " count is ignored
2984 exe "norm! 10\<home>"
2985 call assert_equal(1, col('.'))
2986 exe "norm! \<home>"
2987 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2988 exe "norm! 5\<c-home>"
2989 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2990 exe "norm! \<c-home>"
2991 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002992 exe "norm! G\<c-kHome>"
2993 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002994
2995 " clean up
2996 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002997endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002998
Bram Moolenaar1671f442020-03-10 07:48:13 +01002999" Test for <End> and <C-End> keys
3000func Test_normal_nvend()
3001 new
3002 call setline(1, map(range(1, 10), '"line" .. v:val'))
3003 exe "normal! \<End>"
3004 call assert_equal(5, col('.'))
3005 exe "normal! 4\<End>"
3006 call assert_equal([4, 5], [line('.'), col('.')])
3007 exe "normal! \<C-End>"
3008 call assert_equal([10, 6], [line('.'), col('.')])
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003009
3010 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003011endfunc
3012
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003013" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01003014func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003015 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003016 new
3017 set tw=0
3018 call append(0, 'here are some words')
3019 norm! 1gg0elcwZZZ
3020 call assert_equal('hereZZZare some words', getline('.'))
3021 norm! 1gg0elcWYYY
3022 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003023 norm! 2gg0cwfoo
3024 call assert_equal('foo', getline('.'))
3025
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003026 call setline(1, 'one; two')
3027 call cursor(1, 1)
3028 call feedkeys('cwvim', 'xt')
3029 call assert_equal('vim; two', getline(1))
3030 call feedkeys('0cWone', 'xt')
3031 call assert_equal('one two', getline(1))
3032 "When cursor is at the end of a word 'ce' will change until the end of the
3033 "next word, but 'cw' will change only one character
3034 call setline(1, 'one two')
3035 call feedkeys('0ecwce', 'xt')
3036 call assert_equal('once two', getline(1))
3037 call setline(1, 'one two')
3038 call feedkeys('0ecely', 'xt')
3039 call assert_equal('only', getline(1))
3040
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003041 " clean up
3042 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003043endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003044
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003045" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003046func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003047 new
3048 call append(0, 'here are some words')
3049 exe "norm! 1gg0a\<C-\>\<C-N>"
3050 call assert_equal('n', mode())
3051 call assert_equal(1, col('.'))
3052 call assert_equal('', visualmode())
3053 exe "norm! 1gg0viw\<C-\>\<C-N>"
3054 call assert_equal('n', mode())
3055 call assert_equal(4, col('.'))
3056 exe "norm! 1gg0a\<C-\>\<C-G>"
3057 call assert_equal('n', mode())
3058 call assert_equal(1, col('.'))
3059 "imap <buffer> , <c-\><c-n>
3060 set im
3061 exe ":norm! \<c-\>\<c-n>dw"
3062 set noim
3063 call assert_equal('are some words', getline(1))
3064 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02003065 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01003066
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003067 " clean up
3068 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003069endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003070
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003071" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003072func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003073 new
3074 set sts=2 sw=2 ts=8 tw=0
3075 call append(0, ["aaa\tbbb\tccc", '', '', ''])
3076 let a=getline(1)
3077 norm! 2gg0
3078 exe "norm! a\<c-r>=a\<cr>"
3079 norm! 3gg0
3080 exe "norm! a\<c-r>\<c-r>=a\<cr>"
3081 norm! 4gg0
3082 exe "norm! a\<c-r>\<c-o>=a\<cr>"
3083 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
3084
3085 " clean up
3086 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02003087 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003088endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003089
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003090" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003091func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003092 call Setup_NewWindow()
3093 call assert_equal(5, &scroll)
3094 exe "norm! \<c-d>"
3095 call assert_equal('6', getline('.'))
3096 exe "norm! 2\<c-d>"
3097 call assert_equal('8', getline('.'))
3098 call assert_equal(2, &scroll)
3099 set scroll=5
3100 exe "norm! \<c-u>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02003101 call assert_equal('3', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003102 1
3103 set scrolloff=5
3104 exe "norm! \<c-d>"
3105 call assert_equal('10', getline('.'))
3106 exe "norm! \<c-u>"
3107 call assert_equal('5', getline('.'))
3108 1
3109 set scrolloff=99
3110 exe "norm! \<c-d>"
3111 call assert_equal('10', getline('.'))
3112 set scrolloff=0
3113 100
3114 exe "norm! $\<c-u>"
3115 call assert_equal('95', getline('.'))
3116 call assert_equal([0, 95, 1, 0, 1], getcurpos())
3117 100
3118 set nostartofline
3119 exe "norm! $\<c-u>"
3120 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00003121 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003122 " cleanup
3123 set startofline
3124 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003125endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003126
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003127func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003128 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003129 " The ~ register does not exist
3130 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003131 return
3132 endif
3133
3134 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003135 " unfortunately, without a gui, we can't really test much here,
3136 " so simply test that ~p fails (which uses the drop register)
3137 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003138 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003139 call assert_equal([], getreg('~', 1, 1))
3140 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003141 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003142 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003143endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003144
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003145func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003146 new
3147 " How to test this?
3148 " let's just for now test, that the buffer
3149 " does not change
3150 call feedkeys("\<c-s>", 't')
3151 call assert_equal([''], getline(1,'$'))
3152
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003153 " no valid commands
3154 exe "norm! \<char-0x100>"
3155 call assert_equal([''], getline(1,'$'))
3156
3157 exe "norm! ä"
3158 call assert_equal([''], getline(1,'$'))
3159
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003160 " clean up
3161 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003162endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003163
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003164func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003165 " This was causing a crash or ml_get error.
3166 enew!
3167 call setline(1,'xxx')
3168 normal $
3169 new
3170 call setline(1, range(1,2))
3171 2
3172 exe "norm \<C-V>$"
3173 bw!
3174 norm yp
3175 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003176endfunc
3177
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003178func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003179 new
3180 exe "norm! \<c-w>c"
3181 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003182 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003183endfunc
3184
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003185func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003186 new
3187 call setline(1, 'one two three four five six seven eight nine ten')
3188 1
3189 norm! 3d2w
3190 call assert_equal('seven eight nine ten', getline(1))
3191 bw!
3192endfunc
3193
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003194func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003195 CheckFeature timers
3196 CheckFeature cmdline_hist
Bram Moolenaarc255b782022-11-26 19:16:48 +00003197
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003198 func! DoTimerWork(id)
Sean Dewar1fb41032023-08-16 17:15:05 +01003199 call assert_equal(1, getbufinfo('')[0].command)
Bram Moolenaarc255b782022-11-26 19:16:48 +00003200
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003201 " should fail, with E11, but does fail with E23?
3202 "call feedkeys("\<c-^>", 'tm')
3203
Bram Moolenaarc255b782022-11-26 19:16:48 +00003204 " should fail with E11 - "Invalid in command-line window"
Bram Moolenaare2e40752020-09-04 21:18:46 +02003205 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaarc255b782022-11-26 19:16:48 +00003206
3207 " Return from commandline window.
3208 call feedkeys("\<CR>", 't')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003209 endfunc
3210
3211 let oldlang=v:lang
3212 lang C
3213 set updatetime=20
3214 call timer_start(100, 'DoTimerWork')
3215 try
3216 " throws E23, for whatever reason...
3217 call feedkeys('q:', 'x!')
3218 catch /E23/
3219 " no-op
3220 endtry
Bram Moolenaarc255b782022-11-26 19:16:48 +00003221
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003222 " clean up
Bram Moolenaarc255b782022-11-26 19:16:48 +00003223 delfunc DoTimerWork
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003224 set updatetime=4000
3225 exe "lang" oldlang
3226 bw!
3227endfunc
3228
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003229func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003230 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003231 " Don't sleep after the warning message.
3232 call test_settime(1)
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01003233 call writefile(['foo'], 'Xreadonly.log', 'D')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003234 new Xreadonly.log
3235 setl ro
3236 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003237 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003238 call assert_equal(['foo'], getline(1,'$'))
3239 call assert_equal('Xreadonly.log', bufname(''))
3240
3241 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003242 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003243 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003244endfunc
3245
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003246func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003247 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003248 new
3249 call setline(1, 'abcde fghij klmnopq')
3250 norm! 1gg$
3251 set rl
3252 call assert_equal(19, col('.'))
3253 call feedkeys('l', 'tx')
3254 call assert_equal(18, col('.'))
3255 call feedkeys('h', 'tx')
3256 call assert_equal(19, col('.'))
3257 call feedkeys("\<right>", 'tx')
3258 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003259 call feedkeys("\<left>", 'tx')
3260 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003261 call feedkeys("\<s-right>", 'tx')
3262 call assert_equal(13, col('.'))
3263 call feedkeys("\<c-right>", 'tx')
3264 call assert_equal(7, col('.'))
3265 call feedkeys("\<c-left>", 'tx')
3266 call assert_equal(13, col('.'))
3267 call feedkeys("\<s-left>", 'tx')
3268 call assert_equal(19, col('.'))
3269 call feedkeys("<<", 'tx')
3270 call assert_equal(' abcde fghij klmnopq',getline(1))
3271 call feedkeys(">>", 'tx')
3272 call assert_equal('abcde fghij klmnopq',getline(1))
3273
3274 " cleanup
3275 set norl
3276 bw!
3277endfunc
3278
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003279func Test_normal54_Ctrl_bsl()
3280 new
3281 call setline(1, 'abcdefghijklmn')
3282 exe "norm! df\<c-\>\<c-n>"
3283 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3284 exe "norm! df\<c-\>\<c-g>"
3285 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3286 exe "norm! df\<c-\>m"
3287 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003288
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003289 call setline(2, 'abcdefghijklmnāf')
3290 norm! 2gg0
3291 exe "norm! df\<Char-0x101>"
3292 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3293 norm! 1gg0
3294 exe "norm! df\<esc>"
3295 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003296
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003297 " clean up
3298 bw!
3299endfunc
3300
3301func Test_normal_large_count()
3302 " This may fail with 32bit long, how do we detect that?
3303 new
3304 normal o
3305 normal 6666666666dL
3306 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003307endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003308
3309func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003310 new
3311 normal grádv}
3312 call assert_equal('á', getline(1))
3313 normal grád}
3314 call assert_equal('', getline(1))
3315 bwipe!
3316endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003317
3318" Test for the gr (virtual replace) command
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003319func Test_gr_command()
3320 enew!
zeertzjq4f026ea2023-02-26 14:47:24 +00003321 " Test for the bug fixed by 7.4.387
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003322 let save_cpo = &cpo
3323 call append(0, ['First line', 'Second line', 'Third line'])
3324 exe "normal i\<C-G>u"
3325 call cursor(2, 1)
3326 set cpo-=X
3327 normal 4gro
3328 call assert_equal('oooond line', getline(2))
3329 undo
3330 set cpo+=X
3331 normal 4gro
3332 call assert_equal('ooooecond line', getline(2))
3333 let &cpo = save_cpo
zeertzjq4f026ea2023-02-26 14:47:24 +00003334
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003335 normal! ggvegrx
3336 call assert_equal('xxxxx line', getline(1))
3337 exe "normal! gggr\<C-V>122"
3338 call assert_equal('zxxxx line', getline(1))
zeertzjq4f026ea2023-02-26 14:47:24 +00003339
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003340 set virtualedit=all
3341 normal! 15|grl
3342 call assert_equal('zxxxx line l', getline(1))
3343 set virtualedit&
3344 set nomodifiable
3345 call assert_fails('normal! grx', 'E21:')
3346 call assert_fails('normal! gRx', 'E21:')
zeertzjq4f026ea2023-02-26 14:47:24 +00003347 call assert_nobeep("normal! gr\<Esc>")
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003348 set modifiable&
zeertzjq4f026ea2023-02-26 14:47:24 +00003349
3350 call assert_nobeep("normal! gr\<Esc>")
zeertzjqf86dea82023-03-05 21:15:06 +00003351 call assert_nobeep("normal! cgr\<Esc>")
3352 call assert_beeps("normal! cgrx")
zeertzjq4f026ea2023-02-26 14:47:24 +00003353
3354 call assert_equal('zxxxx line l', getline(1))
3355 exe "normal! 2|gr\<C-V>\<Esc>"
3356 call assert_equal("z\<Esc>xx line l", getline(1))
3357
3358 call setline(1, 'abcdef')
3359 exe "normal! 0gr\<C-O>lx"
3360 call assert_equal("\<C-O>def", getline(1))
3361
3362 call setline(1, 'abcdef')
3363 exe "normal! 0gr\<C-G>lx"
3364 call assert_equal("\<C-G>def", getline(1))
3365
3366 bwipe!
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003367endfunc
3368
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003369func Test_nv_hat_count()
3370 %bwipeout!
3371 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003372 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003373
3374 edit Xfoo
3375 let l:foo_nr = bufnr('Xfoo')
3376
3377 edit Xbar
3378 let l:bar_nr = bufnr('Xbar')
3379
3380 " Make sure we are not just using the alternate file.
3381 edit Xbaz
3382
3383 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3384 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3385
3386 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3387 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3388
3389 %bwipeout!
3390endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003391
3392func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003393 " Make sure no buffers are changed.
3394 %bwipe!
3395
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003396 exe "normal \<C-C>"
3397 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003398
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003399 new
3400 cal setline(1, 'hi!')
3401 exe "normal \<C-C>"
3402 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003403
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003404 bwipe!
3405endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003406
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01003407func Test_mode_updated_after_ctrl_c()
3408 CheckScreendump
3409
3410 let buf = RunVimInTerminal('', {'rows': 5})
3411 call term_sendkeys(buf, "i")
3412 call term_sendkeys(buf, "\<C-O>")
3413 " wait a moment so that the "-- (insert) --" message is displayed
3414 call TermWait(buf, 50)
3415 call term_sendkeys(buf, "\<C-C>")
3416 call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
3417
3418 call StopVimInTerminal(buf)
3419endfunc
3420
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003421" Test for '[m', ']m', '[M' and ']M'
3422" Jumping to beginning and end of methods in Java-like languages
3423func Test_java_motion()
3424 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003425 call assert_beeps('normal! [m')
3426 call assert_beeps('normal! ]m')
3427 call assert_beeps('normal! [M')
3428 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003429 let lines =<< trim [CODE]
3430 Piece of Java
3431 {
3432 tt m1 {
3433 t1;
3434 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003435
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003436 tt m2 {
3437 t2;
3438 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003439
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003440 tt m3 {
3441 if (x)
3442 {
3443 t3;
3444 }
3445 } e3
3446 }
3447 [CODE]
3448 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003449
3450 normal gg
3451
3452 normal 2]maA
3453 call assert_equal("\ttt m1 {A", getline('.'))
3454 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3455
3456 normal j]maB
3457 call assert_equal("\ttt m2 {B", getline('.'))
3458 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3459
3460 normal ]maC
3461 call assert_equal("\ttt m3 {C", getline('.'))
3462 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3463
3464 normal [maD
3465 call assert_equal("\ttt m3 {DC", getline('.'))
3466 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3467
3468 normal k2[maE
3469 call assert_equal("\ttt m1 {EA", getline('.'))
3470 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3471
3472 normal 3[maF
3473 call assert_equal("{F", getline('.'))
3474 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3475
3476 normal ]MaG
3477 call assert_equal("\t}G e1", getline('.'))
3478 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3479
3480 normal j2]MaH
3481 call assert_equal("\t}H e3", getline('.'))
3482 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3483
3484 normal ]M]M
3485 normal aI
3486 call assert_equal("}I", getline('.'))
3487 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3488
3489 normal 2[MaJ
3490 call assert_equal("\t}JH e3", getline('.'))
3491 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3492
3493 normal k[MaK
3494 call assert_equal("\t}K e2", getline('.'))
3495 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3496
3497 normal 3[MaL
3498 call assert_equal("{LF", getline('.'))
3499 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3500
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003501 call cursor(2, 1)
3502 call assert_beeps('norm! 5]m')
3503
3504 " jumping to a method in a fold should open the fold
3505 6,10fold
3506 call feedkeys("gg3]m", 'xt')
3507 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3508 call assert_equal(-1, foldclosedend(7))
3509
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003510 bwipe!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003511endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003512
Bram Moolenaar004a6782020-04-11 17:09:31 +02003513" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003514func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003515 call Setup_NewWindow()
3516 " Make long lines that will wrap
3517 %s/$/\=repeat(' foobar', 10)/
3518 20vsp
3519 set wrap
3520 " Test for g$ with count
3521 norm! gg
3522 norm! 0vg$y
3523 call assert_equal(20, col("'>"))
3524 call assert_equal('1 foobar foobar foob', getreg(0))
3525 norm! gg
3526 norm! 0v4g$y
3527 call assert_equal(72, col("'>"))
3528 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3529 norm! gg
3530 norm! 0v6g$y
3531 call assert_equal(40, col("'>"))
3532 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3533 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3534 set nowrap
3535 " clean up
3536 norm! gg
3537 norm! 0vg$y
3538 call assert_equal(20, col("'>"))
3539 call assert_equal('1 foobar foobar foob', getreg(0))
3540 norm! gg
3541 norm! 0v4g$y
3542 call assert_equal(20, col("'>"))
3543 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3544 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3545 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3546 \ '4 foobar foobar foob', getreg(0))
3547 norm! gg
3548 norm! 0v6g$y
3549 call assert_equal(20, col("'>"))
3550 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3551 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3552 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3553 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3554 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3555 \ '6 foobar foobar foob', getreg(0))
3556 " Move to last line, also down movement is not possible, should still move
3557 " the cursor to the last visible char
3558 norm! G
3559 norm! 0v6g$y
3560 call assert_equal(20, col("'>"))
3561 call assert_equal('100 foobar foobar fo', getreg(0))
3562 bw!
3563endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003564
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003565func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003566 " needs 80 column new window
3567 new
3568 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003569 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003570 put =[repeat('x',90)..' {{{1', 'x {{{1']
3571 norm! gk
3572 " In a 80 column wide terminal the window will be only 78 char
3573 " (because Vim will leave space for the other window),
3574 " but if the terminal is larger, it will be 80 chars, so verify the
3575 " cursor column correctly.
3576 call assert_equal(winwidth(0)+1, col('.'))
3577 call assert_equal(winwidth(0)+1, virtcol('.'))
3578 norm! j
3579 call assert_equal(6, col('.'))
3580 call assert_equal(6, virtcol('.'))
3581 norm! gk
3582 call assert_equal(95, col('.'))
3583 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003584 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003585
3586 " needs 80 column new window
3587 new
3588 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003589 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003590 set number
3591 set numberwidth=10
3592 set cpoptions+=n
3593 put =[repeat('0',90), repeat('1',90)]
3594 norm! 075l
3595 call assert_equal(76, col('.'))
3596 norm! gk
3597 call assert_equal(1, col('.'))
3598 norm! gk
3599 call assert_equal(76, col('.'))
3600 norm! gk
3601 call assert_equal(1, col('.'))
3602 norm! gj
3603 call assert_equal(76, col('.'))
3604 norm! gj
3605 call assert_equal(1, col('.'))
3606 norm! gj
3607 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003608 " When 'nowrap' is set, gk and gj behave like k and j
3609 set nowrap
3610 normal! gk
3611 call assert_equal([2, 76], [line('.'), col('.')])
3612 normal! gj
3613 call assert_equal([3, 76], [line('.'), col('.')])
3614 %bw!
3615 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003616endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003617
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003618" Test for using : to run a multi-line Ex command in operator pending mode
3619func Test_normal_yank_with_excmd()
3620 new
3621 call setline(1, ['foo', 'bar', 'baz'])
3622 let @a = ''
3623 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3624 call assert_equal('f', @a)
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003625
3626 bwipe!
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003627endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003628
3629" Test for supplying a count to a normal-mode command across a cursorhold call
3630func Test_normal_cursorhold_with_count()
3631 func s:cHold()
3632 let g:cHold_Called += 1
3633 endfunc
3634 new
3635 augroup normalcHoldTest
3636 au!
3637 au CursorHold <buffer> call s:cHold()
3638 augroup END
3639 let g:cHold_Called = 0
3640 call feedkeys("3\<CursorHold>2ix", 'xt')
3641 call assert_equal(1, g:cHold_Called)
3642 call assert_equal(repeat('x', 32), getline(1))
3643 augroup normalcHoldTest
3644 au!
3645 augroup END
3646 au! normalcHoldTest
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003647
3648 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003649 delfunc s:cHold
3650endfunc
3651
3652" Test for using a count and a command with CTRL-W
3653func Test_wincmd_with_count()
3654 call feedkeys("\<C-W>12n", 'xt')
3655 call assert_equal(12, winheight(0))
3656endfunc
3657
3658" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003659func Test_horiz_motion()
3660 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003661 normal! gg
3662 call assert_beeps('normal! b')
3663 call assert_beeps('normal! B')
3664 call assert_beeps('normal! gE')
3665 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003666 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3667 call setline(1, 'one ,two ,three')
3668 exe "normal! $\<S-BS>"
3669 call assert_equal(11, col('.'))
3670 exe "normal! $\<C-BS>"
3671 call assert_equal(10, col('.'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003672
3673 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003674endfunc
3675
zeertzjq30b6d612023-05-07 17:39:23 +01003676" Test for using a ":" command in operator pending mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003677func Test_normal_colon_op()
3678 new
3679 call setline(1, ['one', 'two'])
3680 call assert_beeps("normal! Gc:d\<CR>")
zeertzjq30b6d612023-05-07 17:39:23 +01003681 call assert_equal(['one'], getline(1, '$'))
3682
3683 call setline(1, ['one…two…three!'])
3684 normal! $
3685 " Using ":" as a movement is characterwise exclusive
3686 call feedkeys("d:normal! F…\<CR>", 'xt')
3687 call assert_equal(['one…two!'], getline(1, '$'))
3688 " Check that redoing a command with 0x80 bytes works
3689 call feedkeys('.', 'xt')
3690 call assert_equal(['one!'], getline(1, '$'))
3691
3692 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3693 " Add this to the command history
3694 call feedkeys(":normal! G0\<CR>", 'xt')
3695 " Use :normal! with control characters in operator pending mode
3696 call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
3697 call assert_equal(['one', 'two', 'five'], getline(1, '$'))
3698 " Check that redoing a command with control characters works
3699 call feedkeys('.', 'xt')
3700 call assert_equal(['five'], getline(1, '$'))
3701
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003702 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003703endfunc
3704
Bram Moolenaar004a6782020-04-11 17:09:31 +02003705" Test for d and D commands
3706func Test_normal_delete_cmd()
3707 new
3708 " D in an empty line
3709 call setline(1, '')
3710 normal D
3711 call assert_equal('', getline(1))
3712 " D in an empty line in virtualedit mode
3713 set virtualedit=all
3714 normal D
3715 call assert_equal('', getline(1))
3716 set virtualedit&
3717 " delete to a readonly register
3718 call setline(1, ['abcd'])
3719 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003720
3721 " D and d with 'nomodifiable'
3722 call setline(1, ['abcd'])
3723 setlocal nomodifiable
3724 call assert_fails('normal D', 'E21:')
3725 call assert_fails('normal d$', 'E21:')
3726
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003727 bwipe!
Bram Moolenaar004a6782020-04-11 17:09:31 +02003728endfunc
3729
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003730" Test for deleting or changing characters across lines with 'whichwrap'
3731" containing 's'. Should count <EOL> as one character.
3732func Test_normal_op_across_lines()
3733 new
3734 set whichwrap&
3735 call setline(1, ['one two', 'three four'])
3736 exe "norm! $3d\<Space>"
3737 call assert_equal(['one twhree four'], getline(1, '$'))
3738
3739 call setline(1, ['one two', 'three four'])
3740 exe "norm! $3c\<Space>x"
3741 call assert_equal(['one twxhree four'], getline(1, '$'))
3742
3743 set whichwrap+=l
3744 call setline(1, ['one two', 'three four'])
3745 exe "norm! $3x"
3746 call assert_equal(['one twhree four'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003747
3748 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003749 set whichwrap&
3750endfunc
3751
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003752" Test for 'w' and 'b' commands
3753func Test_normal_word_move()
3754 new
3755 call setline(1, ['foo bar a', '', 'foo bar b'])
3756 " copy a single character word at the end of a line
3757 normal 1G$yw
3758 call assert_equal('a', @")
3759 " copy a single character word at the end of a file
3760 normal G$yw
3761 call assert_equal('b', @")
3762 " check for a word movement handling an empty line properly
3763 normal 1G$vwy
3764 call assert_equal("a\n\n", @")
3765
3766 " copy using 'b' command
3767 %d
3768 " non-empty blank line at the start of file
3769 call setline(1, [' ', 'foo bar'])
3770 normal 2Gyb
3771 call assert_equal(" \n", @")
3772 " try to copy backwards from the start of the file
3773 call setline(1, ['one two', 'foo bar'])
3774 call assert_beeps('normal ggyb')
3775 " 'b' command should stop at an empty line
3776 call setline(1, ['one two', '', 'foo bar'])
3777 normal 3Gyb
3778 call assert_equal("\n", @")
3779 normal 3Gy2b
3780 call assert_equal("two\n", @")
3781 " 'b' command should not stop at a non-empty blank line
3782 call setline(1, ['one two', ' ', 'foo bar'])
3783 normal 3Gyb
3784 call assert_equal("two\n ", @")
3785
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003786 bwipe!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003787endfunc
3788
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003789" Test for 'scrolloff' with a long line that doesn't fit in the screen
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003790func Test_normal_scrolloff()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003791 10new
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003792 60vnew
3793 call setline(1, ' 1 ' .. repeat('a', 57)
3794 \ .. ' 2 ' .. repeat('b', 57)
3795 \ .. ' 3 ' .. repeat('c', 57)
3796 \ .. ' 4 ' .. repeat('d', 57)
3797 \ .. ' 5 ' .. repeat('e', 57)
3798 \ .. ' 6 ' .. repeat('f', 57)
3799 \ .. ' 7 ' .. repeat('g', 57)
3800 \ .. ' 8 ' .. repeat('h', 57)
3801 \ .. ' 9 ' .. repeat('i', 57)
3802 \ .. '10 ' .. repeat('j', 57)
3803 \ .. '11 ' .. repeat('k', 57)
3804 \ .. '12 ' .. repeat('l', 57)
3805 \ .. '13 ' .. repeat('m', 57)
3806 \ .. '14 ' .. repeat('n', 57)
3807 \ .. '15 ' .. repeat('o', 57)
3808 \ .. '16 ' .. repeat('p', 57)
3809 \ .. '17 ' .. repeat('q', 57)
3810 \ .. '18 ' .. repeat('r', 57)
3811 \ .. '19 ' .. repeat('s', 57)
3812 \ .. '20 ' .. repeat('t', 57)
3813 \ .. '21 ' .. repeat('u', 57)
3814 \ .. '22 ' .. repeat('v', 57)
3815 \ .. '23 ' .. repeat('w', 57)
3816 \ .. '24 ' .. repeat('x', 57)
3817 \ .. '25 ' .. repeat('y', 57)
3818 \ .. '26 ' .. repeat('z', 57)
3819 \ )
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003820 set scrolloff=10
3821 normal gg10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003822 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003823 normal 10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003824 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003825 normal 10gk
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003826 call assert_equal(6, winline())
3827 normal 0
3828 call assert_equal(1, winline())
3829 normal $
3830 call assert_equal(10, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003831
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003832 set scrolloff&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003833 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003834endfunc
3835
3836" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3837func Test_normal_vert_scroll_longline()
3838 10new
3839 80vnew
3840 call setline(1, range(1, 10))
3841 call append(5, repeat('a', 1000))
3842 exe "normal gg\<C-F>"
3843 call assert_equal(6, line('.'))
3844 exe "normal \<C-F>\<C-F>"
3845 call assert_equal(11, line('.'))
3846 call assert_equal(1, winline())
3847 exe "normal \<C-B>"
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02003848 call assert_equal(11, line('.'))
3849 call assert_equal(5, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003850 exe "normal \<C-B>\<C-B>"
3851 call assert_equal(5, line('.'))
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003852 call assert_equal(5, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003853
3854 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003855endfunc
3856
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003857" Test for jumping in a file using %
3858func Test_normal_percent_jump()
3859 new
3860 call setline(1, range(1, 100))
3861
3862 " jumping to a folded line should open the fold
3863 25,75fold
3864 call feedkeys('50%', 'xt')
3865 call assert_equal(50, line('.'))
3866 call assert_equal(-1, foldclosedend(50))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003867
3868 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003869endfunc
3870
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003871" Test for << and >> commands to shift text by 'shiftwidth'
3872func Test_normal_shift_rightleft()
3873 new
3874 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3875 set shiftwidth=2 tabstop=8
3876 normal gg6>>
3877 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3878 \ getline(1, '$'))
3879 normal ggVG2>>
3880 call assert_equal([' one', '', "\t ", "\ttwo",
3881 \ "\t three", "\t four"], getline(1, '$'))
3882 normal gg6<<
3883 call assert_equal([' one', '', "\t ", ' two', "\t three",
3884 \ "\t four"], getline(1, '$'))
3885 normal ggVG2<<
3886 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3887 \ getline(1, '$'))
3888 set shiftwidth& tabstop&
3889 bw!
3890endfunc
3891
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003892" Some commands like yy, cc, dd, >>, << and !! accept a count after
3893" typing the first letter of the command.
3894func Test_normal_count_after_operator()
3895 new
3896 setlocal shiftwidth=4 tabstop=8 autoindent
3897 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3898 let @a = ''
3899 normal! j"ay4y
3900 call assert_equal("two\nthree\nfour\nfive\n", @a)
3901 normal! 3G>2>
3902 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3903 \ getline(1, '$'))
3904 exe "normal! 3G0c2cred\nblue"
3905 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3906 \ getline(1, '$'))
3907 exe "normal! gg<8<"
3908 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3909 \ getline(1, '$'))
3910 exe "normal! ggd3d"
3911 call assert_equal(['blue', 'five'], getline(1, '$'))
3912 call setline(1, range(1, 4))
3913 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3914 call assert_equal('".,.+2!', @:)
3915 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3916 call assert_equal('".!', @:)
3917 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3918 call assert_equal('".,$!', @:)
3919 bw!
3920endfunc
3921
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003922func Test_normal_gj_on_extra_wide_char()
3923 new | 25vsp
3924 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3925 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3926 \ ' dreizehn v ierzehn fünfzehn'
3927 put =text
3928 call cursor(2,1)
3929 norm! gj
3930 call assert_equal([0,2,25,0], getpos('.'))
3931 bw!
3932endfunc
3933
Bram Moolenaar03725c52021-11-24 12:17:53 +00003934func Test_normal_count_out_of_range()
3935 new
3936 call setline(1, 'text')
3937 normal 44444444444|
3938 call assert_equal(999999999, v:count)
3939 normal 444444444444|
3940 call assert_equal(999999999, v:count)
3941 normal 4444444444444|
3942 call assert_equal(999999999, v:count)
3943 normal 4444444444444444444|
3944 call assert_equal(999999999, v:count)
3945
3946 normal 9y99999999|
3947 call assert_equal(899999991, v:count)
3948 normal 10y99999999|
3949 call assert_equal(999999999, v:count)
3950 normal 44444444444y44444444444|
3951 call assert_equal(999999999, v:count)
3952 bwipe!
3953endfunc
3954
zeertzjqcdeb6572022-11-15 13:46:12 +00003955" Test that mouse shape is restored to Normal mode after failed "c" operation.
3956func Test_mouse_shape_after_failed_change()
3957 CheckFeature mouseshape
3958 CheckCanRunGui
3959
3960 let lines =<< trim END
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003961 vim9script
zeertzjqcdeb6572022-11-15 13:46:12 +00003962 set mouseshape+=o:busy
3963 setlocal nomodifiable
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003964 var mouse_shapes = []
zeertzjqcdeb6572022-11-15 13:46:12 +00003965
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003966 feedkeys('c')
3967 timer_start(50, (_) => {
3968 mouse_shapes += [getmouseshape()]
3969 timer_start(50, (_) => {
3970 feedkeys('c')
3971 timer_start(50, (_) => {
3972 mouse_shapes += [getmouseshape()]
3973 timer_start(50, (_) => {
3974 writefile(mouse_shapes, 'Xmouseshapes')
3975 quit
3976 })
3977 })
3978 })
3979 })
zeertzjqcdeb6572022-11-15 13:46:12 +00003980 END
3981 call writefile(lines, 'Xmouseshape.vim', 'D')
3982 call RunVim([], [], "-g -S Xmouseshape.vim")
Yee Cheng Chin24078e32024-11-12 20:26:48 +01003983 call WaitForAssert({-> assert_equal(['busy', 'arrow'], readfile('Xmouseshapes'))}, 300)
zeertzjqcdeb6572022-11-15 13:46:12 +00003984
3985 call delete('Xmouseshapes')
3986endfunc
3987
zeertzjqf86dea82023-03-05 21:15:06 +00003988" Test that mouse shape is restored to Normal mode after cancelling "gr".
3989func Test_mouse_shape_after_cancelling_gr()
3990 CheckFeature mouseshape
3991 CheckCanRunGui
3992
3993 let lines =<< trim END
3994 vim9script
3995 var mouse_shapes = []
3996
3997 feedkeys('gr')
3998 timer_start(50, (_) => {
3999 mouse_shapes += [getmouseshape()]
4000 timer_start(50, (_) => {
4001 feedkeys("\<Esc>")
4002 timer_start(50, (_) => {
4003 mouse_shapes += [getmouseshape()]
4004 timer_start(50, (_) => {
4005 writefile(mouse_shapes, 'Xmouseshapes')
4006 quit
4007 })
4008 })
4009 })
4010 })
4011 END
4012 call writefile(lines, 'Xmouseshape.vim', 'D')
4013 call RunVim([], [], "-g -S Xmouseshape.vim")
Yee Cheng Chin24078e32024-11-12 20:26:48 +01004014 call WaitForAssert({-> assert_equal(['beam', 'arrow'], readfile('Xmouseshapes'))}, 300)
zeertzjqf86dea82023-03-05 21:15:06 +00004015
4016 call delete('Xmouseshapes')
4017endfunc
4018
Luuk van Baalaa6ba302023-05-09 16:01:17 +01004019" Test that "j" does not skip lines when scrolling below botline and
4020" 'foldmethod' is not "manual".
4021func Test_normal_j_below_botline()
4022 CheckScreendump
4023
4024 let lines =<< trim END
4025 set number foldmethod=diff scrolloff=0
4026 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
4027 norm Lj
4028 END
4029 call writefile(lines, 'XNormalJBelowBotline', 'D')
4030 let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
4031
4032 call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
4033
4034 call StopVimInTerminal(buf)
4035endfunc
4036
Christian Brabandt2d63e4b2023-08-12 00:03:57 +02004037" Test for r (replace) command with CTRL_V and CTRL_Q
4038func Test_normal_r_ctrl_v_cmd()
4039 new
4040 call append(0, 'This is a simple test: abcd')
4041 exe "norm! 1gg$r\<C-V>\<C-V>"
4042 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4043 exe "norm! 1gg$hr\<C-Q>\<C-Q>"
4044 call assert_equal(['This is a simple test: ab', ''], getline(1,'$'))
4045 exe "norm! 1gg$2hr\<C-V>x7e"
4046 call assert_equal(['This is a simple test: a~', ''], getline(1,'$'))
4047 exe "norm! 1gg$3hr\<C-Q>x7e"
4048 call assert_equal(['This is a simple test: ~~', ''], getline(1,'$'))
4049
4050 if &encoding == 'utf-8'
4051 exe "norm! 1gg$4hr\<C-V>u20ac"
4052 call assert_equal(['This is a simple test:€~~', ''], getline(1,'$'))
4053 exe "norm! 1gg$5hr\<C-Q>u20ac"
4054 call assert_equal(['This is a simple test€€~~', ''], getline(1,'$'))
4055 exe "norm! 1gg0R\<C-V>xff WAS \<esc>"
4056 call assert_equal(['ÿ WAS a simple test€€~~', ''], getline(1,'$'))
4057 exe "norm! 1gg0elR\<C-Q>xffNOT\<esc>"
4058 call assert_equal(['ÿ WASÿNOT simple test€€~~', ''], getline(1,'$'))
4059 endif
4060
4061 call setline(1, 'This is a simple test: abcd')
4062 exe "norm! 1gg$gr\<C-V>\<C-V>"
4063 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4064 exe "norm! 1gg$hgr\<C-Q>\<C-Q>"
4065 call assert_equal(['This is a simple test: ab ', ''], getline(1,'$'))
4066 exe "norm! 1gg$2hgr\<C-V>x7e"
4067 call assert_equal(['This is a simple test: a~ ', ''], getline(1,'$'))
4068 exe "norm! 1gg$3hgr\<C-Q>x7e"
4069 call assert_equal(['This is a simple test: ~~ ', ''], getline(1,'$'))
4070
4071 " clean up
4072 bw!
4073endfunc
4074
zeertzjqb25dbb32023-08-13 18:11:05 +02004075" Test clicking on a TAB or an unprintable character in Normal mode
4076func Test_normal_click_on_ctrl_char()
4077 let save_mouse = &mouse
4078 set mouse=a
4079 new
4080
4081 call setline(1, "a\<Tab>b\<C-K>c")
4082 redraw
4083 call test_setmouse(1, 1)
4084 call feedkeys("\<LeftMouse>", 'xt')
4085 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4086 call test_setmouse(1, 2)
4087 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004088 call assert_equal([0, 1, 2, 0, 2], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004089 call test_setmouse(1, 3)
4090 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004091 call assert_equal([0, 1, 2, 0, 3], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004092 call test_setmouse(1, 7)
4093 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004094 call assert_equal([0, 1, 2, 0, 7], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004095 call test_setmouse(1, 8)
4096 call feedkeys("\<LeftMouse>", 'xt')
4097 call assert_equal([0, 1, 2, 0, 8], getcurpos())
4098 call test_setmouse(1, 9)
4099 call feedkeys("\<LeftMouse>", 'xt')
4100 call assert_equal([0, 1, 3, 0, 9], getcurpos())
4101 call test_setmouse(1, 10)
4102 call feedkeys("\<LeftMouse>", 'xt')
4103 call assert_equal([0, 1, 4, 0, 10], getcurpos())
4104 call test_setmouse(1, 11)
4105 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004106 call assert_equal([0, 1, 4, 0, 11], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004107 call test_setmouse(1, 12)
4108 call feedkeys("\<LeftMouse>", 'xt')
4109 call assert_equal([0, 1, 5, 0, 12], getcurpos())
4110 call test_setmouse(1, 13)
4111 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004112 call assert_equal([0, 1, 5, 0, 13], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004113
4114 bwipe!
4115 let &mouse = save_mouse
4116endfunc
4117
zeertzjq99941602023-08-19 13:08:50 +02004118" Test clicking on a double-width character in Normal mode
4119func Test_normal_click_on_double_width_char()
4120 let save_mouse = &mouse
4121 set mouse=a
4122 new
4123
4124 call setline(1, "口口")
4125 redraw
4126 call test_setmouse(1, 1)
4127 call feedkeys("\<LeftMouse>", 'xt')
4128 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4129 call test_setmouse(1, 2)
4130 call feedkeys("\<LeftMouse>", 'xt')
4131 call assert_equal([0, 1, 1, 0, 2], getcurpos())
4132 call test_setmouse(1, 3)
4133 call feedkeys("\<LeftMouse>", 'xt')
4134 call assert_equal([0, 1, 4, 0, 3], getcurpos())
4135 call test_setmouse(1, 4)
4136 call feedkeys("\<LeftMouse>", 'xt')
4137 call assert_equal([0, 1, 4, 0, 4], getcurpos())
4138
4139 bwipe!
4140 let &mouse = save_mouse
4141endfunc
4142
zeertzjq03cd6972023-09-20 20:08:40 +02004143func Test_normal_click_on_empty_line()
4144 let save_mouse = &mouse
4145 set mouse=a
4146 botright new
4147 call setline(1, ['', '', ''])
4148 let row = win_screenpos(0)[0] + 2
4149 20vsplit
4150 redraw
4151
4152 call test_setmouse(row, 1)
4153 call feedkeys("\<LeftMouse>", 'xt')
4154 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4155 call test_setmouse(row, 2)
4156 call feedkeys("\<LeftMouse>", 'xt')
4157 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4158 call test_setmouse(row, 10)
4159 call feedkeys("\<LeftMouse>", 'xt')
4160 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4161
4162 call test_setmouse(row, 21 + 1)
4163 call feedkeys("\<LeftMouse>", 'xt')
4164 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4165 call test_setmouse(row, 21 + 2)
4166 call feedkeys("\<LeftMouse>", 'xt')
4167 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4168 call test_setmouse(row, 21 + 10)
4169 call feedkeys("\<LeftMouse>", 'xt')
4170 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4171
4172 bwipe!
4173 let &mouse = save_mouse
4174endfunc
4175
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004176func Test_normal33_g_cmd_nonblank()
zeertzjq654bdbb2023-08-20 18:24:20 +02004177 " Test that g<End> goes to the last non-blank char and g$ to the last
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004178 " visible column
4179 20vnew
4180 setlocal nowrap nonumber signcolumn=no
4181 call setline(1, ['fooo fooo fooo fooo fooo fooo fooo fooo '])
zeertzjq654bdbb2023-08-20 18:24:20 +02004182 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004183 call assert_equal(11, col('.'))
4184 normal 0g$
4185 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004186 exe "normal 0g\<kEnd>"
4187 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004188 setlocal wrap
zeertzjq654bdbb2023-08-20 18:24:20 +02004189 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004190 call assert_equal(11, col('.'))
4191 normal 0g$
4192 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004193 exe "normal 0g\<kEnd>"
4194 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004195 bw!
4196endfunc
4197
Christian Brabandt58f9bef2023-11-14 21:02:30 +01004198func Test_normal34_zet_large()
4199 " shouldn't cause overflow
4200 norm! z9765405999999999999
4201endfunc
4202
zeertzjqad493ef2024-03-29 10:23:19 +01004203" Test for { and } paragraph movements in a single line
4204func Test_brace_single_line()
4205 new
4206 call setline(1, ['foobar one two three'])
4207 1
4208 norm! 0}
4209
4210 call assert_equal([0, 1, 20, 0], getpos('.'))
4211 norm! {
4212 call assert_equal([0, 1, 1, 0], getpos('.'))
4213 bw!
4214endfunc
4215
4216" Test for Ctrl-B/Ctrl-U in buffer with a single line
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004217func Test_single_line_scroll()
4218 CheckFeature textprop
Gary Johnson9e6549d2023-12-27 19:12:43 +01004219
4220 new
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004221 call setline(1, ['foobar one two three'])
4222 let vt = 'virt_above'
4223 call prop_type_add(vt, {'highlight': 'IncSearch'})
4224 call prop_add(1, 0, {'type': vt, 'text': '---', 'text_align': 'above'})
zeertzjqad493ef2024-03-29 10:23:19 +01004225 call cursor(1, 1)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004226
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004227 " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004228 set smoothscroll
4229 exe "normal \<C-E>"
4230 call assert_notequal(0, winsaveview().skipcol)
4231 exe "normal \<C-B>"
4232 call assert_equal(0, winsaveview().skipcol)
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004233 exe "normal \<C-E>"
4234 call assert_notequal(0, winsaveview().skipcol)
4235 exe "normal \<C-U>"
4236 call assert_equal(0, winsaveview().skipcol)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004237
4238 set smoothscroll&
Gary Johnson9e6549d2023-12-27 19:12:43 +01004239 bw!
zeertzjqad493ef2024-03-29 10:23:19 +01004240 call prop_type_delete(vt)
Gary Johnson9e6549d2023-12-27 19:12:43 +01004241endfunc
4242
Luuk van Baalbd28cae2024-04-03 22:50:40 +02004243" Test for zb in buffer with a single line and filler lines
4244func Test_single_line_filler_zb()
4245 call setline(1, ['', 'foobar one two three'])
4246 diffthis
4247 new
4248 call setline(1, ['foobar one two three'])
4249 diffthis
4250
4251 " zb scrolls to reveal filler lines at the start of the buffer.
4252 exe "normal \<C-E>zb"
4253 call assert_equal(1, winsaveview().topfill)
4254
4255 bw!
4256endfunc
4257
Luuk van Baal78c51502024-04-09 21:30:19 +02004258" Test for Ctrl-U not getting stuck at end of buffer with 'scrolloff'.
4259func Test_halfpage_scrolloff_eob()
4260 set scrolloff=5
4261
4262 call setline(1, range(1, 100))
4263 exe "norm! Gzz\<C-U>zz"
4264 call assert_notequal(100, line('.'))
4265
4266 set scrolloff&
4267 bwipe!
4268endfunc
4269
Luuk van Baalaa8e22b2024-04-10 17:33:43 +02004270" Test for Ctrl-U/D moving the cursor at the buffer boundaries.
4271func Test_halfpage_cursor_startend()
4272 call setline(1, range(1, 100))
4273 exe "norm! jztj\<C-U>"
4274 call assert_equal(1, line('.'))
4275 exe "norm! G\<C-Y>k\<C-D>"
4276 call assert_equal(100, line('.'))
4277 bwipe!
4278endfunc
4279
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02004280" Test for Ctrl-F/B moving the cursor to the window boundaries.
4281func Test_page_cursor_topbot()
4282 10new
4283 call setline(1, range(1, 100))
4284 exe "norm! gg2\<C-F>"
4285 call assert_equal(17, line('.'))
4286 exe "norm! \<C-B>"
4287 call assert_equal(18, line('.'))
4288 exe "norm! \<C-B>\<C-F>"
4289 call assert_equal(9, line('.'))
Luuk van Baal8ccb8902024-07-04 17:35:56 +02004290 " Not when already at the start of the buffer.
4291 exe "norm! ggj\<C-B>"
4292 call assert_equal(2, line('.'))
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02004293 bwipe!
4294endfunc
4295
Luuk van Baal58448e02024-05-11 11:27:52 +02004296" Test for Ctrl-D with long line
4297func Test_halfpage_longline()
4298 10new
zeertzjqfa117382024-09-29 10:14:32 +02004299 40vsplit
Luuk van Baal58448e02024-05-11 11:27:52 +02004300 call setline(1, ['long'->repeat(1000), 'short'])
4301 exe "norm! \<C-D>"
4302 call assert_equal(2, line('.'))
4303 bwipe!
4304endfunc
Christian Brabandteff20eb2024-05-15 21:35:36 +02004305
4306" Test for Ctrl-E with long line and very narrow window,
zeertzjq8feed3a2024-09-29 10:37:47 +02004307" used to cause an infinite loop
Christian Brabandteff20eb2024-05-15 21:35:36 +02004308func Test_scroll_longline_no_loop()
4309 4vnew
4310 setl smoothscroll number showbreak=> scrolloff=2
4311 call setline(1, repeat(['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'], 3))
4312 exe "normal! \<C-E>"
4313 bwipe!
4314endfunc
Christian Brabandtf8702ae2024-08-28 20:39:24 +02004315
4316" Test for go command
4317func Test_normal_go()
4318 new
4319 call setline(1, ['one two three four'])
4320 call cursor(1, 5)
4321 norm! dvgo
4322 call assert_equal('wo three four', getline(1))
4323 norm! ...
4324 call assert_equal('three four', getline(1))
4325
4326 bwipe!
4327endfunc
zeertzjqdf098fe2025-01-22 22:27:30 +01004328
Luuk van Baalc9825032025-04-13 17:45:34 +02004329" Test for Ctrl-D with 'scrolloff' and narrow window does not get stuck.
4330func Test_scroll_longline_scrolloff()
4331 11new
4332 36vsplit
4333 set scrolloff=5
4334
4335 call setline(1, ['']->repeat(5))
4336 call setline(6, ['foo'->repeat(20)]->repeat(2))
4337 call setline(8, ['bar'->repeat(30)])
4338 call setline(9, ['']->repeat(5))
4339 exe "normal! \<C-D>"
4340 call assert_equal(6, line('w0'))
4341 exe "normal! \<C-D>"
4342 call assert_equal(7, line('w0'))
4343
4344 set scrolloff&
4345 bwipe!
4346endfunc
4347
Luuk van Baalacf0ebe2025-05-12 20:45:41 +02004348" Benchmark test for Ctrl-F with 'nosmoothscroll'
4349func Test_scroll_longline_benchmark()
4350 call setline(1, ['foo'->repeat(20000)] + [''])
4351 let start = reltime()
4352 exe "normal! \<C-F>"
4353 call assert_inrange(0, 0.1, reltimefloat(reltime(start)))
4354 bwipe!
4355endfunc
4356
Luuk van Baalc6c72d12025-05-14 20:21:55 +02004357" Test Ctrl-B with 'nosmoothscroll' not stuck with line exactly window width.
4358func Test_scroll_longline_winwidth()
4359 10new
4360 call setline(1, ['']->repeat(20) + ['A'->repeat(20 * winwidth(0))] + ['']->repeat(20))
4361 exe "normal! G3\<C-B>"
4362 call assert_equal(22, line('w0'))
4363 exe "normal! \<C-B>"
4364 call assert_equal(21, line('w0'))
4365 exe "normal! \<C-B>"
4366 call assert_equal(11, line('w0'))
4367 exe "normal! \<C-B>"
4368 call assert_equal(3, line('w0'))
4369 exe "normal! \<C-B>"
4370 call assert_equal(1, line('w0'))
4371 bwipe!
4372endfunc
4373
Christian Brabandt5d5cbb22024-01-05 18:19:52 +01004374" vim: shiftwidth=2 sts=2 expandtab nofoldenable