blob: 3a7248fd082dc1611c82b876a073468ca0fb36fd [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
405 call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
406 " Second fold
407 46
408 norm! V10jzf
409 " check that folds have been created
410 call assert_equal('46/*{{{*/', getline(46))
411 call assert_equal('60/*}}}*/', getline(60))
412 norm! k
413 call assert_equal('45', getline('.'))
414 norm! j
415 call assert_equal('46/*{{{*/', getline('.'))
416 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
424 call assert_equal('46/*{{{*/', getline('.'))
425 norm! j
426 call assert_equal('47', getline('.'))
427 norm! k
428 norm! zcVzO
429 call assert_equal('46/*{{{*/', getline('.'))
430 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
437 call assert_equal('50/*{{{*/', getline('.'))
438 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 Baal5a2e3ec2024-03-28 10:07:29 +01001283 call assert_equal(36, line('w0'))
1284 call assert_equal(46, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001285 exe "normal \<C-U>"
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001286 call assert_equal(1, line('w0'))
1287 call assert_equal(40, line('.'))
1288 exe "normal \<C-U>"
1289 call assert_equal(30, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001290 exe "normal \<C-U>"
1291 call assert_equal(1, line('.'))
1292 set scroll&
1293
1294 " Test for scrolling to the top of the file with <C-U> and a fold
1295 10
1296 normal ztL
1297 exe "normal \<C-U>\<C-U>"
1298 call assert_equal(1, line('w0'))
1299
1300 " Test for CTRL-D on a folded line
1301 %d
1302 call setline(1, range(1, 100))
1303 50,100fold
1304 75
1305 normal z-
1306 exe "normal \<C-D>"
1307 call assert_equal(50, line('.'))
1308 call assert_equal(100, line('w$'))
1309 normal z.
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001310 exe "normal \<C-D>"
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01001311 call assert_equal(1, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001312 call assert_equal(50, line('.'))
1313 normal zt
1314 exe "normal \<C-D>"
1315 call assert_equal(50, line('w0'))
1316
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001317 " Test for <S-CR>. Page down.
1318 %d
1319 call setline(1, range(1, 100))
1320 call feedkeys("\<S-CR>", 'xt')
1321 call assert_equal(14, line('w0'))
1322 call assert_equal(28, line('w$'))
1323
1324 " Test for <S-->. Page up.
1325 call feedkeys("\<S-->", 'xt')
1326 call assert_equal(1, line('w0'))
1327 call assert_equal(15, line('w$'))
1328
Bram Moolenaar1671f442020-03-10 07:48:13 +01001329 set foldenable&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00001330 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01001331endfunc
1332
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001333func Test_scroll_in_ex_mode()
1334 " This was using invalid memory because w_botline was invalid.
1335 let lines =<< trim END
1336 diffsplit
1337 norm os00(
1338 call writefile(['done'], 'Xdone')
1339 qa!
1340 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001341 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001342 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1343 call assert_equal(['done'], readfile('Xdone'))
1344
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001345 call delete('Xdone')
1346endfunc
1347
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001348" Test for the 'sidescroll' option
1349func Test_sidescroll_opt()
1350 new
1351 20vnew
1352
1353 " scroll by 2 characters horizontally
1354 set sidescroll=2 nowrap
1355 call setline(1, repeat('a', 40))
1356 normal g$l
1357 call assert_equal(19, screenpos(0, 1, 21).col)
1358 normal l
1359 call assert_equal(20, screenpos(0, 1, 22).col)
1360 normal g0h
1361 call assert_equal(2, screenpos(0, 1, 2).col)
1362 call assert_equal(20, screenpos(0, 1, 20).col)
1363
1364 " when 'sidescroll' is 0, cursor positioned at the center
1365 set sidescroll=0
1366 normal g$l
1367 call assert_equal(11, screenpos(0, 1, 21).col)
1368 normal g0h
1369 call assert_equal(10, screenpos(0, 1, 10).col)
1370
1371 %bw!
1372 set wrap& sidescroll&
1373endfunc
1374
Bram Moolenaar004a6782020-04-11 17:09:31 +02001375" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001376func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001377 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001378 call Setup_NewWindow()
1379 50
1380 setl foldenable fdm=marker foldlevel=5
1381
Bram Moolenaar1671f442020-03-10 07:48:13 +01001382 call assert_beeps('normal! zj')
1383 call assert_beeps('normal! zk')
1384
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001385 " Test for zF
1386 " First fold
1387 norm! 4zF
1388 " check that folds have been created
1389 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1390
1391 " Test for zd
1392 51
1393 norm! 2zF
1394 call assert_equal(2, foldlevel('.'))
1395 norm! kzd
1396 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1397 norm! j
1398 call assert_equal(1, foldlevel('.'))
1399
1400 " Test for zD
1401 " also deletes partially selected folds recursively
1402 51
1403 norm! zF
1404 call assert_equal(2, foldlevel('.'))
1405 norm! kV2jzD
1406 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1407
1408 " Test for zE
1409 85
1410 norm! 4zF
1411 86
1412 norm! 2zF
1413 90
1414 norm! 4zF
1415 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1416 norm! zE
1417 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1418
1419 " Test for zn
1420 50
1421 set foldlevel=0
1422 norm! 2zF
1423 norm! zn
1424 norm! k
1425 call assert_equal('49', getline('.'))
1426 norm! j
1427 call assert_equal('50/*{{{*/', getline('.'))
1428 norm! j
1429 call assert_equal('51/*}}}*/', getline('.'))
1430 norm! j
1431 call assert_equal('52', getline('.'))
1432 call assert_equal(0, &foldenable)
1433
1434 " Test for zN
1435 49
1436 norm! zN
1437 call assert_equal('49', getline('.'))
1438 norm! j
1439 call assert_equal('50/*{{{*/', getline('.'))
1440 norm! j
1441 call assert_equal('52', getline('.'))
1442 call assert_equal(1, &foldenable)
1443
1444 " Test for zi
1445 norm! zi
1446 call assert_equal(0, &foldenable)
1447 norm! zi
1448 call assert_equal(1, &foldenable)
1449 norm! zi
1450 call assert_equal(0, &foldenable)
1451 norm! zi
1452 call assert_equal(1, &foldenable)
1453
1454 " Test for za
1455 50
1456 norm! za
1457 norm! k
1458 call assert_equal('49', getline('.'))
1459 norm! j
1460 call assert_equal('50/*{{{*/', getline('.'))
1461 norm! j
1462 call assert_equal('51/*}}}*/', getline('.'))
1463 norm! j
1464 call assert_equal('52', getline('.'))
1465 50
1466 norm! za
1467 norm! k
1468 call assert_equal('49', getline('.'))
1469 norm! j
1470 call assert_equal('50/*{{{*/', getline('.'))
1471 norm! j
1472 call assert_equal('52', getline('.'))
1473
1474 49
1475 norm! 5zF
1476 norm! k
1477 call assert_equal('48', getline('.'))
1478 norm! j
1479 call assert_equal('49/*{{{*/', getline('.'))
1480 norm! j
1481 call assert_equal('55', getline('.'))
1482 49
1483 norm! za
1484 call assert_equal('49/*{{{*/', getline('.'))
1485 norm! j
1486 call assert_equal('50/*{{{*/', getline('.'))
1487 norm! j
1488 call assert_equal('52', getline('.'))
1489 set nofoldenable
1490 " close fold and set foldenable
1491 norm! za
1492 call assert_equal(1, &foldenable)
1493
1494 50
1495 " have to use {count}za to open all folds and make the cursor visible
1496 norm! 2za
1497 norm! 2k
1498 call assert_equal('48', getline('.'))
1499 norm! j
1500 call assert_equal('49/*{{{*/', getline('.'))
1501 norm! j
1502 call assert_equal('50/*{{{*/', getline('.'))
1503 norm! j
1504 call assert_equal('51/*}}}*/', getline('.'))
1505 norm! j
1506 call assert_equal('52', getline('.'))
1507
1508 " Test for zA
1509 49
1510 set foldlevel=0
1511 50
1512 norm! zA
1513 norm! 2k
1514 call assert_equal('48', getline('.'))
1515 norm! j
1516 call assert_equal('49/*{{{*/', getline('.'))
1517 norm! j
1518 call assert_equal('50/*{{{*/', getline('.'))
1519 norm! j
1520 call assert_equal('51/*}}}*/', getline('.'))
1521 norm! j
1522 call assert_equal('52', getline('.'))
1523
Dominique Pelle923dce22021-11-21 11:36:04 +00001524 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001525 50
1526 set nofoldenable
1527 norm! zA
1528 call assert_equal(1, &foldenable)
1529 norm! k
1530 call assert_equal('48', getline('.'))
1531 norm! j
1532 call assert_equal('49/*{{{*/', getline('.'))
1533 norm! j
1534 call assert_equal('55', getline('.'))
1535
1536 " Test for zc
1537 norm! zE
1538 50
1539 norm! 2zF
1540 49
1541 norm! 5zF
1542 set nofoldenable
1543 50
1544 " There most likely is a bug somewhere:
1545 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1546 " TODO: Should this only close the inner most fold or both folds?
1547 norm! zc
1548 call assert_equal(1, &foldenable)
1549 norm! k
1550 call assert_equal('48', getline('.'))
1551 norm! j
1552 call assert_equal('49/*{{{*/', getline('.'))
1553 norm! j
1554 call assert_equal('55', getline('.'))
1555 set nofoldenable
1556 50
1557 norm! Vjzc
1558 norm! k
1559 call assert_equal('48', getline('.'))
1560 norm! j
1561 call assert_equal('49/*{{{*/', getline('.'))
1562 norm! j
1563 call assert_equal('55', getline('.'))
1564
1565 " Test for zC
1566 set nofoldenable
1567 50
1568 norm! zCk
1569 call assert_equal('48', getline('.'))
1570 norm! j
1571 call assert_equal('49/*{{{*/', getline('.'))
1572 norm! j
1573 call assert_equal('55', getline('.'))
1574
1575 " Test for zx
1576 " 1) close folds at line 49-54
1577 set nofoldenable
1578 48
1579 norm! zx
1580 call assert_equal(1, &foldenable)
1581 norm! j
1582 call assert_equal('49/*{{{*/', getline('.'))
1583 norm! j
1584 call assert_equal('55', getline('.'))
1585
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001586 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001587 51
1588 set nofoldenable
1589 norm! zx
1590 call assert_equal(1, &foldenable)
1591 norm! 3k
1592 call assert_equal('48', getline('.'))
1593 norm! j
1594 call assert_equal('49/*{{{*/', getline('.'))
1595 norm! j
1596 call assert_equal('50/*{{{*/', getline('.'))
1597 norm! j
1598 call assert_equal('51/*}}}*/', getline('.'))
1599 norm! j
1600 call assert_equal('52', getline('.'))
1601 norm! j
1602 call assert_equal('53', getline('.'))
1603 norm! j
1604 call assert_equal('54/*}}}*/', getline('.'))
1605 norm! j
1606 call assert_equal('55', getline('.'))
1607
1608 " 3) close one level of folds
1609 48
1610 set nofoldenable
1611 set foldlevel=1
1612 norm! zx
1613 call assert_equal(1, &foldenable)
1614 call assert_equal('48', getline('.'))
1615 norm! j
1616 call assert_equal('49/*{{{*/', getline('.'))
1617 norm! j
1618 call assert_equal('50/*{{{*/', getline('.'))
1619 norm! j
1620 call assert_equal('52', getline('.'))
1621 norm! j
1622 call assert_equal('53', getline('.'))
1623 norm! j
1624 call assert_equal('54/*}}}*/', getline('.'))
1625 norm! j
1626 call assert_equal('55', getline('.'))
1627
1628 " Test for zX
1629 " Close all folds
1630 set foldlevel=0 nofoldenable
1631 50
1632 norm! zX
1633 call assert_equal(1, &foldenable)
1634 norm! k
1635 call assert_equal('48', getline('.'))
1636 norm! j
1637 call assert_equal('49/*{{{*/', getline('.'))
1638 norm! j
1639 call assert_equal('55', getline('.'))
1640
1641 " Test for zm
1642 50
1643 set nofoldenable foldlevel=2
1644 norm! zm
1645 call assert_equal(1, &foldenable)
1646 call assert_equal(1, &foldlevel)
1647 norm! zm
1648 call assert_equal(0, &foldlevel)
1649 norm! zm
1650 call assert_equal(0, &foldlevel)
1651 norm! k
1652 call assert_equal('48', getline('.'))
1653 norm! j
1654 call assert_equal('49/*{{{*/', getline('.'))
1655 norm! j
1656 call assert_equal('55', getline('.'))
1657
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001658 " Test for zm with a count
1659 50
1660 set foldlevel=2
1661 norm! 3zm
1662 call assert_equal(0, &foldlevel)
1663 call assert_equal(49, foldclosed(line('.')))
1664
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001665 " Test for zM
1666 48
1667 set nofoldenable foldlevel=99
1668 norm! zM
1669 call assert_equal(1, &foldenable)
1670 call assert_equal(0, &foldlevel)
1671 call assert_equal('48', getline('.'))
1672 norm! j
1673 call assert_equal('49/*{{{*/', getline('.'))
1674 norm! j
1675 call assert_equal('55', getline('.'))
1676
1677 " Test for zr
1678 48
1679 set nofoldenable foldlevel=0
1680 norm! zr
1681 call assert_equal(0, &foldenable)
1682 call assert_equal(1, &foldlevel)
1683 set foldlevel=0 foldenable
1684 norm! zr
1685 call assert_equal(1, &foldenable)
1686 call assert_equal(1, &foldlevel)
1687 norm! zr
1688 call assert_equal(2, &foldlevel)
1689 call assert_equal('48', getline('.'))
1690 norm! j
1691 call assert_equal('49/*{{{*/', getline('.'))
1692 norm! j
1693 call assert_equal('50/*{{{*/', getline('.'))
1694 norm! j
1695 call assert_equal('51/*}}}*/', getline('.'))
1696 norm! j
1697 call assert_equal('52', getline('.'))
1698
1699 " Test for zR
1700 48
1701 set nofoldenable foldlevel=0
1702 norm! zR
1703 call assert_equal(0, &foldenable)
1704 call assert_equal(2, &foldlevel)
1705 set foldenable foldlevel=0
1706 norm! zR
1707 call assert_equal(1, &foldenable)
1708 call assert_equal(2, &foldlevel)
1709 call assert_equal('48', getline('.'))
1710 norm! j
1711 call assert_equal('49/*{{{*/', getline('.'))
1712 norm! j
1713 call assert_equal('50/*{{{*/', getline('.'))
1714 norm! j
1715 call assert_equal('51/*}}}*/', getline('.'))
1716 norm! j
1717 call assert_equal('52', getline('.'))
1718 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1719 48
1720 call assert_equal('48', getline('.'))
1721 norm! j
1722 call assert_equal('49/*{{{*/', getline('.'))
1723 norm! j
1724 call assert_equal('50/*{{{*/', getline('.'))
1725 norm! j
1726 call assert_equal('a /*{{{*/', getline('.'))
1727 norm! j
1728 call assert_equal('51/*}}}*/', getline('.'))
1729 norm! j
1730 call assert_equal('52', getline('.'))
1731 48
1732 norm! zR
1733 call assert_equal(1, &foldenable)
1734 call assert_equal(3, &foldlevel)
1735 call assert_equal('48', getline('.'))
1736 norm! j
1737 call assert_equal('49/*{{{*/', getline('.'))
1738 norm! j
1739 call assert_equal('50/*{{{*/', getline('.'))
1740 norm! j
1741 call assert_equal('a /*{{{*/', getline('.'))
1742 norm! j
1743 call assert_equal('b /*}}}*/', getline('.'))
1744 norm! j
1745 call assert_equal('51/*}}}*/', getline('.'))
1746 norm! j
1747 call assert_equal('52', getline('.'))
1748
1749 " clean up
1750 setl nofoldenable fdm=marker foldlevel=0
1751 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001752endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001753
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001754func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001755 " Reading from redirected file doesn't work on MS-Windows
1756 CheckNotMSWindows
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001757 call writefile(['1a', 'foo', 'bar', '.', 'w! Xn20file2', 'q!'], 'Xn20script', 'D')
1758 call writefile(['1', '2'], 'Xn20file', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001759 call system(GetVimCommand() .. ' -e -s < Xn20script Xn20file')
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001760 let a = readfile('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001761 call assert_equal(['1', 'foo', 'bar', '2'], a)
1762
1763 " clean up
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001764 call delete('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001765 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001766endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001767
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001768func Test_normal21_nv_hat()
1769
1770 " Edit a fresh file and wipe the buffer list so that there is no alternate
1771 " file present. Next, check for the expected command failures.
1772 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001773 call assert_fails(':buffer #', 'E86:')
1774 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001775 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001776
1777 " Test for the expected behavior when switching between two named buffers.
1778 edit Xfoo | edit Xbar
1779 call feedkeys("\<C-^>", 'tx')
1780 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1781 call feedkeys("\<C-^>", 'tx')
1782 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1783
1784 " Test for the expected behavior when only one buffer is named.
1785 enew | let l:nr = bufnr('%')
1786 call feedkeys("\<C-^>", 'tx')
1787 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1788 call feedkeys("\<C-^>", 'tx')
1789 call assert_equal('', bufname('%'))
1790 call assert_equal(l:nr, bufnr('%'))
1791
1792 " Test that no action is taken by "<C-^>" when an operator is pending.
1793 edit Xfoo
1794 call feedkeys("ci\<C-^>", 'tx')
1795 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1796
1797 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001798endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001799
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001800func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001801 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001802 " let shell = &shell
1803 " let &shell = 'sh'
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001804 call writefile(['1', '2'], 'Xn22file', 'D')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001805 let args = ' -N -i NONE --noplugins -X --not-a-term'
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001806 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xn22file')
1807 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001808 call assert_equal([], a)
1809 " Test for ZQ
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001810 call writefile(['1', '2'], 'Xn22file')
1811 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xn22file')
1812 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001813 call assert_equal(['1', '2'], a)
1814
Bram Moolenaar1671f442020-03-10 07:48:13 +01001815 " Unsupported Z command
1816 call assert_beeps('normal! ZW')
1817
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001818 " clean up
Bram Moolenaar0913a102016-09-03 19:11:59 +02001819 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001820endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001821
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001822func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001823 " Test for K command
1824 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001825 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001826 let k = &keywordprg
1827 set keywordprg=:help
1828 1
1829 norm! VK
1830 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1831 call assert_equal('help', &ft)
1832 call assert_match('\*version8.txt\*', getline('.'))
1833 helpclose
1834 norm! 0K
1835 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1836 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001837 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001838 helpclose
1839
Bram Moolenaar426f3752016-11-04 21:22:37 +01001840 set keywordprg=:new
1841 set iskeyword+=%
1842 set iskeyword+=\|
1843 2
1844 norm! K
1845 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1846 bwipe!
1847 3
1848 norm! K
1849 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1850 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001851 if !has('win32')
1852 4
1853 norm! K
1854 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1855 bwipe!
1856 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001857 set iskeyword-=%
1858 set iskeyword-=\|
1859
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001860 " Test for specifying a count to K
1861 1
1862 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1863 set keywordprg=:Kprog
1864 norm! 3K
1865 call assert_equal('3 version8', g:Kprog_Args)
1866 delcom Kprog
1867
Bram Moolenaar0913a102016-09-03 19:11:59 +02001868 " Only expect "man" to work on Unix
1869 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001870 let &keywordprg = k
1871 bw!
1872 return
1873 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001874
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001875 let not_gnu_man = has('mac') || has('bsd')
1876 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001877 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001878 set keywordprg=man\ -P\ cat
1879 else
1880 set keywordprg=man\ --pager=cat
1881 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001882 " Test for using man
1883 2
1884 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001885 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001886 call assert_match("man -P cat 'man'", a)
1887 else
1888 call assert_match("man --pager=cat 'man'", a)
1889 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001890
Bram Moolenaar1671f442020-03-10 07:48:13 +01001891 " Error cases
1892 call setline(1, '#$#')
1893 call assert_fails('normal! ggK', 'E349:')
1894 call setline(1, '---')
1895 call assert_fails('normal! ggv2lK', 'E349:')
1896 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001897 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001898 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001899 norm! V
1900 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001901
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001902 " clean up
1903 let &keywordprg = k
1904 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001905endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001906
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001907func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001908 " Testing for g?? g?g?
1909 new
1910 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1911 1
1912 norm! g??
1913 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1914 norm! g?g?
1915 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1916
1917 " clean up
1918 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001919endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001920
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001921func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001922 CheckFeature quickfix
1923
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001924 " Testing for CTRL-] g CTRL-] g]
1925 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1926 h
1927 " Test for CTRL-]
1928 call search('\<x\>$')
1929 exe "norm! \<c-]>"
1930 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1931 norm! yiW
1932 call assert_equal("*x*", @0)
1933 exe ":norm \<c-o>"
1934
1935 " Test for g_CTRL-]
1936 call search('\<v_u\>$')
1937 exe "norm! g\<c-]>"
1938 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1939 norm! yiW
1940 call assert_equal("*v_u*", @0)
1941 exe ":norm \<c-o>"
1942
1943 " Test for g]
1944 call search('\<i_<Esc>$')
1945 let a = execute(":norm! g]")
1946 call assert_match('i_<Esc>.*insert.txt', a)
1947
1948 if !empty(exepath('cscope')) && has('cscope')
1949 " setting cscopetag changes how g] works
1950 set cst
1951 exe "norm! g]"
1952 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1953 norm! yiW
1954 call assert_equal("*i_<Esc>*", @0)
1955 exe ":norm \<c-o>"
1956 " Test for CTRL-W g]
1957 exe "norm! \<C-W>g]"
1958 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1959 norm! yiW
1960 call assert_equal("*i_<Esc>*", @0)
1961 call assert_equal(3, winnr('$'))
1962 helpclose
1963 set nocst
1964 endif
1965
1966 " Test for CTRL-W g]
1967 let a = execute("norm! \<C-W>g]")
1968 call assert_match('i_<Esc>.*insert.txt', a)
1969
1970 " Test for CTRL-W CTRL-]
1971 exe "norm! \<C-W>\<C-]>"
1972 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1973 norm! yiW
1974 call assert_equal("*i_<Esc>*", @0)
1975 call assert_equal(3, winnr('$'))
1976 helpclose
1977
1978 " Test for CTRL-W g CTRL-]
1979 exe "norm! \<C-W>g\<C-]>"
1980 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1981 norm! yiW
1982 call assert_equal("*i_<Esc>*", @0)
1983 call assert_equal(3, winnr('$'))
1984 helpclose
1985
1986 " clean up
1987 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001988endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001989
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001990func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001991 " Test for ]p ]P [p and [P
1992 new
1993 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1994 1
1995 /Error/y a
1996 2
1997 norm! "a]pj"a[p
1998 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1999 1
2000 /^\s\{4}/
2001 exe "norm! \"a]P3Eldt'"
2002 exe "norm! j\"a[P2Eldt'"
2003 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
2004
2005 " clean up
2006 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002007endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002008
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002009func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002010 " Test for [' [` ]' ]`
2011 call Setup_NewWindow()
2012 1,21s/.\+/ & b/
2013 1
2014 norm! $ma
2015 5
2016 norm! $mb
2017 10
2018 norm! $mc
2019 15
2020 norm! $md
2021 20
2022 norm! $me
2023
2024 " Test for ['
2025 9
2026 norm! 2['
2027 call assert_equal(' 1 b', getline('.'))
2028 call assert_equal(1, line('.'))
2029 call assert_equal(3, col('.'))
2030
2031 " Test for ]'
2032 norm! ]'
2033 call assert_equal(' 5 b', getline('.'))
2034 call assert_equal(5, line('.'))
2035 call assert_equal(3, col('.'))
2036
zeertzjqcf344342022-07-06 12:57:31 +01002037 " No mark before line 1, cursor moves to first non-blank on current line
2038 1
2039 norm! 5|['
2040 call assert_equal(' 1 b', getline('.'))
2041 call assert_equal(1, line('.'))
2042 call assert_equal(3, col('.'))
2043
2044 " No mark after line 21, cursor moves to first non-blank on current line
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002045 21
zeertzjqcf344342022-07-06 12:57:31 +01002046 norm! 5|]'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002047 call assert_equal(' 21 b', getline('.'))
2048 call assert_equal(21, line('.'))
2049 call assert_equal(3, col('.'))
2050
2051 " Test for [`
2052 norm! 2[`
2053 call assert_equal(' 15 b', getline('.'))
2054 call assert_equal(15, line('.'))
2055 call assert_equal(8, col('.'))
2056
2057 " Test for ]`
2058 norm! ]`
2059 call assert_equal(' 20 b', getline('.'))
2060 call assert_equal(20, line('.'))
2061 call assert_equal(8, col('.'))
2062
zeertzjqcf344342022-07-06 12:57:31 +01002063 " No mark before line 1, cursor does not move
2064 1
2065 norm! 5|[`
2066 call assert_equal(' 1 b', getline('.'))
2067 call assert_equal(1, line('.'))
2068 call assert_equal(5, col('.'))
2069
2070 " No mark after line 21, cursor does not move
2071 21
2072 norm! 5|]`
2073 call assert_equal(' 21 b', getline('.'))
2074 call assert_equal(21, line('.'))
2075 call assert_equal(5, col('.'))
2076
2077 " Count too large for [`
2078 " cursor moves to first lowercase mark
2079 norm! 99[`
2080 call assert_equal(' 1 b', getline('.'))
2081 call assert_equal(1, line('.'))
2082 call assert_equal(7, col('.'))
2083
2084 " Count too large for ]`
2085 " cursor moves to last lowercase mark
2086 norm! 99]`
2087 call assert_equal(' 20 b', getline('.'))
2088 call assert_equal(20, line('.'))
2089 call assert_equal(8, col('.'))
2090
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002091 " clean up
2092 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002093endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002094
Bram Moolenaar1671f442020-03-10 07:48:13 +01002095" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002096func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002097 new
2098 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2099
2100 $
2101 norm! d(
2102 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2103 norm! 2d(
2104 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2105 1
2106 norm! 0d)
2107 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2108
2109 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2110 $
2111 norm! $d(
2112 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2113
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002114 " Move to the next sentence from a paragraph macro
2115 %d
2116 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2117 call cursor(1, 1)
2118 normal )
2119 call assert_equal([2, 1], [line('.'), col('.')])
2120 normal )
2121 call assert_equal([2, 12], [line('.'), col('.')])
2122 normal ((
2123 call assert_equal([1, 1], [line('.'), col('.')])
2124
Bram Moolenaar1671f442020-03-10 07:48:13 +01002125 " It is an error if a next sentence is not found
2126 %d
2127 call setline(1, '.SH')
2128 call assert_beeps('normal )')
2129
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002130 " If only dot is present, don't treat that as a sentence
2131 call setline(1, '. This is a sentence.')
2132 normal $((
2133 call assert_equal(3, col('.'))
2134
Bram Moolenaar1671f442020-03-10 07:48:13 +01002135 " Jumping to a fold should open the fold
2136 call setline(1, ['', '', 'one', 'two', 'three'])
2137 set foldenable
2138 2,$fold
2139 call feedkeys(')', 'xt')
2140 call assert_equal(3, line('.'))
2141 call assert_equal(1, foldlevel('.'))
2142 call assert_equal(-1, foldclosed('.'))
2143 set foldenable&
2144
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002145 " clean up
2146 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002147endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002148
Bram Moolenaar1671f442020-03-10 07:48:13 +01002149" Test for { and } paragraph movements
2150func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002151 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002152 A paragraph begins after each empty line, and also at each of a set of
2153 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2154 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2155 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2156 the first column). A section boundary is also a paragraph boundary.
2157 Note that a blank line (only containing white space) is NOT a paragraph
2158 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002159
2160
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002161 Also note that this does not include a '{' or '}' in the first column. When
2162 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2163 paragraph boundary |posix|.
2164 {
2165 This is no paragraph
2166 unless the '{' is set
2167 in 'cpoptions'
2168 }
2169 .IP
2170 The nroff macros IP separates a paragraph
2171 That means, it must be a '.'
2172 followed by IP
2173 .LPIt does not matter, if afterwards some
2174 more characters follow.
2175 .SHAlso section boundaries from the nroff
2176 macros terminate a paragraph. That means
2177 a character like this:
2178 .NH
2179 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002180 [DATA]
2181
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002182 new
2183 call append(0, text)
2184 1
2185 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002186
2187 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002188 .IP
2189 The nroff macros IP separates a paragraph
2190 That means, it must be a '.'
2191 followed by IP
2192 .LPIt does not matter, if afterwards some
2193 more characters follow.
2194 .SHAlso section boundaries from the nroff
2195 macros terminate a paragraph. That means
2196 a character like this:
2197 .NH
2198 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002199
2200 [DATA]
2201 call assert_equal(expected, getline(1, '$'))
2202
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002203 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002204
2205 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002206 .LPIt does not matter, if afterwards some
2207 more characters follow.
2208 .SHAlso section boundaries from the nroff
2209 macros terminate a paragraph. That means
2210 a character like this:
2211 .NH
2212 End of text here
Bram Moolenaar94722c52023-01-28 19:19:03 +00002213
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002214 [DATA]
2215 call assert_equal(expected, getline(1, '$'))
2216
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002217 $
2218 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002219
2220 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002221 .LPIt does not matter, if afterwards some
2222 more characters follow.
2223 .SHAlso section boundaries from the nroff
2224 macros terminate a paragraph. That means
2225 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002226
2227 [DATA]
2228 call assert_equal(expected, getline(1, '$'))
2229
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002230 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002231
2232 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002233 .LPIt does not matter, if afterwards some
2234 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002235
2236 [DATA]
2237 call assert_equal(expected, getline(1, '$'))
2238
dundargocdc4c37b2024-01-12 18:02:10 +01002239 " Test with { in cpoptions
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002240 %d
2241 call append(0, text)
2242 set cpo+={
2243 1
2244 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002245
2246 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002247 {
2248 This is no paragraph
2249 unless the '{' is set
2250 in 'cpoptions'
2251 }
2252 .IP
2253 The nroff macros IP separates a paragraph
2254 That means, it must be a '.'
2255 followed by IP
2256 .LPIt does not matter, if afterwards some
2257 more characters follow.
2258 .SHAlso section boundaries from the nroff
2259 macros terminate a paragraph. That means
2260 a character like this:
2261 .NH
2262 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002263
2264 [DATA]
2265 call assert_equal(expected, getline(1, '$'))
2266
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002267 $
2268 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002269
2270 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002271 {
2272 This is no paragraph
2273 unless the '{' is set
2274 in 'cpoptions'
2275 }
2276 .IP
2277 The nroff macros IP separates a paragraph
2278 That means, it must be a '.'
2279 followed by IP
2280 .LPIt does not matter, if afterwards some
2281 more characters follow.
2282 .SHAlso section boundaries from the nroff
2283 macros terminate a paragraph. That means
2284 a character like this:
2285 .NH
2286 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002287
2288 [DATA]
2289 call assert_equal(expected, getline(1, '$'))
2290
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002291 norm! gg}
2292 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002293
2294 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002295 {
2296 This is no paragraph
2297 unless the '{' is set
2298 in 'cpoptions'
2299 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002300
2301 [DATA]
2302 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002303
Bram Moolenaar1671f442020-03-10 07:48:13 +01002304 " Jumping to a fold should open the fold
2305 %d
2306 call setline(1, ['', 'one', 'two', ''])
2307 set foldenable
2308 2,$fold
2309 call feedkeys('}', 'xt')
2310 call assert_equal(4, line('.'))
2311 call assert_equal(1, foldlevel('.'))
2312 call assert_equal(-1, foldclosed('.'))
2313 set foldenable&
2314
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002315 " clean up
2316 set cpo-={
2317 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002318endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002319
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002320" Test for section movements
2321func Test_normal_section()
2322 new
2323 let lines =<< trim [END]
2324 int foo()
2325 {
2326 if (1)
2327 {
2328 a = 1;
2329 }
2330 }
2331 [END]
2332 call setline(1, lines)
2333
2334 " jumping to a folded line using [[ should open the fold
2335 2,3fold
2336 call cursor(5, 1)
2337 call feedkeys("[[", 'xt')
2338 call assert_equal(2, line('.'))
2339 call assert_equal(-1, foldclosedend(line('.')))
2340
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002341 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002342endfunc
2343
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002344" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002345func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002346 new
2347 call append(0, 'This is a simple test: äüöß')
2348 norm! 1ggVu
2349 call assert_equal('this is a simple test: äüöß', getline('.'))
2350 norm! VU
glepnirbd1232a2024-02-12 22:14:53 +01002351 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002352 norm! guu
glepnirbd1232a2024-02-12 22:14:53 +01002353 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002354 norm! gUgU
glepnirbd1232a2024-02-12 22:14:53 +01002355 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002356 norm! gugu
glepnirbd1232a2024-02-12 22:14:53 +01002357 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002358 norm! gUU
glepnirbd1232a2024-02-12 22:14:53 +01002359 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002360 norm! 010~
glepnirbd1232a2024-02-12 22:14:53 +01002361 call assert_equal('this is a SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002362 norm! V~
glepnirbd1232a2024-02-12 22:14:53 +01002363 call assert_equal('THIS IS A simple test: äüöß', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002364 call assert_beeps('norm! c~')
2365 %d
2366 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002367
zeertzjq8c55d602024-03-13 20:42:26 +01002368 " Test with multiple lines
2369 call setline(1, ['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'])
2370 norm! ggguG
2371 call assert_equal(['aa', 'bbbb', 'cccccc', 'dddddddd'], getline(1, '$'))
2372 norm! GgUgg
2373 call assert_equal(['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'], getline(1, '$'))
2374 %d
2375
Bram Moolenaar1671f442020-03-10 07:48:13 +01002376 " Test for changing case across lines using 'whichwrap'
2377 call setline(1, ['aaaaaa', 'aaaaaa'])
2378 normal! gg10~
2379 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2380 set whichwrap+=~
2381 normal! gg10~
2382 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2383 set whichwrap&
2384
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002385 " try changing the case with a double byte encoding (DBCS)
2386 %bw!
2387 let enc = &enc
2388 set encoding=cp932
2389 call setline(1, "\u8470")
2390 normal ~
2391 normal gU$gu$gUgUg~g~gugu
2392 call assert_equal("\u8470", getline(1))
2393 let &encoding = enc
2394
Bram Moolenaar1671f442020-03-10 07:48:13 +01002395 " clean up
2396 bw!
2397endfunc
2398
2399" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2400" is available but toupper()/tolower() don't do the right thing.
2401func Test_normal_changecase_turkish()
2402 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002403 try
2404 lang tr_TR.UTF-8
2405 set casemap=
2406 let iupper = toupper('i')
2407 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002408 call setline(1, 'iI')
2409 1normal gUU
2410 call assert_equal("\u0130I", getline(1))
2411 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002412
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002413 call setline(1, 'iI')
2414 1normal guu
2415 call assert_equal("i\u0131", getline(1))
2416 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002417 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002418 call setline(1, 'iI')
2419 1normal gUU
2420 call assert_equal("II", getline(1))
2421 call assert_equal("II", toupper("iI"))
2422
2423 call setline(1, 'iI')
2424 1normal guu
2425 call assert_equal("ii", getline(1))
2426 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002427 else
2428 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2429 endif
2430 set casemap&
2431 call setline(1, 'iI')
2432 1normal gUU
2433 call assert_equal("II", getline(1))
2434 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002435
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002436 call setline(1, 'iI')
2437 1normal guu
2438 call assert_equal("ii", getline(1))
2439 call assert_equal("ii", tolower("iI"))
2440
2441 lang en_US.UTF-8
2442 catch /E197:/
2443 " can't use Turkish locale
2444 throw 'Skipped: Turkish locale not available'
2445 endtry
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002446
2447 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002448endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002449
Bram Moolenaar1671f442020-03-10 07:48:13 +01002450" Test for r (replace) command
2451func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002452 new
2453 call append(0, 'This is a simple test: abcd')
2454 exe "norm! 1gg$r\<cr>"
2455 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2456 exe "norm! 1gg2wlr\<cr>"
2457 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2458 exe "norm! 2gg0W5r\<cr>"
2459 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2460 set autoindent
2461 call setline(2, ['simple test: abc', ''])
2462 exe "norm! 2gg0W5r\<cr>"
2463 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2464 exe "norm! 1ggVr\<cr>"
2465 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2466 call setline(1, 'This is a')
2467 exe "norm! 1gg05rf"
2468 call assert_equal('fffffis a', getline(1))
2469
Bram Moolenaar1671f442020-03-10 07:48:13 +01002470 " When replacing characters, copy characters from above and below lines
2471 " using CTRL-Y and CTRL-E.
2472 " Different code paths are used for utf-8 and latin1 encodings
2473 set showmatch
2474 for enc in ['latin1', 'utf-8']
2475 enew!
2476 let &encoding = enc
2477 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2478 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2479 call assert_equal(' {a}x [b]x', getline(2))
2480 endfor
2481 set showmatch&
2482
2483 " r command should fail in operator pending mode
2484 call assert_beeps('normal! cr')
2485
Bram Moolenaar004a6782020-04-11 17:09:31 +02002486 " replace a tab character in visual mode
2487 %d
2488 call setline(1, ["a\tb", "c\td", "e\tf"])
2489 normal gglvjjrx
2490 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2491
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002492 " replace with a multibyte character (with multiple composing characters)
2493 %d
2494 new
2495 call setline(1, 'aaa')
2496 exe "normal $ra\u0328\u0301"
2497 call assert_equal("aaa\u0328\u0301", getline(1))
2498
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002499 " clean up
2500 set noautoindent
2501 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002502endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002503
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002504" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002505func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002506 new
2507 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2508 1
2509 norm! $g*
2510 call assert_equal('x_foo', @/)
2511 call assert_equal('x_foobar.abc', getline('.'))
2512 norm! $g#
2513 call assert_equal('abc', @/)
2514 call assert_equal('abc.x_foo', getline('.'))
2515
2516 " clean up
2517 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002518endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002519
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002520" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2521" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002522func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002523 call Setup_NewWindow()
2524 " Test for g`
2525 clearjumps
2526 norm! ma10j
2527 let a=execute(':jumps')
2528 " empty jumplist
2529 call assert_equal('>', a[-1:])
2530 norm! g`a
2531 call assert_equal('>', a[-1:])
2532 call assert_equal(1, line('.'))
2533 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002534 call cursor(10, 1)
2535 norm! g'a
2536 call assert_equal('>', a[-1:])
2537 call assert_equal(1, line('.'))
zeertzjq30585e02023-03-06 08:10:04 +00002538 let v:errmsg = ''
zeertzjqf86dea82023-03-05 21:15:06 +00002539 call assert_nobeep("normal! g`\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002540 call assert_equal('', v:errmsg)
zeertzjqf86dea82023-03-05 21:15:06 +00002541 call assert_nobeep("normal! g'\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002542 call assert_equal('', v:errmsg)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002543
2544 " Test for g; and g,
2545 norm! g;
2546 " there is only one change in the changelist
2547 " currently, when we setup the window
2548 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002549 call assert_fails(':norm! g;', 'E662:')
2550 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002551 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002552 call append('$', ['a', 'b', 'c', 'd'])
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002553 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002554 call append('$', ['Z', 'Y', 'X', 'W'])
2555 let a = execute(':changes')
2556 call assert_match('2\s\+0\s\+2', a)
2557 call assert_match('101\s\+0\s\+a', a)
2558 call assert_match('105\s\+0\s\+Z', a)
2559 norm! 3g;
2560 call assert_equal(2, line('.'))
2561 norm! 2g,
2562 call assert_equal(105, line('.'))
2563
2564 " Test for g& - global substitute
2565 %d
2566 call setline(1, range(1,10))
2567 call append('$', ['a', 'b', 'c', 'd'])
2568 $s/\w/&&/g
2569 exe "norm! /[1-8]\<cr>"
2570 norm! g&
2571 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2572
Bram Moolenaar1671f442020-03-10 07:48:13 +01002573 " Jumping to a fold using gg should open the fold
2574 set foldenable
2575 set foldopen+=jump
2576 5,8fold
2577 call feedkeys('6gg', 'xt')
2578 call assert_equal(1, foldlevel('.'))
2579 call assert_equal(-1, foldclosed('.'))
2580 set foldopen-=jump
2581 set foldenable&
2582
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002583 " Test for gv
2584 %d
2585 call append('$', repeat(['abcdefgh'], 8))
2586 exe "norm! 2gg02l\<c-v>2j2ly"
2587 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2588 " in visual mode, gv swaps current and last selected region
2589 exe "norm! G0\<c-v>4k4lgvd"
2590 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2591 exe "norm! G0\<c-v>4k4ly"
2592 exe "norm! gvood"
2593 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Christian Brabandtee17b6f2023-09-09 11:23:50 +02002594 " gv cannot be used in operator pending mode
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002595 call assert_beeps('normal! cgv')
2596 " gv should beep without a previously selected visual area
2597 new
2598 call assert_beeps('normal! gv')
2599 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002600
2601 " Test for gk/gj
2602 %d
2603 15vsp
2604 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002605 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2606 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2607 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002608 $put =lineA
2609 $put =lineB
2610
2611 norm! 3gg0dgk
2612 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2613 set nu
2614 norm! 3gg0gjdgj
2615 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2616
2617 " Test for gJ
2618 norm! 2gggJ
2619 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2620 call assert_equal(16, col('.'))
2621 " shouldn't do anything
2622 norm! 10gJ
2623 call assert_equal(1, col('.'))
2624
2625 " Test for g0 g^ gm g$
2626 exe "norm! 2gg0gji "
2627 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2628 norm! g0yl
2629 call assert_equal(12, col('.'))
2630 call assert_equal(' ', getreg(0))
2631 norm! g$yl
2632 call assert_equal(22, col('.'))
2633 call assert_equal('3', getreg(0))
2634 norm! gmyl
2635 call assert_equal(17, col('.'))
2636 call assert_equal('n', getreg(0))
2637 norm! g^yl
2638 call assert_equal(15, col('.'))
2639 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002640 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002641
Bram Moolenaar74ede802021-05-29 19:18:01 +02002642 " Test for g$ with double-width character half displayed
2643 vsplit
2644 9wincmd |
2645 setlocal nowrap nonumber
2646 call setline(2, 'asdfasdfヨ')
2647 2
2648 normal 0g$
2649 call assert_equal(8, col('.'))
2650 10wincmd |
2651 normal 0g$
2652 call assert_equal(9, col('.'))
2653
2654 setlocal signcolumn=yes
2655 11wincmd |
2656 normal 0g$
2657 call assert_equal(8, col('.'))
2658 12wincmd |
2659 normal 0g$
2660 call assert_equal(9, col('.'))
2661
2662 close
2663
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002664 " Test for g_
2665 call assert_beeps('normal! 100g_')
2666 call setline(2, [' foo ', ' foobar '])
2667 normal! 2ggg_
2668 call assert_equal(5, col('.'))
2669 normal! 2g_
2670 call assert_equal(8, col('.'))
2671
2672 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002673 $put =lineC
2674
2675 " Test for gM
2676 norm! gMyl
2677 call assert_equal(73, col('.'))
2678 call assert_equal('0', getreg(0))
2679 " Test for 20gM
2680 norm! 20gMyl
2681 call assert_equal(29, col('.'))
2682 call assert_equal('S', getreg(0))
2683 " Test for 60gM
2684 norm! 60gMyl
2685 call assert_equal(87, col('.'))
2686 call assert_equal('E', getreg(0))
2687
Bram Moolenaar71c41252021-12-26 15:00:07 +00002688 " Test for gM with Tab characters
2689 call setline('.', "\ta\tb\tc\td\te\tf")
2690 norm! gMyl
2691 call assert_equal(6, col('.'))
2692 call assert_equal("c", getreg(0))
2693
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002694 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002695 call setline('.', lineC)
2696 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002697 set ff=unix
2698 let a=execute(":norm! g\<c-g>")
2699 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2700
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002701 " Test for gI
2702 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002703 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002704
2705 " Test for gi
2706 wincmd c
2707 %d
2708 set tw=0
2709 call setline(1, ['foobar', 'new line'])
2710 norm! A next word
2711 $put ='third line'
2712 norm! gi another word
2713 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002714 call setline(1, 'foobar')
2715 normal! Ggifirst line
2716 call assert_equal('foobarfirst line', getline(1))
2717 " Test gi in 'virtualedit' mode with cursor after the end of the line
2718 set virtualedit=all
2719 call setline(1, 'foo')
2720 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2721 call setline(1, 'foo')
2722 normal! Ggifirst line
2723 call assert_equal('foo first line', getline(1))
2724 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002725
Dominique Pelle923dce22021-11-21 11:36:04 +00002726 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002727 exe "normal! g\<C-\>\<C-G>"
2728 call assert_equal('foo first line', getline('.'))
2729
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002730 " clean up
2731 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002732endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002733
Bram Moolenaarce416b42022-04-03 12:59:34 +01002734func Test_normal_ex_substitute()
2735 " This was hanging on the substitute prompt.
2736 new
2737 call setline(1, 'a')
2738 exe "normal! gggQs/a/b/c\<CR>"
2739 call assert_equal('a', getline(1))
2740 bwipe!
2741endfunc
2742
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002743" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002744func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002745 new
2746
2747 let a = execute(":norm! g\<c-g>")
2748 call assert_equal("\n--No lines in buffer--", a)
2749
Bram Moolenaar1671f442020-03-10 07:48:13 +01002750 " Test for CTRL-G (same as :file)
2751 let a = execute(":norm! \<c-g>")
2752 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2753
Bram Moolenaar05295832018-08-24 22:07:58 +02002754 call setline(1, ['first line', 'second line'])
2755
2756 " Test g CTRL-g with dos, mac and unix file type.
2757 norm! gojll
2758 set ff=dos
2759 let a = execute(":norm! g\<c-g>")
2760 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2761
2762 set ff=mac
2763 let a = execute(":norm! g\<c-g>")
2764 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2765
2766 set ff=unix
2767 let a = execute(":norm! g\<c-g>")
2768 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2769
2770 " Test g CTRL-g in visual mode (v)
2771 let a = execute(":norm! gojllvlg\<c-g>")
2772 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2773
2774 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2775 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2776 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2777
2778 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2779 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2780 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2781
2782 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2783 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2784 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2785
2786 " There should be one byte less with noeol
2787 set bin noeol
2788 let a = execute(":norm! \<Esc>gog\<c-g>")
2789 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2790 set bin & eol&
2791
Bram Moolenaar30276f22019-01-24 17:59:39 +01002792 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002793
Bram Moolenaar30276f22019-01-24 17:59:39 +01002794 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2795 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 +02002796
Bram Moolenaar30276f22019-01-24 17:59:39 +01002797 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2798 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 +02002799
Bram Moolenaar30276f22019-01-24 17:59:39 +01002800 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2801 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 +02002802
Bram Moolenaar30276f22019-01-24 17:59:39 +01002803 set fenc=utf8 bomb
2804 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2805 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 +02002806
Bram Moolenaar30276f22019-01-24 17:59:39 +01002807 set fenc=utf16 bomb
2808 let a = execute(":norm! g\<c-g>")
2809 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 +02002810
Bram Moolenaar30276f22019-01-24 17:59:39 +01002811 set fenc=utf32 bomb
2812 let a = execute(":norm! g\<c-g>")
2813 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 +02002814
Bram Moolenaar30276f22019-01-24 17:59:39 +01002815 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002816
2817 set ff&
2818 bwipe!
2819endfunc
2820
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002821" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002822func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002823 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002824 let a=execute(':norm! 1G0g8')
2825 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002826
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002827 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2828 let a=execute(':norm! 1G$g8')
2829 call assert_equal("\nc3 b6 ", a)
2830
2831 call setline(1, "a\u0302")
2832 let a=execute(':norm! 1G0g8')
2833 call assert_equal("\n61 + cc 82 ", a)
2834
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002835 " clean up
2836 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002837endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002838
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002839" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002840func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002841 new
2842
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002843 " With invalid byte.
2844 call setline(1, "___\xff___")
2845 norm! 1G08g8g
2846 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2847
2848 " With invalid byte before the cursor.
2849 call setline(1, "___\xff___")
2850 norm! 1G$h8g8g
2851 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2852
2853 " With truncated sequence.
2854 call setline(1, "___\xE2\x82___")
2855 norm! 1G08g8g
2856 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2857
2858 " With overlong sequence.
2859 call setline(1, "___\xF0\x82\x82\xAC___")
2860 norm! 1G08g8g
2861 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2862
2863 " With valid utf8.
2864 call setline(1, "café")
2865 norm! 1G08g8
2866 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2867
2868 bw!
2869endfunc
2870
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002871" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002872func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002873 " Cannot capture its output,
2874 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002875 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002876 echo "a\nb\nc\nd"
2877 let b=execute(':norm! g<')
2878 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002879endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002880
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002881" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002882func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002883 new
2884 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002885 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002886 " Test for gp gP
2887 call append(1, range(1,10))
2888 1
2889 norm! 1yy
2890 3
2891 norm! gp
2892 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2893 $
2894 norm! gP
2895 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2896
2897 " Test for go
2898 norm! 26go
2899 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2900 norm! 27go
2901 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2902 norm! 28go
2903 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2904 set ff=dos
2905 norm! 29go
2906 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2907 set ff=unix
2908 norm! gg0
2909 norm! 101go
2910 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2911 norm! 103go
2912 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2913 " count > buffer content
2914 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002915 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002916 " clean up
2917 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002918endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002919
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002920" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002921func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002922 tabnew 1.txt
2923 tabnew 2.txt
2924 tabnew 3.txt
2925 norm! 1gt
2926 call assert_equal(1, tabpagenr())
2927 norm! 3gt
2928 call assert_equal(3, tabpagenr())
2929 norm! 1gT
2930 " count gT goes not to the absolute tabpagenumber
2931 " but, but goes to the count previous tabpagenumber
2932 call assert_equal(2, tabpagenr())
2933 " wrap around
2934 norm! 3gT
2935 call assert_equal(3, tabpagenr())
2936 " gt does not wrap around
2937 norm! 5gt
2938 call assert_equal(3, tabpagenr())
2939
2940 for i in range(3)
2941 tabclose
2942 endfor
2943 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002944 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002945endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002946
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002947" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002948func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002949 new
2950 call setline(1, range(10))
2951 $
2952 setl et sw=2
2953 norm! V10>$
2954 " count is ignored
2955 exe "norm! 10\<home>"
2956 call assert_equal(1, col('.'))
2957 exe "norm! \<home>"
2958 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2959 exe "norm! 5\<c-home>"
2960 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2961 exe "norm! \<c-home>"
2962 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002963 exe "norm! G\<c-kHome>"
2964 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002965
2966 " clean up
2967 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002968endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002969
Bram Moolenaar1671f442020-03-10 07:48:13 +01002970" Test for <End> and <C-End> keys
2971func Test_normal_nvend()
2972 new
2973 call setline(1, map(range(1, 10), '"line" .. v:val'))
2974 exe "normal! \<End>"
2975 call assert_equal(5, col('.'))
2976 exe "normal! 4\<End>"
2977 call assert_equal([4, 5], [line('.'), col('.')])
2978 exe "normal! \<C-End>"
2979 call assert_equal([10, 6], [line('.'), col('.')])
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002980
2981 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01002982endfunc
2983
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002984" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002985func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002986 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002987 new
2988 set tw=0
2989 call append(0, 'here are some words')
2990 norm! 1gg0elcwZZZ
2991 call assert_equal('hereZZZare some words', getline('.'))
2992 norm! 1gg0elcWYYY
2993 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002994 norm! 2gg0cwfoo
2995 call assert_equal('foo', getline('.'))
2996
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002997 call setline(1, 'one; two')
2998 call cursor(1, 1)
2999 call feedkeys('cwvim', 'xt')
3000 call assert_equal('vim; two', getline(1))
3001 call feedkeys('0cWone', 'xt')
3002 call assert_equal('one two', getline(1))
3003 "When cursor is at the end of a word 'ce' will change until the end of the
3004 "next word, but 'cw' will change only one character
3005 call setline(1, 'one two')
3006 call feedkeys('0ecwce', 'xt')
3007 call assert_equal('once two', getline(1))
3008 call setline(1, 'one two')
3009 call feedkeys('0ecely', 'xt')
3010 call assert_equal('only', getline(1))
3011
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003012 " clean up
3013 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003014endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003015
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003016" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003017func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003018 new
3019 call append(0, 'here are some words')
3020 exe "norm! 1gg0a\<C-\>\<C-N>"
3021 call assert_equal('n', mode())
3022 call assert_equal(1, col('.'))
3023 call assert_equal('', visualmode())
3024 exe "norm! 1gg0viw\<C-\>\<C-N>"
3025 call assert_equal('n', mode())
3026 call assert_equal(4, col('.'))
3027 exe "norm! 1gg0a\<C-\>\<C-G>"
3028 call assert_equal('n', mode())
3029 call assert_equal(1, col('.'))
3030 "imap <buffer> , <c-\><c-n>
3031 set im
3032 exe ":norm! \<c-\>\<c-n>dw"
3033 set noim
3034 call assert_equal('are some words', getline(1))
3035 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02003036 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01003037
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003038 " clean up
3039 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003040endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003041
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003042" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003043func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003044 new
3045 set sts=2 sw=2 ts=8 tw=0
3046 call append(0, ["aaa\tbbb\tccc", '', '', ''])
3047 let a=getline(1)
3048 norm! 2gg0
3049 exe "norm! a\<c-r>=a\<cr>"
3050 norm! 3gg0
3051 exe "norm! a\<c-r>\<c-r>=a\<cr>"
3052 norm! 4gg0
3053 exe "norm! a\<c-r>\<c-o>=a\<cr>"
3054 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
3055
3056 " clean up
3057 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02003058 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003059endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003060
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003061" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003062func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003063 call Setup_NewWindow()
3064 call assert_equal(5, &scroll)
3065 exe "norm! \<c-d>"
3066 call assert_equal('6', getline('.'))
3067 exe "norm! 2\<c-d>"
3068 call assert_equal('8', getline('.'))
3069 call assert_equal(2, &scroll)
3070 set scroll=5
3071 exe "norm! \<c-u>"
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003072 call assert_equal('3', getline('w0'))
3073 call assert_equal('8', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003074 1
3075 set scrolloff=5
3076 exe "norm! \<c-d>"
3077 call assert_equal('10', getline('.'))
3078 exe "norm! \<c-u>"
3079 call assert_equal('5', getline('.'))
3080 1
3081 set scrolloff=99
3082 exe "norm! \<c-d>"
3083 call assert_equal('10', getline('.'))
3084 set scrolloff=0
3085 100
3086 exe "norm! $\<c-u>"
3087 call assert_equal('95', getline('.'))
3088 call assert_equal([0, 95, 1, 0, 1], getcurpos())
3089 100
3090 set nostartofline
3091 exe "norm! $\<c-u>"
3092 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00003093 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003094 " cleanup
3095 set startofline
3096 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003097endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003098
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003099func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003100 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003101 " The ~ register does not exist
3102 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003103 return
3104 endif
3105
3106 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003107 " unfortunately, without a gui, we can't really test much here,
3108 " so simply test that ~p fails (which uses the drop register)
3109 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003110 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003111 call assert_equal([], getreg('~', 1, 1))
3112 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003113 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003114 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003115endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003116
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003117func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003118 new
3119 " How to test this?
3120 " let's just for now test, that the buffer
3121 " does not change
3122 call feedkeys("\<c-s>", 't')
3123 call assert_equal([''], getline(1,'$'))
3124
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003125 " no valid commands
3126 exe "norm! \<char-0x100>"
3127 call assert_equal([''], getline(1,'$'))
3128
3129 exe "norm! ä"
3130 call assert_equal([''], getline(1,'$'))
3131
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003132 " clean up
3133 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003134endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003135
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003136func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003137 " This was causing a crash or ml_get error.
3138 enew!
3139 call setline(1,'xxx')
3140 normal $
3141 new
3142 call setline(1, range(1,2))
3143 2
3144 exe "norm \<C-V>$"
3145 bw!
3146 norm yp
3147 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003148endfunc
3149
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003150func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003151 new
3152 exe "norm! \<c-w>c"
3153 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003154 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003155endfunc
3156
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003157func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003158 new
3159 call setline(1, 'one two three four five six seven eight nine ten')
3160 1
3161 norm! 3d2w
3162 call assert_equal('seven eight nine ten', getline(1))
3163 bw!
3164endfunc
3165
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003166func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003167 CheckFeature timers
3168 CheckFeature cmdline_hist
Bram Moolenaarc255b782022-11-26 19:16:48 +00003169
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003170 func! DoTimerWork(id)
Sean Dewar1fb41032023-08-16 17:15:05 +01003171 call assert_equal(1, getbufinfo('')[0].command)
Bram Moolenaarc255b782022-11-26 19:16:48 +00003172
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003173 " should fail, with E11, but does fail with E23?
3174 "call feedkeys("\<c-^>", 'tm')
3175
Bram Moolenaarc255b782022-11-26 19:16:48 +00003176 " should fail with E11 - "Invalid in command-line window"
Bram Moolenaare2e40752020-09-04 21:18:46 +02003177 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaarc255b782022-11-26 19:16:48 +00003178
3179 " Return from commandline window.
3180 call feedkeys("\<CR>", 't')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003181 endfunc
3182
3183 let oldlang=v:lang
3184 lang C
3185 set updatetime=20
3186 call timer_start(100, 'DoTimerWork')
3187 try
3188 " throws E23, for whatever reason...
3189 call feedkeys('q:', 'x!')
3190 catch /E23/
3191 " no-op
3192 endtry
Bram Moolenaarc255b782022-11-26 19:16:48 +00003193
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003194 " clean up
Bram Moolenaarc255b782022-11-26 19:16:48 +00003195 delfunc DoTimerWork
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003196 set updatetime=4000
3197 exe "lang" oldlang
3198 bw!
3199endfunc
3200
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003201func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003202 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003203 " Don't sleep after the warning message.
3204 call test_settime(1)
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01003205 call writefile(['foo'], 'Xreadonly.log', 'D')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003206 new Xreadonly.log
3207 setl ro
3208 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003209 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003210 call assert_equal(['foo'], getline(1,'$'))
3211 call assert_equal('Xreadonly.log', bufname(''))
3212
3213 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003214 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003215 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003216endfunc
3217
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003218func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003219 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003220 new
3221 call setline(1, 'abcde fghij klmnopq')
3222 norm! 1gg$
3223 set rl
3224 call assert_equal(19, col('.'))
3225 call feedkeys('l', 'tx')
3226 call assert_equal(18, col('.'))
3227 call feedkeys('h', 'tx')
3228 call assert_equal(19, col('.'))
3229 call feedkeys("\<right>", 'tx')
3230 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003231 call feedkeys("\<left>", 'tx')
3232 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003233 call feedkeys("\<s-right>", 'tx')
3234 call assert_equal(13, col('.'))
3235 call feedkeys("\<c-right>", 'tx')
3236 call assert_equal(7, col('.'))
3237 call feedkeys("\<c-left>", 'tx')
3238 call assert_equal(13, col('.'))
3239 call feedkeys("\<s-left>", 'tx')
3240 call assert_equal(19, col('.'))
3241 call feedkeys("<<", 'tx')
3242 call assert_equal(' abcde fghij klmnopq',getline(1))
3243 call feedkeys(">>", 'tx')
3244 call assert_equal('abcde fghij klmnopq',getline(1))
3245
3246 " cleanup
3247 set norl
3248 bw!
3249endfunc
3250
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003251func Test_normal54_Ctrl_bsl()
3252 new
3253 call setline(1, 'abcdefghijklmn')
3254 exe "norm! df\<c-\>\<c-n>"
3255 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3256 exe "norm! df\<c-\>\<c-g>"
3257 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3258 exe "norm! df\<c-\>m"
3259 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003260
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003261 call setline(2, 'abcdefghijklmnāf')
3262 norm! 2gg0
3263 exe "norm! df\<Char-0x101>"
3264 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3265 norm! 1gg0
3266 exe "norm! df\<esc>"
3267 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003268
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003269 " clean up
3270 bw!
3271endfunc
3272
3273func Test_normal_large_count()
3274 " This may fail with 32bit long, how do we detect that?
3275 new
3276 normal o
3277 normal 6666666666dL
3278 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003279endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003280
3281func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003282 new
3283 normal grádv}
3284 call assert_equal('á', getline(1))
3285 normal grád}
3286 call assert_equal('', getline(1))
3287 bwipe!
3288endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003289
3290" Test for the gr (virtual replace) command
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003291func Test_gr_command()
3292 enew!
zeertzjq4f026ea2023-02-26 14:47:24 +00003293 " Test for the bug fixed by 7.4.387
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003294 let save_cpo = &cpo
3295 call append(0, ['First line', 'Second line', 'Third line'])
3296 exe "normal i\<C-G>u"
3297 call cursor(2, 1)
3298 set cpo-=X
3299 normal 4gro
3300 call assert_equal('oooond line', getline(2))
3301 undo
3302 set cpo+=X
3303 normal 4gro
3304 call assert_equal('ooooecond line', getline(2))
3305 let &cpo = save_cpo
zeertzjq4f026ea2023-02-26 14:47:24 +00003306
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003307 normal! ggvegrx
3308 call assert_equal('xxxxx line', getline(1))
3309 exe "normal! gggr\<C-V>122"
3310 call assert_equal('zxxxx line', getline(1))
zeertzjq4f026ea2023-02-26 14:47:24 +00003311
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003312 set virtualedit=all
3313 normal! 15|grl
3314 call assert_equal('zxxxx line l', getline(1))
3315 set virtualedit&
3316 set nomodifiable
3317 call assert_fails('normal! grx', 'E21:')
3318 call assert_fails('normal! gRx', 'E21:')
zeertzjq4f026ea2023-02-26 14:47:24 +00003319 call assert_nobeep("normal! gr\<Esc>")
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003320 set modifiable&
zeertzjq4f026ea2023-02-26 14:47:24 +00003321
3322 call assert_nobeep("normal! gr\<Esc>")
zeertzjqf86dea82023-03-05 21:15:06 +00003323 call assert_nobeep("normal! cgr\<Esc>")
3324 call assert_beeps("normal! cgrx")
zeertzjq4f026ea2023-02-26 14:47:24 +00003325
3326 call assert_equal('zxxxx line l', getline(1))
3327 exe "normal! 2|gr\<C-V>\<Esc>"
3328 call assert_equal("z\<Esc>xx line l", getline(1))
3329
3330 call setline(1, 'abcdef')
3331 exe "normal! 0gr\<C-O>lx"
3332 call assert_equal("\<C-O>def", getline(1))
3333
3334 call setline(1, 'abcdef')
3335 exe "normal! 0gr\<C-G>lx"
3336 call assert_equal("\<C-G>def", getline(1))
3337
3338 bwipe!
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003339endfunc
3340
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003341func Test_nv_hat_count()
3342 %bwipeout!
3343 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003344 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003345
3346 edit Xfoo
3347 let l:foo_nr = bufnr('Xfoo')
3348
3349 edit Xbar
3350 let l:bar_nr = bufnr('Xbar')
3351
3352 " Make sure we are not just using the alternate file.
3353 edit Xbaz
3354
3355 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3356 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3357
3358 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3359 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3360
3361 %bwipeout!
3362endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003363
3364func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003365 " Make sure no buffers are changed.
3366 %bwipe!
3367
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003368 exe "normal \<C-C>"
3369 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003370
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003371 new
3372 cal setline(1, 'hi!')
3373 exe "normal \<C-C>"
3374 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003375
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003376 bwipe!
3377endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003378
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01003379func Test_mode_updated_after_ctrl_c()
3380 CheckScreendump
3381
3382 let buf = RunVimInTerminal('', {'rows': 5})
3383 call term_sendkeys(buf, "i")
3384 call term_sendkeys(buf, "\<C-O>")
3385 " wait a moment so that the "-- (insert) --" message is displayed
3386 call TermWait(buf, 50)
3387 call term_sendkeys(buf, "\<C-C>")
3388 call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
3389
3390 call StopVimInTerminal(buf)
3391endfunc
3392
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003393" Test for '[m', ']m', '[M' and ']M'
3394" Jumping to beginning and end of methods in Java-like languages
3395func Test_java_motion()
3396 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003397 call assert_beeps('normal! [m')
3398 call assert_beeps('normal! ]m')
3399 call assert_beeps('normal! [M')
3400 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003401 let lines =<< trim [CODE]
3402 Piece of Java
3403 {
3404 tt m1 {
3405 t1;
3406 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003407
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003408 tt m2 {
3409 t2;
3410 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003411
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003412 tt m3 {
3413 if (x)
3414 {
3415 t3;
3416 }
3417 } e3
3418 }
3419 [CODE]
3420 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003421
3422 normal gg
3423
3424 normal 2]maA
3425 call assert_equal("\ttt m1 {A", getline('.'))
3426 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3427
3428 normal j]maB
3429 call assert_equal("\ttt m2 {B", getline('.'))
3430 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3431
3432 normal ]maC
3433 call assert_equal("\ttt m3 {C", getline('.'))
3434 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3435
3436 normal [maD
3437 call assert_equal("\ttt m3 {DC", getline('.'))
3438 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3439
3440 normal k2[maE
3441 call assert_equal("\ttt m1 {EA", getline('.'))
3442 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3443
3444 normal 3[maF
3445 call assert_equal("{F", getline('.'))
3446 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3447
3448 normal ]MaG
3449 call assert_equal("\t}G e1", getline('.'))
3450 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3451
3452 normal j2]MaH
3453 call assert_equal("\t}H e3", getline('.'))
3454 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3455
3456 normal ]M]M
3457 normal aI
3458 call assert_equal("}I", getline('.'))
3459 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3460
3461 normal 2[MaJ
3462 call assert_equal("\t}JH e3", getline('.'))
3463 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3464
3465 normal k[MaK
3466 call assert_equal("\t}K e2", getline('.'))
3467 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3468
3469 normal 3[MaL
3470 call assert_equal("{LF", getline('.'))
3471 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3472
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003473 call cursor(2, 1)
3474 call assert_beeps('norm! 5]m')
3475
3476 " jumping to a method in a fold should open the fold
3477 6,10fold
3478 call feedkeys("gg3]m", 'xt')
3479 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3480 call assert_equal(-1, foldclosedend(7))
3481
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003482 bwipe!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003483endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003484
Bram Moolenaar004a6782020-04-11 17:09:31 +02003485" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003486func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003487 call Setup_NewWindow()
3488 " Make long lines that will wrap
3489 %s/$/\=repeat(' foobar', 10)/
3490 20vsp
3491 set wrap
3492 " Test for g$ with count
3493 norm! gg
3494 norm! 0vg$y
3495 call assert_equal(20, col("'>"))
3496 call assert_equal('1 foobar foobar foob', getreg(0))
3497 norm! gg
3498 norm! 0v4g$y
3499 call assert_equal(72, col("'>"))
3500 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3501 norm! gg
3502 norm! 0v6g$y
3503 call assert_equal(40, col("'>"))
3504 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3505 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3506 set nowrap
3507 " clean up
3508 norm! gg
3509 norm! 0vg$y
3510 call assert_equal(20, col("'>"))
3511 call assert_equal('1 foobar foobar foob', getreg(0))
3512 norm! gg
3513 norm! 0v4g$y
3514 call assert_equal(20, col("'>"))
3515 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3516 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3517 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3518 \ '4 foobar foobar foob', getreg(0))
3519 norm! gg
3520 norm! 0v6g$y
3521 call assert_equal(20, col("'>"))
3522 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3523 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3524 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3525 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3526 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3527 \ '6 foobar foobar foob', getreg(0))
3528 " Move to last line, also down movement is not possible, should still move
3529 " the cursor to the last visible char
3530 norm! G
3531 norm! 0v6g$y
3532 call assert_equal(20, col("'>"))
3533 call assert_equal('100 foobar foobar fo', getreg(0))
3534 bw!
3535endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003536
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003537func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003538 " needs 80 column new window
3539 new
3540 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003541 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003542 put =[repeat('x',90)..' {{{1', 'x {{{1']
3543 norm! gk
3544 " In a 80 column wide terminal the window will be only 78 char
3545 " (because Vim will leave space for the other window),
3546 " but if the terminal is larger, it will be 80 chars, so verify the
3547 " cursor column correctly.
3548 call assert_equal(winwidth(0)+1, col('.'))
3549 call assert_equal(winwidth(0)+1, virtcol('.'))
3550 norm! j
3551 call assert_equal(6, col('.'))
3552 call assert_equal(6, virtcol('.'))
3553 norm! gk
3554 call assert_equal(95, col('.'))
3555 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003556 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003557
3558 " needs 80 column new window
3559 new
3560 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003561 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003562 set number
3563 set numberwidth=10
3564 set cpoptions+=n
3565 put =[repeat('0',90), repeat('1',90)]
3566 norm! 075l
3567 call assert_equal(76, col('.'))
3568 norm! gk
3569 call assert_equal(1, col('.'))
3570 norm! gk
3571 call assert_equal(76, col('.'))
3572 norm! gk
3573 call assert_equal(1, col('.'))
3574 norm! gj
3575 call assert_equal(76, col('.'))
3576 norm! gj
3577 call assert_equal(1, col('.'))
3578 norm! gj
3579 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003580 " When 'nowrap' is set, gk and gj behave like k and j
3581 set nowrap
3582 normal! gk
3583 call assert_equal([2, 76], [line('.'), col('.')])
3584 normal! gj
3585 call assert_equal([3, 76], [line('.'), col('.')])
3586 %bw!
3587 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003588endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003589
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003590" Test for using : to run a multi-line Ex command in operator pending mode
3591func Test_normal_yank_with_excmd()
3592 new
3593 call setline(1, ['foo', 'bar', 'baz'])
3594 let @a = ''
3595 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3596 call assert_equal('f', @a)
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003597
3598 bwipe!
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003599endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003600
3601" Test for supplying a count to a normal-mode command across a cursorhold call
3602func Test_normal_cursorhold_with_count()
3603 func s:cHold()
3604 let g:cHold_Called += 1
3605 endfunc
3606 new
3607 augroup normalcHoldTest
3608 au!
3609 au CursorHold <buffer> call s:cHold()
3610 augroup END
3611 let g:cHold_Called = 0
3612 call feedkeys("3\<CursorHold>2ix", 'xt')
3613 call assert_equal(1, g:cHold_Called)
3614 call assert_equal(repeat('x', 32), getline(1))
3615 augroup normalcHoldTest
3616 au!
3617 augroup END
3618 au! normalcHoldTest
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003619
3620 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003621 delfunc s:cHold
3622endfunc
3623
3624" Test for using a count and a command with CTRL-W
3625func Test_wincmd_with_count()
3626 call feedkeys("\<C-W>12n", 'xt')
3627 call assert_equal(12, winheight(0))
3628endfunc
3629
3630" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003631func Test_horiz_motion()
3632 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003633 normal! gg
3634 call assert_beeps('normal! b')
3635 call assert_beeps('normal! B')
3636 call assert_beeps('normal! gE')
3637 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003638 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3639 call setline(1, 'one ,two ,three')
3640 exe "normal! $\<S-BS>"
3641 call assert_equal(11, col('.'))
3642 exe "normal! $\<C-BS>"
3643 call assert_equal(10, col('.'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003644
3645 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003646endfunc
3647
zeertzjq30b6d612023-05-07 17:39:23 +01003648" Test for using a ":" command in operator pending mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003649func Test_normal_colon_op()
3650 new
3651 call setline(1, ['one', 'two'])
3652 call assert_beeps("normal! Gc:d\<CR>")
zeertzjq30b6d612023-05-07 17:39:23 +01003653 call assert_equal(['one'], getline(1, '$'))
3654
3655 call setline(1, ['one…two…three!'])
3656 normal! $
3657 " Using ":" as a movement is characterwise exclusive
3658 call feedkeys("d:normal! F…\<CR>", 'xt')
3659 call assert_equal(['one…two!'], getline(1, '$'))
3660 " Check that redoing a command with 0x80 bytes works
3661 call feedkeys('.', 'xt')
3662 call assert_equal(['one!'], getline(1, '$'))
3663
3664 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3665 " Add this to the command history
3666 call feedkeys(":normal! G0\<CR>", 'xt')
3667 " Use :normal! with control characters in operator pending mode
3668 call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
3669 call assert_equal(['one', 'two', 'five'], getline(1, '$'))
3670 " Check that redoing a command with control characters works
3671 call feedkeys('.', 'xt')
3672 call assert_equal(['five'], getline(1, '$'))
3673
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003674 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003675endfunc
3676
Bram Moolenaar004a6782020-04-11 17:09:31 +02003677" Test for d and D commands
3678func Test_normal_delete_cmd()
3679 new
3680 " D in an empty line
3681 call setline(1, '')
3682 normal D
3683 call assert_equal('', getline(1))
3684 " D in an empty line in virtualedit mode
3685 set virtualedit=all
3686 normal D
3687 call assert_equal('', getline(1))
3688 set virtualedit&
3689 " delete to a readonly register
3690 call setline(1, ['abcd'])
3691 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003692
3693 " D and d with 'nomodifiable'
3694 call setline(1, ['abcd'])
3695 setlocal nomodifiable
3696 call assert_fails('normal D', 'E21:')
3697 call assert_fails('normal d$', 'E21:')
3698
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003699 bwipe!
Bram Moolenaar004a6782020-04-11 17:09:31 +02003700endfunc
3701
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003702" Test for deleting or changing characters across lines with 'whichwrap'
3703" containing 's'. Should count <EOL> as one character.
3704func Test_normal_op_across_lines()
3705 new
3706 set whichwrap&
3707 call setline(1, ['one two', 'three four'])
3708 exe "norm! $3d\<Space>"
3709 call assert_equal(['one twhree four'], getline(1, '$'))
3710
3711 call setline(1, ['one two', 'three four'])
3712 exe "norm! $3c\<Space>x"
3713 call assert_equal(['one twxhree four'], getline(1, '$'))
3714
3715 set whichwrap+=l
3716 call setline(1, ['one two', 'three four'])
3717 exe "norm! $3x"
3718 call assert_equal(['one twhree four'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003719
3720 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003721 set whichwrap&
3722endfunc
3723
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003724" Test for 'w' and 'b' commands
3725func Test_normal_word_move()
3726 new
3727 call setline(1, ['foo bar a', '', 'foo bar b'])
3728 " copy a single character word at the end of a line
3729 normal 1G$yw
3730 call assert_equal('a', @")
3731 " copy a single character word at the end of a file
3732 normal G$yw
3733 call assert_equal('b', @")
3734 " check for a word movement handling an empty line properly
3735 normal 1G$vwy
3736 call assert_equal("a\n\n", @")
3737
3738 " copy using 'b' command
3739 %d
3740 " non-empty blank line at the start of file
3741 call setline(1, [' ', 'foo bar'])
3742 normal 2Gyb
3743 call assert_equal(" \n", @")
3744 " try to copy backwards from the start of the file
3745 call setline(1, ['one two', 'foo bar'])
3746 call assert_beeps('normal ggyb')
3747 " 'b' command should stop at an empty line
3748 call setline(1, ['one two', '', 'foo bar'])
3749 normal 3Gyb
3750 call assert_equal("\n", @")
3751 normal 3Gy2b
3752 call assert_equal("two\n", @")
3753 " 'b' command should not stop at a non-empty blank line
3754 call setline(1, ['one two', ' ', 'foo bar'])
3755 normal 3Gyb
3756 call assert_equal("two\n ", @")
3757
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003758 bwipe!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003759endfunc
3760
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003761" Test for 'scrolloff' with a long line that doesn't fit in the screen
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003762func Test_normal_scrolloff()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003763 10new
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003764 60vnew
3765 call setline(1, ' 1 ' .. repeat('a', 57)
3766 \ .. ' 2 ' .. repeat('b', 57)
3767 \ .. ' 3 ' .. repeat('c', 57)
3768 \ .. ' 4 ' .. repeat('d', 57)
3769 \ .. ' 5 ' .. repeat('e', 57)
3770 \ .. ' 6 ' .. repeat('f', 57)
3771 \ .. ' 7 ' .. repeat('g', 57)
3772 \ .. ' 8 ' .. repeat('h', 57)
3773 \ .. ' 9 ' .. repeat('i', 57)
3774 \ .. '10 ' .. repeat('j', 57)
3775 \ .. '11 ' .. repeat('k', 57)
3776 \ .. '12 ' .. repeat('l', 57)
3777 \ .. '13 ' .. repeat('m', 57)
3778 \ .. '14 ' .. repeat('n', 57)
3779 \ .. '15 ' .. repeat('o', 57)
3780 \ .. '16 ' .. repeat('p', 57)
3781 \ .. '17 ' .. repeat('q', 57)
3782 \ .. '18 ' .. repeat('r', 57)
3783 \ .. '19 ' .. repeat('s', 57)
3784 \ .. '20 ' .. repeat('t', 57)
3785 \ .. '21 ' .. repeat('u', 57)
3786 \ .. '22 ' .. repeat('v', 57)
3787 \ .. '23 ' .. repeat('w', 57)
3788 \ .. '24 ' .. repeat('x', 57)
3789 \ .. '25 ' .. repeat('y', 57)
3790 \ .. '26 ' .. repeat('z', 57)
3791 \ )
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003792 set scrolloff=10
3793 normal gg10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003794 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003795 normal 10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003796 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003797 normal 10gk
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003798 call assert_equal(6, winline())
3799 normal 0
3800 call assert_equal(1, winline())
3801 normal $
3802 call assert_equal(10, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003803
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003804 set scrolloff&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003805 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003806endfunc
3807
3808" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3809func Test_normal_vert_scroll_longline()
3810 10new
3811 80vnew
3812 call setline(1, range(1, 10))
3813 call append(5, repeat('a', 1000))
3814 exe "normal gg\<C-F>"
3815 call assert_equal(6, line('.'))
3816 exe "normal \<C-F>\<C-F>"
3817 call assert_equal(11, line('.'))
3818 call assert_equal(1, winline())
3819 exe "normal \<C-B>"
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003820 call assert_equal(10, line('.'))
3821 call assert_equal(10, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003822 exe "normal \<C-B>\<C-B>"
3823 call assert_equal(5, line('.'))
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003824 call assert_equal(5, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003825
3826 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003827endfunc
3828
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003829" Test for jumping in a file using %
3830func Test_normal_percent_jump()
3831 new
3832 call setline(1, range(1, 100))
3833
3834 " jumping to a folded line should open the fold
3835 25,75fold
3836 call feedkeys('50%', 'xt')
3837 call assert_equal(50, line('.'))
3838 call assert_equal(-1, foldclosedend(50))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003839
3840 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003841endfunc
3842
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003843" Test for << and >> commands to shift text by 'shiftwidth'
3844func Test_normal_shift_rightleft()
3845 new
3846 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3847 set shiftwidth=2 tabstop=8
3848 normal gg6>>
3849 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3850 \ getline(1, '$'))
3851 normal ggVG2>>
3852 call assert_equal([' one', '', "\t ", "\ttwo",
3853 \ "\t three", "\t four"], getline(1, '$'))
3854 normal gg6<<
3855 call assert_equal([' one', '', "\t ", ' two', "\t three",
3856 \ "\t four"], getline(1, '$'))
3857 normal ggVG2<<
3858 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3859 \ getline(1, '$'))
3860 set shiftwidth& tabstop&
3861 bw!
3862endfunc
3863
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003864" Some commands like yy, cc, dd, >>, << and !! accept a count after
3865" typing the first letter of the command.
3866func Test_normal_count_after_operator()
3867 new
3868 setlocal shiftwidth=4 tabstop=8 autoindent
3869 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3870 let @a = ''
3871 normal! j"ay4y
3872 call assert_equal("two\nthree\nfour\nfive\n", @a)
3873 normal! 3G>2>
3874 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3875 \ getline(1, '$'))
3876 exe "normal! 3G0c2cred\nblue"
3877 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3878 \ getline(1, '$'))
3879 exe "normal! gg<8<"
3880 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3881 \ getline(1, '$'))
3882 exe "normal! ggd3d"
3883 call assert_equal(['blue', 'five'], getline(1, '$'))
3884 call setline(1, range(1, 4))
3885 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3886 call assert_equal('".,.+2!', @:)
3887 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3888 call assert_equal('".!', @:)
3889 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3890 call assert_equal('".,$!', @:)
3891 bw!
3892endfunc
3893
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003894func Test_normal_gj_on_extra_wide_char()
3895 new | 25vsp
3896 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3897 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3898 \ ' dreizehn v ierzehn fünfzehn'
3899 put =text
3900 call cursor(2,1)
3901 norm! gj
3902 call assert_equal([0,2,25,0], getpos('.'))
3903 bw!
3904endfunc
3905
Bram Moolenaar03725c52021-11-24 12:17:53 +00003906func Test_normal_count_out_of_range()
3907 new
3908 call setline(1, 'text')
3909 normal 44444444444|
3910 call assert_equal(999999999, v:count)
3911 normal 444444444444|
3912 call assert_equal(999999999, v:count)
3913 normal 4444444444444|
3914 call assert_equal(999999999, v:count)
3915 normal 4444444444444444444|
3916 call assert_equal(999999999, v:count)
3917
3918 normal 9y99999999|
3919 call assert_equal(899999991, v:count)
3920 normal 10y99999999|
3921 call assert_equal(999999999, v:count)
3922 normal 44444444444y44444444444|
3923 call assert_equal(999999999, v:count)
3924 bwipe!
3925endfunc
3926
zeertzjqcdeb6572022-11-15 13:46:12 +00003927" Test that mouse shape is restored to Normal mode after failed "c" operation.
3928func Test_mouse_shape_after_failed_change()
3929 CheckFeature mouseshape
3930 CheckCanRunGui
3931
3932 let lines =<< trim END
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003933 vim9script
zeertzjqcdeb6572022-11-15 13:46:12 +00003934 set mouseshape+=o:busy
3935 setlocal nomodifiable
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003936 var mouse_shapes = []
zeertzjqcdeb6572022-11-15 13:46:12 +00003937
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003938 feedkeys('c')
3939 timer_start(50, (_) => {
3940 mouse_shapes += [getmouseshape()]
3941 timer_start(50, (_) => {
3942 feedkeys('c')
3943 timer_start(50, (_) => {
3944 mouse_shapes += [getmouseshape()]
3945 timer_start(50, (_) => {
3946 writefile(mouse_shapes, 'Xmouseshapes')
3947 quit
3948 })
3949 })
3950 })
3951 })
zeertzjqcdeb6572022-11-15 13:46:12 +00003952 END
3953 call writefile(lines, 'Xmouseshape.vim', 'D')
3954 call RunVim([], [], "-g -S Xmouseshape.vim")
3955 sleep 300m
3956 call assert_equal(['busy', 'arrow'], readfile('Xmouseshapes'))
3957
3958 call delete('Xmouseshapes')
3959endfunc
3960
zeertzjqf86dea82023-03-05 21:15:06 +00003961" Test that mouse shape is restored to Normal mode after cancelling "gr".
3962func Test_mouse_shape_after_cancelling_gr()
3963 CheckFeature mouseshape
3964 CheckCanRunGui
3965
3966 let lines =<< trim END
3967 vim9script
3968 var mouse_shapes = []
3969
3970 feedkeys('gr')
3971 timer_start(50, (_) => {
3972 mouse_shapes += [getmouseshape()]
3973 timer_start(50, (_) => {
3974 feedkeys("\<Esc>")
3975 timer_start(50, (_) => {
3976 mouse_shapes += [getmouseshape()]
3977 timer_start(50, (_) => {
3978 writefile(mouse_shapes, 'Xmouseshapes')
3979 quit
3980 })
3981 })
3982 })
3983 })
3984 END
3985 call writefile(lines, 'Xmouseshape.vim', 'D')
3986 call RunVim([], [], "-g -S Xmouseshape.vim")
3987 sleep 300m
3988 call assert_equal(['beam', 'arrow'], readfile('Xmouseshapes'))
3989
3990 call delete('Xmouseshapes')
3991endfunc
3992
Luuk van Baalaa6ba302023-05-09 16:01:17 +01003993" Test that "j" does not skip lines when scrolling below botline and
3994" 'foldmethod' is not "manual".
3995func Test_normal_j_below_botline()
3996 CheckScreendump
3997
3998 let lines =<< trim END
3999 set number foldmethod=diff scrolloff=0
4000 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
4001 norm Lj
4002 END
4003 call writefile(lines, 'XNormalJBelowBotline', 'D')
4004 let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
4005
4006 call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
4007
4008 call StopVimInTerminal(buf)
4009endfunc
4010
Christian Brabandt2d63e4b2023-08-12 00:03:57 +02004011" Test for r (replace) command with CTRL_V and CTRL_Q
4012func Test_normal_r_ctrl_v_cmd()
4013 new
4014 call append(0, 'This is a simple test: abcd')
4015 exe "norm! 1gg$r\<C-V>\<C-V>"
4016 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4017 exe "norm! 1gg$hr\<C-Q>\<C-Q>"
4018 call assert_equal(['This is a simple test: ab', ''], getline(1,'$'))
4019 exe "norm! 1gg$2hr\<C-V>x7e"
4020 call assert_equal(['This is a simple test: a~', ''], getline(1,'$'))
4021 exe "norm! 1gg$3hr\<C-Q>x7e"
4022 call assert_equal(['This is a simple test: ~~', ''], getline(1,'$'))
4023
4024 if &encoding == 'utf-8'
4025 exe "norm! 1gg$4hr\<C-V>u20ac"
4026 call assert_equal(['This is a simple test:€~~', ''], getline(1,'$'))
4027 exe "norm! 1gg$5hr\<C-Q>u20ac"
4028 call assert_equal(['This is a simple test€€~~', ''], getline(1,'$'))
4029 exe "norm! 1gg0R\<C-V>xff WAS \<esc>"
4030 call assert_equal(['ÿ WAS a simple test€€~~', ''], getline(1,'$'))
4031 exe "norm! 1gg0elR\<C-Q>xffNOT\<esc>"
4032 call assert_equal(['ÿ WASÿNOT simple test€€~~', ''], getline(1,'$'))
4033 endif
4034
4035 call setline(1, 'This is a simple test: abcd')
4036 exe "norm! 1gg$gr\<C-V>\<C-V>"
4037 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4038 exe "norm! 1gg$hgr\<C-Q>\<C-Q>"
4039 call assert_equal(['This is a simple test: ab ', ''], getline(1,'$'))
4040 exe "norm! 1gg$2hgr\<C-V>x7e"
4041 call assert_equal(['This is a simple test: a~ ', ''], getline(1,'$'))
4042 exe "norm! 1gg$3hgr\<C-Q>x7e"
4043 call assert_equal(['This is a simple test: ~~ ', ''], getline(1,'$'))
4044
4045 " clean up
4046 bw!
4047endfunc
4048
zeertzjqb25dbb32023-08-13 18:11:05 +02004049" Test clicking on a TAB or an unprintable character in Normal mode
4050func Test_normal_click_on_ctrl_char()
4051 let save_mouse = &mouse
4052 set mouse=a
4053 new
4054
4055 call setline(1, "a\<Tab>b\<C-K>c")
4056 redraw
4057 call test_setmouse(1, 1)
4058 call feedkeys("\<LeftMouse>", 'xt')
4059 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4060 call test_setmouse(1, 2)
4061 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004062 call assert_equal([0, 1, 2, 0, 2], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004063 call test_setmouse(1, 3)
4064 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004065 call assert_equal([0, 1, 2, 0, 3], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004066 call test_setmouse(1, 7)
4067 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004068 call assert_equal([0, 1, 2, 0, 7], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004069 call test_setmouse(1, 8)
4070 call feedkeys("\<LeftMouse>", 'xt')
4071 call assert_equal([0, 1, 2, 0, 8], getcurpos())
4072 call test_setmouse(1, 9)
4073 call feedkeys("\<LeftMouse>", 'xt')
4074 call assert_equal([0, 1, 3, 0, 9], getcurpos())
4075 call test_setmouse(1, 10)
4076 call feedkeys("\<LeftMouse>", 'xt')
4077 call assert_equal([0, 1, 4, 0, 10], getcurpos())
4078 call test_setmouse(1, 11)
4079 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004080 call assert_equal([0, 1, 4, 0, 11], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004081 call test_setmouse(1, 12)
4082 call feedkeys("\<LeftMouse>", 'xt')
4083 call assert_equal([0, 1, 5, 0, 12], getcurpos())
4084 call test_setmouse(1, 13)
4085 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004086 call assert_equal([0, 1, 5, 0, 13], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004087
4088 bwipe!
4089 let &mouse = save_mouse
4090endfunc
4091
zeertzjq99941602023-08-19 13:08:50 +02004092" Test clicking on a double-width character in Normal mode
4093func Test_normal_click_on_double_width_char()
4094 let save_mouse = &mouse
4095 set mouse=a
4096 new
4097
4098 call setline(1, "口口")
4099 redraw
4100 call test_setmouse(1, 1)
4101 call feedkeys("\<LeftMouse>", 'xt')
4102 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4103 call test_setmouse(1, 2)
4104 call feedkeys("\<LeftMouse>", 'xt')
4105 call assert_equal([0, 1, 1, 0, 2], getcurpos())
4106 call test_setmouse(1, 3)
4107 call feedkeys("\<LeftMouse>", 'xt')
4108 call assert_equal([0, 1, 4, 0, 3], getcurpos())
4109 call test_setmouse(1, 4)
4110 call feedkeys("\<LeftMouse>", 'xt')
4111 call assert_equal([0, 1, 4, 0, 4], getcurpos())
4112
4113 bwipe!
4114 let &mouse = save_mouse
4115endfunc
4116
zeertzjq03cd6972023-09-20 20:08:40 +02004117func Test_normal_click_on_empty_line()
4118 let save_mouse = &mouse
4119 set mouse=a
4120 botright new
4121 call setline(1, ['', '', ''])
4122 let row = win_screenpos(0)[0] + 2
4123 20vsplit
4124 redraw
4125
4126 call test_setmouse(row, 1)
4127 call feedkeys("\<LeftMouse>", 'xt')
4128 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4129 call test_setmouse(row, 2)
4130 call feedkeys("\<LeftMouse>", 'xt')
4131 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4132 call test_setmouse(row, 10)
4133 call feedkeys("\<LeftMouse>", 'xt')
4134 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4135
4136 call test_setmouse(row, 21 + 1)
4137 call feedkeys("\<LeftMouse>", 'xt')
4138 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4139 call test_setmouse(row, 21 + 2)
4140 call feedkeys("\<LeftMouse>", 'xt')
4141 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4142 call test_setmouse(row, 21 + 10)
4143 call feedkeys("\<LeftMouse>", 'xt')
4144 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4145
4146 bwipe!
4147 let &mouse = save_mouse
4148endfunc
4149
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004150func Test_normal33_g_cmd_nonblank()
zeertzjq654bdbb2023-08-20 18:24:20 +02004151 " Test that g<End> goes to the last non-blank char and g$ to the last
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004152 " visible column
4153 20vnew
4154 setlocal nowrap nonumber signcolumn=no
4155 call setline(1, ['fooo fooo fooo fooo fooo fooo fooo fooo '])
zeertzjq654bdbb2023-08-20 18:24:20 +02004156 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004157 call assert_equal(11, col('.'))
4158 normal 0g$
4159 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004160 exe "normal 0g\<kEnd>"
4161 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004162 setlocal wrap
zeertzjq654bdbb2023-08-20 18:24:20 +02004163 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004164 call assert_equal(11, col('.'))
4165 normal 0g$
4166 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004167 exe "normal 0g\<kEnd>"
4168 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004169 bw!
4170endfunc
4171
Christian Brabandt58f9bef2023-11-14 21:02:30 +01004172func Test_normal34_zet_large()
4173 " shouldn't cause overflow
4174 norm! z9765405999999999999
4175endfunc
4176
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004177" Test for { and } paragraph movements and Ctrl-B in buffer with a single line
4178func Test_single_line_scroll()
4179 CheckFeature textprop
Gary Johnson9e6549d2023-12-27 19:12:43 +01004180
4181 new
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004182 call setline(1, ['foobar one two three'])
4183 let vt = 'virt_above'
4184 call prop_type_add(vt, {'highlight': 'IncSearch'})
4185 call prop_add(1, 0, {'type': vt, 'text': '---', 'text_align': 'above'})
Gary Johnson9e6549d2023-12-27 19:12:43 +01004186 1
4187 norm! 0}
4188
4189 call assert_equal([0, 1, 20, 0], getpos('.'))
4190 norm! {
4191 call assert_equal([0, 1, 1, 0], getpos('.'))
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004192
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004193 " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004194 set smoothscroll
4195 exe "normal \<C-E>"
4196 call assert_notequal(0, winsaveview().skipcol)
4197 exe "normal \<C-B>"
4198 call assert_equal(0, winsaveview().skipcol)
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004199 exe "normal \<C-E>"
4200 call assert_notequal(0, winsaveview().skipcol)
4201 exe "normal \<C-U>"
4202 call assert_equal(0, winsaveview().skipcol)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004203
4204 set smoothscroll&
Gary Johnson9e6549d2023-12-27 19:12:43 +01004205 bw!
4206endfunc
4207
Christian Brabandt5d5cbb22024-01-05 18:19:52 +01004208" vim: shiftwidth=2 sts=2 expandtab nofoldenable