blob: cbd90ec4e7e49a869e922e75c2819408753d4336 [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,'$'))
phaniumcb279922025-06-16 20:19:15 +02002607 " gv works in operator pending mode
2608 call assert_nobeep('normal! cgvxyza')
2609 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'xyza', 'xyza', 'xyza', 'xyza', 'xyza'], getline(1,'$'))
2610 exe "norm! ^\<c-v>Gydgv..cgvbc"
2611 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'bc', 'bc', 'bc', 'bc', 'bc'], getline(1,'$'))
2612 exe "norm! v^GragggUgv"
2613 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'bA', 'AA', 'AA', 'AA', 'Ac'], getline(1,'$'))
2614
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002615 " gv should beep without a previously selected visual area
2616 new
2617 call assert_beeps('normal! gv')
2618 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002619
2620 " Test for gk/gj
2621 %d
2622 15vsp
2623 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002624 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2625 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2626 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002627 $put =lineA
2628 $put =lineB
2629
2630 norm! 3gg0dgk
2631 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2632 set nu
2633 norm! 3gg0gjdgj
2634 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2635
2636 " Test for gJ
2637 norm! 2gggJ
2638 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2639 call assert_equal(16, col('.'))
2640 " shouldn't do anything
2641 norm! 10gJ
2642 call assert_equal(1, col('.'))
2643
2644 " Test for g0 g^ gm g$
2645 exe "norm! 2gg0gji "
2646 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2647 norm! g0yl
2648 call assert_equal(12, col('.'))
2649 call assert_equal(' ', getreg(0))
2650 norm! g$yl
2651 call assert_equal(22, col('.'))
2652 call assert_equal('3', getreg(0))
2653 norm! gmyl
2654 call assert_equal(17, col('.'))
2655 call assert_equal('n', getreg(0))
2656 norm! g^yl
2657 call assert_equal(15, col('.'))
2658 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002659 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002660
Bram Moolenaar74ede802021-05-29 19:18:01 +02002661 " Test for g$ with double-width character half displayed
2662 vsplit
2663 9wincmd |
2664 setlocal nowrap nonumber
2665 call setline(2, 'asdfasdfヨ')
2666 2
2667 normal 0g$
2668 call assert_equal(8, col('.'))
2669 10wincmd |
2670 normal 0g$
2671 call assert_equal(9, col('.'))
2672
2673 setlocal signcolumn=yes
2674 11wincmd |
2675 normal 0g$
2676 call assert_equal(8, col('.'))
2677 12wincmd |
2678 normal 0g$
2679 call assert_equal(9, col('.'))
2680
2681 close
2682
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002683 " Test for g_
2684 call assert_beeps('normal! 100g_')
2685 call setline(2, [' foo ', ' foobar '])
2686 normal! 2ggg_
2687 call assert_equal(5, col('.'))
2688 normal! 2g_
2689 call assert_equal(8, col('.'))
2690
2691 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002692 $put =lineC
2693
2694 " Test for gM
2695 norm! gMyl
2696 call assert_equal(73, col('.'))
2697 call assert_equal('0', getreg(0))
2698 " Test for 20gM
2699 norm! 20gMyl
2700 call assert_equal(29, col('.'))
2701 call assert_equal('S', getreg(0))
2702 " Test for 60gM
2703 norm! 60gMyl
2704 call assert_equal(87, col('.'))
2705 call assert_equal('E', getreg(0))
2706
zeertzjq757c37d2025-03-27 18:21:49 +01002707 " Have an odd number of chars in the line
2708 norm! A.
2709 call assert_equal(145, col('.'))
2710 norm! gMyl
2711 call assert_equal(73, col('.'))
2712 call assert_equal('0', getreg(0))
2713
2714 " 'listchars' "eol" should not affect gM behavior
2715 setlocal list listchars=eol:$
2716 norm! $
2717 call assert_equal(145, col('.'))
2718 norm! gMyl
2719 call assert_equal(73, col('.'))
2720 call assert_equal('0', getreg(0))
2721 setlocal nolist
2722
Bram Moolenaar71c41252021-12-26 15:00:07 +00002723 " Test for gM with Tab characters
2724 call setline('.', "\ta\tb\tc\td\te\tf")
2725 norm! gMyl
2726 call assert_equal(6, col('.'))
2727 call assert_equal("c", getreg(0))
2728
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002729 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002730 call setline('.', lineC)
2731 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002732 set ff=unix
2733 let a=execute(":norm! g\<c-g>")
2734 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2735
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002736 " Test for gI
2737 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002738 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002739
2740 " Test for gi
2741 wincmd c
2742 %d
2743 set tw=0
2744 call setline(1, ['foobar', 'new line'])
2745 norm! A next word
2746 $put ='third line'
2747 norm! gi another word
2748 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002749 call setline(1, 'foobar')
2750 normal! Ggifirst line
2751 call assert_equal('foobarfirst line', getline(1))
2752 " Test gi in 'virtualedit' mode with cursor after the end of the line
2753 set virtualedit=all
2754 call setline(1, 'foo')
2755 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2756 call setline(1, 'foo')
2757 normal! Ggifirst line
2758 call assert_equal('foo first line', getline(1))
2759 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002760
Dominique Pelle923dce22021-11-21 11:36:04 +00002761 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002762 exe "normal! g\<C-\>\<C-G>"
2763 call assert_equal('foo first line', getline('.'))
2764
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002765 " clean up
2766 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002767endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002768
Bram Moolenaarce416b42022-04-03 12:59:34 +01002769func Test_normal_ex_substitute()
2770 " This was hanging on the substitute prompt.
2771 new
2772 call setline(1, 'a')
2773 exe "normal! gggQs/a/b/c\<CR>"
2774 call assert_equal('a', getline(1))
2775 bwipe!
2776endfunc
2777
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002778" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002779func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002780 new
2781
2782 let a = execute(":norm! g\<c-g>")
2783 call assert_equal("\n--No lines in buffer--", a)
2784
Bram Moolenaar1671f442020-03-10 07:48:13 +01002785 " Test for CTRL-G (same as :file)
2786 let a = execute(":norm! \<c-g>")
2787 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2788
Bram Moolenaar05295832018-08-24 22:07:58 +02002789 call setline(1, ['first line', 'second line'])
2790
2791 " Test g CTRL-g with dos, mac and unix file type.
2792 norm! gojll
2793 set ff=dos
2794 let a = execute(":norm! g\<c-g>")
2795 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2796
2797 set ff=mac
2798 let a = execute(":norm! g\<c-g>")
2799 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2800
2801 set ff=unix
2802 let a = execute(":norm! g\<c-g>")
2803 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2804
2805 " Test g CTRL-g in visual mode (v)
2806 let a = execute(":norm! gojllvlg\<c-g>")
2807 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2808
2809 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2810 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2811 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2812
2813 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2814 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2815 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2816
2817 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2818 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2819 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2820
2821 " There should be one byte less with noeol
2822 set bin noeol
2823 let a = execute(":norm! \<Esc>gog\<c-g>")
2824 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2825 set bin & eol&
2826
Bram Moolenaar30276f22019-01-24 17:59:39 +01002827 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002828
Bram Moolenaar30276f22019-01-24 17:59:39 +01002829 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2830 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 +02002831
Bram Moolenaar30276f22019-01-24 17:59:39 +01002832 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2833 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 +02002834
Bram Moolenaar30276f22019-01-24 17:59:39 +01002835 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2836 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 +02002837
Bram Moolenaar30276f22019-01-24 17:59:39 +01002838 set fenc=utf8 bomb
2839 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2840 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 +02002841
Bram Moolenaar30276f22019-01-24 17:59:39 +01002842 set fenc=utf16 bomb
2843 let a = execute(":norm! g\<c-g>")
2844 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 +02002845
Bram Moolenaar30276f22019-01-24 17:59:39 +01002846 set fenc=utf32 bomb
2847 let a = execute(":norm! g\<c-g>")
2848 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 +02002849
Bram Moolenaar30276f22019-01-24 17:59:39 +01002850 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002851
2852 set ff&
2853 bwipe!
2854endfunc
2855
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002856" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002857func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002858 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002859 let a=execute(':norm! 1G0g8')
2860 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002861
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002862 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2863 let a=execute(':norm! 1G$g8')
2864 call assert_equal("\nc3 b6 ", a)
2865
2866 call setline(1, "a\u0302")
2867 let a=execute(':norm! 1G0g8')
2868 call assert_equal("\n61 + cc 82 ", a)
2869
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002870 " clean up
2871 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002872endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002873
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002874" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002875func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002876 new
2877
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002878 " With invalid byte.
2879 call setline(1, "___\xff___")
2880 norm! 1G08g8g
2881 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2882
2883 " With invalid byte before the cursor.
2884 call setline(1, "___\xff___")
2885 norm! 1G$h8g8g
2886 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2887
2888 " With truncated sequence.
2889 call setline(1, "___\xE2\x82___")
2890 norm! 1G08g8g
2891 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2892
2893 " With overlong sequence.
2894 call setline(1, "___\xF0\x82\x82\xAC___")
2895 norm! 1G08g8g
2896 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2897
2898 " With valid utf8.
2899 call setline(1, "café")
2900 norm! 1G08g8
2901 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2902
2903 bw!
2904endfunc
2905
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002906" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002907func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002908 " Cannot capture its output,
2909 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002910 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002911 echo "a\nb\nc\nd"
2912 let b=execute(':norm! g<')
2913 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002914endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002915
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002916" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002917func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002918 new
2919 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002920 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002921 " Test for gp gP
2922 call append(1, range(1,10))
2923 1
2924 norm! 1yy
2925 3
2926 norm! gp
2927 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2928 $
2929 norm! gP
2930 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2931
2932 " Test for go
2933 norm! 26go
2934 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2935 norm! 27go
2936 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2937 norm! 28go
2938 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2939 set ff=dos
2940 norm! 29go
2941 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2942 set ff=unix
2943 norm! gg0
2944 norm! 101go
2945 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2946 norm! 103go
2947 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2948 " count > buffer content
2949 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002950 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002951 " clean up
2952 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002953endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002954
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002955" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002956func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002957 tabnew 1.txt
2958 tabnew 2.txt
2959 tabnew 3.txt
2960 norm! 1gt
2961 call assert_equal(1, tabpagenr())
2962 norm! 3gt
2963 call assert_equal(3, tabpagenr())
2964 norm! 1gT
2965 " count gT goes not to the absolute tabpagenumber
2966 " but, but goes to the count previous tabpagenumber
2967 call assert_equal(2, tabpagenr())
2968 " wrap around
2969 norm! 3gT
2970 call assert_equal(3, tabpagenr())
2971 " gt does not wrap around
2972 norm! 5gt
2973 call assert_equal(3, tabpagenr())
2974
2975 for i in range(3)
2976 tabclose
2977 endfor
2978 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002979 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002980endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002981
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002982" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002983func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002984 new
2985 call setline(1, range(10))
2986 $
2987 setl et sw=2
2988 norm! V10>$
2989 " count is ignored
2990 exe "norm! 10\<home>"
2991 call assert_equal(1, col('.'))
2992 exe "norm! \<home>"
2993 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2994 exe "norm! 5\<c-home>"
2995 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2996 exe "norm! \<c-home>"
2997 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002998 exe "norm! G\<c-kHome>"
2999 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003000
3001 " clean up
3002 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003003endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003004
Bram Moolenaar1671f442020-03-10 07:48:13 +01003005" Test for <End> and <C-End> keys
3006func Test_normal_nvend()
3007 new
3008 call setline(1, map(range(1, 10), '"line" .. v:val'))
3009 exe "normal! \<End>"
3010 call assert_equal(5, col('.'))
3011 exe "normal! 4\<End>"
3012 call assert_equal([4, 5], [line('.'), col('.')])
3013 exe "normal! \<C-End>"
3014 call assert_equal([10, 6], [line('.'), col('.')])
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003015
3016 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003017endfunc
3018
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003019" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01003020func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003021 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003022 new
3023 set tw=0
3024 call append(0, 'here are some words')
3025 norm! 1gg0elcwZZZ
3026 call assert_equal('hereZZZare some words', getline('.'))
3027 norm! 1gg0elcWYYY
3028 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003029 norm! 2gg0cwfoo
3030 call assert_equal('foo', getline('.'))
3031
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003032 call setline(1, 'one; two')
3033 call cursor(1, 1)
3034 call feedkeys('cwvim', 'xt')
3035 call assert_equal('vim; two', getline(1))
3036 call feedkeys('0cWone', 'xt')
3037 call assert_equal('one two', getline(1))
3038 "When cursor is at the end of a word 'ce' will change until the end of the
3039 "next word, but 'cw' will change only one character
3040 call setline(1, 'one two')
3041 call feedkeys('0ecwce', 'xt')
3042 call assert_equal('once two', getline(1))
3043 call setline(1, 'one two')
3044 call feedkeys('0ecely', 'xt')
3045 call assert_equal('only', getline(1))
3046
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003047 " clean up
3048 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003049endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003050
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003051" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003052func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003053 new
3054 call append(0, 'here are some words')
3055 exe "norm! 1gg0a\<C-\>\<C-N>"
3056 call assert_equal('n', mode())
3057 call assert_equal(1, col('.'))
3058 call assert_equal('', visualmode())
3059 exe "norm! 1gg0viw\<C-\>\<C-N>"
3060 call assert_equal('n', mode())
3061 call assert_equal(4, col('.'))
3062 exe "norm! 1gg0a\<C-\>\<C-G>"
3063 call assert_equal('n', mode())
3064 call assert_equal(1, col('.'))
3065 "imap <buffer> , <c-\><c-n>
3066 set im
3067 exe ":norm! \<c-\>\<c-n>dw"
3068 set noim
3069 call assert_equal('are some words', getline(1))
3070 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02003071 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01003072
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003073 " clean up
3074 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003075endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003076
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003077" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003078func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003079 new
3080 set sts=2 sw=2 ts=8 tw=0
3081 call append(0, ["aaa\tbbb\tccc", '', '', ''])
3082 let a=getline(1)
3083 norm! 2gg0
3084 exe "norm! a\<c-r>=a\<cr>"
3085 norm! 3gg0
3086 exe "norm! a\<c-r>\<c-r>=a\<cr>"
3087 norm! 4gg0
3088 exe "norm! a\<c-r>\<c-o>=a\<cr>"
3089 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
3090
3091 " clean up
3092 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02003093 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003094endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003095
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003096" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003097func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003098 call Setup_NewWindow()
3099 call assert_equal(5, &scroll)
3100 exe "norm! \<c-d>"
3101 call assert_equal('6', getline('.'))
3102 exe "norm! 2\<c-d>"
3103 call assert_equal('8', getline('.'))
3104 call assert_equal(2, &scroll)
3105 set scroll=5
3106 exe "norm! \<c-u>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02003107 call assert_equal('3', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003108 1
3109 set scrolloff=5
3110 exe "norm! \<c-d>"
3111 call assert_equal('10', getline('.'))
3112 exe "norm! \<c-u>"
3113 call assert_equal('5', getline('.'))
3114 1
3115 set scrolloff=99
3116 exe "norm! \<c-d>"
3117 call assert_equal('10', getline('.'))
3118 set scrolloff=0
3119 100
3120 exe "norm! $\<c-u>"
3121 call assert_equal('95', getline('.'))
3122 call assert_equal([0, 95, 1, 0, 1], getcurpos())
3123 100
3124 set nostartofline
3125 exe "norm! $\<c-u>"
3126 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00003127 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003128 " cleanup
3129 set startofline
3130 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003131endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003132
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003133func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003134 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003135 " The ~ register does not exist
3136 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003137 return
3138 endif
3139
3140 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003141 " unfortunately, without a gui, we can't really test much here,
3142 " so simply test that ~p fails (which uses the drop register)
3143 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003144 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003145 call assert_equal([], getreg('~', 1, 1))
3146 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003147 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003148 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003149endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003150
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003151func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003152 new
3153 " How to test this?
3154 " let's just for now test, that the buffer
3155 " does not change
3156 call feedkeys("\<c-s>", 't')
3157 call assert_equal([''], getline(1,'$'))
3158
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003159 " no valid commands
3160 exe "norm! \<char-0x100>"
3161 call assert_equal([''], getline(1,'$'))
3162
3163 exe "norm! ä"
3164 call assert_equal([''], getline(1,'$'))
3165
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003166 " clean up
3167 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003168endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003169
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003170func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003171 " This was causing a crash or ml_get error.
3172 enew!
3173 call setline(1,'xxx')
3174 normal $
3175 new
3176 call setline(1, range(1,2))
3177 2
3178 exe "norm \<C-V>$"
3179 bw!
3180 norm yp
3181 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003182endfunc
3183
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003184func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003185 new
3186 exe "norm! \<c-w>c"
3187 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003188 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003189endfunc
3190
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003191func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003192 new
3193 call setline(1, 'one two three four five six seven eight nine ten')
3194 1
3195 norm! 3d2w
3196 call assert_equal('seven eight nine ten', getline(1))
3197 bw!
3198endfunc
3199
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003200func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003201 CheckFeature timers
3202 CheckFeature cmdline_hist
Bram Moolenaarc255b782022-11-26 19:16:48 +00003203
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003204 func! DoTimerWork(id)
Sean Dewar1fb41032023-08-16 17:15:05 +01003205 call assert_equal(1, getbufinfo('')[0].command)
Bram Moolenaarc255b782022-11-26 19:16:48 +00003206
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003207 " should fail, with E11, but does fail with E23?
3208 "call feedkeys("\<c-^>", 'tm')
3209
Bram Moolenaarc255b782022-11-26 19:16:48 +00003210 " should fail with E11 - "Invalid in command-line window"
Bram Moolenaare2e40752020-09-04 21:18:46 +02003211 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaarc255b782022-11-26 19:16:48 +00003212
3213 " Return from commandline window.
3214 call feedkeys("\<CR>", 't')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003215 endfunc
3216
3217 let oldlang=v:lang
3218 lang C
3219 set updatetime=20
3220 call timer_start(100, 'DoTimerWork')
3221 try
3222 " throws E23, for whatever reason...
3223 call feedkeys('q:', 'x!')
3224 catch /E23/
3225 " no-op
3226 endtry
Bram Moolenaarc255b782022-11-26 19:16:48 +00003227
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003228 " clean up
Bram Moolenaarc255b782022-11-26 19:16:48 +00003229 delfunc DoTimerWork
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003230 set updatetime=4000
3231 exe "lang" oldlang
3232 bw!
3233endfunc
3234
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003235func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003236 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003237 " Don't sleep after the warning message.
3238 call test_settime(1)
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01003239 call writefile(['foo'], 'Xreadonly.log', 'D')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003240 new Xreadonly.log
3241 setl ro
3242 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003243 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003244 call assert_equal(['foo'], getline(1,'$'))
3245 call assert_equal('Xreadonly.log', bufname(''))
3246
3247 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003248 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003249 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003250endfunc
3251
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003252func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003253 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003254 new
3255 call setline(1, 'abcde fghij klmnopq')
3256 norm! 1gg$
3257 set rl
3258 call assert_equal(19, col('.'))
3259 call feedkeys('l', 'tx')
3260 call assert_equal(18, col('.'))
3261 call feedkeys('h', 'tx')
3262 call assert_equal(19, col('.'))
3263 call feedkeys("\<right>", 'tx')
3264 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003265 call feedkeys("\<left>", 'tx')
3266 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003267 call feedkeys("\<s-right>", 'tx')
3268 call assert_equal(13, col('.'))
3269 call feedkeys("\<c-right>", 'tx')
3270 call assert_equal(7, col('.'))
3271 call feedkeys("\<c-left>", 'tx')
3272 call assert_equal(13, col('.'))
3273 call feedkeys("\<s-left>", 'tx')
3274 call assert_equal(19, col('.'))
3275 call feedkeys("<<", 'tx')
3276 call assert_equal(' abcde fghij klmnopq',getline(1))
3277 call feedkeys(">>", 'tx')
3278 call assert_equal('abcde fghij klmnopq',getline(1))
3279
3280 " cleanup
3281 set norl
3282 bw!
3283endfunc
3284
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003285func Test_normal54_Ctrl_bsl()
3286 new
3287 call setline(1, 'abcdefghijklmn')
3288 exe "norm! df\<c-\>\<c-n>"
3289 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3290 exe "norm! df\<c-\>\<c-g>"
3291 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3292 exe "norm! df\<c-\>m"
3293 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003294
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003295 call setline(2, 'abcdefghijklmnāf')
3296 norm! 2gg0
3297 exe "norm! df\<Char-0x101>"
3298 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3299 norm! 1gg0
3300 exe "norm! df\<esc>"
3301 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003302
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003303 " clean up
3304 bw!
3305endfunc
3306
3307func Test_normal_large_count()
3308 " This may fail with 32bit long, how do we detect that?
3309 new
3310 normal o
3311 normal 6666666666dL
3312 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003313endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003314
3315func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003316 new
3317 normal grádv}
3318 call assert_equal('á', getline(1))
3319 normal grád}
3320 call assert_equal('', getline(1))
3321 bwipe!
3322endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003323
3324" Test for the gr (virtual replace) command
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003325func Test_gr_command()
3326 enew!
zeertzjq4f026ea2023-02-26 14:47:24 +00003327 " Test for the bug fixed by 7.4.387
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003328 let save_cpo = &cpo
3329 call append(0, ['First line', 'Second line', 'Third line'])
3330 exe "normal i\<C-G>u"
3331 call cursor(2, 1)
3332 set cpo-=X
3333 normal 4gro
3334 call assert_equal('oooond line', getline(2))
3335 undo
3336 set cpo+=X
3337 normal 4gro
3338 call assert_equal('ooooecond line', getline(2))
3339 let &cpo = save_cpo
zeertzjq4f026ea2023-02-26 14:47:24 +00003340
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003341 normal! ggvegrx
3342 call assert_equal('xxxxx line', getline(1))
3343 exe "normal! gggr\<C-V>122"
3344 call assert_equal('zxxxx line', getline(1))
zeertzjq4f026ea2023-02-26 14:47:24 +00003345
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003346 set virtualedit=all
3347 normal! 15|grl
3348 call assert_equal('zxxxx line l', getline(1))
3349 set virtualedit&
3350 set nomodifiable
3351 call assert_fails('normal! grx', 'E21:')
3352 call assert_fails('normal! gRx', 'E21:')
zeertzjq4f026ea2023-02-26 14:47:24 +00003353 call assert_nobeep("normal! gr\<Esc>")
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003354 set modifiable&
zeertzjq4f026ea2023-02-26 14:47:24 +00003355
3356 call assert_nobeep("normal! gr\<Esc>")
zeertzjqf86dea82023-03-05 21:15:06 +00003357 call assert_nobeep("normal! cgr\<Esc>")
3358 call assert_beeps("normal! cgrx")
zeertzjq4f026ea2023-02-26 14:47:24 +00003359
3360 call assert_equal('zxxxx line l', getline(1))
3361 exe "normal! 2|gr\<C-V>\<Esc>"
3362 call assert_equal("z\<Esc>xx line l", getline(1))
3363
3364 call setline(1, 'abcdef')
3365 exe "normal! 0gr\<C-O>lx"
3366 call assert_equal("\<C-O>def", getline(1))
3367
3368 call setline(1, 'abcdef')
3369 exe "normal! 0gr\<C-G>lx"
3370 call assert_equal("\<C-G>def", getline(1))
3371
3372 bwipe!
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003373endfunc
3374
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003375func Test_nv_hat_count()
3376 %bwipeout!
3377 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003378 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003379
3380 edit Xfoo
3381 let l:foo_nr = bufnr('Xfoo')
3382
3383 edit Xbar
3384 let l:bar_nr = bufnr('Xbar')
3385
3386 " Make sure we are not just using the alternate file.
3387 edit Xbaz
3388
3389 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3390 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3391
3392 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3393 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3394
3395 %bwipeout!
3396endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003397
3398func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003399 " Make sure no buffers are changed.
3400 %bwipe!
3401
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003402 exe "normal \<C-C>"
3403 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003404
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003405 new
3406 cal setline(1, 'hi!')
3407 exe "normal \<C-C>"
3408 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003409
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003410 bwipe!
3411endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003412
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01003413func Test_mode_updated_after_ctrl_c()
3414 CheckScreendump
3415
3416 let buf = RunVimInTerminal('', {'rows': 5})
3417 call term_sendkeys(buf, "i")
3418 call term_sendkeys(buf, "\<C-O>")
3419 " wait a moment so that the "-- (insert) --" message is displayed
3420 call TermWait(buf, 50)
3421 call term_sendkeys(buf, "\<C-C>")
3422 call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
3423
3424 call StopVimInTerminal(buf)
3425endfunc
3426
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003427" Test for '[m', ']m', '[M' and ']M'
3428" Jumping to beginning and end of methods in Java-like languages
3429func Test_java_motion()
3430 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003431 call assert_beeps('normal! [m')
3432 call assert_beeps('normal! ]m')
3433 call assert_beeps('normal! [M')
3434 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003435 let lines =<< trim [CODE]
3436 Piece of Java
3437 {
3438 tt m1 {
3439 t1;
3440 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003441
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003442 tt m2 {
3443 t2;
3444 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003445
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003446 tt m3 {
3447 if (x)
3448 {
3449 t3;
3450 }
3451 } e3
3452 }
3453 [CODE]
3454 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003455
3456 normal gg
3457
3458 normal 2]maA
3459 call assert_equal("\ttt m1 {A", getline('.'))
3460 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3461
3462 normal j]maB
3463 call assert_equal("\ttt m2 {B", getline('.'))
3464 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3465
3466 normal ]maC
3467 call assert_equal("\ttt m3 {C", getline('.'))
3468 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3469
3470 normal [maD
3471 call assert_equal("\ttt m3 {DC", getline('.'))
3472 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3473
3474 normal k2[maE
3475 call assert_equal("\ttt m1 {EA", getline('.'))
3476 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3477
3478 normal 3[maF
3479 call assert_equal("{F", getline('.'))
3480 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3481
3482 normal ]MaG
3483 call assert_equal("\t}G e1", getline('.'))
3484 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3485
3486 normal j2]MaH
3487 call assert_equal("\t}H e3", getline('.'))
3488 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3489
3490 normal ]M]M
3491 normal aI
3492 call assert_equal("}I", getline('.'))
3493 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3494
3495 normal 2[MaJ
3496 call assert_equal("\t}JH e3", getline('.'))
3497 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3498
3499 normal k[MaK
3500 call assert_equal("\t}K e2", getline('.'))
3501 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3502
3503 normal 3[MaL
3504 call assert_equal("{LF", getline('.'))
3505 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3506
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003507 call cursor(2, 1)
3508 call assert_beeps('norm! 5]m')
3509
3510 " jumping to a method in a fold should open the fold
3511 6,10fold
3512 call feedkeys("gg3]m", 'xt')
3513 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3514 call assert_equal(-1, foldclosedend(7))
3515
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003516 bwipe!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003517endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003518
Bram Moolenaar004a6782020-04-11 17:09:31 +02003519" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003520func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003521 call Setup_NewWindow()
3522 " Make long lines that will wrap
3523 %s/$/\=repeat(' foobar', 10)/
3524 20vsp
3525 set wrap
3526 " Test for g$ with count
3527 norm! gg
3528 norm! 0vg$y
3529 call assert_equal(20, col("'>"))
3530 call assert_equal('1 foobar foobar foob', getreg(0))
3531 norm! gg
3532 norm! 0v4g$y
3533 call assert_equal(72, col("'>"))
3534 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3535 norm! gg
3536 norm! 0v6g$y
3537 call assert_equal(40, col("'>"))
3538 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3539 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3540 set nowrap
3541 " clean up
3542 norm! gg
3543 norm! 0vg$y
3544 call assert_equal(20, col("'>"))
3545 call assert_equal('1 foobar foobar foob', getreg(0))
3546 norm! gg
3547 norm! 0v4g$y
3548 call assert_equal(20, col("'>"))
3549 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3550 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3551 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3552 \ '4 foobar foobar foob', getreg(0))
3553 norm! gg
3554 norm! 0v6g$y
3555 call assert_equal(20, col("'>"))
3556 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3557 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3558 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3559 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3560 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3561 \ '6 foobar foobar foob', getreg(0))
3562 " Move to last line, also down movement is not possible, should still move
3563 " the cursor to the last visible char
3564 norm! G
3565 norm! 0v6g$y
3566 call assert_equal(20, col("'>"))
3567 call assert_equal('100 foobar foobar fo', getreg(0))
3568 bw!
3569endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003570
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003571func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003572 " needs 80 column new window
3573 new
3574 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003575 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003576 put =[repeat('x',90)..' {{{1', 'x {{{1']
3577 norm! gk
3578 " In a 80 column wide terminal the window will be only 78 char
3579 " (because Vim will leave space for the other window),
3580 " but if the terminal is larger, it will be 80 chars, so verify the
3581 " cursor column correctly.
3582 call assert_equal(winwidth(0)+1, col('.'))
3583 call assert_equal(winwidth(0)+1, virtcol('.'))
3584 norm! j
3585 call assert_equal(6, col('.'))
3586 call assert_equal(6, virtcol('.'))
3587 norm! gk
3588 call assert_equal(95, col('.'))
3589 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003590 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003591
3592 " needs 80 column new window
3593 new
3594 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003595 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003596 set number
3597 set numberwidth=10
3598 set cpoptions+=n
3599 put =[repeat('0',90), repeat('1',90)]
3600 norm! 075l
3601 call assert_equal(76, col('.'))
3602 norm! gk
3603 call assert_equal(1, col('.'))
3604 norm! gk
3605 call assert_equal(76, col('.'))
3606 norm! gk
3607 call assert_equal(1, col('.'))
3608 norm! gj
3609 call assert_equal(76, col('.'))
3610 norm! gj
3611 call assert_equal(1, col('.'))
3612 norm! gj
3613 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003614 " When 'nowrap' is set, gk and gj behave like k and j
3615 set nowrap
3616 normal! gk
3617 call assert_equal([2, 76], [line('.'), col('.')])
3618 normal! gj
3619 call assert_equal([3, 76], [line('.'), col('.')])
3620 %bw!
3621 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003622endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003623
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003624" Test for using : to run a multi-line Ex command in operator pending mode
3625func Test_normal_yank_with_excmd()
3626 new
3627 call setline(1, ['foo', 'bar', 'baz'])
3628 let @a = ''
3629 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3630 call assert_equal('f', @a)
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003631
3632 bwipe!
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003633endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003634
3635" Test for supplying a count to a normal-mode command across a cursorhold call
3636func Test_normal_cursorhold_with_count()
3637 func s:cHold()
3638 let g:cHold_Called += 1
3639 endfunc
3640 new
3641 augroup normalcHoldTest
3642 au!
3643 au CursorHold <buffer> call s:cHold()
3644 augroup END
3645 let g:cHold_Called = 0
3646 call feedkeys("3\<CursorHold>2ix", 'xt')
3647 call assert_equal(1, g:cHold_Called)
3648 call assert_equal(repeat('x', 32), getline(1))
3649 augroup normalcHoldTest
3650 au!
3651 augroup END
3652 au! normalcHoldTest
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003653
3654 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003655 delfunc s:cHold
3656endfunc
3657
3658" Test for using a count and a command with CTRL-W
3659func Test_wincmd_with_count()
3660 call feedkeys("\<C-W>12n", 'xt')
3661 call assert_equal(12, winheight(0))
3662endfunc
3663
3664" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003665func Test_horiz_motion()
3666 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003667 normal! gg
3668 call assert_beeps('normal! b')
3669 call assert_beeps('normal! B')
3670 call assert_beeps('normal! gE')
3671 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003672 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3673 call setline(1, 'one ,two ,three')
3674 exe "normal! $\<S-BS>"
3675 call assert_equal(11, col('.'))
3676 exe "normal! $\<C-BS>"
3677 call assert_equal(10, col('.'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003678
3679 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003680endfunc
3681
zeertzjq30b6d612023-05-07 17:39:23 +01003682" Test for using a ":" command in operator pending mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003683func Test_normal_colon_op()
3684 new
3685 call setline(1, ['one', 'two'])
3686 call assert_beeps("normal! Gc:d\<CR>")
zeertzjq30b6d612023-05-07 17:39:23 +01003687 call assert_equal(['one'], getline(1, '$'))
3688
3689 call setline(1, ['one…two…three!'])
3690 normal! $
3691 " Using ":" as a movement is characterwise exclusive
3692 call feedkeys("d:normal! F…\<CR>", 'xt')
3693 call assert_equal(['one…two!'], getline(1, '$'))
3694 " Check that redoing a command with 0x80 bytes works
3695 call feedkeys('.', 'xt')
3696 call assert_equal(['one!'], getline(1, '$'))
3697
3698 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3699 " Add this to the command history
3700 call feedkeys(":normal! G0\<CR>", 'xt')
3701 " Use :normal! with control characters in operator pending mode
3702 call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
3703 call assert_equal(['one', 'two', 'five'], getline(1, '$'))
3704 " Check that redoing a command with control characters works
3705 call feedkeys('.', 'xt')
3706 call assert_equal(['five'], getline(1, '$'))
3707
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003708 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003709endfunc
3710
Bram Moolenaar004a6782020-04-11 17:09:31 +02003711" Test for d and D commands
3712func Test_normal_delete_cmd()
3713 new
3714 " D in an empty line
3715 call setline(1, '')
3716 normal D
3717 call assert_equal('', getline(1))
3718 " D in an empty line in virtualedit mode
3719 set virtualedit=all
3720 normal D
3721 call assert_equal('', getline(1))
3722 set virtualedit&
3723 " delete to a readonly register
3724 call setline(1, ['abcd'])
3725 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003726
3727 " D and d with 'nomodifiable'
3728 call setline(1, ['abcd'])
3729 setlocal nomodifiable
3730 call assert_fails('normal D', 'E21:')
3731 call assert_fails('normal d$', 'E21:')
3732
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003733 bwipe!
Bram Moolenaar004a6782020-04-11 17:09:31 +02003734endfunc
3735
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003736" Test for deleting or changing characters across lines with 'whichwrap'
3737" containing 's'. Should count <EOL> as one character.
3738func Test_normal_op_across_lines()
3739 new
3740 set whichwrap&
3741 call setline(1, ['one two', 'three four'])
3742 exe "norm! $3d\<Space>"
3743 call assert_equal(['one twhree four'], getline(1, '$'))
3744
3745 call setline(1, ['one two', 'three four'])
3746 exe "norm! $3c\<Space>x"
3747 call assert_equal(['one twxhree four'], getline(1, '$'))
3748
3749 set whichwrap+=l
3750 call setline(1, ['one two', 'three four'])
3751 exe "norm! $3x"
3752 call assert_equal(['one twhree four'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003753
3754 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003755 set whichwrap&
3756endfunc
3757
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003758" Test for 'w' and 'b' commands
3759func Test_normal_word_move()
3760 new
3761 call setline(1, ['foo bar a', '', 'foo bar b'])
3762 " copy a single character word at the end of a line
3763 normal 1G$yw
3764 call assert_equal('a', @")
3765 " copy a single character word at the end of a file
3766 normal G$yw
3767 call assert_equal('b', @")
3768 " check for a word movement handling an empty line properly
3769 normal 1G$vwy
3770 call assert_equal("a\n\n", @")
3771
3772 " copy using 'b' command
3773 %d
3774 " non-empty blank line at the start of file
3775 call setline(1, [' ', 'foo bar'])
3776 normal 2Gyb
3777 call assert_equal(" \n", @")
3778 " try to copy backwards from the start of the file
3779 call setline(1, ['one two', 'foo bar'])
3780 call assert_beeps('normal ggyb')
3781 " 'b' command should stop at an empty line
3782 call setline(1, ['one two', '', 'foo bar'])
3783 normal 3Gyb
3784 call assert_equal("\n", @")
3785 normal 3Gy2b
3786 call assert_equal("two\n", @")
3787 " 'b' command should not stop at a non-empty blank line
3788 call setline(1, ['one two', ' ', 'foo bar'])
3789 normal 3Gyb
3790 call assert_equal("two\n ", @")
3791
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003792 bwipe!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003793endfunc
3794
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003795" Test for 'scrolloff' with a long line that doesn't fit in the screen
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003796func Test_normal_scrolloff()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003797 10new
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003798 60vnew
3799 call setline(1, ' 1 ' .. repeat('a', 57)
3800 \ .. ' 2 ' .. repeat('b', 57)
3801 \ .. ' 3 ' .. repeat('c', 57)
3802 \ .. ' 4 ' .. repeat('d', 57)
3803 \ .. ' 5 ' .. repeat('e', 57)
3804 \ .. ' 6 ' .. repeat('f', 57)
3805 \ .. ' 7 ' .. repeat('g', 57)
3806 \ .. ' 8 ' .. repeat('h', 57)
3807 \ .. ' 9 ' .. repeat('i', 57)
3808 \ .. '10 ' .. repeat('j', 57)
3809 \ .. '11 ' .. repeat('k', 57)
3810 \ .. '12 ' .. repeat('l', 57)
3811 \ .. '13 ' .. repeat('m', 57)
3812 \ .. '14 ' .. repeat('n', 57)
3813 \ .. '15 ' .. repeat('o', 57)
3814 \ .. '16 ' .. repeat('p', 57)
3815 \ .. '17 ' .. repeat('q', 57)
3816 \ .. '18 ' .. repeat('r', 57)
3817 \ .. '19 ' .. repeat('s', 57)
3818 \ .. '20 ' .. repeat('t', 57)
3819 \ .. '21 ' .. repeat('u', 57)
3820 \ .. '22 ' .. repeat('v', 57)
3821 \ .. '23 ' .. repeat('w', 57)
3822 \ .. '24 ' .. repeat('x', 57)
3823 \ .. '25 ' .. repeat('y', 57)
3824 \ .. '26 ' .. repeat('z', 57)
3825 \ )
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003826 set scrolloff=10
3827 normal gg10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003828 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003829 normal 10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003830 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003831 normal 10gk
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003832 call assert_equal(6, winline())
3833 normal 0
3834 call assert_equal(1, winline())
3835 normal $
3836 call assert_equal(10, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003837
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003838 set scrolloff&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003839 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003840endfunc
3841
3842" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3843func Test_normal_vert_scroll_longline()
3844 10new
3845 80vnew
3846 call setline(1, range(1, 10))
3847 call append(5, repeat('a', 1000))
3848 exe "normal gg\<C-F>"
3849 call assert_equal(6, line('.'))
3850 exe "normal \<C-F>\<C-F>"
3851 call assert_equal(11, line('.'))
3852 call assert_equal(1, winline())
3853 exe "normal \<C-B>"
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02003854 call assert_equal(11, line('.'))
3855 call assert_equal(5, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003856 exe "normal \<C-B>\<C-B>"
3857 call assert_equal(5, line('.'))
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003858 call assert_equal(5, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003859
3860 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003861endfunc
3862
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003863" Test for jumping in a file using %
3864func Test_normal_percent_jump()
3865 new
3866 call setline(1, range(1, 100))
3867
3868 " jumping to a folded line should open the fold
3869 25,75fold
3870 call feedkeys('50%', 'xt')
3871 call assert_equal(50, line('.'))
3872 call assert_equal(-1, foldclosedend(50))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003873
3874 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003875endfunc
3876
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003877" Test for << and >> commands to shift text by 'shiftwidth'
3878func Test_normal_shift_rightleft()
3879 new
3880 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3881 set shiftwidth=2 tabstop=8
3882 normal gg6>>
3883 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3884 \ getline(1, '$'))
3885 normal ggVG2>>
3886 call assert_equal([' one', '', "\t ", "\ttwo",
3887 \ "\t three", "\t four"], getline(1, '$'))
3888 normal gg6<<
3889 call assert_equal([' one', '', "\t ", ' two', "\t three",
3890 \ "\t four"], getline(1, '$'))
3891 normal ggVG2<<
3892 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3893 \ getline(1, '$'))
3894 set shiftwidth& tabstop&
3895 bw!
3896endfunc
3897
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003898" Some commands like yy, cc, dd, >>, << and !! accept a count after
3899" typing the first letter of the command.
3900func Test_normal_count_after_operator()
3901 new
3902 setlocal shiftwidth=4 tabstop=8 autoindent
3903 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3904 let @a = ''
3905 normal! j"ay4y
3906 call assert_equal("two\nthree\nfour\nfive\n", @a)
3907 normal! 3G>2>
3908 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3909 \ getline(1, '$'))
3910 exe "normal! 3G0c2cred\nblue"
3911 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3912 \ getline(1, '$'))
3913 exe "normal! gg<8<"
3914 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3915 \ getline(1, '$'))
3916 exe "normal! ggd3d"
3917 call assert_equal(['blue', 'five'], getline(1, '$'))
3918 call setline(1, range(1, 4))
3919 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3920 call assert_equal('".,.+2!', @:)
3921 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3922 call assert_equal('".!', @:)
3923 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3924 call assert_equal('".,$!', @:)
3925 bw!
3926endfunc
3927
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003928func Test_normal_gj_on_extra_wide_char()
3929 new | 25vsp
3930 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3931 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3932 \ ' dreizehn v ierzehn fünfzehn'
3933 put =text
3934 call cursor(2,1)
3935 norm! gj
3936 call assert_equal([0,2,25,0], getpos('.'))
3937 bw!
3938endfunc
3939
Bram Moolenaar03725c52021-11-24 12:17:53 +00003940func Test_normal_count_out_of_range()
3941 new
3942 call setline(1, 'text')
3943 normal 44444444444|
3944 call assert_equal(999999999, v:count)
3945 normal 444444444444|
3946 call assert_equal(999999999, v:count)
3947 normal 4444444444444|
3948 call assert_equal(999999999, v:count)
3949 normal 4444444444444444444|
3950 call assert_equal(999999999, v:count)
3951
3952 normal 9y99999999|
3953 call assert_equal(899999991, v:count)
3954 normal 10y99999999|
3955 call assert_equal(999999999, v:count)
3956 normal 44444444444y44444444444|
3957 call assert_equal(999999999, v:count)
3958 bwipe!
3959endfunc
3960
zeertzjqcdeb6572022-11-15 13:46:12 +00003961" Test that mouse shape is restored to Normal mode after failed "c" operation.
3962func Test_mouse_shape_after_failed_change()
3963 CheckFeature mouseshape
3964 CheckCanRunGui
3965
3966 let lines =<< trim END
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003967 vim9script
zeertzjqcdeb6572022-11-15 13:46:12 +00003968 set mouseshape+=o:busy
3969 setlocal nomodifiable
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003970 var mouse_shapes = []
zeertzjqcdeb6572022-11-15 13:46:12 +00003971
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003972 feedkeys('c')
3973 timer_start(50, (_) => {
3974 mouse_shapes += [getmouseshape()]
3975 timer_start(50, (_) => {
3976 feedkeys('c')
3977 timer_start(50, (_) => {
3978 mouse_shapes += [getmouseshape()]
3979 timer_start(50, (_) => {
3980 writefile(mouse_shapes, 'Xmouseshapes')
3981 quit
3982 })
3983 })
3984 })
3985 })
zeertzjqcdeb6572022-11-15 13:46:12 +00003986 END
3987 call writefile(lines, 'Xmouseshape.vim', 'D')
3988 call RunVim([], [], "-g -S Xmouseshape.vim")
Yee Cheng Chin24078e32024-11-12 20:26:48 +01003989 call WaitForAssert({-> assert_equal(['busy', 'arrow'], readfile('Xmouseshapes'))}, 300)
zeertzjqcdeb6572022-11-15 13:46:12 +00003990
3991 call delete('Xmouseshapes')
3992endfunc
3993
zeertzjqf86dea82023-03-05 21:15:06 +00003994" Test that mouse shape is restored to Normal mode after cancelling "gr".
3995func Test_mouse_shape_after_cancelling_gr()
3996 CheckFeature mouseshape
3997 CheckCanRunGui
3998
3999 let lines =<< trim END
4000 vim9script
4001 var mouse_shapes = []
4002
4003 feedkeys('gr')
4004 timer_start(50, (_) => {
4005 mouse_shapes += [getmouseshape()]
4006 timer_start(50, (_) => {
4007 feedkeys("\<Esc>")
4008 timer_start(50, (_) => {
4009 mouse_shapes += [getmouseshape()]
4010 timer_start(50, (_) => {
4011 writefile(mouse_shapes, 'Xmouseshapes')
4012 quit
4013 })
4014 })
4015 })
4016 })
4017 END
4018 call writefile(lines, 'Xmouseshape.vim', 'D')
4019 call RunVim([], [], "-g -S Xmouseshape.vim")
Yee Cheng Chin24078e32024-11-12 20:26:48 +01004020 call WaitForAssert({-> assert_equal(['beam', 'arrow'], readfile('Xmouseshapes'))}, 300)
zeertzjqf86dea82023-03-05 21:15:06 +00004021
4022 call delete('Xmouseshapes')
4023endfunc
4024
Luuk van Baalaa6ba302023-05-09 16:01:17 +01004025" Test that "j" does not skip lines when scrolling below botline and
4026" 'foldmethod' is not "manual".
4027func Test_normal_j_below_botline()
4028 CheckScreendump
4029
4030 let lines =<< trim END
4031 set number foldmethod=diff scrolloff=0
4032 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
4033 norm Lj
4034 END
4035 call writefile(lines, 'XNormalJBelowBotline', 'D')
4036 let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
4037
4038 call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
4039
4040 call StopVimInTerminal(buf)
4041endfunc
4042
Christian Brabandt2d63e4b2023-08-12 00:03:57 +02004043" Test for r (replace) command with CTRL_V and CTRL_Q
4044func Test_normal_r_ctrl_v_cmd()
4045 new
4046 call append(0, 'This is a simple test: abcd')
4047 exe "norm! 1gg$r\<C-V>\<C-V>"
4048 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4049 exe "norm! 1gg$hr\<C-Q>\<C-Q>"
4050 call assert_equal(['This is a simple test: ab', ''], getline(1,'$'))
4051 exe "norm! 1gg$2hr\<C-V>x7e"
4052 call assert_equal(['This is a simple test: a~', ''], getline(1,'$'))
4053 exe "norm! 1gg$3hr\<C-Q>x7e"
4054 call assert_equal(['This is a simple test: ~~', ''], getline(1,'$'))
4055
4056 if &encoding == 'utf-8'
4057 exe "norm! 1gg$4hr\<C-V>u20ac"
4058 call assert_equal(['This is a simple test:€~~', ''], getline(1,'$'))
4059 exe "norm! 1gg$5hr\<C-Q>u20ac"
4060 call assert_equal(['This is a simple test€€~~', ''], getline(1,'$'))
4061 exe "norm! 1gg0R\<C-V>xff WAS \<esc>"
4062 call assert_equal(['ÿ WAS a simple test€€~~', ''], getline(1,'$'))
4063 exe "norm! 1gg0elR\<C-Q>xffNOT\<esc>"
4064 call assert_equal(['ÿ WASÿNOT simple test€€~~', ''], getline(1,'$'))
4065 endif
4066
4067 call setline(1, 'This is a simple test: abcd')
4068 exe "norm! 1gg$gr\<C-V>\<C-V>"
4069 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4070 exe "norm! 1gg$hgr\<C-Q>\<C-Q>"
4071 call assert_equal(['This is a simple test: ab ', ''], getline(1,'$'))
4072 exe "norm! 1gg$2hgr\<C-V>x7e"
4073 call assert_equal(['This is a simple test: a~ ', ''], getline(1,'$'))
4074 exe "norm! 1gg$3hgr\<C-Q>x7e"
4075 call assert_equal(['This is a simple test: ~~ ', ''], getline(1,'$'))
4076
4077 " clean up
4078 bw!
4079endfunc
4080
zeertzjqb25dbb32023-08-13 18:11:05 +02004081" Test clicking on a TAB or an unprintable character in Normal mode
4082func Test_normal_click_on_ctrl_char()
4083 let save_mouse = &mouse
4084 set mouse=a
4085 new
4086
4087 call setline(1, "a\<Tab>b\<C-K>c")
4088 redraw
4089 call test_setmouse(1, 1)
4090 call feedkeys("\<LeftMouse>", 'xt')
4091 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4092 call test_setmouse(1, 2)
4093 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004094 call assert_equal([0, 1, 2, 0, 2], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004095 call test_setmouse(1, 3)
4096 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004097 call assert_equal([0, 1, 2, 0, 3], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004098 call test_setmouse(1, 7)
4099 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004100 call assert_equal([0, 1, 2, 0, 7], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004101 call test_setmouse(1, 8)
4102 call feedkeys("\<LeftMouse>", 'xt')
4103 call assert_equal([0, 1, 2, 0, 8], getcurpos())
4104 call test_setmouse(1, 9)
4105 call feedkeys("\<LeftMouse>", 'xt')
4106 call assert_equal([0, 1, 3, 0, 9], getcurpos())
4107 call test_setmouse(1, 10)
4108 call feedkeys("\<LeftMouse>", 'xt')
4109 call assert_equal([0, 1, 4, 0, 10], getcurpos())
4110 call test_setmouse(1, 11)
4111 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004112 call assert_equal([0, 1, 4, 0, 11], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004113 call test_setmouse(1, 12)
4114 call feedkeys("\<LeftMouse>", 'xt')
4115 call assert_equal([0, 1, 5, 0, 12], getcurpos())
4116 call test_setmouse(1, 13)
4117 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004118 call assert_equal([0, 1, 5, 0, 13], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004119
4120 bwipe!
4121 let &mouse = save_mouse
4122endfunc
4123
zeertzjq99941602023-08-19 13:08:50 +02004124" Test clicking on a double-width character in Normal mode
4125func Test_normal_click_on_double_width_char()
4126 let save_mouse = &mouse
4127 set mouse=a
4128 new
4129
4130 call setline(1, "口口")
4131 redraw
4132 call test_setmouse(1, 1)
4133 call feedkeys("\<LeftMouse>", 'xt')
4134 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4135 call test_setmouse(1, 2)
4136 call feedkeys("\<LeftMouse>", 'xt')
4137 call assert_equal([0, 1, 1, 0, 2], getcurpos())
4138 call test_setmouse(1, 3)
4139 call feedkeys("\<LeftMouse>", 'xt')
4140 call assert_equal([0, 1, 4, 0, 3], getcurpos())
4141 call test_setmouse(1, 4)
4142 call feedkeys("\<LeftMouse>", 'xt')
4143 call assert_equal([0, 1, 4, 0, 4], getcurpos())
4144
4145 bwipe!
4146 let &mouse = save_mouse
4147endfunc
4148
zeertzjq03cd6972023-09-20 20:08:40 +02004149func Test_normal_click_on_empty_line()
4150 let save_mouse = &mouse
4151 set mouse=a
4152 botright new
4153 call setline(1, ['', '', ''])
4154 let row = win_screenpos(0)[0] + 2
4155 20vsplit
4156 redraw
4157
4158 call test_setmouse(row, 1)
4159 call feedkeys("\<LeftMouse>", 'xt')
4160 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4161 call test_setmouse(row, 2)
4162 call feedkeys("\<LeftMouse>", 'xt')
4163 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4164 call test_setmouse(row, 10)
4165 call feedkeys("\<LeftMouse>", 'xt')
4166 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4167
4168 call test_setmouse(row, 21 + 1)
4169 call feedkeys("\<LeftMouse>", 'xt')
4170 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4171 call test_setmouse(row, 21 + 2)
4172 call feedkeys("\<LeftMouse>", 'xt')
4173 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4174 call test_setmouse(row, 21 + 10)
4175 call feedkeys("\<LeftMouse>", 'xt')
4176 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4177
4178 bwipe!
4179 let &mouse = save_mouse
4180endfunc
4181
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004182func Test_normal33_g_cmd_nonblank()
zeertzjq654bdbb2023-08-20 18:24:20 +02004183 " Test that g<End> goes to the last non-blank char and g$ to the last
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004184 " visible column
4185 20vnew
4186 setlocal nowrap nonumber signcolumn=no
4187 call setline(1, ['fooo fooo fooo fooo fooo fooo fooo fooo '])
zeertzjq654bdbb2023-08-20 18:24:20 +02004188 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004189 call assert_equal(11, col('.'))
4190 normal 0g$
4191 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004192 exe "normal 0g\<kEnd>"
4193 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004194 setlocal wrap
zeertzjq654bdbb2023-08-20 18:24:20 +02004195 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004196 call assert_equal(11, col('.'))
4197 normal 0g$
4198 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004199 exe "normal 0g\<kEnd>"
4200 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004201 bw!
4202endfunc
4203
Christian Brabandt58f9bef2023-11-14 21:02:30 +01004204func Test_normal34_zet_large()
4205 " shouldn't cause overflow
4206 norm! z9765405999999999999
4207endfunc
4208
zeertzjqad493ef2024-03-29 10:23:19 +01004209" Test for { and } paragraph movements in a single line
4210func Test_brace_single_line()
4211 new
4212 call setline(1, ['foobar one two three'])
4213 1
4214 norm! 0}
4215
4216 call assert_equal([0, 1, 20, 0], getpos('.'))
4217 norm! {
4218 call assert_equal([0, 1, 1, 0], getpos('.'))
4219 bw!
4220endfunc
4221
4222" Test for Ctrl-B/Ctrl-U in buffer with a single line
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004223func Test_single_line_scroll()
4224 CheckFeature textprop
Gary Johnson9e6549d2023-12-27 19:12:43 +01004225
4226 new
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004227 call setline(1, ['foobar one two three'])
4228 let vt = 'virt_above'
4229 call prop_type_add(vt, {'highlight': 'IncSearch'})
4230 call prop_add(1, 0, {'type': vt, 'text': '---', 'text_align': 'above'})
zeertzjqad493ef2024-03-29 10:23:19 +01004231 call cursor(1, 1)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004232
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004233 " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004234 set smoothscroll
4235 exe "normal \<C-E>"
4236 call assert_notequal(0, winsaveview().skipcol)
4237 exe "normal \<C-B>"
4238 call assert_equal(0, winsaveview().skipcol)
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004239 exe "normal \<C-E>"
4240 call assert_notequal(0, winsaveview().skipcol)
4241 exe "normal \<C-U>"
4242 call assert_equal(0, winsaveview().skipcol)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004243
4244 set smoothscroll&
Gary Johnson9e6549d2023-12-27 19:12:43 +01004245 bw!
zeertzjqad493ef2024-03-29 10:23:19 +01004246 call prop_type_delete(vt)
Gary Johnson9e6549d2023-12-27 19:12:43 +01004247endfunc
4248
Luuk van Baalbd28cae2024-04-03 22:50:40 +02004249" Test for zb in buffer with a single line and filler lines
4250func Test_single_line_filler_zb()
4251 call setline(1, ['', 'foobar one two three'])
4252 diffthis
4253 new
4254 call setline(1, ['foobar one two three'])
4255 diffthis
4256
4257 " zb scrolls to reveal filler lines at the start of the buffer.
4258 exe "normal \<C-E>zb"
4259 call assert_equal(1, winsaveview().topfill)
4260
4261 bw!
4262endfunc
4263
Luuk van Baal78c51502024-04-09 21:30:19 +02004264" Test for Ctrl-U not getting stuck at end of buffer with 'scrolloff'.
4265func Test_halfpage_scrolloff_eob()
4266 set scrolloff=5
4267
4268 call setline(1, range(1, 100))
4269 exe "norm! Gzz\<C-U>zz"
4270 call assert_notequal(100, line('.'))
4271
4272 set scrolloff&
4273 bwipe!
4274endfunc
4275
Luuk van Baalaa8e22b2024-04-10 17:33:43 +02004276" Test for Ctrl-U/D moving the cursor at the buffer boundaries.
4277func Test_halfpage_cursor_startend()
4278 call setline(1, range(1, 100))
4279 exe "norm! jztj\<C-U>"
4280 call assert_equal(1, line('.'))
4281 exe "norm! G\<C-Y>k\<C-D>"
4282 call assert_equal(100, line('.'))
4283 bwipe!
4284endfunc
4285
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02004286" Test for Ctrl-F/B moving the cursor to the window boundaries.
4287func Test_page_cursor_topbot()
4288 10new
4289 call setline(1, range(1, 100))
4290 exe "norm! gg2\<C-F>"
4291 call assert_equal(17, line('.'))
4292 exe "norm! \<C-B>"
4293 call assert_equal(18, line('.'))
4294 exe "norm! \<C-B>\<C-F>"
4295 call assert_equal(9, line('.'))
Luuk van Baal8ccb8902024-07-04 17:35:56 +02004296 " Not when already at the start of the buffer.
4297 exe "norm! ggj\<C-B>"
4298 call assert_equal(2, line('.'))
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02004299 bwipe!
4300endfunc
4301
Luuk van Baal58448e02024-05-11 11:27:52 +02004302" Test for Ctrl-D with long line
4303func Test_halfpage_longline()
4304 10new
zeertzjqfa117382024-09-29 10:14:32 +02004305 40vsplit
Luuk van Baal58448e02024-05-11 11:27:52 +02004306 call setline(1, ['long'->repeat(1000), 'short'])
4307 exe "norm! \<C-D>"
4308 call assert_equal(2, line('.'))
4309 bwipe!
4310endfunc
Christian Brabandteff20eb2024-05-15 21:35:36 +02004311
4312" Test for Ctrl-E with long line and very narrow window,
zeertzjq8feed3a2024-09-29 10:37:47 +02004313" used to cause an infinite loop
Christian Brabandteff20eb2024-05-15 21:35:36 +02004314func Test_scroll_longline_no_loop()
4315 4vnew
4316 setl smoothscroll number showbreak=> scrolloff=2
4317 call setline(1, repeat(['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'], 3))
4318 exe "normal! \<C-E>"
4319 bwipe!
4320endfunc
Christian Brabandtf8702ae2024-08-28 20:39:24 +02004321
4322" Test for go command
4323func Test_normal_go()
4324 new
4325 call setline(1, ['one two three four'])
4326 call cursor(1, 5)
4327 norm! dvgo
4328 call assert_equal('wo three four', getline(1))
4329 norm! ...
4330 call assert_equal('three four', getline(1))
4331
4332 bwipe!
4333endfunc
zeertzjqdf098fe2025-01-22 22:27:30 +01004334
Luuk van Baalc9825032025-04-13 17:45:34 +02004335" Test for Ctrl-D with 'scrolloff' and narrow window does not get stuck.
4336func Test_scroll_longline_scrolloff()
4337 11new
4338 36vsplit
4339 set scrolloff=5
4340
4341 call setline(1, ['']->repeat(5))
4342 call setline(6, ['foo'->repeat(20)]->repeat(2))
4343 call setline(8, ['bar'->repeat(30)])
4344 call setline(9, ['']->repeat(5))
4345 exe "normal! \<C-D>"
4346 call assert_equal(6, line('w0'))
4347 exe "normal! \<C-D>"
4348 call assert_equal(7, line('w0'))
4349
4350 set scrolloff&
4351 bwipe!
4352endfunc
4353
Luuk van Baalacf0ebe2025-05-12 20:45:41 +02004354" Benchmark test for Ctrl-F with 'nosmoothscroll'
4355func Test_scroll_longline_benchmark()
4356 call setline(1, ['foo'->repeat(20000)] + [''])
4357 let start = reltime()
4358 exe "normal! \<C-F>"
4359 call assert_inrange(0, 0.1, reltimefloat(reltime(start)))
4360 bwipe!
4361endfunc
4362
Luuk van Baalc6c72d12025-05-14 20:21:55 +02004363" Test Ctrl-B with 'nosmoothscroll' not stuck with line exactly window width.
4364func Test_scroll_longline_winwidth()
4365 10new
4366 call setline(1, ['']->repeat(20) + ['A'->repeat(20 * winwidth(0))] + ['']->repeat(20))
4367 exe "normal! G3\<C-B>"
4368 call assert_equal(22, line('w0'))
4369 exe "normal! \<C-B>"
4370 call assert_equal(21, line('w0'))
4371 exe "normal! \<C-B>"
4372 call assert_equal(11, line('w0'))
4373 exe "normal! \<C-B>"
4374 call assert_equal(3, line('w0'))
4375 exe "normal! \<C-B>"
4376 call assert_equal(1, line('w0'))
4377 bwipe!
4378endfunc
4379
Christian Brabandt5d5cbb22024-01-05 18:19:52 +01004380" vim: shiftwidth=2 sts=2 expandtab nofoldenable