blob: 0fd53b501e474119fa7f33fb7398de92aefbd101 [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
2350 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2351 norm! guu
2352 call assert_equal('this is a simple test: äüöss', getline('.'))
2353 norm! gUgU
2354 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2355 norm! gugu
2356 call assert_equal('this is a simple test: äüöss', getline('.'))
2357 norm! gUU
2358 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
2359 norm! 010~
2360 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
2361 norm! V~
2362 call assert_equal('THIS IS A simple test: äüöss', 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
Bram Moolenaar1671f442020-03-10 07:48:13 +01002367 " Test for changing case across lines using 'whichwrap'
2368 call setline(1, ['aaaaaa', 'aaaaaa'])
2369 normal! gg10~
2370 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2371 set whichwrap+=~
2372 normal! gg10~
2373 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2374 set whichwrap&
2375
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002376 " try changing the case with a double byte encoding (DBCS)
2377 %bw!
2378 let enc = &enc
2379 set encoding=cp932
2380 call setline(1, "\u8470")
2381 normal ~
2382 normal gU$gu$gUgUg~g~gugu
2383 call assert_equal("\u8470", getline(1))
2384 let &encoding = enc
2385
Bram Moolenaar1671f442020-03-10 07:48:13 +01002386 " clean up
2387 bw!
2388endfunc
2389
2390" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2391" is available but toupper()/tolower() don't do the right thing.
2392func Test_normal_changecase_turkish()
2393 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002394 try
2395 lang tr_TR.UTF-8
2396 set casemap=
2397 let iupper = toupper('i')
2398 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002399 call setline(1, 'iI')
2400 1normal gUU
2401 call assert_equal("\u0130I", getline(1))
2402 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002403
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002404 call setline(1, 'iI')
2405 1normal guu
2406 call assert_equal("i\u0131", getline(1))
2407 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002408 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002409 call setline(1, 'iI')
2410 1normal gUU
2411 call assert_equal("II", getline(1))
2412 call assert_equal("II", toupper("iI"))
2413
2414 call setline(1, 'iI')
2415 1normal guu
2416 call assert_equal("ii", getline(1))
2417 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002418 else
2419 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2420 endif
2421 set casemap&
2422 call setline(1, 'iI')
2423 1normal gUU
2424 call assert_equal("II", getline(1))
2425 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002426
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002427 call setline(1, 'iI')
2428 1normal guu
2429 call assert_equal("ii", getline(1))
2430 call assert_equal("ii", tolower("iI"))
2431
2432 lang en_US.UTF-8
2433 catch /E197:/
2434 " can't use Turkish locale
2435 throw 'Skipped: Turkish locale not available'
2436 endtry
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002437
2438 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002439endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002440
Bram Moolenaar1671f442020-03-10 07:48:13 +01002441" Test for r (replace) command
2442func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002443 new
2444 call append(0, 'This is a simple test: abcd')
2445 exe "norm! 1gg$r\<cr>"
2446 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2447 exe "norm! 1gg2wlr\<cr>"
2448 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2449 exe "norm! 2gg0W5r\<cr>"
2450 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2451 set autoindent
2452 call setline(2, ['simple test: abc', ''])
2453 exe "norm! 2gg0W5r\<cr>"
2454 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2455 exe "norm! 1ggVr\<cr>"
2456 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2457 call setline(1, 'This is a')
2458 exe "norm! 1gg05rf"
2459 call assert_equal('fffffis a', getline(1))
2460
Bram Moolenaar1671f442020-03-10 07:48:13 +01002461 " When replacing characters, copy characters from above and below lines
2462 " using CTRL-Y and CTRL-E.
2463 " Different code paths are used for utf-8 and latin1 encodings
2464 set showmatch
2465 for enc in ['latin1', 'utf-8']
2466 enew!
2467 let &encoding = enc
2468 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2469 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2470 call assert_equal(' {a}x [b]x', getline(2))
2471 endfor
2472 set showmatch&
2473
2474 " r command should fail in operator pending mode
2475 call assert_beeps('normal! cr')
2476
Bram Moolenaar004a6782020-04-11 17:09:31 +02002477 " replace a tab character in visual mode
2478 %d
2479 call setline(1, ["a\tb", "c\td", "e\tf"])
2480 normal gglvjjrx
2481 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2482
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002483 " replace with a multibyte character (with multiple composing characters)
2484 %d
2485 new
2486 call setline(1, 'aaa')
2487 exe "normal $ra\u0328\u0301"
2488 call assert_equal("aaa\u0328\u0301", getline(1))
2489
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002490 " clean up
2491 set noautoindent
2492 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002493endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002494
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002495" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002496func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002497 new
2498 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2499 1
2500 norm! $g*
2501 call assert_equal('x_foo', @/)
2502 call assert_equal('x_foobar.abc', getline('.'))
2503 norm! $g#
2504 call assert_equal('abc', @/)
2505 call assert_equal('abc.x_foo', getline('.'))
2506
2507 " clean up
2508 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002509endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002510
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002511" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2512" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002513func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002514 call Setup_NewWindow()
2515 " Test for g`
2516 clearjumps
2517 norm! ma10j
2518 let a=execute(':jumps')
2519 " empty jumplist
2520 call assert_equal('>', a[-1:])
2521 norm! g`a
2522 call assert_equal('>', a[-1:])
2523 call assert_equal(1, line('.'))
2524 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002525 call cursor(10, 1)
2526 norm! g'a
2527 call assert_equal('>', a[-1:])
2528 call assert_equal(1, line('.'))
zeertzjq30585e02023-03-06 08:10:04 +00002529 let v:errmsg = ''
zeertzjqf86dea82023-03-05 21:15:06 +00002530 call assert_nobeep("normal! g`\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002531 call assert_equal('', v:errmsg)
zeertzjqf86dea82023-03-05 21:15:06 +00002532 call assert_nobeep("normal! g'\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002533 call assert_equal('', v:errmsg)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002534
2535 " Test for g; and g,
2536 norm! g;
2537 " there is only one change in the changelist
2538 " currently, when we setup the window
2539 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002540 call assert_fails(':norm! g;', 'E662:')
2541 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002542 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002543 call append('$', ['a', 'b', 'c', 'd'])
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002544 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002545 call append('$', ['Z', 'Y', 'X', 'W'])
2546 let a = execute(':changes')
2547 call assert_match('2\s\+0\s\+2', a)
2548 call assert_match('101\s\+0\s\+a', a)
2549 call assert_match('105\s\+0\s\+Z', a)
2550 norm! 3g;
2551 call assert_equal(2, line('.'))
2552 norm! 2g,
2553 call assert_equal(105, line('.'))
2554
2555 " Test for g& - global substitute
2556 %d
2557 call setline(1, range(1,10))
2558 call append('$', ['a', 'b', 'c', 'd'])
2559 $s/\w/&&/g
2560 exe "norm! /[1-8]\<cr>"
2561 norm! g&
2562 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2563
Bram Moolenaar1671f442020-03-10 07:48:13 +01002564 " Jumping to a fold using gg should open the fold
2565 set foldenable
2566 set foldopen+=jump
2567 5,8fold
2568 call feedkeys('6gg', 'xt')
2569 call assert_equal(1, foldlevel('.'))
2570 call assert_equal(-1, foldclosed('.'))
2571 set foldopen-=jump
2572 set foldenable&
2573
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002574 " Test for gv
2575 %d
2576 call append('$', repeat(['abcdefgh'], 8))
2577 exe "norm! 2gg02l\<c-v>2j2ly"
2578 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2579 " in visual mode, gv swaps current and last selected region
2580 exe "norm! G0\<c-v>4k4lgvd"
2581 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2582 exe "norm! G0\<c-v>4k4ly"
2583 exe "norm! gvood"
2584 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Christian Brabandtee17b6f2023-09-09 11:23:50 +02002585 " gv cannot be used in operator pending mode
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002586 call assert_beeps('normal! cgv')
2587 " gv should beep without a previously selected visual area
2588 new
2589 call assert_beeps('normal! gv')
2590 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002591
2592 " Test for gk/gj
2593 %d
2594 15vsp
2595 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002596 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2597 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2598 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002599 $put =lineA
2600 $put =lineB
2601
2602 norm! 3gg0dgk
2603 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2604 set nu
2605 norm! 3gg0gjdgj
2606 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2607
2608 " Test for gJ
2609 norm! 2gggJ
2610 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2611 call assert_equal(16, col('.'))
2612 " shouldn't do anything
2613 norm! 10gJ
2614 call assert_equal(1, col('.'))
2615
2616 " Test for g0 g^ gm g$
2617 exe "norm! 2gg0gji "
2618 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2619 norm! g0yl
2620 call assert_equal(12, col('.'))
2621 call assert_equal(' ', getreg(0))
2622 norm! g$yl
2623 call assert_equal(22, col('.'))
2624 call assert_equal('3', getreg(0))
2625 norm! gmyl
2626 call assert_equal(17, col('.'))
2627 call assert_equal('n', getreg(0))
2628 norm! g^yl
2629 call assert_equal(15, col('.'))
2630 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002631 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002632
Bram Moolenaar74ede802021-05-29 19:18:01 +02002633 " Test for g$ with double-width character half displayed
2634 vsplit
2635 9wincmd |
2636 setlocal nowrap nonumber
2637 call setline(2, 'asdfasdfヨ')
2638 2
2639 normal 0g$
2640 call assert_equal(8, col('.'))
2641 10wincmd |
2642 normal 0g$
2643 call assert_equal(9, col('.'))
2644
2645 setlocal signcolumn=yes
2646 11wincmd |
2647 normal 0g$
2648 call assert_equal(8, col('.'))
2649 12wincmd |
2650 normal 0g$
2651 call assert_equal(9, col('.'))
2652
2653 close
2654
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002655 " Test for g_
2656 call assert_beeps('normal! 100g_')
2657 call setline(2, [' foo ', ' foobar '])
2658 normal! 2ggg_
2659 call assert_equal(5, col('.'))
2660 normal! 2g_
2661 call assert_equal(8, col('.'))
2662
2663 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002664 $put =lineC
2665
2666 " Test for gM
2667 norm! gMyl
2668 call assert_equal(73, col('.'))
2669 call assert_equal('0', getreg(0))
2670 " Test for 20gM
2671 norm! 20gMyl
2672 call assert_equal(29, col('.'))
2673 call assert_equal('S', getreg(0))
2674 " Test for 60gM
2675 norm! 60gMyl
2676 call assert_equal(87, col('.'))
2677 call assert_equal('E', getreg(0))
2678
Bram Moolenaar71c41252021-12-26 15:00:07 +00002679 " Test for gM with Tab characters
2680 call setline('.', "\ta\tb\tc\td\te\tf")
2681 norm! gMyl
2682 call assert_equal(6, col('.'))
2683 call assert_equal("c", getreg(0))
2684
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002685 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002686 call setline('.', lineC)
2687 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002688 set ff=unix
2689 let a=execute(":norm! g\<c-g>")
2690 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2691
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002692 " Test for gI
2693 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002694 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002695
2696 " Test for gi
2697 wincmd c
2698 %d
2699 set tw=0
2700 call setline(1, ['foobar', 'new line'])
2701 norm! A next word
2702 $put ='third line'
2703 norm! gi another word
2704 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002705 call setline(1, 'foobar')
2706 normal! Ggifirst line
2707 call assert_equal('foobarfirst line', getline(1))
2708 " Test gi in 'virtualedit' mode with cursor after the end of the line
2709 set virtualedit=all
2710 call setline(1, 'foo')
2711 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2712 call setline(1, 'foo')
2713 normal! Ggifirst line
2714 call assert_equal('foo first line', getline(1))
2715 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002716
Dominique Pelle923dce22021-11-21 11:36:04 +00002717 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002718 exe "normal! g\<C-\>\<C-G>"
2719 call assert_equal('foo first line', getline('.'))
2720
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002721 " clean up
2722 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002723endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002724
Bram Moolenaarce416b42022-04-03 12:59:34 +01002725func Test_normal_ex_substitute()
2726 " This was hanging on the substitute prompt.
2727 new
2728 call setline(1, 'a')
2729 exe "normal! gggQs/a/b/c\<CR>"
2730 call assert_equal('a', getline(1))
2731 bwipe!
2732endfunc
2733
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002734" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002735func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002736 new
2737
2738 let a = execute(":norm! g\<c-g>")
2739 call assert_equal("\n--No lines in buffer--", a)
2740
Bram Moolenaar1671f442020-03-10 07:48:13 +01002741 " Test for CTRL-G (same as :file)
2742 let a = execute(":norm! \<c-g>")
2743 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2744
Bram Moolenaar05295832018-08-24 22:07:58 +02002745 call setline(1, ['first line', 'second line'])
2746
2747 " Test g CTRL-g with dos, mac and unix file type.
2748 norm! gojll
2749 set ff=dos
2750 let a = execute(":norm! g\<c-g>")
2751 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2752
2753 set ff=mac
2754 let a = execute(":norm! g\<c-g>")
2755 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2756
2757 set ff=unix
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 14 of 23", a)
2760
2761 " Test g CTRL-g in visual mode (v)
2762 let a = execute(":norm! gojllvlg\<c-g>")
2763 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2764
2765 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2766 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2767 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2768
2769 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2770 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2771 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2772
2773 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2774 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2775 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2776
2777 " There should be one byte less with noeol
2778 set bin noeol
2779 let a = execute(":norm! \<Esc>gog\<c-g>")
2780 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2781 set bin & eol&
2782
Bram Moolenaar30276f22019-01-24 17:59:39 +01002783 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002784
Bram Moolenaar30276f22019-01-24 17:59:39 +01002785 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2786 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 +02002787
Bram Moolenaar30276f22019-01-24 17:59:39 +01002788 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2789 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 +02002790
Bram Moolenaar30276f22019-01-24 17:59:39 +01002791 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2792 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 +02002793
Bram Moolenaar30276f22019-01-24 17:59:39 +01002794 set fenc=utf8 bomb
2795 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2796 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 +02002797
Bram Moolenaar30276f22019-01-24 17:59:39 +01002798 set fenc=utf16 bomb
2799 let a = execute(":norm! g\<c-g>")
2800 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 +02002801
Bram Moolenaar30276f22019-01-24 17:59:39 +01002802 set fenc=utf32 bomb
2803 let a = execute(":norm! g\<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(+4 for BOM)", a)
Bram Moolenaar05295832018-08-24 22:07:58 +02002805
Bram Moolenaar30276f22019-01-24 17:59:39 +01002806 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002807
2808 set ff&
2809 bwipe!
2810endfunc
2811
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002812" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002813func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002814 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002815 let a=execute(':norm! 1G0g8')
2816 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002817
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002818 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2819 let a=execute(':norm! 1G$g8')
2820 call assert_equal("\nc3 b6 ", a)
2821
2822 call setline(1, "a\u0302")
2823 let a=execute(':norm! 1G0g8')
2824 call assert_equal("\n61 + cc 82 ", a)
2825
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002826 " clean up
2827 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002828endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002829
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002830" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002831func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002832 new
2833
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002834 " With invalid byte.
2835 call setline(1, "___\xff___")
2836 norm! 1G08g8g
2837 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2838
2839 " With invalid byte before the cursor.
2840 call setline(1, "___\xff___")
2841 norm! 1G$h8g8g
2842 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2843
2844 " With truncated sequence.
2845 call setline(1, "___\xE2\x82___")
2846 norm! 1G08g8g
2847 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2848
2849 " With overlong sequence.
2850 call setline(1, "___\xF0\x82\x82\xAC___")
2851 norm! 1G08g8g
2852 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2853
2854 " With valid utf8.
2855 call setline(1, "café")
2856 norm! 1G08g8
2857 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2858
2859 bw!
2860endfunc
2861
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002862" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002863func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002864 " Cannot capture its output,
2865 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002866 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002867 echo "a\nb\nc\nd"
2868 let b=execute(':norm! g<')
2869 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002870endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002871
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002872" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002873func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002874 new
2875 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002876 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002877 " Test for gp gP
2878 call append(1, range(1,10))
2879 1
2880 norm! 1yy
2881 3
2882 norm! gp
2883 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2884 $
2885 norm! gP
2886 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2887
2888 " Test for go
2889 norm! 26go
2890 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2891 norm! 27go
2892 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2893 norm! 28go
2894 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2895 set ff=dos
2896 norm! 29go
2897 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2898 set ff=unix
2899 norm! gg0
2900 norm! 101go
2901 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2902 norm! 103go
2903 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2904 " count > buffer content
2905 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002906 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002907 " clean up
2908 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002909endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002910
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002911" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002912func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002913 tabnew 1.txt
2914 tabnew 2.txt
2915 tabnew 3.txt
2916 norm! 1gt
2917 call assert_equal(1, tabpagenr())
2918 norm! 3gt
2919 call assert_equal(3, tabpagenr())
2920 norm! 1gT
2921 " count gT goes not to the absolute tabpagenumber
2922 " but, but goes to the count previous tabpagenumber
2923 call assert_equal(2, tabpagenr())
2924 " wrap around
2925 norm! 3gT
2926 call assert_equal(3, tabpagenr())
2927 " gt does not wrap around
2928 norm! 5gt
2929 call assert_equal(3, tabpagenr())
2930
2931 for i in range(3)
2932 tabclose
2933 endfor
2934 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002935 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002936endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002937
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002938" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002939func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002940 new
2941 call setline(1, range(10))
2942 $
2943 setl et sw=2
2944 norm! V10>$
2945 " count is ignored
2946 exe "norm! 10\<home>"
2947 call assert_equal(1, col('.'))
2948 exe "norm! \<home>"
2949 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2950 exe "norm! 5\<c-home>"
2951 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2952 exe "norm! \<c-home>"
2953 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002954 exe "norm! G\<c-kHome>"
2955 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002956
2957 " clean up
2958 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002959endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002960
Bram Moolenaar1671f442020-03-10 07:48:13 +01002961" Test for <End> and <C-End> keys
2962func Test_normal_nvend()
2963 new
2964 call setline(1, map(range(1, 10), '"line" .. v:val'))
2965 exe "normal! \<End>"
2966 call assert_equal(5, col('.'))
2967 exe "normal! 4\<End>"
2968 call assert_equal([4, 5], [line('.'), col('.')])
2969 exe "normal! \<C-End>"
2970 call assert_equal([10, 6], [line('.'), col('.')])
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002971
2972 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01002973endfunc
2974
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002975" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002976func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002977 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002978 new
2979 set tw=0
2980 call append(0, 'here are some words')
2981 norm! 1gg0elcwZZZ
2982 call assert_equal('hereZZZare some words', getline('.'))
2983 norm! 1gg0elcWYYY
2984 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002985 norm! 2gg0cwfoo
2986 call assert_equal('foo', getline('.'))
2987
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002988 call setline(1, 'one; two')
2989 call cursor(1, 1)
2990 call feedkeys('cwvim', 'xt')
2991 call assert_equal('vim; two', getline(1))
2992 call feedkeys('0cWone', 'xt')
2993 call assert_equal('one two', getline(1))
2994 "When cursor is at the end of a word 'ce' will change until the end of the
2995 "next word, but 'cw' will change only one character
2996 call setline(1, 'one two')
2997 call feedkeys('0ecwce', 'xt')
2998 call assert_equal('once two', getline(1))
2999 call setline(1, 'one two')
3000 call feedkeys('0ecely', 'xt')
3001 call assert_equal('only', getline(1))
3002
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003003 " clean up
3004 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003005endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003006
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003007" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003008func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003009 new
3010 call append(0, 'here are some words')
3011 exe "norm! 1gg0a\<C-\>\<C-N>"
3012 call assert_equal('n', mode())
3013 call assert_equal(1, col('.'))
3014 call assert_equal('', visualmode())
3015 exe "norm! 1gg0viw\<C-\>\<C-N>"
3016 call assert_equal('n', mode())
3017 call assert_equal(4, col('.'))
3018 exe "norm! 1gg0a\<C-\>\<C-G>"
3019 call assert_equal('n', mode())
3020 call assert_equal(1, col('.'))
3021 "imap <buffer> , <c-\><c-n>
3022 set im
3023 exe ":norm! \<c-\>\<c-n>dw"
3024 set noim
3025 call assert_equal('are some words', getline(1))
3026 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02003027 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01003028
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003029 " clean up
3030 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003031endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003032
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003033" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003034func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003035 new
3036 set sts=2 sw=2 ts=8 tw=0
3037 call append(0, ["aaa\tbbb\tccc", '', '', ''])
3038 let a=getline(1)
3039 norm! 2gg0
3040 exe "norm! a\<c-r>=a\<cr>"
3041 norm! 3gg0
3042 exe "norm! a\<c-r>\<c-r>=a\<cr>"
3043 norm! 4gg0
3044 exe "norm! a\<c-r>\<c-o>=a\<cr>"
3045 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
3046
3047 " clean up
3048 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02003049 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003050endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003051
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003052" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003053func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003054 call Setup_NewWindow()
3055 call assert_equal(5, &scroll)
3056 exe "norm! \<c-d>"
3057 call assert_equal('6', getline('.'))
3058 exe "norm! 2\<c-d>"
3059 call assert_equal('8', getline('.'))
3060 call assert_equal(2, &scroll)
3061 set scroll=5
3062 exe "norm! \<c-u>"
3063 call assert_equal('3', getline('.'))
3064 1
3065 set scrolloff=5
3066 exe "norm! \<c-d>"
3067 call assert_equal('10', getline('.'))
3068 exe "norm! \<c-u>"
3069 call assert_equal('5', getline('.'))
3070 1
3071 set scrolloff=99
3072 exe "norm! \<c-d>"
3073 call assert_equal('10', getline('.'))
3074 set scrolloff=0
3075 100
3076 exe "norm! $\<c-u>"
3077 call assert_equal('95', getline('.'))
3078 call assert_equal([0, 95, 1, 0, 1], getcurpos())
3079 100
3080 set nostartofline
3081 exe "norm! $\<c-u>"
3082 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00003083 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003084 " cleanup
3085 set startofline
3086 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003087endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003088
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003089func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003090 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003091 " The ~ register does not exist
3092 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003093 return
3094 endif
3095
3096 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003097 " unfortunately, without a gui, we can't really test much here,
3098 " so simply test that ~p fails (which uses the drop register)
3099 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003100 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003101 call assert_equal([], getreg('~', 1, 1))
3102 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003103 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003104 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003105endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003106
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003107func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003108 new
3109 " How to test this?
3110 " let's just for now test, that the buffer
3111 " does not change
3112 call feedkeys("\<c-s>", 't')
3113 call assert_equal([''], getline(1,'$'))
3114
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003115 " no valid commands
3116 exe "norm! \<char-0x100>"
3117 call assert_equal([''], getline(1,'$'))
3118
3119 exe "norm! ä"
3120 call assert_equal([''], getline(1,'$'))
3121
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003122 " clean up
3123 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003124endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003125
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003126func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003127 " This was causing a crash or ml_get error.
3128 enew!
3129 call setline(1,'xxx')
3130 normal $
3131 new
3132 call setline(1, range(1,2))
3133 2
3134 exe "norm \<C-V>$"
3135 bw!
3136 norm yp
3137 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003138endfunc
3139
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003140func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003141 new
3142 exe "norm! \<c-w>c"
3143 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003144 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003145endfunc
3146
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003147func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003148 new
3149 call setline(1, 'one two three four five six seven eight nine ten')
3150 1
3151 norm! 3d2w
3152 call assert_equal('seven eight nine ten', getline(1))
3153 bw!
3154endfunc
3155
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003156func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003157 CheckFeature timers
3158 CheckFeature cmdline_hist
Bram Moolenaarc255b782022-11-26 19:16:48 +00003159
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003160 func! DoTimerWork(id)
3161 call assert_equal('[Command Line]', bufname(''))
Bram Moolenaarc255b782022-11-26 19:16:48 +00003162
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003163 " should fail, with E11, but does fail with E23?
3164 "call feedkeys("\<c-^>", 'tm')
3165
Bram Moolenaarc255b782022-11-26 19:16:48 +00003166 " should fail with E11 - "Invalid in command-line window"
Bram Moolenaare2e40752020-09-04 21:18:46 +02003167 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaarc255b782022-11-26 19:16:48 +00003168
3169 " Return from commandline window.
3170 call feedkeys("\<CR>", 't')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003171 endfunc
3172
3173 let oldlang=v:lang
3174 lang C
3175 set updatetime=20
3176 call timer_start(100, 'DoTimerWork')
3177 try
3178 " throws E23, for whatever reason...
3179 call feedkeys('q:', 'x!')
3180 catch /E23/
3181 " no-op
3182 endtry
Bram Moolenaarc255b782022-11-26 19:16:48 +00003183
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003184 " clean up
Bram Moolenaarc255b782022-11-26 19:16:48 +00003185 delfunc DoTimerWork
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003186 set updatetime=4000
3187 exe "lang" oldlang
3188 bw!
3189endfunc
3190
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003191func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003192 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003193 " Don't sleep after the warning message.
3194 call test_settime(1)
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01003195 call writefile(['foo'], 'Xreadonly.log', 'D')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003196 new Xreadonly.log
3197 setl ro
3198 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003199 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003200 call assert_equal(['foo'], getline(1,'$'))
3201 call assert_equal('Xreadonly.log', bufname(''))
3202
3203 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003204 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003205 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003206endfunc
3207
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003208func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003209 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003210 new
3211 call setline(1, 'abcde fghij klmnopq')
3212 norm! 1gg$
3213 set rl
3214 call assert_equal(19, col('.'))
3215 call feedkeys('l', 'tx')
3216 call assert_equal(18, col('.'))
3217 call feedkeys('h', 'tx')
3218 call assert_equal(19, col('.'))
3219 call feedkeys("\<right>", 'tx')
3220 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003221 call feedkeys("\<left>", 'tx')
3222 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003223 call feedkeys("\<s-right>", 'tx')
3224 call assert_equal(13, col('.'))
3225 call feedkeys("\<c-right>", 'tx')
3226 call assert_equal(7, col('.'))
3227 call feedkeys("\<c-left>", 'tx')
3228 call assert_equal(13, col('.'))
3229 call feedkeys("\<s-left>", 'tx')
3230 call assert_equal(19, col('.'))
3231 call feedkeys("<<", 'tx')
3232 call assert_equal(' abcde fghij klmnopq',getline(1))
3233 call feedkeys(">>", 'tx')
3234 call assert_equal('abcde fghij klmnopq',getline(1))
3235
3236 " cleanup
3237 set norl
3238 bw!
3239endfunc
3240
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003241func Test_normal54_Ctrl_bsl()
3242 new
3243 call setline(1, 'abcdefghijklmn')
3244 exe "norm! df\<c-\>\<c-n>"
3245 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3246 exe "norm! df\<c-\>\<c-g>"
3247 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3248 exe "norm! df\<c-\>m"
3249 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003250
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003251 call setline(2, 'abcdefghijklmnāf')
3252 norm! 2gg0
3253 exe "norm! df\<Char-0x101>"
3254 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3255 norm! 1gg0
3256 exe "norm! df\<esc>"
3257 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003258
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003259 " clean up
3260 bw!
3261endfunc
3262
3263func Test_normal_large_count()
3264 " This may fail with 32bit long, how do we detect that?
3265 new
3266 normal o
3267 normal 6666666666dL
3268 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003269endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003270
3271func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003272 new
3273 normal grádv}
3274 call assert_equal('á', getline(1))
3275 normal grád}
3276 call assert_equal('', getline(1))
3277 bwipe!
3278endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003279
3280" Test for the gr (virtual replace) command
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003281func Test_gr_command()
3282 enew!
zeertzjq4f026ea2023-02-26 14:47:24 +00003283 " Test for the bug fixed by 7.4.387
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003284 let save_cpo = &cpo
3285 call append(0, ['First line', 'Second line', 'Third line'])
3286 exe "normal i\<C-G>u"
3287 call cursor(2, 1)
3288 set cpo-=X
3289 normal 4gro
3290 call assert_equal('oooond line', getline(2))
3291 undo
3292 set cpo+=X
3293 normal 4gro
3294 call assert_equal('ooooecond line', getline(2))
3295 let &cpo = save_cpo
zeertzjq4f026ea2023-02-26 14:47:24 +00003296
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003297 normal! ggvegrx
3298 call assert_equal('xxxxx line', getline(1))
3299 exe "normal! gggr\<C-V>122"
3300 call assert_equal('zxxxx line', getline(1))
zeertzjq4f026ea2023-02-26 14:47:24 +00003301
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003302 set virtualedit=all
3303 normal! 15|grl
3304 call assert_equal('zxxxx line l', getline(1))
3305 set virtualedit&
3306 set nomodifiable
3307 call assert_fails('normal! grx', 'E21:')
3308 call assert_fails('normal! gRx', 'E21:')
zeertzjq4f026ea2023-02-26 14:47:24 +00003309 call assert_nobeep("normal! gr\<Esc>")
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003310 set modifiable&
zeertzjq4f026ea2023-02-26 14:47:24 +00003311
3312 call assert_nobeep("normal! gr\<Esc>")
zeertzjqf86dea82023-03-05 21:15:06 +00003313 call assert_nobeep("normal! cgr\<Esc>")
3314 call assert_beeps("normal! cgrx")
zeertzjq4f026ea2023-02-26 14:47:24 +00003315
3316 call assert_equal('zxxxx line l', getline(1))
3317 exe "normal! 2|gr\<C-V>\<Esc>"
3318 call assert_equal("z\<Esc>xx line l", getline(1))
3319
3320 call setline(1, 'abcdef')
3321 exe "normal! 0gr\<C-O>lx"
3322 call assert_equal("\<C-O>def", getline(1))
3323
3324 call setline(1, 'abcdef')
3325 exe "normal! 0gr\<C-G>lx"
3326 call assert_equal("\<C-G>def", getline(1))
3327
3328 bwipe!
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003329endfunc
3330
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003331func Test_nv_hat_count()
3332 %bwipeout!
3333 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003334 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003335
3336 edit Xfoo
3337 let l:foo_nr = bufnr('Xfoo')
3338
3339 edit Xbar
3340 let l:bar_nr = bufnr('Xbar')
3341
3342 " Make sure we are not just using the alternate file.
3343 edit Xbaz
3344
3345 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3346 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3347
3348 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3349 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3350
3351 %bwipeout!
3352endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003353
3354func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003355 " Make sure no buffers are changed.
3356 %bwipe!
3357
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003358 exe "normal \<C-C>"
3359 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003360
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003361 new
3362 cal setline(1, 'hi!')
3363 exe "normal \<C-C>"
3364 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003365
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003366 bwipe!
3367endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003368
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01003369func Test_mode_updated_after_ctrl_c()
3370 CheckScreendump
3371
3372 let buf = RunVimInTerminal('', {'rows': 5})
3373 call term_sendkeys(buf, "i")
3374 call term_sendkeys(buf, "\<C-O>")
3375 " wait a moment so that the "-- (insert) --" message is displayed
3376 call TermWait(buf, 50)
3377 call term_sendkeys(buf, "\<C-C>")
3378 call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
3379
3380 call StopVimInTerminal(buf)
3381endfunc
3382
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003383" Test for '[m', ']m', '[M' and ']M'
3384" Jumping to beginning and end of methods in Java-like languages
3385func Test_java_motion()
3386 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003387 call assert_beeps('normal! [m')
3388 call assert_beeps('normal! ]m')
3389 call assert_beeps('normal! [M')
3390 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003391 let lines =<< trim [CODE]
3392 Piece of Java
3393 {
3394 tt m1 {
3395 t1;
3396 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003397
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003398 tt m2 {
3399 t2;
3400 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003401
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003402 tt m3 {
3403 if (x)
3404 {
3405 t3;
3406 }
3407 } e3
3408 }
3409 [CODE]
3410 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003411
3412 normal gg
3413
3414 normal 2]maA
3415 call assert_equal("\ttt m1 {A", getline('.'))
3416 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3417
3418 normal j]maB
3419 call assert_equal("\ttt m2 {B", getline('.'))
3420 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3421
3422 normal ]maC
3423 call assert_equal("\ttt m3 {C", getline('.'))
3424 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3425
3426 normal [maD
3427 call assert_equal("\ttt m3 {DC", getline('.'))
3428 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3429
3430 normal k2[maE
3431 call assert_equal("\ttt m1 {EA", getline('.'))
3432 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3433
3434 normal 3[maF
3435 call assert_equal("{F", getline('.'))
3436 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3437
3438 normal ]MaG
3439 call assert_equal("\t}G e1", getline('.'))
3440 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3441
3442 normal j2]MaH
3443 call assert_equal("\t}H e3", getline('.'))
3444 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3445
3446 normal ]M]M
3447 normal aI
3448 call assert_equal("}I", getline('.'))
3449 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3450
3451 normal 2[MaJ
3452 call assert_equal("\t}JH e3", getline('.'))
3453 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3454
3455 normal k[MaK
3456 call assert_equal("\t}K e2", getline('.'))
3457 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3458
3459 normal 3[MaL
3460 call assert_equal("{LF", getline('.'))
3461 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3462
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003463 call cursor(2, 1)
3464 call assert_beeps('norm! 5]m')
3465
3466 " jumping to a method in a fold should open the fold
3467 6,10fold
3468 call feedkeys("gg3]m", 'xt')
3469 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3470 call assert_equal(-1, foldclosedend(7))
3471
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003472 bwipe!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003473endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003474
Bram Moolenaar004a6782020-04-11 17:09:31 +02003475" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003476func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003477 call Setup_NewWindow()
3478 " Make long lines that will wrap
3479 %s/$/\=repeat(' foobar', 10)/
3480 20vsp
3481 set wrap
3482 " Test for g$ with count
3483 norm! gg
3484 norm! 0vg$y
3485 call assert_equal(20, col("'>"))
3486 call assert_equal('1 foobar foobar foob', getreg(0))
3487 norm! gg
3488 norm! 0v4g$y
3489 call assert_equal(72, col("'>"))
3490 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3491 norm! gg
3492 norm! 0v6g$y
3493 call assert_equal(40, col("'>"))
3494 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3495 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3496 set nowrap
3497 " clean up
3498 norm! gg
3499 norm! 0vg$y
3500 call assert_equal(20, col("'>"))
3501 call assert_equal('1 foobar foobar foob', getreg(0))
3502 norm! gg
3503 norm! 0v4g$y
3504 call assert_equal(20, col("'>"))
3505 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3506 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3507 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3508 \ '4 foobar foobar foob', getreg(0))
3509 norm! gg
3510 norm! 0v6g$y
3511 call assert_equal(20, col("'>"))
3512 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3513 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3514 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3515 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3516 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3517 \ '6 foobar foobar foob', getreg(0))
3518 " Move to last line, also down movement is not possible, should still move
3519 " the cursor to the last visible char
3520 norm! G
3521 norm! 0v6g$y
3522 call assert_equal(20, col("'>"))
3523 call assert_equal('100 foobar foobar fo', getreg(0))
3524 bw!
3525endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003526
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003527func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003528 " needs 80 column new window
3529 new
3530 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003531 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003532 put =[repeat('x',90)..' {{{1', 'x {{{1']
3533 norm! gk
3534 " In a 80 column wide terminal the window will be only 78 char
3535 " (because Vim will leave space for the other window),
3536 " but if the terminal is larger, it will be 80 chars, so verify the
3537 " cursor column correctly.
3538 call assert_equal(winwidth(0)+1, col('.'))
3539 call assert_equal(winwidth(0)+1, virtcol('.'))
3540 norm! j
3541 call assert_equal(6, col('.'))
3542 call assert_equal(6, virtcol('.'))
3543 norm! gk
3544 call assert_equal(95, col('.'))
3545 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003546 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003547
3548 " needs 80 column new window
3549 new
3550 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003551 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003552 set number
3553 set numberwidth=10
3554 set cpoptions+=n
3555 put =[repeat('0',90), repeat('1',90)]
3556 norm! 075l
3557 call assert_equal(76, col('.'))
3558 norm! gk
3559 call assert_equal(1, col('.'))
3560 norm! gk
3561 call assert_equal(76, col('.'))
3562 norm! gk
3563 call assert_equal(1, col('.'))
3564 norm! gj
3565 call assert_equal(76, col('.'))
3566 norm! gj
3567 call assert_equal(1, col('.'))
3568 norm! gj
3569 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003570 " When 'nowrap' is set, gk and gj behave like k and j
3571 set nowrap
3572 normal! gk
3573 call assert_equal([2, 76], [line('.'), col('.')])
3574 normal! gj
3575 call assert_equal([3, 76], [line('.'), col('.')])
3576 %bw!
3577 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003578endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003579
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003580" Test for using : to run a multi-line Ex command in operator pending mode
3581func Test_normal_yank_with_excmd()
3582 new
3583 call setline(1, ['foo', 'bar', 'baz'])
3584 let @a = ''
3585 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3586 call assert_equal('f', @a)
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003587
3588 bwipe!
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003589endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003590
3591" Test for supplying a count to a normal-mode command across a cursorhold call
3592func Test_normal_cursorhold_with_count()
3593 func s:cHold()
3594 let g:cHold_Called += 1
3595 endfunc
3596 new
3597 augroup normalcHoldTest
3598 au!
3599 au CursorHold <buffer> call s:cHold()
3600 augroup END
3601 let g:cHold_Called = 0
3602 call feedkeys("3\<CursorHold>2ix", 'xt')
3603 call assert_equal(1, g:cHold_Called)
3604 call assert_equal(repeat('x', 32), getline(1))
3605 augroup normalcHoldTest
3606 au!
3607 augroup END
3608 au! normalcHoldTest
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003609
3610 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003611 delfunc s:cHold
3612endfunc
3613
3614" Test for using a count and a command with CTRL-W
3615func Test_wincmd_with_count()
3616 call feedkeys("\<C-W>12n", 'xt')
3617 call assert_equal(12, winheight(0))
3618endfunc
3619
3620" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003621func Test_horiz_motion()
3622 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003623 normal! gg
3624 call assert_beeps('normal! b')
3625 call assert_beeps('normal! B')
3626 call assert_beeps('normal! gE')
3627 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003628 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3629 call setline(1, 'one ,two ,three')
3630 exe "normal! $\<S-BS>"
3631 call assert_equal(11, col('.'))
3632 exe "normal! $\<C-BS>"
3633 call assert_equal(10, col('.'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003634
3635 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003636endfunc
3637
zeertzjq30b6d612023-05-07 17:39:23 +01003638" Test for using a ":" command in operator pending mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003639func Test_normal_colon_op()
3640 new
3641 call setline(1, ['one', 'two'])
3642 call assert_beeps("normal! Gc:d\<CR>")
zeertzjq30b6d612023-05-07 17:39:23 +01003643 call assert_equal(['one'], getline(1, '$'))
3644
3645 call setline(1, ['one…two…three!'])
3646 normal! $
3647 " Using ":" as a movement is characterwise exclusive
3648 call feedkeys("d:normal! F…\<CR>", 'xt')
3649 call assert_equal(['one…two!'], getline(1, '$'))
3650 " Check that redoing a command with 0x80 bytes works
3651 call feedkeys('.', 'xt')
3652 call assert_equal(['one!'], getline(1, '$'))
3653
3654 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3655 " Add this to the command history
3656 call feedkeys(":normal! G0\<CR>", 'xt')
3657 " Use :normal! with control characters in operator pending mode
3658 call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
3659 call assert_equal(['one', 'two', 'five'], getline(1, '$'))
3660 " Check that redoing a command with control characters works
3661 call feedkeys('.', 'xt')
3662 call assert_equal(['five'], getline(1, '$'))
3663
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003664 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003665endfunc
3666
Bram Moolenaar004a6782020-04-11 17:09:31 +02003667" Test for d and D commands
3668func Test_normal_delete_cmd()
3669 new
3670 " D in an empty line
3671 call setline(1, '')
3672 normal D
3673 call assert_equal('', getline(1))
3674 " D in an empty line in virtualedit mode
3675 set virtualedit=all
3676 normal D
3677 call assert_equal('', getline(1))
3678 set virtualedit&
3679 " delete to a readonly register
3680 call setline(1, ['abcd'])
3681 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003682
3683 " D and d with 'nomodifiable'
3684 call setline(1, ['abcd'])
3685 setlocal nomodifiable
3686 call assert_fails('normal D', 'E21:')
3687 call assert_fails('normal d$', 'E21:')
3688
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003689 bwipe!
Bram Moolenaar004a6782020-04-11 17:09:31 +02003690endfunc
3691
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003692" Test for deleting or changing characters across lines with 'whichwrap'
3693" containing 's'. Should count <EOL> as one character.
3694func Test_normal_op_across_lines()
3695 new
3696 set whichwrap&
3697 call setline(1, ['one two', 'three four'])
3698 exe "norm! $3d\<Space>"
3699 call assert_equal(['one twhree four'], getline(1, '$'))
3700
3701 call setline(1, ['one two', 'three four'])
3702 exe "norm! $3c\<Space>x"
3703 call assert_equal(['one twxhree four'], getline(1, '$'))
3704
3705 set whichwrap+=l
3706 call setline(1, ['one two', 'three four'])
3707 exe "norm! $3x"
3708 call assert_equal(['one twhree four'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003709
3710 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003711 set whichwrap&
3712endfunc
3713
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003714" Test for 'w' and 'b' commands
3715func Test_normal_word_move()
3716 new
3717 call setline(1, ['foo bar a', '', 'foo bar b'])
3718 " copy a single character word at the end of a line
3719 normal 1G$yw
3720 call assert_equal('a', @")
3721 " copy a single character word at the end of a file
3722 normal G$yw
3723 call assert_equal('b', @")
3724 " check for a word movement handling an empty line properly
3725 normal 1G$vwy
3726 call assert_equal("a\n\n", @")
3727
3728 " copy using 'b' command
3729 %d
3730 " non-empty blank line at the start of file
3731 call setline(1, [' ', 'foo bar'])
3732 normal 2Gyb
3733 call assert_equal(" \n", @")
3734 " try to copy backwards from the start of the file
3735 call setline(1, ['one two', 'foo bar'])
3736 call assert_beeps('normal ggyb')
3737 " 'b' command should stop at an empty line
3738 call setline(1, ['one two', '', 'foo bar'])
3739 normal 3Gyb
3740 call assert_equal("\n", @")
3741 normal 3Gy2b
3742 call assert_equal("two\n", @")
3743 " 'b' command should not stop at a non-empty blank line
3744 call setline(1, ['one two', ' ', 'foo bar'])
3745 normal 3Gyb
3746 call assert_equal("two\n ", @")
3747
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003748 bwipe!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003749endfunc
3750
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003751" Test for 'scrolloff' with a long line that doesn't fit in the screen
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003752func Test_normal_scrolloff()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003753 10new
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003754 60vnew
3755 call setline(1, ' 1 ' .. repeat('a', 57)
3756 \ .. ' 2 ' .. repeat('b', 57)
3757 \ .. ' 3 ' .. repeat('c', 57)
3758 \ .. ' 4 ' .. repeat('d', 57)
3759 \ .. ' 5 ' .. repeat('e', 57)
3760 \ .. ' 6 ' .. repeat('f', 57)
3761 \ .. ' 7 ' .. repeat('g', 57)
3762 \ .. ' 8 ' .. repeat('h', 57)
3763 \ .. ' 9 ' .. repeat('i', 57)
3764 \ .. '10 ' .. repeat('j', 57)
3765 \ .. '11 ' .. repeat('k', 57)
3766 \ .. '12 ' .. repeat('l', 57)
3767 \ .. '13 ' .. repeat('m', 57)
3768 \ .. '14 ' .. repeat('n', 57)
3769 \ .. '15 ' .. repeat('o', 57)
3770 \ .. '16 ' .. repeat('p', 57)
3771 \ .. '17 ' .. repeat('q', 57)
3772 \ .. '18 ' .. repeat('r', 57)
3773 \ .. '19 ' .. repeat('s', 57)
3774 \ .. '20 ' .. repeat('t', 57)
3775 \ .. '21 ' .. repeat('u', 57)
3776 \ .. '22 ' .. repeat('v', 57)
3777 \ .. '23 ' .. repeat('w', 57)
3778 \ .. '24 ' .. repeat('x', 57)
3779 \ .. '25 ' .. repeat('y', 57)
3780 \ .. '26 ' .. repeat('z', 57)
3781 \ )
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003782 set scrolloff=10
3783 normal gg10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003784 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003785 normal 10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003786 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003787 normal 10gk
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003788 call assert_equal(6, winline())
3789 normal 0
3790 call assert_equal(1, winline())
3791 normal $
3792 call assert_equal(10, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003793
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003794 set scrolloff&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003795 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003796endfunc
3797
3798" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3799func Test_normal_vert_scroll_longline()
3800 10new
3801 80vnew
3802 call setline(1, range(1, 10))
3803 call append(5, repeat('a', 1000))
3804 exe "normal gg\<C-F>"
3805 call assert_equal(6, line('.'))
3806 exe "normal \<C-F>\<C-F>"
3807 call assert_equal(11, line('.'))
3808 call assert_equal(1, winline())
3809 exe "normal \<C-B>"
3810 call assert_equal(10, line('.'))
3811 call assert_equal(3, winline())
3812 exe "normal \<C-B>\<C-B>"
3813 call assert_equal(5, line('.'))
3814 call assert_equal(5, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003815
3816 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003817endfunc
3818
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003819" Test for jumping in a file using %
3820func Test_normal_percent_jump()
3821 new
3822 call setline(1, range(1, 100))
3823
3824 " jumping to a folded line should open the fold
3825 25,75fold
3826 call feedkeys('50%', 'xt')
3827 call assert_equal(50, line('.'))
3828 call assert_equal(-1, foldclosedend(50))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003829
3830 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003831endfunc
3832
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003833" Test for << and >> commands to shift text by 'shiftwidth'
3834func Test_normal_shift_rightleft()
3835 new
3836 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3837 set shiftwidth=2 tabstop=8
3838 normal gg6>>
3839 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3840 \ getline(1, '$'))
3841 normal ggVG2>>
3842 call assert_equal([' one', '', "\t ", "\ttwo",
3843 \ "\t three", "\t four"], getline(1, '$'))
3844 normal gg6<<
3845 call assert_equal([' one', '', "\t ", ' two', "\t three",
3846 \ "\t four"], getline(1, '$'))
3847 normal ggVG2<<
3848 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3849 \ getline(1, '$'))
3850 set shiftwidth& tabstop&
3851 bw!
3852endfunc
3853
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003854" Some commands like yy, cc, dd, >>, << and !! accept a count after
3855" typing the first letter of the command.
3856func Test_normal_count_after_operator()
3857 new
3858 setlocal shiftwidth=4 tabstop=8 autoindent
3859 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3860 let @a = ''
3861 normal! j"ay4y
3862 call assert_equal("two\nthree\nfour\nfive\n", @a)
3863 normal! 3G>2>
3864 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3865 \ getline(1, '$'))
3866 exe "normal! 3G0c2cred\nblue"
3867 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3868 \ getline(1, '$'))
3869 exe "normal! gg<8<"
3870 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3871 \ getline(1, '$'))
3872 exe "normal! ggd3d"
3873 call assert_equal(['blue', 'five'], getline(1, '$'))
3874 call setline(1, range(1, 4))
3875 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3876 call assert_equal('".,.+2!', @:)
3877 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3878 call assert_equal('".!', @:)
3879 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3880 call assert_equal('".,$!', @:)
3881 bw!
3882endfunc
3883
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003884func Test_normal_gj_on_extra_wide_char()
3885 new | 25vsp
3886 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3887 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3888 \ ' dreizehn v ierzehn fünfzehn'
3889 put =text
3890 call cursor(2,1)
3891 norm! gj
3892 call assert_equal([0,2,25,0], getpos('.'))
3893 bw!
3894endfunc
3895
Bram Moolenaar03725c52021-11-24 12:17:53 +00003896func Test_normal_count_out_of_range()
3897 new
3898 call setline(1, 'text')
3899 normal 44444444444|
3900 call assert_equal(999999999, v:count)
3901 normal 444444444444|
3902 call assert_equal(999999999, v:count)
3903 normal 4444444444444|
3904 call assert_equal(999999999, v:count)
3905 normal 4444444444444444444|
3906 call assert_equal(999999999, v:count)
3907
3908 normal 9y99999999|
3909 call assert_equal(899999991, v:count)
3910 normal 10y99999999|
3911 call assert_equal(999999999, v:count)
3912 normal 44444444444y44444444444|
3913 call assert_equal(999999999, v:count)
3914 bwipe!
3915endfunc
3916
zeertzjqcdeb6572022-11-15 13:46:12 +00003917" Test that mouse shape is restored to Normal mode after failed "c" operation.
3918func Test_mouse_shape_after_failed_change()
3919 CheckFeature mouseshape
3920 CheckCanRunGui
3921
3922 let lines =<< trim END
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003923 vim9script
zeertzjqcdeb6572022-11-15 13:46:12 +00003924 set mouseshape+=o:busy
3925 setlocal nomodifiable
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003926 var mouse_shapes = []
zeertzjqcdeb6572022-11-15 13:46:12 +00003927
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003928 feedkeys('c')
3929 timer_start(50, (_) => {
3930 mouse_shapes += [getmouseshape()]
3931 timer_start(50, (_) => {
3932 feedkeys('c')
3933 timer_start(50, (_) => {
3934 mouse_shapes += [getmouseshape()]
3935 timer_start(50, (_) => {
3936 writefile(mouse_shapes, 'Xmouseshapes')
3937 quit
3938 })
3939 })
3940 })
3941 })
zeertzjqcdeb6572022-11-15 13:46:12 +00003942 END
3943 call writefile(lines, 'Xmouseshape.vim', 'D')
3944 call RunVim([], [], "-g -S Xmouseshape.vim")
3945 sleep 300m
3946 call assert_equal(['busy', 'arrow'], readfile('Xmouseshapes'))
3947
3948 call delete('Xmouseshapes')
3949endfunc
3950
zeertzjqf86dea82023-03-05 21:15:06 +00003951" Test that mouse shape is restored to Normal mode after cancelling "gr".
3952func Test_mouse_shape_after_cancelling_gr()
3953 CheckFeature mouseshape
3954 CheckCanRunGui
3955
3956 let lines =<< trim END
3957 vim9script
3958 var mouse_shapes = []
3959
3960 feedkeys('gr')
3961 timer_start(50, (_) => {
3962 mouse_shapes += [getmouseshape()]
3963 timer_start(50, (_) => {
3964 feedkeys("\<Esc>")
3965 timer_start(50, (_) => {
3966 mouse_shapes += [getmouseshape()]
3967 timer_start(50, (_) => {
3968 writefile(mouse_shapes, 'Xmouseshapes')
3969 quit
3970 })
3971 })
3972 })
3973 })
3974 END
3975 call writefile(lines, 'Xmouseshape.vim', 'D')
3976 call RunVim([], [], "-g -S Xmouseshape.vim")
3977 sleep 300m
3978 call assert_equal(['beam', 'arrow'], readfile('Xmouseshapes'))
3979
3980 call delete('Xmouseshapes')
3981endfunc
3982
Luuk van Baalaa6ba302023-05-09 16:01:17 +01003983" Test that "j" does not skip lines when scrolling below botline and
3984" 'foldmethod' is not "manual".
3985func Test_normal_j_below_botline()
3986 CheckScreendump
3987
3988 let lines =<< trim END
3989 set number foldmethod=diff scrolloff=0
3990 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
3991 norm Lj
3992 END
3993 call writefile(lines, 'XNormalJBelowBotline', 'D')
3994 let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
3995
3996 call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
3997
3998 call StopVimInTerminal(buf)
3999endfunc
4000
Christian Brabandt2d63e4b2023-08-12 00:03:57 +02004001" Test for r (replace) command with CTRL_V and CTRL_Q
4002func Test_normal_r_ctrl_v_cmd()
4003 new
4004 call append(0, 'This is a simple test: abcd')
4005 exe "norm! 1gg$r\<C-V>\<C-V>"
4006 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4007 exe "norm! 1gg$hr\<C-Q>\<C-Q>"
4008 call assert_equal(['This is a simple test: ab', ''], getline(1,'$'))
4009 exe "norm! 1gg$2hr\<C-V>x7e"
4010 call assert_equal(['This is a simple test: a~', ''], getline(1,'$'))
4011 exe "norm! 1gg$3hr\<C-Q>x7e"
4012 call assert_equal(['This is a simple test: ~~', ''], getline(1,'$'))
4013
4014 if &encoding == 'utf-8'
4015 exe "norm! 1gg$4hr\<C-V>u20ac"
4016 call assert_equal(['This is a simple test:€~~', ''], getline(1,'$'))
4017 exe "norm! 1gg$5hr\<C-Q>u20ac"
4018 call assert_equal(['This is a simple test€€~~', ''], getline(1,'$'))
4019 exe "norm! 1gg0R\<C-V>xff WAS \<esc>"
4020 call assert_equal(['ÿ WAS a simple test€€~~', ''], getline(1,'$'))
4021 exe "norm! 1gg0elR\<C-Q>xffNOT\<esc>"
4022 call assert_equal(['ÿ WASÿNOT simple test€€~~', ''], getline(1,'$'))
4023 endif
4024
4025 call setline(1, 'This is a simple test: abcd')
4026 exe "norm! 1gg$gr\<C-V>\<C-V>"
4027 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4028 exe "norm! 1gg$hgr\<C-Q>\<C-Q>"
4029 call assert_equal(['This is a simple test: ab ', ''], getline(1,'$'))
4030 exe "norm! 1gg$2hgr\<C-V>x7e"
4031 call assert_equal(['This is a simple test: a~ ', ''], getline(1,'$'))
4032 exe "norm! 1gg$3hgr\<C-Q>x7e"
4033 call assert_equal(['This is a simple test: ~~ ', ''], getline(1,'$'))
4034
4035 " clean up
4036 bw!
4037endfunc
4038
zeertzjqb25dbb32023-08-13 18:11:05 +02004039" Test clicking on a TAB or an unprintable character in Normal mode
4040func Test_normal_click_on_ctrl_char()
4041 let save_mouse = &mouse
4042 set mouse=a
4043 new
4044
4045 call setline(1, "a\<Tab>b\<C-K>c")
4046 redraw
4047 call test_setmouse(1, 1)
4048 call feedkeys("\<LeftMouse>", 'xt')
4049 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4050 call test_setmouse(1, 2)
4051 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004052 call assert_equal([0, 1, 2, 0, 2], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004053 call test_setmouse(1, 3)
4054 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004055 call assert_equal([0, 1, 2, 0, 3], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004056 call test_setmouse(1, 7)
4057 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004058 call assert_equal([0, 1, 2, 0, 7], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004059 call test_setmouse(1, 8)
4060 call feedkeys("\<LeftMouse>", 'xt')
4061 call assert_equal([0, 1, 2, 0, 8], getcurpos())
4062 call test_setmouse(1, 9)
4063 call feedkeys("\<LeftMouse>", 'xt')
4064 call assert_equal([0, 1, 3, 0, 9], getcurpos())
4065 call test_setmouse(1, 10)
4066 call feedkeys("\<LeftMouse>", 'xt')
4067 call assert_equal([0, 1, 4, 0, 10], getcurpos())
4068 call test_setmouse(1, 11)
4069 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004070 call assert_equal([0, 1, 4, 0, 11], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004071 call test_setmouse(1, 12)
4072 call feedkeys("\<LeftMouse>", 'xt')
4073 call assert_equal([0, 1, 5, 0, 12], getcurpos())
4074 call test_setmouse(1, 13)
4075 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004076 call assert_equal([0, 1, 5, 0, 13], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004077
4078 bwipe!
4079 let &mouse = save_mouse
4080endfunc
4081
zeertzjq99941602023-08-19 13:08:50 +02004082" Test clicking on a double-width character in Normal mode
4083func Test_normal_click_on_double_width_char()
4084 let save_mouse = &mouse
4085 set mouse=a
4086 new
4087
4088 call setline(1, "口口")
4089 redraw
4090 call test_setmouse(1, 1)
4091 call feedkeys("\<LeftMouse>", 'xt')
4092 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4093 call test_setmouse(1, 2)
4094 call feedkeys("\<LeftMouse>", 'xt')
4095 call assert_equal([0, 1, 1, 0, 2], getcurpos())
4096 call test_setmouse(1, 3)
4097 call feedkeys("\<LeftMouse>", 'xt')
4098 call assert_equal([0, 1, 4, 0, 3], getcurpos())
4099 call test_setmouse(1, 4)
4100 call feedkeys("\<LeftMouse>", 'xt')
4101 call assert_equal([0, 1, 4, 0, 4], getcurpos())
4102
4103 bwipe!
4104 let &mouse = save_mouse
4105endfunc
4106
zeertzjq03cd6972023-09-20 20:08:40 +02004107func Test_normal_click_on_empty_line()
4108 let save_mouse = &mouse
4109 set mouse=a
4110 botright new
4111 call setline(1, ['', '', ''])
4112 let row = win_screenpos(0)[0] + 2
4113 20vsplit
4114 redraw
4115
4116 call test_setmouse(row, 1)
4117 call feedkeys("\<LeftMouse>", 'xt')
4118 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4119 call test_setmouse(row, 2)
4120 call feedkeys("\<LeftMouse>", 'xt')
4121 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4122 call test_setmouse(row, 10)
4123 call feedkeys("\<LeftMouse>", 'xt')
4124 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4125
4126 call test_setmouse(row, 21 + 1)
4127 call feedkeys("\<LeftMouse>", 'xt')
4128 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4129 call test_setmouse(row, 21 + 2)
4130 call feedkeys("\<LeftMouse>", 'xt')
4131 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4132 call test_setmouse(row, 21 + 10)
4133 call feedkeys("\<LeftMouse>", 'xt')
4134 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4135
4136 bwipe!
4137 let &mouse = save_mouse
4138endfunc
4139
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004140func Test_normal33_g_cmd_nonblank()
zeertzjq654bdbb2023-08-20 18:24:20 +02004141 " Test that g<End> goes to the last non-blank char and g$ to the last
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004142 " visible column
4143 20vnew
4144 setlocal nowrap nonumber signcolumn=no
4145 call setline(1, ['fooo fooo fooo fooo fooo fooo fooo fooo '])
zeertzjq654bdbb2023-08-20 18:24:20 +02004146 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004147 call assert_equal(11, col('.'))
4148 normal 0g$
4149 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004150 exe "normal 0g\<kEnd>"
4151 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004152 setlocal wrap
zeertzjq654bdbb2023-08-20 18:24:20 +02004153 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004154 call assert_equal(11, col('.'))
4155 normal 0g$
4156 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004157 exe "normal 0g\<kEnd>"
4158 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004159 bw!
4160endfunc
4161
Christian Brabandt58f9bef2023-11-14 21:02:30 +01004162func Test_normal34_zet_large()
4163 " shouldn't cause overflow
4164 norm! z9765405999999999999
4165endfunc
4166
Gary Johnson9e6549d2023-12-27 19:12:43 +01004167" Test for { and } paragraph movements in a single line
4168func Test_brace_single_line()
4169 let text =<< trim [DATA]
4170 foobar one two three
4171 [DATA]
4172
4173 new
4174 call setline(1, text)
4175 1
4176 norm! 0}
4177
4178 call assert_equal([0, 1, 20, 0], getpos('.'))
4179 norm! {
4180 call assert_equal([0, 1, 1, 0], getpos('.'))
4181 bw!
4182endfunc
4183
Christian Brabandt5d5cbb22024-01-05 18:19:52 +01004184" vim: shiftwidth=2 sts=2 expandtab nofoldenable