blob: b18063747b0e0a17df2987c7d1ecac0939ec59d1 [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')
133 call assert_equal([0, 2, 1, 0], getpos("'<"))
134 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>"
915 call assert_equal('92', getline('.'))
916 call assert_equal([0, 92, 1, 0, 1], getcurpos())
917 100
918 set nostartofline
919 exe "norm! $\<c-b>"
920 call assert_equal('92', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +0000921 call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200922 " cleanup
923 set startofline
924 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200925endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200926
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100927func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200928 10new
929 norm oxxxxxxx
930 exe "norm 2\<c-f>"
931 " check with valgrind that cursor is put back in column 1
932 exe "norm 2\<c-b>"
933 bw!
934endfunc
935
Bram Moolenaar1671f442020-03-10 07:48:13 +0100936" Test for errors with z command
937func Test_normal_z_error()
938 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200939 call assert_beeps('normal! zq')
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000940 call assert_beeps('normal! cz1')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100941endfunc
942
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100943func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200944 " basic test for z commands that scroll the window
945 call Setup_NewWindow()
946 100
947 norm! >>
948 " Test for z<cr>
949 exe "norm! z\<cr>"
950 call assert_equal(' 100', getline('.'))
951 call assert_equal(100, winsaveview()['topline'])
952 call assert_equal([0, 100, 2, 0, 9], getcurpos())
953
954 " Test for zt
955 21
956 norm! >>0zt
957 call assert_equal(' 21', getline('.'))
958 call assert_equal(21, winsaveview()['topline'])
959 call assert_equal([0, 21, 1, 0, 8], getcurpos())
960
961 " Test for zb
962 30
963 norm! >>$ztzb
964 call assert_equal(' 30', getline('.'))
965 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
naohiro ono56200ee2022-01-01 14:59:44 +0000966 call assert_equal([0, 30, 3, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200967
968 " Test for z-
969 1
970 30
971 norm! 0z-
972 call assert_equal(' 30', getline('.'))
973 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
974 call assert_equal([0, 30, 2, 0, 9], getcurpos())
975
976 " Test for z{height}<cr>
977 call assert_equal(10, winheight(0))
978 exe "norm! z12\<cr>"
979 call assert_equal(12, winheight(0))
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000980 exe "norm! z15\<Del>0\<cr>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200981 call assert_equal(10, winheight(0))
982
983 " Test for z.
984 1
985 21
986 norm! 0z.
987 call assert_equal(' 21', getline('.'))
988 call assert_equal(17, winsaveview()['topline'])
989 call assert_equal([0, 21, 2, 0, 9], getcurpos())
990
991 " Test for zz
992 1
993 21
994 norm! 0zz
995 call assert_equal(' 21', getline('.'))
996 call assert_equal(17, winsaveview()['topline'])
997 call assert_equal([0, 21, 1, 0, 8], getcurpos())
998
999 " Test for z+
1000 11
1001 norm! zt
1002 norm! z+
1003 call assert_equal(' 21', getline('.'))
1004 call assert_equal(21, winsaveview()['topline'])
1005 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1006
1007 " Test for [count]z+
1008 1
1009 norm! 21z+
1010 call assert_equal(' 21', getline('.'))
1011 call assert_equal(21, winsaveview()['topline'])
1012 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1013
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001014 " Test for z+ with [count] greater than buffer size
1015 1
1016 norm! 1000z+
1017 call assert_equal(' 100', getline('.'))
1018 call assert_equal(100, winsaveview()['topline'])
1019 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1020
1021 " Test for z+ from the last buffer line
1022 norm! Gz.z+
1023 call assert_equal(' 100', getline('.'))
1024 call assert_equal(100, winsaveview()['topline'])
1025 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1026
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001027 " Test for z^
1028 norm! 22z+0
1029 norm! z^
1030 call assert_equal(' 21', getline('.'))
1031 call assert_equal(12, winsaveview()['topline'])
1032 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1033
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001034 " Test for z^ from first buffer line
1035 norm! ggz^
1036 call assert_equal('1', getline('.'))
1037 call assert_equal(1, winsaveview()['topline'])
1038 call assert_equal([0, 1, 1, 0, 1], getcurpos())
1039
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001040 " Test for [count]z^
1041 1
1042 norm! 30z^
1043 call assert_equal(' 21', getline('.'))
1044 call assert_equal(12, winsaveview()['topline'])
1045 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1046
1047 " cleanup
1048 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001049endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001050
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001051func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001052 " basic test for z commands that scroll the window
1053 10new
1054 15vsp
1055 set nowrap listchars=
1056 let lineA='abcdefghijklmnopqrstuvwxyz'
1057 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1058 $put =lineA
1059 $put =lineB
1060 1d
1061
Bram Moolenaar1671f442020-03-10 07:48:13 +01001062 " Test for zl and zh with a count
1063 norm! 0z10l
1064 call assert_equal([11, 1], [col('.'), wincol()])
1065 norm! z4h
1066 call assert_equal([11, 5], [col('.'), wincol()])
1067 normal! 2gg
1068
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001069 " Test for zl
1070 1
1071 norm! 5zl
1072 call assert_equal(lineA, getline('.'))
1073 call assert_equal(6, col('.'))
1074 call assert_equal(5, winsaveview()['leftcol'])
1075 norm! yl
1076 call assert_equal('f', @0)
1077
1078 " Test for zh
1079 norm! 2zh
1080 call assert_equal(lineA, getline('.'))
1081 call assert_equal(6, col('.'))
1082 norm! yl
1083 call assert_equal('f', @0)
1084 call assert_equal(3, winsaveview()['leftcol'])
1085
1086 " Test for zL
1087 norm! zL
1088 call assert_equal(11, col('.'))
1089 norm! yl
1090 call assert_equal('k', @0)
1091 call assert_equal(10, winsaveview()['leftcol'])
1092 norm! 2zL
1093 call assert_equal(25, col('.'))
1094 norm! yl
1095 call assert_equal('y', @0)
1096 call assert_equal(24, winsaveview()['leftcol'])
1097
1098 " Test for zH
1099 norm! 2zH
1100 call assert_equal(25, col('.'))
1101 call assert_equal(10, winsaveview()['leftcol'])
1102 norm! yl
1103 call assert_equal('y', @0)
1104
1105 " Test for zs
1106 norm! $zs
1107 call assert_equal(26, col('.'))
1108 call assert_equal(25, winsaveview()['leftcol'])
1109 norm! yl
1110 call assert_equal('z', @0)
1111
1112 " Test for ze
1113 norm! ze
1114 call assert_equal(26, col('.'))
1115 call assert_equal(11, winsaveview()['leftcol'])
1116 norm! yl
1117 call assert_equal('z', @0)
1118
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001119 " Test for zs and ze with folds
1120 %fold
1121 norm! $zs
1122 call assert_equal(26, col('.'))
1123 call assert_equal(0, winsaveview()['leftcol'])
1124 norm! yl
1125 call assert_equal('z', @0)
1126 norm! ze
1127 call assert_equal(26, col('.'))
1128 call assert_equal(0, winsaveview()['leftcol'])
1129 norm! yl
1130 call assert_equal('z', @0)
1131
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001132 " cleanup
1133 set wrap listchars=eol:$
1134 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001135endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001136
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001137func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001138 " basic test for z commands that scroll the window
1139 " using 'sidescrolloff' setting
1140 10new
1141 20vsp
1142 set nowrap listchars= sidescrolloff=5
1143 let lineA='abcdefghijklmnopqrstuvwxyz'
1144 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1145 $put =lineA
1146 $put =lineB
1147 1d
1148
1149 " Test for zl
1150 1
1151 norm! 5zl
1152 call assert_equal(lineA, getline('.'))
1153 call assert_equal(11, col('.'))
1154 call assert_equal(5, winsaveview()['leftcol'])
1155 norm! yl
1156 call assert_equal('k', @0)
1157
1158 " Test for zh
1159 norm! 2zh
1160 call assert_equal(lineA, getline('.'))
1161 call assert_equal(11, col('.'))
1162 norm! yl
1163 call assert_equal('k', @0)
1164 call assert_equal(3, winsaveview()['leftcol'])
1165
1166 " Test for zL
1167 norm! 0zL
1168 call assert_equal(16, col('.'))
1169 norm! yl
1170 call assert_equal('p', @0)
1171 call assert_equal(10, winsaveview()['leftcol'])
1172 norm! 2zL
1173 call assert_equal(26, col('.'))
1174 norm! yl
1175 call assert_equal('z', @0)
1176 call assert_equal(15, winsaveview()['leftcol'])
1177
1178 " Test for zH
1179 norm! 2zH
1180 call assert_equal(15, col('.'))
1181 call assert_equal(0, winsaveview()['leftcol'])
1182 norm! yl
1183 call assert_equal('o', @0)
1184
1185 " Test for zs
1186 norm! $zs
1187 call assert_equal(26, col('.'))
1188 call assert_equal(20, winsaveview()['leftcol'])
1189 norm! yl
1190 call assert_equal('z', @0)
1191
1192 " Test for ze
1193 norm! ze
1194 call assert_equal(26, col('.'))
1195 call assert_equal(11, winsaveview()['leftcol'])
1196 norm! yl
1197 call assert_equal('z', @0)
1198
1199 " cleanup
1200 set wrap listchars=eol:$ sidescrolloff=0
1201 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001202endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001203
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001204" Test for commands that scroll the window horizontally. Test with folds.
1205" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1206func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001207 15new
1208 call setline(1, range(1, 100))
1209 exe "normal! 30ggz\<CR>"
1210 set foldenable
1211 33,36fold
1212 40,43fold
1213 46,49fold
1214 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001215
1216 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001217 " Top of the screen = 30
1218 " Folded lines = 9
1219 " Bottom of the screen = 30 + h + 9 - 1
1220 normal! 4L
1221 call assert_equal(35 + h, line('.'))
1222 normal! 4H
1223 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001224
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001225 " Test for using a large count value
1226 %d
1227 call setline(1, range(1, 4))
1228 norm! 6H
1229 call assert_equal(4, line('.'))
1230
1231 " Test for 'M' with folded lines
1232 %d
1233 call setline(1, range(1, 20))
1234 1,5fold
1235 norm! LM
1236 call assert_equal(12, line('.'))
1237
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001238 " Test for the CTRL-E and CTRL-Y commands with folds
1239 %d
1240 call setline(1, range(1, 10))
1241 3,5fold
1242 exe "normal 6G3\<C-E>"
1243 call assert_equal(6, line('w0'))
1244 exe "normal 2\<C-Y>"
1245 call assert_equal(2, line('w0'))
1246
1247 " Test for CTRL-Y on a folded line
1248 %d
1249 call setline(1, range(1, 100))
1250 exe (h + 2) .. "," .. (h + 4) .. "fold"
1251 exe h + 5
1252 normal z-
1253 exe "normal \<C-Y>\<C-Y>"
1254 call assert_equal(h + 1, line('w$'))
1255
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001256 " Test for CTRL-Y from the first line and CTRL-E from the last line
1257 %d
1258 set scrolloff=2
1259 call setline(1, range(1, 4))
1260 exe "normal gg\<C-Y>"
1261 call assert_equal(1, line('w0'))
1262 call assert_equal(1, line('.'))
1263 exe "normal G4\<C-E>\<C-E>"
1264 call assert_equal(4, line('w$'))
1265 call assert_equal(4, line('.'))
1266 set scrolloff&
1267
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001268 " Using <PageUp> and <PageDown> in an empty buffer should beep
1269 %d
1270 call assert_beeps('exe "normal \<PageUp>"')
1271 call assert_beeps('exe "normal \<C-B>"')
1272 call assert_beeps('exe "normal \<PageDown>"')
1273 call assert_beeps('exe "normal \<C-F>"')
1274
1275 " Test for <C-U> and <C-D> with fold
1276 %d
1277 call setline(1, range(1, 100))
1278 10,35fold
1279 set scroll=10
1280 exe "normal \<C-D>"
1281 call assert_equal(36, line('.'))
1282 exe "normal \<C-D>"
1283 call assert_equal(46, line('.'))
1284 exe "normal \<C-U>"
1285 call assert_equal(36, line('.'))
1286 exe "normal \<C-U>"
1287 call assert_equal(10, line('.'))
1288 exe "normal \<C-U>"
1289 call assert_equal(1, line('.'))
1290 set scroll&
1291
1292 " Test for scrolling to the top of the file with <C-U> and a fold
1293 10
1294 normal ztL
1295 exe "normal \<C-U>\<C-U>"
1296 call assert_equal(1, line('w0'))
1297
1298 " Test for CTRL-D on a folded line
1299 %d
1300 call setline(1, range(1, 100))
1301 50,100fold
1302 75
1303 normal z-
1304 exe "normal \<C-D>"
1305 call assert_equal(50, line('.'))
1306 call assert_equal(100, line('w$'))
1307 normal z.
1308 let lnum = winline()
1309 exe "normal \<C-D>"
1310 call assert_equal(lnum, winline())
1311 call assert_equal(50, line('.'))
1312 normal zt
1313 exe "normal \<C-D>"
1314 call assert_equal(50, line('w0'))
1315
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001316 " Test for <S-CR>. Page down.
1317 %d
1318 call setline(1, range(1, 100))
1319 call feedkeys("\<S-CR>", 'xt')
1320 call assert_equal(14, line('w0'))
1321 call assert_equal(28, line('w$'))
1322
1323 " Test for <S-->. Page up.
1324 call feedkeys("\<S-->", 'xt')
1325 call assert_equal(1, line('w0'))
1326 call assert_equal(15, line('w$'))
1327
Bram Moolenaar1671f442020-03-10 07:48:13 +01001328 set foldenable&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00001329 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01001330endfunc
1331
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001332func Test_scroll_in_ex_mode()
1333 " This was using invalid memory because w_botline was invalid.
1334 let lines =<< trim END
1335 diffsplit
1336 norm os00(
1337 call writefile(['done'], 'Xdone')
1338 qa!
1339 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001340 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001341 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1342 call assert_equal(['done'], readfile('Xdone'))
1343
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001344 call delete('Xdone')
1345endfunc
1346
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001347" Test for the 'sidescroll' option
1348func Test_sidescroll_opt()
1349 new
1350 20vnew
1351
1352 " scroll by 2 characters horizontally
1353 set sidescroll=2 nowrap
1354 call setline(1, repeat('a', 40))
1355 normal g$l
1356 call assert_equal(19, screenpos(0, 1, 21).col)
1357 normal l
1358 call assert_equal(20, screenpos(0, 1, 22).col)
1359 normal g0h
1360 call assert_equal(2, screenpos(0, 1, 2).col)
1361 call assert_equal(20, screenpos(0, 1, 20).col)
1362
1363 " when 'sidescroll' is 0, cursor positioned at the center
1364 set sidescroll=0
1365 normal g$l
1366 call assert_equal(11, screenpos(0, 1, 21).col)
1367 normal g0h
1368 call assert_equal(10, screenpos(0, 1, 10).col)
1369
1370 %bw!
1371 set wrap& sidescroll&
1372endfunc
1373
Bram Moolenaar004a6782020-04-11 17:09:31 +02001374" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001375func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001376 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001377 call Setup_NewWindow()
1378 50
1379 setl foldenable fdm=marker foldlevel=5
1380
Bram Moolenaar1671f442020-03-10 07:48:13 +01001381 call assert_beeps('normal! zj')
1382 call assert_beeps('normal! zk')
1383
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001384 " Test for zF
1385 " First fold
1386 norm! 4zF
1387 " check that folds have been created
1388 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1389
1390 " Test for zd
1391 51
1392 norm! 2zF
1393 call assert_equal(2, foldlevel('.'))
1394 norm! kzd
1395 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1396 norm! j
1397 call assert_equal(1, foldlevel('.'))
1398
1399 " Test for zD
1400 " also deletes partially selected folds recursively
1401 51
1402 norm! zF
1403 call assert_equal(2, foldlevel('.'))
1404 norm! kV2jzD
1405 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1406
1407 " Test for zE
1408 85
1409 norm! 4zF
1410 86
1411 norm! 2zF
1412 90
1413 norm! 4zF
1414 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1415 norm! zE
1416 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1417
1418 " Test for zn
1419 50
1420 set foldlevel=0
1421 norm! 2zF
1422 norm! zn
1423 norm! k
1424 call assert_equal('49', getline('.'))
1425 norm! j
1426 call assert_equal('50/*{{{*/', getline('.'))
1427 norm! j
1428 call assert_equal('51/*}}}*/', getline('.'))
1429 norm! j
1430 call assert_equal('52', getline('.'))
1431 call assert_equal(0, &foldenable)
1432
1433 " Test for zN
1434 49
1435 norm! zN
1436 call assert_equal('49', getline('.'))
1437 norm! j
1438 call assert_equal('50/*{{{*/', getline('.'))
1439 norm! j
1440 call assert_equal('52', getline('.'))
1441 call assert_equal(1, &foldenable)
1442
1443 " Test for zi
1444 norm! zi
1445 call assert_equal(0, &foldenable)
1446 norm! zi
1447 call assert_equal(1, &foldenable)
1448 norm! zi
1449 call assert_equal(0, &foldenable)
1450 norm! zi
1451 call assert_equal(1, &foldenable)
1452
1453 " Test for za
1454 50
1455 norm! za
1456 norm! k
1457 call assert_equal('49', getline('.'))
1458 norm! j
1459 call assert_equal('50/*{{{*/', getline('.'))
1460 norm! j
1461 call assert_equal('51/*}}}*/', getline('.'))
1462 norm! j
1463 call assert_equal('52', getline('.'))
1464 50
1465 norm! za
1466 norm! k
1467 call assert_equal('49', getline('.'))
1468 norm! j
1469 call assert_equal('50/*{{{*/', getline('.'))
1470 norm! j
1471 call assert_equal('52', getline('.'))
1472
1473 49
1474 norm! 5zF
1475 norm! k
1476 call assert_equal('48', getline('.'))
1477 norm! j
1478 call assert_equal('49/*{{{*/', getline('.'))
1479 norm! j
1480 call assert_equal('55', getline('.'))
1481 49
1482 norm! za
1483 call assert_equal('49/*{{{*/', getline('.'))
1484 norm! j
1485 call assert_equal('50/*{{{*/', getline('.'))
1486 norm! j
1487 call assert_equal('52', getline('.'))
1488 set nofoldenable
1489 " close fold and set foldenable
1490 norm! za
1491 call assert_equal(1, &foldenable)
1492
1493 50
1494 " have to use {count}za to open all folds and make the cursor visible
1495 norm! 2za
1496 norm! 2k
1497 call assert_equal('48', getline('.'))
1498 norm! j
1499 call assert_equal('49/*{{{*/', getline('.'))
1500 norm! j
1501 call assert_equal('50/*{{{*/', getline('.'))
1502 norm! j
1503 call assert_equal('51/*}}}*/', getline('.'))
1504 norm! j
1505 call assert_equal('52', getline('.'))
1506
1507 " Test for zA
1508 49
1509 set foldlevel=0
1510 50
1511 norm! zA
1512 norm! 2k
1513 call assert_equal('48', getline('.'))
1514 norm! j
1515 call assert_equal('49/*{{{*/', getline('.'))
1516 norm! j
1517 call assert_equal('50/*{{{*/', getline('.'))
1518 norm! j
1519 call assert_equal('51/*}}}*/', getline('.'))
1520 norm! j
1521 call assert_equal('52', getline('.'))
1522
Dominique Pelle923dce22021-11-21 11:36:04 +00001523 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001524 50
1525 set nofoldenable
1526 norm! zA
1527 call assert_equal(1, &foldenable)
1528 norm! k
1529 call assert_equal('48', getline('.'))
1530 norm! j
1531 call assert_equal('49/*{{{*/', getline('.'))
1532 norm! j
1533 call assert_equal('55', getline('.'))
1534
1535 " Test for zc
1536 norm! zE
1537 50
1538 norm! 2zF
1539 49
1540 norm! 5zF
1541 set nofoldenable
1542 50
1543 " There most likely is a bug somewhere:
1544 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1545 " TODO: Should this only close the inner most fold or both folds?
1546 norm! zc
1547 call assert_equal(1, &foldenable)
1548 norm! k
1549 call assert_equal('48', getline('.'))
1550 norm! j
1551 call assert_equal('49/*{{{*/', getline('.'))
1552 norm! j
1553 call assert_equal('55', getline('.'))
1554 set nofoldenable
1555 50
1556 norm! Vjzc
1557 norm! k
1558 call assert_equal('48', getline('.'))
1559 norm! j
1560 call assert_equal('49/*{{{*/', getline('.'))
1561 norm! j
1562 call assert_equal('55', getline('.'))
1563
1564 " Test for zC
1565 set nofoldenable
1566 50
1567 norm! zCk
1568 call assert_equal('48', getline('.'))
1569 norm! j
1570 call assert_equal('49/*{{{*/', getline('.'))
1571 norm! j
1572 call assert_equal('55', getline('.'))
1573
1574 " Test for zx
1575 " 1) close folds at line 49-54
1576 set nofoldenable
1577 48
1578 norm! zx
1579 call assert_equal(1, &foldenable)
1580 norm! j
1581 call assert_equal('49/*{{{*/', getline('.'))
1582 norm! j
1583 call assert_equal('55', getline('.'))
1584
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001585 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001586 51
1587 set nofoldenable
1588 norm! zx
1589 call assert_equal(1, &foldenable)
1590 norm! 3k
1591 call assert_equal('48', getline('.'))
1592 norm! j
1593 call assert_equal('49/*{{{*/', getline('.'))
1594 norm! j
1595 call assert_equal('50/*{{{*/', getline('.'))
1596 norm! j
1597 call assert_equal('51/*}}}*/', getline('.'))
1598 norm! j
1599 call assert_equal('52', getline('.'))
1600 norm! j
1601 call assert_equal('53', getline('.'))
1602 norm! j
1603 call assert_equal('54/*}}}*/', getline('.'))
1604 norm! j
1605 call assert_equal('55', getline('.'))
1606
1607 " 3) close one level of folds
1608 48
1609 set nofoldenable
1610 set foldlevel=1
1611 norm! zx
1612 call assert_equal(1, &foldenable)
1613 call assert_equal('48', getline('.'))
1614 norm! j
1615 call assert_equal('49/*{{{*/', getline('.'))
1616 norm! j
1617 call assert_equal('50/*{{{*/', getline('.'))
1618 norm! j
1619 call assert_equal('52', getline('.'))
1620 norm! j
1621 call assert_equal('53', getline('.'))
1622 norm! j
1623 call assert_equal('54/*}}}*/', getline('.'))
1624 norm! j
1625 call assert_equal('55', getline('.'))
1626
1627 " Test for zX
1628 " Close all folds
1629 set foldlevel=0 nofoldenable
1630 50
1631 norm! zX
1632 call assert_equal(1, &foldenable)
1633 norm! k
1634 call assert_equal('48', getline('.'))
1635 norm! j
1636 call assert_equal('49/*{{{*/', getline('.'))
1637 norm! j
1638 call assert_equal('55', getline('.'))
1639
1640 " Test for zm
1641 50
1642 set nofoldenable foldlevel=2
1643 norm! zm
1644 call assert_equal(1, &foldenable)
1645 call assert_equal(1, &foldlevel)
1646 norm! zm
1647 call assert_equal(0, &foldlevel)
1648 norm! zm
1649 call assert_equal(0, &foldlevel)
1650 norm! k
1651 call assert_equal('48', getline('.'))
1652 norm! j
1653 call assert_equal('49/*{{{*/', getline('.'))
1654 norm! j
1655 call assert_equal('55', getline('.'))
1656
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001657 " Test for zm with a count
1658 50
1659 set foldlevel=2
1660 norm! 3zm
1661 call assert_equal(0, &foldlevel)
1662 call assert_equal(49, foldclosed(line('.')))
1663
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001664 " Test for zM
1665 48
1666 set nofoldenable foldlevel=99
1667 norm! zM
1668 call assert_equal(1, &foldenable)
1669 call assert_equal(0, &foldlevel)
1670 call assert_equal('48', getline('.'))
1671 norm! j
1672 call assert_equal('49/*{{{*/', getline('.'))
1673 norm! j
1674 call assert_equal('55', getline('.'))
1675
1676 " Test for zr
1677 48
1678 set nofoldenable foldlevel=0
1679 norm! zr
1680 call assert_equal(0, &foldenable)
1681 call assert_equal(1, &foldlevel)
1682 set foldlevel=0 foldenable
1683 norm! zr
1684 call assert_equal(1, &foldenable)
1685 call assert_equal(1, &foldlevel)
1686 norm! zr
1687 call assert_equal(2, &foldlevel)
1688 call assert_equal('48', getline('.'))
1689 norm! j
1690 call assert_equal('49/*{{{*/', getline('.'))
1691 norm! j
1692 call assert_equal('50/*{{{*/', getline('.'))
1693 norm! j
1694 call assert_equal('51/*}}}*/', getline('.'))
1695 norm! j
1696 call assert_equal('52', getline('.'))
1697
1698 " Test for zR
1699 48
1700 set nofoldenable foldlevel=0
1701 norm! zR
1702 call assert_equal(0, &foldenable)
1703 call assert_equal(2, &foldlevel)
1704 set foldenable foldlevel=0
1705 norm! zR
1706 call assert_equal(1, &foldenable)
1707 call assert_equal(2, &foldlevel)
1708 call assert_equal('48', getline('.'))
1709 norm! j
1710 call assert_equal('49/*{{{*/', getline('.'))
1711 norm! j
1712 call assert_equal('50/*{{{*/', getline('.'))
1713 norm! j
1714 call assert_equal('51/*}}}*/', getline('.'))
1715 norm! j
1716 call assert_equal('52', getline('.'))
1717 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1718 48
1719 call assert_equal('48', getline('.'))
1720 norm! j
1721 call assert_equal('49/*{{{*/', getline('.'))
1722 norm! j
1723 call assert_equal('50/*{{{*/', getline('.'))
1724 norm! j
1725 call assert_equal('a /*{{{*/', getline('.'))
1726 norm! j
1727 call assert_equal('51/*}}}*/', getline('.'))
1728 norm! j
1729 call assert_equal('52', getline('.'))
1730 48
1731 norm! zR
1732 call assert_equal(1, &foldenable)
1733 call assert_equal(3, &foldlevel)
1734 call assert_equal('48', getline('.'))
1735 norm! j
1736 call assert_equal('49/*{{{*/', getline('.'))
1737 norm! j
1738 call assert_equal('50/*{{{*/', getline('.'))
1739 norm! j
1740 call assert_equal('a /*{{{*/', getline('.'))
1741 norm! j
1742 call assert_equal('b /*}}}*/', getline('.'))
1743 norm! j
1744 call assert_equal('51/*}}}*/', getline('.'))
1745 norm! j
1746 call assert_equal('52', getline('.'))
1747
1748 " clean up
1749 setl nofoldenable fdm=marker foldlevel=0
1750 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001751endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001752
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001753func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001754 " Reading from redirected file doesn't work on MS-Windows
1755 CheckNotMSWindows
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001756 call writefile(['1a', 'foo', 'bar', '.', 'w! Xn20file2', 'q!'], 'Xn20script', 'D')
1757 call writefile(['1', '2'], 'Xn20file', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001758 call system(GetVimCommand() .. ' -e -s < Xn20script Xn20file')
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001759 let a = readfile('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001760 call assert_equal(['1', 'foo', 'bar', '2'], a)
1761
1762 " clean up
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001763 call delete('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001764 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001765endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001766
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001767func Test_normal21_nv_hat()
1768
1769 " Edit a fresh file and wipe the buffer list so that there is no alternate
1770 " file present. Next, check for the expected command failures.
1771 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001772 call assert_fails(':buffer #', 'E86:')
1773 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001774 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001775
1776 " Test for the expected behavior when switching between two named buffers.
1777 edit Xfoo | edit Xbar
1778 call feedkeys("\<C-^>", 'tx')
1779 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1780 call feedkeys("\<C-^>", 'tx')
1781 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1782
1783 " Test for the expected behavior when only one buffer is named.
1784 enew | let l:nr = bufnr('%')
1785 call feedkeys("\<C-^>", 'tx')
1786 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1787 call feedkeys("\<C-^>", 'tx')
1788 call assert_equal('', bufname('%'))
1789 call assert_equal(l:nr, bufnr('%'))
1790
1791 " Test that no action is taken by "<C-^>" when an operator is pending.
1792 edit Xfoo
1793 call feedkeys("ci\<C-^>", 'tx')
1794 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1795
1796 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001797endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001798
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001799func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001800 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001801 " let shell = &shell
1802 " let &shell = 'sh'
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001803 call writefile(['1', '2'], 'Xn22file', 'D')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001804 let args = ' -N -i NONE --noplugins -X --not-a-term'
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001805 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xn22file')
1806 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001807 call assert_equal([], a)
1808 " Test for ZQ
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001809 call writefile(['1', '2'], 'Xn22file')
1810 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xn22file')
1811 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001812 call assert_equal(['1', '2'], a)
1813
Bram Moolenaar1671f442020-03-10 07:48:13 +01001814 " Unsupported Z command
1815 call assert_beeps('normal! ZW')
1816
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001817 " clean up
Bram Moolenaar0913a102016-09-03 19:11:59 +02001818 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001819endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001820
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001821func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001822 " Test for K command
1823 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001824 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001825 let k = &keywordprg
1826 set keywordprg=:help
1827 1
1828 norm! VK
1829 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1830 call assert_equal('help', &ft)
1831 call assert_match('\*version8.txt\*', getline('.'))
1832 helpclose
1833 norm! 0K
1834 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1835 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001836 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001837 helpclose
1838
Bram Moolenaar426f3752016-11-04 21:22:37 +01001839 set keywordprg=:new
1840 set iskeyword+=%
1841 set iskeyword+=\|
1842 2
1843 norm! K
1844 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1845 bwipe!
1846 3
1847 norm! K
1848 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1849 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001850 if !has('win32')
1851 4
1852 norm! K
1853 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1854 bwipe!
1855 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001856 set iskeyword-=%
1857 set iskeyword-=\|
1858
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001859 " Test for specifying a count to K
1860 1
1861 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1862 set keywordprg=:Kprog
1863 norm! 3K
1864 call assert_equal('3 version8', g:Kprog_Args)
1865 delcom Kprog
1866
Bram Moolenaar0913a102016-09-03 19:11:59 +02001867 " Only expect "man" to work on Unix
1868 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001869 let &keywordprg = k
1870 bw!
1871 return
1872 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001873
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001874 let not_gnu_man = has('mac') || has('bsd')
1875 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001876 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001877 set keywordprg=man\ -P\ cat
1878 else
1879 set keywordprg=man\ --pager=cat
1880 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001881 " Test for using man
1882 2
1883 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001884 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001885 call assert_match("man -P cat 'man'", a)
1886 else
1887 call assert_match("man --pager=cat 'man'", a)
1888 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001889
Bram Moolenaar1671f442020-03-10 07:48:13 +01001890 " Error cases
1891 call setline(1, '#$#')
1892 call assert_fails('normal! ggK', 'E349:')
1893 call setline(1, '---')
1894 call assert_fails('normal! ggv2lK', 'E349:')
1895 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001896 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001897 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001898 norm! V
1899 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001900
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001901 " clean up
1902 let &keywordprg = k
1903 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001904endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001905
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001906func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001907 " Testing for g?? g?g?
1908 new
1909 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1910 1
1911 norm! g??
1912 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1913 norm! g?g?
1914 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1915
1916 " clean up
1917 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001918endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001919
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001920func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001921 CheckFeature quickfix
1922
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001923 " Testing for CTRL-] g CTRL-] g]
1924 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1925 h
1926 " Test for CTRL-]
1927 call search('\<x\>$')
1928 exe "norm! \<c-]>"
1929 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1930 norm! yiW
1931 call assert_equal("*x*", @0)
1932 exe ":norm \<c-o>"
1933
1934 " Test for g_CTRL-]
1935 call search('\<v_u\>$')
1936 exe "norm! g\<c-]>"
1937 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1938 norm! yiW
1939 call assert_equal("*v_u*", @0)
1940 exe ":norm \<c-o>"
1941
1942 " Test for g]
1943 call search('\<i_<Esc>$')
1944 let a = execute(":norm! g]")
1945 call assert_match('i_<Esc>.*insert.txt', a)
1946
1947 if !empty(exepath('cscope')) && has('cscope')
1948 " setting cscopetag changes how g] works
1949 set cst
1950 exe "norm! g]"
1951 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1952 norm! yiW
1953 call assert_equal("*i_<Esc>*", @0)
1954 exe ":norm \<c-o>"
1955 " Test for CTRL-W g]
1956 exe "norm! \<C-W>g]"
1957 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1958 norm! yiW
1959 call assert_equal("*i_<Esc>*", @0)
1960 call assert_equal(3, winnr('$'))
1961 helpclose
1962 set nocst
1963 endif
1964
1965 " Test for CTRL-W g]
1966 let a = execute("norm! \<C-W>g]")
1967 call assert_match('i_<Esc>.*insert.txt', a)
1968
1969 " Test for CTRL-W CTRL-]
1970 exe "norm! \<C-W>\<C-]>"
1971 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1972 norm! yiW
1973 call assert_equal("*i_<Esc>*", @0)
1974 call assert_equal(3, winnr('$'))
1975 helpclose
1976
1977 " Test for CTRL-W g CTRL-]
1978 exe "norm! \<C-W>g\<C-]>"
1979 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1980 norm! yiW
1981 call assert_equal("*i_<Esc>*", @0)
1982 call assert_equal(3, winnr('$'))
1983 helpclose
1984
1985 " clean up
1986 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001987endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001988
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001989func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001990 " Test for ]p ]P [p and [P
1991 new
1992 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1993 1
1994 /Error/y a
1995 2
1996 norm! "a]pj"a[p
1997 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1998 1
1999 /^\s\{4}/
2000 exe "norm! \"a]P3Eldt'"
2001 exe "norm! j\"a[P2Eldt'"
2002 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
2003
2004 " clean up
2005 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002006endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002007
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002008func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002009 " Test for [' [` ]' ]`
2010 call Setup_NewWindow()
2011 1,21s/.\+/ & b/
2012 1
2013 norm! $ma
2014 5
2015 norm! $mb
2016 10
2017 norm! $mc
2018 15
2019 norm! $md
2020 20
2021 norm! $me
2022
2023 " Test for ['
2024 9
2025 norm! 2['
2026 call assert_equal(' 1 b', getline('.'))
2027 call assert_equal(1, line('.'))
2028 call assert_equal(3, col('.'))
2029
2030 " Test for ]'
2031 norm! ]'
2032 call assert_equal(' 5 b', getline('.'))
2033 call assert_equal(5, line('.'))
2034 call assert_equal(3, col('.'))
2035
zeertzjqcf344342022-07-06 12:57:31 +01002036 " No mark before line 1, cursor moves to first non-blank on current line
2037 1
2038 norm! 5|['
2039 call assert_equal(' 1 b', getline('.'))
2040 call assert_equal(1, line('.'))
2041 call assert_equal(3, col('.'))
2042
2043 " No mark after line 21, cursor moves to first non-blank on current line
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002044 21
zeertzjqcf344342022-07-06 12:57:31 +01002045 norm! 5|]'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002046 call assert_equal(' 21 b', getline('.'))
2047 call assert_equal(21, line('.'))
2048 call assert_equal(3, col('.'))
2049
2050 " Test for [`
2051 norm! 2[`
2052 call assert_equal(' 15 b', getline('.'))
2053 call assert_equal(15, line('.'))
2054 call assert_equal(8, col('.'))
2055
2056 " Test for ]`
2057 norm! ]`
2058 call assert_equal(' 20 b', getline('.'))
2059 call assert_equal(20, line('.'))
2060 call assert_equal(8, col('.'))
2061
zeertzjqcf344342022-07-06 12:57:31 +01002062 " No mark before line 1, cursor does not move
2063 1
2064 norm! 5|[`
2065 call assert_equal(' 1 b', getline('.'))
2066 call assert_equal(1, line('.'))
2067 call assert_equal(5, col('.'))
2068
2069 " No mark after line 21, cursor does not move
2070 21
2071 norm! 5|]`
2072 call assert_equal(' 21 b', getline('.'))
2073 call assert_equal(21, line('.'))
2074 call assert_equal(5, col('.'))
2075
2076 " Count too large for [`
2077 " cursor moves to first lowercase mark
2078 norm! 99[`
2079 call assert_equal(' 1 b', getline('.'))
2080 call assert_equal(1, line('.'))
2081 call assert_equal(7, col('.'))
2082
2083 " Count too large for ]`
2084 " cursor moves to last lowercase mark
2085 norm! 99]`
2086 call assert_equal(' 20 b', getline('.'))
2087 call assert_equal(20, line('.'))
2088 call assert_equal(8, col('.'))
2089
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002090 " clean up
2091 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002092endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002093
Bram Moolenaar1671f442020-03-10 07:48:13 +01002094" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002095func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002096 new
2097 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2098
2099 $
2100 norm! d(
2101 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2102 norm! 2d(
2103 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2104 1
2105 norm! 0d)
2106 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2107
2108 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2109 $
2110 norm! $d(
2111 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2112
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002113 " Move to the next sentence from a paragraph macro
2114 %d
2115 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2116 call cursor(1, 1)
2117 normal )
2118 call assert_equal([2, 1], [line('.'), col('.')])
2119 normal )
2120 call assert_equal([2, 12], [line('.'), col('.')])
2121 normal ((
2122 call assert_equal([1, 1], [line('.'), col('.')])
2123
Bram Moolenaar1671f442020-03-10 07:48:13 +01002124 " It is an error if a next sentence is not found
2125 %d
2126 call setline(1, '.SH')
2127 call assert_beeps('normal )')
2128
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002129 " If only dot is present, don't treat that as a sentence
2130 call setline(1, '. This is a sentence.')
2131 normal $((
2132 call assert_equal(3, col('.'))
2133
Bram Moolenaar1671f442020-03-10 07:48:13 +01002134 " Jumping to a fold should open the fold
2135 call setline(1, ['', '', 'one', 'two', 'three'])
2136 set foldenable
2137 2,$fold
2138 call feedkeys(')', 'xt')
2139 call assert_equal(3, line('.'))
2140 call assert_equal(1, foldlevel('.'))
2141 call assert_equal(-1, foldclosed('.'))
2142 set foldenable&
2143
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002144 " clean up
2145 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002146endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002147
Bram Moolenaar1671f442020-03-10 07:48:13 +01002148" Test for { and } paragraph movements
2149func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002150 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002151 A paragraph begins after each empty line, and also at each of a set of
2152 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2153 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2154 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2155 the first column). A section boundary is also a paragraph boundary.
2156 Note that a blank line (only containing white space) is NOT a paragraph
2157 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002158
2159
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002160 Also note that this does not include a '{' or '}' in the first column. When
2161 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2162 paragraph boundary |posix|.
2163 {
2164 This is no paragraph
2165 unless the '{' is set
2166 in 'cpoptions'
2167 }
2168 .IP
2169 The nroff macros IP separates a paragraph
2170 That means, it must be a '.'
2171 followed by IP
2172 .LPIt does not matter, if afterwards some
2173 more characters follow.
2174 .SHAlso section boundaries from the nroff
2175 macros terminate a paragraph. That means
2176 a character like this:
2177 .NH
2178 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002179 [DATA]
2180
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002181 new
2182 call append(0, text)
2183 1
2184 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002185
2186 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002187 .IP
2188 The nroff macros IP separates a paragraph
2189 That means, it must be a '.'
2190 followed by IP
2191 .LPIt does not matter, if afterwards some
2192 more characters follow.
2193 .SHAlso section boundaries from the nroff
2194 macros terminate a paragraph. That means
2195 a character like this:
2196 .NH
2197 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002198
2199 [DATA]
2200 call assert_equal(expected, getline(1, '$'))
2201
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002202 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002203
2204 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002205 .LPIt does not matter, if afterwards some
2206 more characters follow.
2207 .SHAlso section boundaries from the nroff
2208 macros terminate a paragraph. That means
2209 a character like this:
2210 .NH
2211 End of text here
Bram Moolenaar94722c52023-01-28 19:19:03 +00002212
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002213 [DATA]
2214 call assert_equal(expected, getline(1, '$'))
2215
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002216 $
2217 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002218
2219 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002220 .LPIt does not matter, if afterwards some
2221 more characters follow.
2222 .SHAlso section boundaries from the nroff
2223 macros terminate a paragraph. That means
2224 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002225
2226 [DATA]
2227 call assert_equal(expected, getline(1, '$'))
2228
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002229 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002230
2231 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002232 .LPIt does not matter, if afterwards some
2233 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002234
2235 [DATA]
2236 call assert_equal(expected, getline(1, '$'))
2237
dundargocdc4c37b2024-01-12 18:02:10 +01002238 " Test with { in cpoptions
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002239 %d
2240 call append(0, text)
2241 set cpo+={
2242 1
2243 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002244
2245 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002246 {
2247 This is no paragraph
2248 unless the '{' is set
2249 in 'cpoptions'
2250 }
2251 .IP
2252 The nroff macros IP separates a paragraph
2253 That means, it must be a '.'
2254 followed by IP
2255 .LPIt does not matter, if afterwards some
2256 more characters follow.
2257 .SHAlso section boundaries from the nroff
2258 macros terminate a paragraph. That means
2259 a character like this:
2260 .NH
2261 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002262
2263 [DATA]
2264 call assert_equal(expected, getline(1, '$'))
2265
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002266 $
2267 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002268
2269 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002270 {
2271 This is no paragraph
2272 unless the '{' is set
2273 in 'cpoptions'
2274 }
2275 .IP
2276 The nroff macros IP separates a paragraph
2277 That means, it must be a '.'
2278 followed by IP
2279 .LPIt does not matter, if afterwards some
2280 more characters follow.
2281 .SHAlso section boundaries from the nroff
2282 macros terminate a paragraph. That means
2283 a character like this:
2284 .NH
2285 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002286
2287 [DATA]
2288 call assert_equal(expected, getline(1, '$'))
2289
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002290 norm! gg}
2291 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002292
2293 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002294 {
2295 This is no paragraph
2296 unless the '{' is set
2297 in 'cpoptions'
2298 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002299
2300 [DATA]
2301 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002302
Bram Moolenaar1671f442020-03-10 07:48:13 +01002303 " Jumping to a fold should open the fold
2304 %d
2305 call setline(1, ['', 'one', 'two', ''])
2306 set foldenable
2307 2,$fold
2308 call feedkeys('}', 'xt')
2309 call assert_equal(4, line('.'))
2310 call assert_equal(1, foldlevel('.'))
2311 call assert_equal(-1, foldclosed('.'))
2312 set foldenable&
2313
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002314 " clean up
2315 set cpo-={
2316 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002317endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002318
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002319" Test for section movements
2320func Test_normal_section()
2321 new
2322 let lines =<< trim [END]
2323 int foo()
2324 {
2325 if (1)
2326 {
2327 a = 1;
2328 }
2329 }
2330 [END]
2331 call setline(1, lines)
2332
2333 " jumping to a folded line using [[ should open the fold
2334 2,3fold
2335 call cursor(5, 1)
2336 call feedkeys("[[", 'xt')
2337 call assert_equal(2, line('.'))
2338 call assert_equal(-1, foldclosedend(line('.')))
2339
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002340 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002341endfunc
2342
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002343" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002344func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002345 new
2346 call append(0, 'This is a simple test: äüöß')
2347 norm! 1ggVu
2348 call assert_equal('this is a simple test: äüöß', getline('.'))
2349 norm! VU
glepnirbd1232a2024-02-12 22:14:53 +01002350 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002351 norm! guu
glepnirbd1232a2024-02-12 22:14:53 +01002352 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002353 norm! gUgU
glepnirbd1232a2024-02-12 22:14:53 +01002354 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002355 norm! gugu
glepnirbd1232a2024-02-12 22:14:53 +01002356 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002357 norm! gUU
glepnirbd1232a2024-02-12 22:14:53 +01002358 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002359 norm! 010~
glepnirbd1232a2024-02-12 22:14:53 +01002360 call assert_equal('this is a SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002361 norm! V~
glepnirbd1232a2024-02-12 22:14:53 +01002362 call assert_equal('THIS IS A simple test: äüöß', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002363 call assert_beeps('norm! c~')
2364 %d
2365 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002366
zeertzjq8c55d602024-03-13 20:42:26 +01002367 " Test with multiple lines
2368 call setline(1, ['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'])
2369 norm! ggguG
2370 call assert_equal(['aa', 'bbbb', 'cccccc', 'dddddddd'], getline(1, '$'))
2371 norm! GgUgg
2372 call assert_equal(['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'], getline(1, '$'))
2373 %d
2374
Bram Moolenaar1671f442020-03-10 07:48:13 +01002375 " Test for changing case across lines using 'whichwrap'
2376 call setline(1, ['aaaaaa', 'aaaaaa'])
2377 normal! gg10~
2378 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2379 set whichwrap+=~
2380 normal! gg10~
2381 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2382 set whichwrap&
2383
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002384 " try changing the case with a double byte encoding (DBCS)
2385 %bw!
2386 let enc = &enc
2387 set encoding=cp932
2388 call setline(1, "\u8470")
2389 normal ~
2390 normal gU$gu$gUgUg~g~gugu
2391 call assert_equal("\u8470", getline(1))
2392 let &encoding = enc
2393
Bram Moolenaar1671f442020-03-10 07:48:13 +01002394 " clean up
2395 bw!
2396endfunc
2397
2398" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2399" is available but toupper()/tolower() don't do the right thing.
2400func Test_normal_changecase_turkish()
2401 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002402 try
2403 lang tr_TR.UTF-8
2404 set casemap=
2405 let iupper = toupper('i')
2406 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002407 call setline(1, 'iI')
2408 1normal gUU
2409 call assert_equal("\u0130I", getline(1))
2410 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002411
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002412 call setline(1, 'iI')
2413 1normal guu
2414 call assert_equal("i\u0131", getline(1))
2415 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002416 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002417 call setline(1, 'iI')
2418 1normal gUU
2419 call assert_equal("II", getline(1))
2420 call assert_equal("II", toupper("iI"))
2421
2422 call setline(1, 'iI')
2423 1normal guu
2424 call assert_equal("ii", getline(1))
2425 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002426 else
2427 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2428 endif
2429 set casemap&
2430 call setline(1, 'iI')
2431 1normal gUU
2432 call assert_equal("II", getline(1))
2433 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002434
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002435 call setline(1, 'iI')
2436 1normal guu
2437 call assert_equal("ii", getline(1))
2438 call assert_equal("ii", tolower("iI"))
2439
2440 lang en_US.UTF-8
2441 catch /E197:/
2442 " can't use Turkish locale
2443 throw 'Skipped: Turkish locale not available'
2444 endtry
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002445
2446 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002447endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002448
Bram Moolenaar1671f442020-03-10 07:48:13 +01002449" Test for r (replace) command
2450func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002451 new
2452 call append(0, 'This is a simple test: abcd')
2453 exe "norm! 1gg$r\<cr>"
2454 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2455 exe "norm! 1gg2wlr\<cr>"
2456 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2457 exe "norm! 2gg0W5r\<cr>"
2458 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2459 set autoindent
2460 call setline(2, ['simple test: abc', ''])
2461 exe "norm! 2gg0W5r\<cr>"
2462 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2463 exe "norm! 1ggVr\<cr>"
2464 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2465 call setline(1, 'This is a')
2466 exe "norm! 1gg05rf"
2467 call assert_equal('fffffis a', getline(1))
2468
Bram Moolenaar1671f442020-03-10 07:48:13 +01002469 " When replacing characters, copy characters from above and below lines
2470 " using CTRL-Y and CTRL-E.
2471 " Different code paths are used for utf-8 and latin1 encodings
2472 set showmatch
2473 for enc in ['latin1', 'utf-8']
2474 enew!
2475 let &encoding = enc
2476 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2477 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2478 call assert_equal(' {a}x [b]x', getline(2))
2479 endfor
2480 set showmatch&
2481
2482 " r command should fail in operator pending mode
2483 call assert_beeps('normal! cr')
2484
Bram Moolenaar004a6782020-04-11 17:09:31 +02002485 " replace a tab character in visual mode
2486 %d
2487 call setline(1, ["a\tb", "c\td", "e\tf"])
2488 normal gglvjjrx
2489 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2490
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002491 " replace with a multibyte character (with multiple composing characters)
2492 %d
2493 new
2494 call setline(1, 'aaa')
2495 exe "normal $ra\u0328\u0301"
2496 call assert_equal("aaa\u0328\u0301", getline(1))
2497
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002498 " clean up
2499 set noautoindent
2500 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002501endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002502
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002503" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002504func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002505 new
2506 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2507 1
2508 norm! $g*
2509 call assert_equal('x_foo', @/)
2510 call assert_equal('x_foobar.abc', getline('.'))
2511 norm! $g#
2512 call assert_equal('abc', @/)
2513 call assert_equal('abc.x_foo', getline('.'))
2514
2515 " clean up
2516 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002517endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002518
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002519" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2520" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002521func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002522 call Setup_NewWindow()
2523 " Test for g`
2524 clearjumps
2525 norm! ma10j
2526 let a=execute(':jumps')
2527 " empty jumplist
2528 call assert_equal('>', a[-1:])
2529 norm! g`a
2530 call assert_equal('>', a[-1:])
2531 call assert_equal(1, line('.'))
2532 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002533 call cursor(10, 1)
2534 norm! g'a
2535 call assert_equal('>', a[-1:])
2536 call assert_equal(1, line('.'))
zeertzjq30585e02023-03-06 08:10:04 +00002537 let v:errmsg = ''
zeertzjqf86dea82023-03-05 21:15:06 +00002538 call assert_nobeep("normal! g`\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002539 call assert_equal('', v:errmsg)
zeertzjqf86dea82023-03-05 21:15:06 +00002540 call assert_nobeep("normal! g'\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002541 call assert_equal('', v:errmsg)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002542
2543 " Test for g; and g,
2544 norm! g;
2545 " there is only one change in the changelist
2546 " currently, when we setup the window
2547 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002548 call assert_fails(':norm! g;', 'E662:')
2549 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002550 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002551 call append('$', ['a', 'b', 'c', 'd'])
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002552 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002553 call append('$', ['Z', 'Y', 'X', 'W'])
2554 let a = execute(':changes')
2555 call assert_match('2\s\+0\s\+2', a)
2556 call assert_match('101\s\+0\s\+a', a)
2557 call assert_match('105\s\+0\s\+Z', a)
2558 norm! 3g;
2559 call assert_equal(2, line('.'))
2560 norm! 2g,
2561 call assert_equal(105, line('.'))
2562
2563 " Test for g& - global substitute
2564 %d
2565 call setline(1, range(1,10))
2566 call append('$', ['a', 'b', 'c', 'd'])
2567 $s/\w/&&/g
2568 exe "norm! /[1-8]\<cr>"
2569 norm! g&
2570 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2571
Bram Moolenaar1671f442020-03-10 07:48:13 +01002572 " Jumping to a fold using gg should open the fold
2573 set foldenable
2574 set foldopen+=jump
2575 5,8fold
2576 call feedkeys('6gg', 'xt')
2577 call assert_equal(1, foldlevel('.'))
2578 call assert_equal(-1, foldclosed('.'))
2579 set foldopen-=jump
2580 set foldenable&
2581
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002582 " Test for gv
2583 %d
2584 call append('$', repeat(['abcdefgh'], 8))
2585 exe "norm! 2gg02l\<c-v>2j2ly"
2586 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2587 " in visual mode, gv swaps current and last selected region
2588 exe "norm! G0\<c-v>4k4lgvd"
2589 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2590 exe "norm! G0\<c-v>4k4ly"
2591 exe "norm! gvood"
2592 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Christian Brabandtee17b6f2023-09-09 11:23:50 +02002593 " gv cannot be used in operator pending mode
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002594 call assert_beeps('normal! cgv')
2595 " gv should beep without a previously selected visual area
2596 new
2597 call assert_beeps('normal! gv')
2598 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002599
2600 " Test for gk/gj
2601 %d
2602 15vsp
2603 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002604 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2605 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2606 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002607 $put =lineA
2608 $put =lineB
2609
2610 norm! 3gg0dgk
2611 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2612 set nu
2613 norm! 3gg0gjdgj
2614 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2615
2616 " Test for gJ
2617 norm! 2gggJ
2618 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2619 call assert_equal(16, col('.'))
2620 " shouldn't do anything
2621 norm! 10gJ
2622 call assert_equal(1, col('.'))
2623
2624 " Test for g0 g^ gm g$
2625 exe "norm! 2gg0gji "
2626 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2627 norm! g0yl
2628 call assert_equal(12, col('.'))
2629 call assert_equal(' ', getreg(0))
2630 norm! g$yl
2631 call assert_equal(22, col('.'))
2632 call assert_equal('3', getreg(0))
2633 norm! gmyl
2634 call assert_equal(17, col('.'))
2635 call assert_equal('n', getreg(0))
2636 norm! g^yl
2637 call assert_equal(15, col('.'))
2638 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002639 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002640
Bram Moolenaar74ede802021-05-29 19:18:01 +02002641 " Test for g$ with double-width character half displayed
2642 vsplit
2643 9wincmd |
2644 setlocal nowrap nonumber
2645 call setline(2, 'asdfasdfヨ')
2646 2
2647 normal 0g$
2648 call assert_equal(8, col('.'))
2649 10wincmd |
2650 normal 0g$
2651 call assert_equal(9, col('.'))
2652
2653 setlocal signcolumn=yes
2654 11wincmd |
2655 normal 0g$
2656 call assert_equal(8, col('.'))
2657 12wincmd |
2658 normal 0g$
2659 call assert_equal(9, col('.'))
2660
2661 close
2662
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002663 " Test for g_
2664 call assert_beeps('normal! 100g_')
2665 call setline(2, [' foo ', ' foobar '])
2666 normal! 2ggg_
2667 call assert_equal(5, col('.'))
2668 normal! 2g_
2669 call assert_equal(8, col('.'))
2670
2671 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002672 $put =lineC
2673
2674 " Test for gM
2675 norm! gMyl
2676 call assert_equal(73, col('.'))
2677 call assert_equal('0', getreg(0))
2678 " Test for 20gM
2679 norm! 20gMyl
2680 call assert_equal(29, col('.'))
2681 call assert_equal('S', getreg(0))
2682 " Test for 60gM
2683 norm! 60gMyl
2684 call assert_equal(87, col('.'))
2685 call assert_equal('E', getreg(0))
2686
Bram Moolenaar71c41252021-12-26 15:00:07 +00002687 " Test for gM with Tab characters
2688 call setline('.', "\ta\tb\tc\td\te\tf")
2689 norm! gMyl
2690 call assert_equal(6, col('.'))
2691 call assert_equal("c", getreg(0))
2692
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002693 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002694 call setline('.', lineC)
2695 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002696 set ff=unix
2697 let a=execute(":norm! g\<c-g>")
2698 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2699
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002700 " Test for gI
2701 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002702 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002703
2704 " Test for gi
2705 wincmd c
2706 %d
2707 set tw=0
2708 call setline(1, ['foobar', 'new line'])
2709 norm! A next word
2710 $put ='third line'
2711 norm! gi another word
2712 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002713 call setline(1, 'foobar')
2714 normal! Ggifirst line
2715 call assert_equal('foobarfirst line', getline(1))
2716 " Test gi in 'virtualedit' mode with cursor after the end of the line
2717 set virtualedit=all
2718 call setline(1, 'foo')
2719 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2720 call setline(1, 'foo')
2721 normal! Ggifirst line
2722 call assert_equal('foo first line', getline(1))
2723 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002724
Dominique Pelle923dce22021-11-21 11:36:04 +00002725 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002726 exe "normal! g\<C-\>\<C-G>"
2727 call assert_equal('foo first line', getline('.'))
2728
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002729 " clean up
2730 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002731endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002732
Bram Moolenaarce416b42022-04-03 12:59:34 +01002733func Test_normal_ex_substitute()
2734 " This was hanging on the substitute prompt.
2735 new
2736 call setline(1, 'a')
2737 exe "normal! gggQs/a/b/c\<CR>"
2738 call assert_equal('a', getline(1))
2739 bwipe!
2740endfunc
2741
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002742" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002743func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002744 new
2745
2746 let a = execute(":norm! g\<c-g>")
2747 call assert_equal("\n--No lines in buffer--", a)
2748
Bram Moolenaar1671f442020-03-10 07:48:13 +01002749 " Test for CTRL-G (same as :file)
2750 let a = execute(":norm! \<c-g>")
2751 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2752
Bram Moolenaar05295832018-08-24 22:07:58 +02002753 call setline(1, ['first line', 'second line'])
2754
2755 " Test g CTRL-g with dos, mac and unix file type.
2756 norm! gojll
2757 set ff=dos
2758 let a = execute(":norm! g\<c-g>")
2759 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2760
2761 set ff=mac
2762 let a = execute(":norm! g\<c-g>")
2763 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2764
2765 set ff=unix
2766 let a = execute(":norm! g\<c-g>")
2767 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2768
2769 " Test g CTRL-g in visual mode (v)
2770 let a = execute(":norm! gojllvlg\<c-g>")
2771 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2772
2773 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2774 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2775 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2776
2777 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2778 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2779 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2780
2781 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2782 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2783 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2784
2785 " There should be one byte less with noeol
2786 set bin noeol
2787 let a = execute(":norm! \<Esc>gog\<c-g>")
2788 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2789 set bin & eol&
2790
Bram Moolenaar30276f22019-01-24 17:59:39 +01002791 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002792
Bram Moolenaar30276f22019-01-24 17:59:39 +01002793 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2794 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 +02002795
Bram Moolenaar30276f22019-01-24 17:59:39 +01002796 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2797 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 +02002798
Bram Moolenaar30276f22019-01-24 17:59:39 +01002799 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2800 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 +02002801
Bram Moolenaar30276f22019-01-24 17:59:39 +01002802 set fenc=utf8 bomb
2803 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2804 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 +02002805
Bram Moolenaar30276f22019-01-24 17:59:39 +01002806 set fenc=utf16 bomb
2807 let a = execute(":norm! g\<c-g>")
2808 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 +02002809
Bram Moolenaar30276f22019-01-24 17:59:39 +01002810 set fenc=utf32 bomb
2811 let a = execute(":norm! g\<c-g>")
2812 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 +02002813
Bram Moolenaar30276f22019-01-24 17:59:39 +01002814 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002815
2816 set ff&
2817 bwipe!
2818endfunc
2819
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002820" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002821func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002822 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002823 let a=execute(':norm! 1G0g8')
2824 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002825
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002826 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2827 let a=execute(':norm! 1G$g8')
2828 call assert_equal("\nc3 b6 ", a)
2829
2830 call setline(1, "a\u0302")
2831 let a=execute(':norm! 1G0g8')
2832 call assert_equal("\n61 + cc 82 ", a)
2833
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002834 " clean up
2835 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002836endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002837
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002838" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002839func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002840 new
2841
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002842 " With invalid byte.
2843 call setline(1, "___\xff___")
2844 norm! 1G08g8g
2845 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2846
2847 " With invalid byte before the cursor.
2848 call setline(1, "___\xff___")
2849 norm! 1G$h8g8g
2850 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2851
2852 " With truncated sequence.
2853 call setline(1, "___\xE2\x82___")
2854 norm! 1G08g8g
2855 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2856
2857 " With overlong sequence.
2858 call setline(1, "___\xF0\x82\x82\xAC___")
2859 norm! 1G08g8g
2860 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2861
2862 " With valid utf8.
2863 call setline(1, "café")
2864 norm! 1G08g8
2865 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2866
2867 bw!
2868endfunc
2869
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002870" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002871func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002872 " Cannot capture its output,
2873 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002874 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002875 echo "a\nb\nc\nd"
2876 let b=execute(':norm! g<')
2877 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002878endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002879
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002880" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002881func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002882 new
2883 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002884 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002885 " Test for gp gP
2886 call append(1, range(1,10))
2887 1
2888 norm! 1yy
2889 3
2890 norm! gp
2891 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2892 $
2893 norm! gP
2894 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2895
2896 " Test for go
2897 norm! 26go
2898 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2899 norm! 27go
2900 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2901 norm! 28go
2902 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2903 set ff=dos
2904 norm! 29go
2905 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2906 set ff=unix
2907 norm! gg0
2908 norm! 101go
2909 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2910 norm! 103go
2911 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2912 " count > buffer content
2913 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002914 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002915 " clean up
2916 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002917endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002918
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002919" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002920func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002921 tabnew 1.txt
2922 tabnew 2.txt
2923 tabnew 3.txt
2924 norm! 1gt
2925 call assert_equal(1, tabpagenr())
2926 norm! 3gt
2927 call assert_equal(3, tabpagenr())
2928 norm! 1gT
2929 " count gT goes not to the absolute tabpagenumber
2930 " but, but goes to the count previous tabpagenumber
2931 call assert_equal(2, tabpagenr())
2932 " wrap around
2933 norm! 3gT
2934 call assert_equal(3, tabpagenr())
2935 " gt does not wrap around
2936 norm! 5gt
2937 call assert_equal(3, tabpagenr())
2938
2939 for i in range(3)
2940 tabclose
2941 endfor
2942 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002943 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002944endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002945
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002946" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002947func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002948 new
2949 call setline(1, range(10))
2950 $
2951 setl et sw=2
2952 norm! V10>$
2953 " count is ignored
2954 exe "norm! 10\<home>"
2955 call assert_equal(1, col('.'))
2956 exe "norm! \<home>"
2957 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2958 exe "norm! 5\<c-home>"
2959 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2960 exe "norm! \<c-home>"
2961 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002962 exe "norm! G\<c-kHome>"
2963 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002964
2965 " clean up
2966 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002967endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002968
Bram Moolenaar1671f442020-03-10 07:48:13 +01002969" Test for <End> and <C-End> keys
2970func Test_normal_nvend()
2971 new
2972 call setline(1, map(range(1, 10), '"line" .. v:val'))
2973 exe "normal! \<End>"
2974 call assert_equal(5, col('.'))
2975 exe "normal! 4\<End>"
2976 call assert_equal([4, 5], [line('.'), col('.')])
2977 exe "normal! \<C-End>"
2978 call assert_equal([10, 6], [line('.'), col('.')])
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002979
2980 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01002981endfunc
2982
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002983" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002984func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002985 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002986 new
2987 set tw=0
2988 call append(0, 'here are some words')
2989 norm! 1gg0elcwZZZ
2990 call assert_equal('hereZZZare some words', getline('.'))
2991 norm! 1gg0elcWYYY
2992 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002993 norm! 2gg0cwfoo
2994 call assert_equal('foo', getline('.'))
2995
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002996 call setline(1, 'one; two')
2997 call cursor(1, 1)
2998 call feedkeys('cwvim', 'xt')
2999 call assert_equal('vim; two', getline(1))
3000 call feedkeys('0cWone', 'xt')
3001 call assert_equal('one two', getline(1))
3002 "When cursor is at the end of a word 'ce' will change until the end of the
3003 "next word, but 'cw' will change only one character
3004 call setline(1, 'one two')
3005 call feedkeys('0ecwce', 'xt')
3006 call assert_equal('once two', getline(1))
3007 call setline(1, 'one two')
3008 call feedkeys('0ecely', 'xt')
3009 call assert_equal('only', getline(1))
3010
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003011 " clean up
3012 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003013endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003014
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003015" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003016func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003017 new
3018 call append(0, 'here are some words')
3019 exe "norm! 1gg0a\<C-\>\<C-N>"
3020 call assert_equal('n', mode())
3021 call assert_equal(1, col('.'))
3022 call assert_equal('', visualmode())
3023 exe "norm! 1gg0viw\<C-\>\<C-N>"
3024 call assert_equal('n', mode())
3025 call assert_equal(4, col('.'))
3026 exe "norm! 1gg0a\<C-\>\<C-G>"
3027 call assert_equal('n', mode())
3028 call assert_equal(1, col('.'))
3029 "imap <buffer> , <c-\><c-n>
3030 set im
3031 exe ":norm! \<c-\>\<c-n>dw"
3032 set noim
3033 call assert_equal('are some words', getline(1))
3034 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02003035 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01003036
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003037 " clean up
3038 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003039endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003040
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003041" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003042func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003043 new
3044 set sts=2 sw=2 ts=8 tw=0
3045 call append(0, ["aaa\tbbb\tccc", '', '', ''])
3046 let a=getline(1)
3047 norm! 2gg0
3048 exe "norm! a\<c-r>=a\<cr>"
3049 norm! 3gg0
3050 exe "norm! a\<c-r>\<c-r>=a\<cr>"
3051 norm! 4gg0
3052 exe "norm! a\<c-r>\<c-o>=a\<cr>"
3053 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
3054
3055 " clean up
3056 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02003057 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003058endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003059
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003060" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003061func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003062 call Setup_NewWindow()
3063 call assert_equal(5, &scroll)
3064 exe "norm! \<c-d>"
3065 call assert_equal('6', getline('.'))
3066 exe "norm! 2\<c-d>"
3067 call assert_equal('8', getline('.'))
3068 call assert_equal(2, &scroll)
3069 set scroll=5
3070 exe "norm! \<c-u>"
3071 call assert_equal('3', getline('.'))
3072 1
3073 set scrolloff=5
3074 exe "norm! \<c-d>"
3075 call assert_equal('10', getline('.'))
3076 exe "norm! \<c-u>"
3077 call assert_equal('5', getline('.'))
3078 1
3079 set scrolloff=99
3080 exe "norm! \<c-d>"
3081 call assert_equal('10', getline('.'))
3082 set scrolloff=0
3083 100
3084 exe "norm! $\<c-u>"
3085 call assert_equal('95', getline('.'))
3086 call assert_equal([0, 95, 1, 0, 1], getcurpos())
3087 100
3088 set nostartofline
3089 exe "norm! $\<c-u>"
3090 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00003091 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003092 " cleanup
3093 set startofline
3094 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003095endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003096
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003097func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003098 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003099 " The ~ register does not exist
3100 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003101 return
3102 endif
3103
3104 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003105 " unfortunately, without a gui, we can't really test much here,
3106 " so simply test that ~p fails (which uses the drop register)
3107 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003108 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003109 call assert_equal([], getreg('~', 1, 1))
3110 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003111 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003112 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003113endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003114
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003115func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003116 new
3117 " How to test this?
3118 " let's just for now test, that the buffer
3119 " does not change
3120 call feedkeys("\<c-s>", 't')
3121 call assert_equal([''], getline(1,'$'))
3122
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003123 " no valid commands
3124 exe "norm! \<char-0x100>"
3125 call assert_equal([''], getline(1,'$'))
3126
3127 exe "norm! ä"
3128 call assert_equal([''], getline(1,'$'))
3129
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003130 " clean up
3131 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003132endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003133
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003134func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003135 " This was causing a crash or ml_get error.
3136 enew!
3137 call setline(1,'xxx')
3138 normal $
3139 new
3140 call setline(1, range(1,2))
3141 2
3142 exe "norm \<C-V>$"
3143 bw!
3144 norm yp
3145 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003146endfunc
3147
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003148func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003149 new
3150 exe "norm! \<c-w>c"
3151 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003152 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003153endfunc
3154
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003155func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003156 new
3157 call setline(1, 'one two three four five six seven eight nine ten')
3158 1
3159 norm! 3d2w
3160 call assert_equal('seven eight nine ten', getline(1))
3161 bw!
3162endfunc
3163
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003164func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003165 CheckFeature timers
3166 CheckFeature cmdline_hist
Bram Moolenaarc255b782022-11-26 19:16:48 +00003167
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003168 func! DoTimerWork(id)
Sean Dewar1fb41032023-08-16 17:15:05 +01003169 call assert_equal(1, getbufinfo('')[0].command)
Bram Moolenaarc255b782022-11-26 19:16:48 +00003170
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003171 " should fail, with E11, but does fail with E23?
3172 "call feedkeys("\<c-^>", 'tm')
3173
Bram Moolenaarc255b782022-11-26 19:16:48 +00003174 " should fail with E11 - "Invalid in command-line window"
Bram Moolenaare2e40752020-09-04 21:18:46 +02003175 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaarc255b782022-11-26 19:16:48 +00003176
3177 " Return from commandline window.
3178 call feedkeys("\<CR>", 't')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003179 endfunc
3180
3181 let oldlang=v:lang
3182 lang C
3183 set updatetime=20
3184 call timer_start(100, 'DoTimerWork')
3185 try
3186 " throws E23, for whatever reason...
3187 call feedkeys('q:', 'x!')
3188 catch /E23/
3189 " no-op
3190 endtry
Bram Moolenaarc255b782022-11-26 19:16:48 +00003191
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003192 " clean up
Bram Moolenaarc255b782022-11-26 19:16:48 +00003193 delfunc DoTimerWork
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003194 set updatetime=4000
3195 exe "lang" oldlang
3196 bw!
3197endfunc
3198
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003199func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003200 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003201 " Don't sleep after the warning message.
3202 call test_settime(1)
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01003203 call writefile(['foo'], 'Xreadonly.log', 'D')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003204 new Xreadonly.log
3205 setl ro
3206 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003207 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003208 call assert_equal(['foo'], getline(1,'$'))
3209 call assert_equal('Xreadonly.log', bufname(''))
3210
3211 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003212 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003213 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003214endfunc
3215
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003216func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003217 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003218 new
3219 call setline(1, 'abcde fghij klmnopq')
3220 norm! 1gg$
3221 set rl
3222 call assert_equal(19, col('.'))
3223 call feedkeys('l', 'tx')
3224 call assert_equal(18, col('.'))
3225 call feedkeys('h', 'tx')
3226 call assert_equal(19, col('.'))
3227 call feedkeys("\<right>", 'tx')
3228 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003229 call feedkeys("\<left>", 'tx')
3230 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003231 call feedkeys("\<s-right>", 'tx')
3232 call assert_equal(13, col('.'))
3233 call feedkeys("\<c-right>", 'tx')
3234 call assert_equal(7, col('.'))
3235 call feedkeys("\<c-left>", 'tx')
3236 call assert_equal(13, col('.'))
3237 call feedkeys("\<s-left>", 'tx')
3238 call assert_equal(19, col('.'))
3239 call feedkeys("<<", 'tx')
3240 call assert_equal(' abcde fghij klmnopq',getline(1))
3241 call feedkeys(">>", 'tx')
3242 call assert_equal('abcde fghij klmnopq',getline(1))
3243
3244 " cleanup
3245 set norl
3246 bw!
3247endfunc
3248
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003249func Test_normal54_Ctrl_bsl()
3250 new
3251 call setline(1, 'abcdefghijklmn')
3252 exe "norm! df\<c-\>\<c-n>"
3253 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3254 exe "norm! df\<c-\>\<c-g>"
3255 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3256 exe "norm! df\<c-\>m"
3257 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003258
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003259 call setline(2, 'abcdefghijklmnāf')
3260 norm! 2gg0
3261 exe "norm! df\<Char-0x101>"
3262 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3263 norm! 1gg0
3264 exe "norm! df\<esc>"
3265 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003266
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003267 " clean up
3268 bw!
3269endfunc
3270
3271func Test_normal_large_count()
3272 " This may fail with 32bit long, how do we detect that?
3273 new
3274 normal o
3275 normal 6666666666dL
3276 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003277endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003278
3279func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003280 new
3281 normal grádv}
3282 call assert_equal('á', getline(1))
3283 normal grád}
3284 call assert_equal('', getline(1))
3285 bwipe!
3286endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003287
3288" Test for the gr (virtual replace) command
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003289func Test_gr_command()
3290 enew!
zeertzjq4f026ea2023-02-26 14:47:24 +00003291 " Test for the bug fixed by 7.4.387
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003292 let save_cpo = &cpo
3293 call append(0, ['First line', 'Second line', 'Third line'])
3294 exe "normal i\<C-G>u"
3295 call cursor(2, 1)
3296 set cpo-=X
3297 normal 4gro
3298 call assert_equal('oooond line', getline(2))
3299 undo
3300 set cpo+=X
3301 normal 4gro
3302 call assert_equal('ooooecond line', getline(2))
3303 let &cpo = save_cpo
zeertzjq4f026ea2023-02-26 14:47:24 +00003304
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003305 normal! ggvegrx
3306 call assert_equal('xxxxx line', getline(1))
3307 exe "normal! gggr\<C-V>122"
3308 call assert_equal('zxxxx line', getline(1))
zeertzjq4f026ea2023-02-26 14:47:24 +00003309
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003310 set virtualedit=all
3311 normal! 15|grl
3312 call assert_equal('zxxxx line l', getline(1))
3313 set virtualedit&
3314 set nomodifiable
3315 call assert_fails('normal! grx', 'E21:')
3316 call assert_fails('normal! gRx', 'E21:')
zeertzjq4f026ea2023-02-26 14:47:24 +00003317 call assert_nobeep("normal! gr\<Esc>")
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003318 set modifiable&
zeertzjq4f026ea2023-02-26 14:47:24 +00003319
3320 call assert_nobeep("normal! gr\<Esc>")
zeertzjqf86dea82023-03-05 21:15:06 +00003321 call assert_nobeep("normal! cgr\<Esc>")
3322 call assert_beeps("normal! cgrx")
zeertzjq4f026ea2023-02-26 14:47:24 +00003323
3324 call assert_equal('zxxxx line l', getline(1))
3325 exe "normal! 2|gr\<C-V>\<Esc>"
3326 call assert_equal("z\<Esc>xx line l", getline(1))
3327
3328 call setline(1, 'abcdef')
3329 exe "normal! 0gr\<C-O>lx"
3330 call assert_equal("\<C-O>def", getline(1))
3331
3332 call setline(1, 'abcdef')
3333 exe "normal! 0gr\<C-G>lx"
3334 call assert_equal("\<C-G>def", getline(1))
3335
3336 bwipe!
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003337endfunc
3338
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003339func Test_nv_hat_count()
3340 %bwipeout!
3341 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003342 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003343
3344 edit Xfoo
3345 let l:foo_nr = bufnr('Xfoo')
3346
3347 edit Xbar
3348 let l:bar_nr = bufnr('Xbar')
3349
3350 " Make sure we are not just using the alternate file.
3351 edit Xbaz
3352
3353 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3354 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3355
3356 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3357 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3358
3359 %bwipeout!
3360endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003361
3362func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003363 " Make sure no buffers are changed.
3364 %bwipe!
3365
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003366 exe "normal \<C-C>"
3367 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003368
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003369 new
3370 cal setline(1, 'hi!')
3371 exe "normal \<C-C>"
3372 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003373
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003374 bwipe!
3375endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003376
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01003377func Test_mode_updated_after_ctrl_c()
3378 CheckScreendump
3379
3380 let buf = RunVimInTerminal('', {'rows': 5})
3381 call term_sendkeys(buf, "i")
3382 call term_sendkeys(buf, "\<C-O>")
3383 " wait a moment so that the "-- (insert) --" message is displayed
3384 call TermWait(buf, 50)
3385 call term_sendkeys(buf, "\<C-C>")
3386 call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
3387
3388 call StopVimInTerminal(buf)
3389endfunc
3390
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003391" Test for '[m', ']m', '[M' and ']M'
3392" Jumping to beginning and end of methods in Java-like languages
3393func Test_java_motion()
3394 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003395 call assert_beeps('normal! [m')
3396 call assert_beeps('normal! ]m')
3397 call assert_beeps('normal! [M')
3398 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003399 let lines =<< trim [CODE]
3400 Piece of Java
3401 {
3402 tt m1 {
3403 t1;
3404 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003405
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003406 tt m2 {
3407 t2;
3408 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003409
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003410 tt m3 {
3411 if (x)
3412 {
3413 t3;
3414 }
3415 } e3
3416 }
3417 [CODE]
3418 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003419
3420 normal gg
3421
3422 normal 2]maA
3423 call assert_equal("\ttt m1 {A", getline('.'))
3424 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3425
3426 normal j]maB
3427 call assert_equal("\ttt m2 {B", getline('.'))
3428 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3429
3430 normal ]maC
3431 call assert_equal("\ttt m3 {C", getline('.'))
3432 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3433
3434 normal [maD
3435 call assert_equal("\ttt m3 {DC", getline('.'))
3436 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3437
3438 normal k2[maE
3439 call assert_equal("\ttt m1 {EA", getline('.'))
3440 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3441
3442 normal 3[maF
3443 call assert_equal("{F", getline('.'))
3444 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3445
3446 normal ]MaG
3447 call assert_equal("\t}G e1", getline('.'))
3448 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3449
3450 normal j2]MaH
3451 call assert_equal("\t}H e3", getline('.'))
3452 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3453
3454 normal ]M]M
3455 normal aI
3456 call assert_equal("}I", getline('.'))
3457 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3458
3459 normal 2[MaJ
3460 call assert_equal("\t}JH e3", getline('.'))
3461 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3462
3463 normal k[MaK
3464 call assert_equal("\t}K e2", getline('.'))
3465 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3466
3467 normal 3[MaL
3468 call assert_equal("{LF", getline('.'))
3469 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3470
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003471 call cursor(2, 1)
3472 call assert_beeps('norm! 5]m')
3473
3474 " jumping to a method in a fold should open the fold
3475 6,10fold
3476 call feedkeys("gg3]m", 'xt')
3477 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3478 call assert_equal(-1, foldclosedend(7))
3479
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003480 bwipe!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003481endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003482
Bram Moolenaar004a6782020-04-11 17:09:31 +02003483" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003484func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003485 call Setup_NewWindow()
3486 " Make long lines that will wrap
3487 %s/$/\=repeat(' foobar', 10)/
3488 20vsp
3489 set wrap
3490 " Test for g$ with count
3491 norm! gg
3492 norm! 0vg$y
3493 call assert_equal(20, col("'>"))
3494 call assert_equal('1 foobar foobar foob', getreg(0))
3495 norm! gg
3496 norm! 0v4g$y
3497 call assert_equal(72, col("'>"))
3498 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3499 norm! gg
3500 norm! 0v6g$y
3501 call assert_equal(40, col("'>"))
3502 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3503 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3504 set nowrap
3505 " clean up
3506 norm! gg
3507 norm! 0vg$y
3508 call assert_equal(20, col("'>"))
3509 call assert_equal('1 foobar foobar foob', getreg(0))
3510 norm! gg
3511 norm! 0v4g$y
3512 call assert_equal(20, col("'>"))
3513 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3514 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3515 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3516 \ '4 foobar foobar foob', getreg(0))
3517 norm! gg
3518 norm! 0v6g$y
3519 call assert_equal(20, col("'>"))
3520 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3521 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3522 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3523 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3524 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3525 \ '6 foobar foobar foob', getreg(0))
3526 " Move to last line, also down movement is not possible, should still move
3527 " the cursor to the last visible char
3528 norm! G
3529 norm! 0v6g$y
3530 call assert_equal(20, col("'>"))
3531 call assert_equal('100 foobar foobar fo', getreg(0))
3532 bw!
3533endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003534
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003535func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003536 " needs 80 column new window
3537 new
3538 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003539 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003540 put =[repeat('x',90)..' {{{1', 'x {{{1']
3541 norm! gk
3542 " In a 80 column wide terminal the window will be only 78 char
3543 " (because Vim will leave space for the other window),
3544 " but if the terminal is larger, it will be 80 chars, so verify the
3545 " cursor column correctly.
3546 call assert_equal(winwidth(0)+1, col('.'))
3547 call assert_equal(winwidth(0)+1, virtcol('.'))
3548 norm! j
3549 call assert_equal(6, col('.'))
3550 call assert_equal(6, virtcol('.'))
3551 norm! gk
3552 call assert_equal(95, col('.'))
3553 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003554 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003555
3556 " needs 80 column new window
3557 new
3558 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003559 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003560 set number
3561 set numberwidth=10
3562 set cpoptions+=n
3563 put =[repeat('0',90), repeat('1',90)]
3564 norm! 075l
3565 call assert_equal(76, col('.'))
3566 norm! gk
3567 call assert_equal(1, col('.'))
3568 norm! gk
3569 call assert_equal(76, col('.'))
3570 norm! gk
3571 call assert_equal(1, col('.'))
3572 norm! gj
3573 call assert_equal(76, col('.'))
3574 norm! gj
3575 call assert_equal(1, col('.'))
3576 norm! gj
3577 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003578 " When 'nowrap' is set, gk and gj behave like k and j
3579 set nowrap
3580 normal! gk
3581 call assert_equal([2, 76], [line('.'), col('.')])
3582 normal! gj
3583 call assert_equal([3, 76], [line('.'), col('.')])
3584 %bw!
3585 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003586endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003587
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003588" Test for using : to run a multi-line Ex command in operator pending mode
3589func Test_normal_yank_with_excmd()
3590 new
3591 call setline(1, ['foo', 'bar', 'baz'])
3592 let @a = ''
3593 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3594 call assert_equal('f', @a)
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003595
3596 bwipe!
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003597endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003598
3599" Test for supplying a count to a normal-mode command across a cursorhold call
3600func Test_normal_cursorhold_with_count()
3601 func s:cHold()
3602 let g:cHold_Called += 1
3603 endfunc
3604 new
3605 augroup normalcHoldTest
3606 au!
3607 au CursorHold <buffer> call s:cHold()
3608 augroup END
3609 let g:cHold_Called = 0
3610 call feedkeys("3\<CursorHold>2ix", 'xt')
3611 call assert_equal(1, g:cHold_Called)
3612 call assert_equal(repeat('x', 32), getline(1))
3613 augroup normalcHoldTest
3614 au!
3615 augroup END
3616 au! normalcHoldTest
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003617
3618 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003619 delfunc s:cHold
3620endfunc
3621
3622" Test for using a count and a command with CTRL-W
3623func Test_wincmd_with_count()
3624 call feedkeys("\<C-W>12n", 'xt')
3625 call assert_equal(12, winheight(0))
3626endfunc
3627
3628" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003629func Test_horiz_motion()
3630 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003631 normal! gg
3632 call assert_beeps('normal! b')
3633 call assert_beeps('normal! B')
3634 call assert_beeps('normal! gE')
3635 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003636 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3637 call setline(1, 'one ,two ,three')
3638 exe "normal! $\<S-BS>"
3639 call assert_equal(11, col('.'))
3640 exe "normal! $\<C-BS>"
3641 call assert_equal(10, col('.'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003642
3643 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003644endfunc
3645
zeertzjq30b6d612023-05-07 17:39:23 +01003646" Test for using a ":" command in operator pending mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003647func Test_normal_colon_op()
3648 new
3649 call setline(1, ['one', 'two'])
3650 call assert_beeps("normal! Gc:d\<CR>")
zeertzjq30b6d612023-05-07 17:39:23 +01003651 call assert_equal(['one'], getline(1, '$'))
3652
3653 call setline(1, ['one…two…three!'])
3654 normal! $
3655 " Using ":" as a movement is characterwise exclusive
3656 call feedkeys("d:normal! F…\<CR>", 'xt')
3657 call assert_equal(['one…two!'], getline(1, '$'))
3658 " Check that redoing a command with 0x80 bytes works
3659 call feedkeys('.', 'xt')
3660 call assert_equal(['one!'], getline(1, '$'))
3661
3662 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3663 " Add this to the command history
3664 call feedkeys(":normal! G0\<CR>", 'xt')
3665 " Use :normal! with control characters in operator pending mode
3666 call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
3667 call assert_equal(['one', 'two', 'five'], getline(1, '$'))
3668 " Check that redoing a command with control characters works
3669 call feedkeys('.', 'xt')
3670 call assert_equal(['five'], getline(1, '$'))
3671
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003672 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003673endfunc
3674
Bram Moolenaar004a6782020-04-11 17:09:31 +02003675" Test for d and D commands
3676func Test_normal_delete_cmd()
3677 new
3678 " D in an empty line
3679 call setline(1, '')
3680 normal D
3681 call assert_equal('', getline(1))
3682 " D in an empty line in virtualedit mode
3683 set virtualedit=all
3684 normal D
3685 call assert_equal('', getline(1))
3686 set virtualedit&
3687 " delete to a readonly register
3688 call setline(1, ['abcd'])
3689 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003690
3691 " D and d with 'nomodifiable'
3692 call setline(1, ['abcd'])
3693 setlocal nomodifiable
3694 call assert_fails('normal D', 'E21:')
3695 call assert_fails('normal d$', 'E21:')
3696
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003697 bwipe!
Bram Moolenaar004a6782020-04-11 17:09:31 +02003698endfunc
3699
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003700" Test for deleting or changing characters across lines with 'whichwrap'
3701" containing 's'. Should count <EOL> as one character.
3702func Test_normal_op_across_lines()
3703 new
3704 set whichwrap&
3705 call setline(1, ['one two', 'three four'])
3706 exe "norm! $3d\<Space>"
3707 call assert_equal(['one twhree four'], getline(1, '$'))
3708
3709 call setline(1, ['one two', 'three four'])
3710 exe "norm! $3c\<Space>x"
3711 call assert_equal(['one twxhree four'], getline(1, '$'))
3712
3713 set whichwrap+=l
3714 call setline(1, ['one two', 'three four'])
3715 exe "norm! $3x"
3716 call assert_equal(['one twhree four'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003717
3718 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003719 set whichwrap&
3720endfunc
3721
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003722" Test for 'w' and 'b' commands
3723func Test_normal_word_move()
3724 new
3725 call setline(1, ['foo bar a', '', 'foo bar b'])
3726 " copy a single character word at the end of a line
3727 normal 1G$yw
3728 call assert_equal('a', @")
3729 " copy a single character word at the end of a file
3730 normal G$yw
3731 call assert_equal('b', @")
3732 " check for a word movement handling an empty line properly
3733 normal 1G$vwy
3734 call assert_equal("a\n\n", @")
3735
3736 " copy using 'b' command
3737 %d
3738 " non-empty blank line at the start of file
3739 call setline(1, [' ', 'foo bar'])
3740 normal 2Gyb
3741 call assert_equal(" \n", @")
3742 " try to copy backwards from the start of the file
3743 call setline(1, ['one two', 'foo bar'])
3744 call assert_beeps('normal ggyb')
3745 " 'b' command should stop at an empty line
3746 call setline(1, ['one two', '', 'foo bar'])
3747 normal 3Gyb
3748 call assert_equal("\n", @")
3749 normal 3Gy2b
3750 call assert_equal("two\n", @")
3751 " 'b' command should not stop at a non-empty blank line
3752 call setline(1, ['one two', ' ', 'foo bar'])
3753 normal 3Gyb
3754 call assert_equal("two\n ", @")
3755
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003756 bwipe!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003757endfunc
3758
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003759" Test for 'scrolloff' with a long line that doesn't fit in the screen
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003760func Test_normal_scrolloff()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003761 10new
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003762 60vnew
3763 call setline(1, ' 1 ' .. repeat('a', 57)
3764 \ .. ' 2 ' .. repeat('b', 57)
3765 \ .. ' 3 ' .. repeat('c', 57)
3766 \ .. ' 4 ' .. repeat('d', 57)
3767 \ .. ' 5 ' .. repeat('e', 57)
3768 \ .. ' 6 ' .. repeat('f', 57)
3769 \ .. ' 7 ' .. repeat('g', 57)
3770 \ .. ' 8 ' .. repeat('h', 57)
3771 \ .. ' 9 ' .. repeat('i', 57)
3772 \ .. '10 ' .. repeat('j', 57)
3773 \ .. '11 ' .. repeat('k', 57)
3774 \ .. '12 ' .. repeat('l', 57)
3775 \ .. '13 ' .. repeat('m', 57)
3776 \ .. '14 ' .. repeat('n', 57)
3777 \ .. '15 ' .. repeat('o', 57)
3778 \ .. '16 ' .. repeat('p', 57)
3779 \ .. '17 ' .. repeat('q', 57)
3780 \ .. '18 ' .. repeat('r', 57)
3781 \ .. '19 ' .. repeat('s', 57)
3782 \ .. '20 ' .. repeat('t', 57)
3783 \ .. '21 ' .. repeat('u', 57)
3784 \ .. '22 ' .. repeat('v', 57)
3785 \ .. '23 ' .. repeat('w', 57)
3786 \ .. '24 ' .. repeat('x', 57)
3787 \ .. '25 ' .. repeat('y', 57)
3788 \ .. '26 ' .. repeat('z', 57)
3789 \ )
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003790 set scrolloff=10
3791 normal gg10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003792 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003793 normal 10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003794 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003795 normal 10gk
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003796 call assert_equal(6, winline())
3797 normal 0
3798 call assert_equal(1, winline())
3799 normal $
3800 call assert_equal(10, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003801
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003802 set scrolloff&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003803 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003804endfunc
3805
3806" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3807func Test_normal_vert_scroll_longline()
3808 10new
3809 80vnew
3810 call setline(1, range(1, 10))
3811 call append(5, repeat('a', 1000))
3812 exe "normal gg\<C-F>"
3813 call assert_equal(6, line('.'))
3814 exe "normal \<C-F>\<C-F>"
3815 call assert_equal(11, line('.'))
3816 call assert_equal(1, winline())
3817 exe "normal \<C-B>"
3818 call assert_equal(10, line('.'))
3819 call assert_equal(3, winline())
3820 exe "normal \<C-B>\<C-B>"
3821 call assert_equal(5, line('.'))
3822 call assert_equal(5, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003823
3824 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003825endfunc
3826
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003827" Test for jumping in a file using %
3828func Test_normal_percent_jump()
3829 new
3830 call setline(1, range(1, 100))
3831
3832 " jumping to a folded line should open the fold
3833 25,75fold
3834 call feedkeys('50%', 'xt')
3835 call assert_equal(50, line('.'))
3836 call assert_equal(-1, foldclosedend(50))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003837
3838 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003839endfunc
3840
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003841" Test for << and >> commands to shift text by 'shiftwidth'
3842func Test_normal_shift_rightleft()
3843 new
3844 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3845 set shiftwidth=2 tabstop=8
3846 normal gg6>>
3847 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3848 \ getline(1, '$'))
3849 normal ggVG2>>
3850 call assert_equal([' one', '', "\t ", "\ttwo",
3851 \ "\t three", "\t four"], getline(1, '$'))
3852 normal gg6<<
3853 call assert_equal([' one', '', "\t ", ' two', "\t three",
3854 \ "\t four"], getline(1, '$'))
3855 normal ggVG2<<
3856 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3857 \ getline(1, '$'))
3858 set shiftwidth& tabstop&
3859 bw!
3860endfunc
3861
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003862" Some commands like yy, cc, dd, >>, << and !! accept a count after
3863" typing the first letter of the command.
3864func Test_normal_count_after_operator()
3865 new
3866 setlocal shiftwidth=4 tabstop=8 autoindent
3867 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3868 let @a = ''
3869 normal! j"ay4y
3870 call assert_equal("two\nthree\nfour\nfive\n", @a)
3871 normal! 3G>2>
3872 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3873 \ getline(1, '$'))
3874 exe "normal! 3G0c2cred\nblue"
3875 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3876 \ getline(1, '$'))
3877 exe "normal! gg<8<"
3878 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3879 \ getline(1, '$'))
3880 exe "normal! ggd3d"
3881 call assert_equal(['blue', 'five'], getline(1, '$'))
3882 call setline(1, range(1, 4))
3883 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3884 call assert_equal('".,.+2!', @:)
3885 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3886 call assert_equal('".!', @:)
3887 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3888 call assert_equal('".,$!', @:)
3889 bw!
3890endfunc
3891
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003892func Test_normal_gj_on_extra_wide_char()
3893 new | 25vsp
3894 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3895 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3896 \ ' dreizehn v ierzehn fünfzehn'
3897 put =text
3898 call cursor(2,1)
3899 norm! gj
3900 call assert_equal([0,2,25,0], getpos('.'))
3901 bw!
3902endfunc
3903
Bram Moolenaar03725c52021-11-24 12:17:53 +00003904func Test_normal_count_out_of_range()
3905 new
3906 call setline(1, 'text')
3907 normal 44444444444|
3908 call assert_equal(999999999, v:count)
3909 normal 444444444444|
3910 call assert_equal(999999999, v:count)
3911 normal 4444444444444|
3912 call assert_equal(999999999, v:count)
3913 normal 4444444444444444444|
3914 call assert_equal(999999999, v:count)
3915
3916 normal 9y99999999|
3917 call assert_equal(899999991, v:count)
3918 normal 10y99999999|
3919 call assert_equal(999999999, v:count)
3920 normal 44444444444y44444444444|
3921 call assert_equal(999999999, v:count)
3922 bwipe!
3923endfunc
3924
zeertzjqcdeb6572022-11-15 13:46:12 +00003925" Test that mouse shape is restored to Normal mode after failed "c" operation.
3926func Test_mouse_shape_after_failed_change()
3927 CheckFeature mouseshape
3928 CheckCanRunGui
3929
3930 let lines =<< trim END
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003931 vim9script
zeertzjqcdeb6572022-11-15 13:46:12 +00003932 set mouseshape+=o:busy
3933 setlocal nomodifiable
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003934 var mouse_shapes = []
zeertzjqcdeb6572022-11-15 13:46:12 +00003935
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003936 feedkeys('c')
3937 timer_start(50, (_) => {
3938 mouse_shapes += [getmouseshape()]
3939 timer_start(50, (_) => {
3940 feedkeys('c')
3941 timer_start(50, (_) => {
3942 mouse_shapes += [getmouseshape()]
3943 timer_start(50, (_) => {
3944 writefile(mouse_shapes, 'Xmouseshapes')
3945 quit
3946 })
3947 })
3948 })
3949 })
zeertzjqcdeb6572022-11-15 13:46:12 +00003950 END
3951 call writefile(lines, 'Xmouseshape.vim', 'D')
3952 call RunVim([], [], "-g -S Xmouseshape.vim")
3953 sleep 300m
3954 call assert_equal(['busy', 'arrow'], readfile('Xmouseshapes'))
3955
3956 call delete('Xmouseshapes')
3957endfunc
3958
zeertzjqf86dea82023-03-05 21:15:06 +00003959" Test that mouse shape is restored to Normal mode after cancelling "gr".
3960func Test_mouse_shape_after_cancelling_gr()
3961 CheckFeature mouseshape
3962 CheckCanRunGui
3963
3964 let lines =<< trim END
3965 vim9script
3966 var mouse_shapes = []
3967
3968 feedkeys('gr')
3969 timer_start(50, (_) => {
3970 mouse_shapes += [getmouseshape()]
3971 timer_start(50, (_) => {
3972 feedkeys("\<Esc>")
3973 timer_start(50, (_) => {
3974 mouse_shapes += [getmouseshape()]
3975 timer_start(50, (_) => {
3976 writefile(mouse_shapes, 'Xmouseshapes')
3977 quit
3978 })
3979 })
3980 })
3981 })
3982 END
3983 call writefile(lines, 'Xmouseshape.vim', 'D')
3984 call RunVim([], [], "-g -S Xmouseshape.vim")
3985 sleep 300m
3986 call assert_equal(['beam', 'arrow'], readfile('Xmouseshapes'))
3987
3988 call delete('Xmouseshapes')
3989endfunc
3990
Luuk van Baalaa6ba302023-05-09 16:01:17 +01003991" Test that "j" does not skip lines when scrolling below botline and
3992" 'foldmethod' is not "manual".
3993func Test_normal_j_below_botline()
3994 CheckScreendump
3995
3996 let lines =<< trim END
3997 set number foldmethod=diff scrolloff=0
3998 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
3999 norm Lj
4000 END
4001 call writefile(lines, 'XNormalJBelowBotline', 'D')
4002 let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
4003
4004 call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
4005
4006 call StopVimInTerminal(buf)
4007endfunc
4008
Christian Brabandt2d63e4b2023-08-12 00:03:57 +02004009" Test for r (replace) command with CTRL_V and CTRL_Q
4010func Test_normal_r_ctrl_v_cmd()
4011 new
4012 call append(0, 'This is a simple test: abcd')
4013 exe "norm! 1gg$r\<C-V>\<C-V>"
4014 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4015 exe "norm! 1gg$hr\<C-Q>\<C-Q>"
4016 call assert_equal(['This is a simple test: ab', ''], getline(1,'$'))
4017 exe "norm! 1gg$2hr\<C-V>x7e"
4018 call assert_equal(['This is a simple test: a~', ''], getline(1,'$'))
4019 exe "norm! 1gg$3hr\<C-Q>x7e"
4020 call assert_equal(['This is a simple test: ~~', ''], getline(1,'$'))
4021
4022 if &encoding == 'utf-8'
4023 exe "norm! 1gg$4hr\<C-V>u20ac"
4024 call assert_equal(['This is a simple test:€~~', ''], getline(1,'$'))
4025 exe "norm! 1gg$5hr\<C-Q>u20ac"
4026 call assert_equal(['This is a simple test€€~~', ''], getline(1,'$'))
4027 exe "norm! 1gg0R\<C-V>xff WAS \<esc>"
4028 call assert_equal(['ÿ WAS a simple test€€~~', ''], getline(1,'$'))
4029 exe "norm! 1gg0elR\<C-Q>xffNOT\<esc>"
4030 call assert_equal(['ÿ WASÿNOT simple test€€~~', ''], getline(1,'$'))
4031 endif
4032
4033 call setline(1, 'This is a simple test: abcd')
4034 exe "norm! 1gg$gr\<C-V>\<C-V>"
4035 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4036 exe "norm! 1gg$hgr\<C-Q>\<C-Q>"
4037 call assert_equal(['This is a simple test: ab ', ''], getline(1,'$'))
4038 exe "norm! 1gg$2hgr\<C-V>x7e"
4039 call assert_equal(['This is a simple test: a~ ', ''], getline(1,'$'))
4040 exe "norm! 1gg$3hgr\<C-Q>x7e"
4041 call assert_equal(['This is a simple test: ~~ ', ''], getline(1,'$'))
4042
4043 " clean up
4044 bw!
4045endfunc
4046
zeertzjqb25dbb32023-08-13 18:11:05 +02004047" Test clicking on a TAB or an unprintable character in Normal mode
4048func Test_normal_click_on_ctrl_char()
4049 let save_mouse = &mouse
4050 set mouse=a
4051 new
4052
4053 call setline(1, "a\<Tab>b\<C-K>c")
4054 redraw
4055 call test_setmouse(1, 1)
4056 call feedkeys("\<LeftMouse>", 'xt')
4057 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4058 call test_setmouse(1, 2)
4059 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004060 call assert_equal([0, 1, 2, 0, 2], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004061 call test_setmouse(1, 3)
4062 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004063 call assert_equal([0, 1, 2, 0, 3], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004064 call test_setmouse(1, 7)
4065 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004066 call assert_equal([0, 1, 2, 0, 7], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004067 call test_setmouse(1, 8)
4068 call feedkeys("\<LeftMouse>", 'xt')
4069 call assert_equal([0, 1, 2, 0, 8], getcurpos())
4070 call test_setmouse(1, 9)
4071 call feedkeys("\<LeftMouse>", 'xt')
4072 call assert_equal([0, 1, 3, 0, 9], getcurpos())
4073 call test_setmouse(1, 10)
4074 call feedkeys("\<LeftMouse>", 'xt')
4075 call assert_equal([0, 1, 4, 0, 10], getcurpos())
4076 call test_setmouse(1, 11)
4077 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004078 call assert_equal([0, 1, 4, 0, 11], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004079 call test_setmouse(1, 12)
4080 call feedkeys("\<LeftMouse>", 'xt')
4081 call assert_equal([0, 1, 5, 0, 12], getcurpos())
4082 call test_setmouse(1, 13)
4083 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004084 call assert_equal([0, 1, 5, 0, 13], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004085
4086 bwipe!
4087 let &mouse = save_mouse
4088endfunc
4089
zeertzjq99941602023-08-19 13:08:50 +02004090" Test clicking on a double-width character in Normal mode
4091func Test_normal_click_on_double_width_char()
4092 let save_mouse = &mouse
4093 set mouse=a
4094 new
4095
4096 call setline(1, "口口")
4097 redraw
4098 call test_setmouse(1, 1)
4099 call feedkeys("\<LeftMouse>", 'xt')
4100 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4101 call test_setmouse(1, 2)
4102 call feedkeys("\<LeftMouse>", 'xt')
4103 call assert_equal([0, 1, 1, 0, 2], getcurpos())
4104 call test_setmouse(1, 3)
4105 call feedkeys("\<LeftMouse>", 'xt')
4106 call assert_equal([0, 1, 4, 0, 3], getcurpos())
4107 call test_setmouse(1, 4)
4108 call feedkeys("\<LeftMouse>", 'xt')
4109 call assert_equal([0, 1, 4, 0, 4], getcurpos())
4110
4111 bwipe!
4112 let &mouse = save_mouse
4113endfunc
4114
zeertzjq03cd6972023-09-20 20:08:40 +02004115func Test_normal_click_on_empty_line()
4116 let save_mouse = &mouse
4117 set mouse=a
4118 botright new
4119 call setline(1, ['', '', ''])
4120 let row = win_screenpos(0)[0] + 2
4121 20vsplit
4122 redraw
4123
4124 call test_setmouse(row, 1)
4125 call feedkeys("\<LeftMouse>", 'xt')
4126 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4127 call test_setmouse(row, 2)
4128 call feedkeys("\<LeftMouse>", 'xt')
4129 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4130 call test_setmouse(row, 10)
4131 call feedkeys("\<LeftMouse>", 'xt')
4132 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4133
4134 call test_setmouse(row, 21 + 1)
4135 call feedkeys("\<LeftMouse>", 'xt')
4136 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4137 call test_setmouse(row, 21 + 2)
4138 call feedkeys("\<LeftMouse>", 'xt')
4139 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4140 call test_setmouse(row, 21 + 10)
4141 call feedkeys("\<LeftMouse>", 'xt')
4142 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4143
4144 bwipe!
4145 let &mouse = save_mouse
4146endfunc
4147
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004148func Test_normal33_g_cmd_nonblank()
zeertzjq654bdbb2023-08-20 18:24:20 +02004149 " Test that g<End> goes to the last non-blank char and g$ to the last
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004150 " visible column
4151 20vnew
4152 setlocal nowrap nonumber signcolumn=no
4153 call setline(1, ['fooo fooo fooo fooo fooo fooo fooo fooo '])
zeertzjq654bdbb2023-08-20 18:24:20 +02004154 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004155 call assert_equal(11, col('.'))
4156 normal 0g$
4157 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004158 exe "normal 0g\<kEnd>"
4159 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004160 setlocal wrap
zeertzjq654bdbb2023-08-20 18:24:20 +02004161 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004162 call assert_equal(11, col('.'))
4163 normal 0g$
4164 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004165 exe "normal 0g\<kEnd>"
4166 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004167 bw!
4168endfunc
4169
Christian Brabandt58f9bef2023-11-14 21:02:30 +01004170func Test_normal34_zet_large()
4171 " shouldn't cause overflow
4172 norm! z9765405999999999999
4173endfunc
4174
Gary Johnson9e6549d2023-12-27 19:12:43 +01004175" Test for { and } paragraph movements in a single line
4176func Test_brace_single_line()
4177 let text =<< trim [DATA]
4178 foobar one two three
4179 [DATA]
4180
4181 new
4182 call setline(1, text)
4183 1
4184 norm! 0}
4185
4186 call assert_equal([0, 1, 20, 0], getpos('.'))
4187 norm! {
4188 call assert_equal([0, 1, 1, 0], getpos('.'))
4189 bw!
4190endfunc
4191
Christian Brabandt5d5cbb22024-01-05 18:19:52 +01004192" vim: shiftwidth=2 sts=2 expandtab nofoldenable