blob: 1acdfcecbb129449092244d353d65829007b4635 [file] [log] [blame]
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001" Test for various Normal mode commands
2
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003source shared.vim
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01004source check.vim
Bram Moolenaarca68ae12020-03-30 19:32:53 +02005source view_util.vim
Bram Moolenaar62aec932022-01-29 21:45:34 +00006import './vim9.vim' as v9
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01007source screendump.vim
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01008
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01009func Setup_NewWindow()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020010 10new
11 call setline(1, range(1,100))
12endfunc
13
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010014func MyFormatExpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020015 " Adds '->$' at lines having numbers followed by trailing whitespace
16 for ln in range(v:lnum, v:lnum+v:count-1)
17 let line = getline(ln)
18 if getline(ln) =~# '\d\s\+$'
19 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
20 endif
21 endfor
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020022endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020023
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010024func CountSpaces(type, ...)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020025 " for testing operatorfunc
26 " will count the number of spaces
27 " and return the result in g:a
28 let sel_save = &selection
29 let &selection = "inclusive"
30 let reg_save = @@
31
32 if a:0 " Invoked from Visual mode, use gv command.
33 silent exe "normal! gvy"
34 elseif a:type == 'line'
35 silent exe "normal! '[V']y"
36 else
37 silent exe "normal! `[v`]y"
38 endif
Bram Moolenaar777e7c22021-10-25 17:07:04 +010039 let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020040 let &selection = sel_save
41 let @@ = reg_save
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020042endfunc
43
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010044func OpfuncDummy(type, ...)
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010045 " for testing operatorfunc
Bram Moolenaar777e7c22021-10-25 17:07:04 +010046 let g:opt = &linebreak
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010047
48 if a:0 " Invoked from Visual mode, use gv command.
49 silent exe "normal! gvy"
50 elseif a:type == 'line'
51 silent exe "normal! '[V']y"
52 else
53 silent exe "normal! `[v`]y"
54 endif
55 " Create a new dummy window
56 new
Bram Moolenaar777e7c22021-10-25 17:07:04 +010057 let g:bufnr = bufnr('%')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020058endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020059
Bram Moolenaar1671f442020-03-10 07:48:13 +010060func Test_normal00_optrans()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020061 new
62 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
63 1
64 exe "norm! Sfoobar\<esc>"
65 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
66 2
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020067 exe "norm! $vbsone"
68 call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020069 norm! VS Second line here
70 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
71 %d
72 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
73 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
74
75 1
76 norm! 2D
77 call assert_equal(['3 this is the third line', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
78 set cpo+=#
79 norm! 4D
80 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
81
82 " clean up
83 set cpo-=#
84 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020085endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020086
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010087func Test_normal01_keymodel()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020088 call Setup_NewWindow()
89 " Test 1: depending on 'keymodel' <s-down> does something different
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020090 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020091 call feedkeys("V\<S-Up>y", 'tx')
92 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020093 set keymodel=startsel
94 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020095 call feedkeys("V\<S-Up>y", 'tx')
96 call assert_equal(['49', '50'], getline("'<", "'>"))
97 " Start visual mode when keymodel = startsel
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020098 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020099 call feedkeys("\<S-Up>y", 'tx')
100 call assert_equal(['49', '5'], getreg(0, 0, 1))
Bram Moolenaar1671f442020-03-10 07:48:13 +0100101 " Use the different Shift special keys
102 50
103 call feedkeys("\<S-Right>\<S-Left>\<S-Up>\<S-Down>\<S-Home>\<S-End>y", 'tx')
104 call assert_equal(['50'], getline("'<", "'>"))
105 call assert_equal(['50', ''], getreg(0, 0, 1))
106
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200107 " Do not start visual mode when keymodel=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200108 set keymodel=
109 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200110 call feedkeys("\<S-Up>y$", 'tx')
111 call assert_equal(['42'], getreg(0, 0, 1))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200112 " Stop visual mode when keymodel=stopsel
113 set keymodel=stopsel
114 50
115 call feedkeys("Vkk\<Up>yy", 'tx')
116 call assert_equal(['47'], getreg(0, 0, 1))
117
118 set keymodel=
119 50
120 call feedkeys("Vkk\<Up>yy", 'tx')
121 call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200122
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200123 " Test for using special keys to start visual selection
124 %d
125 call setline(1, ['red fox tail', 'red fox tail', 'red fox tail'])
126 set keymodel=startsel
127 " Test for <S-PageUp> and <S-PageDown>
128 call cursor(1, 1)
129 call feedkeys("\<S-PageDown>y", 'xt')
130 call assert_equal([0, 1, 1, 0], getpos("'<"))
131 call assert_equal([0, 3, 1, 0], getpos("'>"))
132 call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
Luuk van Baalb9f5b952024-03-26 18:46:45 +0100133 call assert_equal([0, 3, 1, 0], getpos("'<"))
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200134 call assert_equal([0, 3, 8, 0], getpos("'>"))
135 " Test for <S-C-Home> and <S-C-End>
136 call cursor(2, 12)
137 call feedkeys("\<S-C-Home>y", 'xt')
138 call assert_equal([0, 1, 1, 0], getpos("'<"))
139 call assert_equal([0, 2, 12, 0], getpos("'>"))
140 call cursor(1, 4)
141 call feedkeys("\<S-C-End>y", 'xt')
142 call assert_equal([0, 1, 4, 0], getpos("'<"))
143 call assert_equal([0, 3, 13, 0], getpos("'>"))
144 " Test for <S-C-Left> and <S-C-Right>
145 call cursor(2, 5)
146 call feedkeys("\<S-C-Right>y", 'xt')
147 call assert_equal([0, 2, 5, 0], getpos("'<"))
148 call assert_equal([0, 2, 9, 0], getpos("'>"))
149 call cursor(2, 9)
150 call feedkeys("\<S-C-Left>y", 'xt')
151 call assert_equal([0, 2, 5, 0], getpos("'<"))
152 call assert_equal([0, 2, 9, 0], getpos("'>"))
153
154 set keymodel&
155
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200156 " clean up
157 bw!
158endfunc
159
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100160func Test_normal03_join()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200161 " basic join test
162 call Setup_NewWindow()
163 50
164 norm! VJ
165 call assert_equal('50 51', getline('.'))
166 $
167 norm! J
168 call assert_equal('100', getline('.'))
169 $
170 norm! V9-gJ
171 call assert_equal('919293949596979899100', getline('.'))
172 call setline(1, range(1,100))
173 $
174 :j 10
175 call assert_equal('100', getline('.'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200176 call assert_beeps('normal GVJ')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200177 " clean up
178 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200179endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200180
Bram Moolenaar004a6782020-04-11 17:09:31 +0200181" basic filter test
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100182func Test_normal04_filter()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200183 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200184 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200185 call Setup_NewWindow()
186 1
187 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
188 call assert_equal('| 1', getline('.'))
189 90
190 :sil :!echo one
191 call feedkeys('.', 'tx')
192 call assert_equal('| 90', getline('.'))
193 95
194 set cpo+=!
195 " 2 <CR>, 1: for executing the command,
196 " 2: clear hit-enter-prompt
197 call feedkeys("!!\n", 'tx')
198 call feedkeys(":!echo one\n\n", 'tx')
199 call feedkeys(".", 'tx')
200 call assert_equal('one', getline('.'))
201 set cpo-=!
202 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200203endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200204
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100205func Test_normal05_formatexpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200206 " basic formatexpr test
207 call Setup_NewWindow()
208 %d_
209 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
210 1
211 set formatexpr=MyFormatExpr()
212 norm! gqG
213 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
214 set formatexpr=
215 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200216endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200217
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200218func Test_normal05_formatexpr_newbuf()
219 " Edit another buffer in the 'formatexpr' function
220 new
221 func! Format()
222 edit another
223 endfunc
224 set formatexpr=Format()
225 norm gqG
226 bw!
227 set formatexpr=
228endfunc
229
230func Test_normal05_formatexpr_setopt()
231 " Change the 'formatexpr' value in the function
232 new
233 func! Format()
234 set formatexpr=
235 endfunc
236 set formatexpr=Format()
237 norm gqG
238 bw!
239 set formatexpr=
240endfunc
241
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200242" When 'formatexpr' returns non-zero, internal formatting is used.
243func Test_normal_formatexpr_returns_nonzero()
244 new
245 call setline(1, ['one', 'two'])
246 func! Format()
247 return 1
248 endfunc
249 setlocal formatexpr=Format()
250 normal VGgq
251 call assert_equal(['one two'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +0000252
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200253 setlocal formatexpr=
254 delfunc Format
Yee Cheng Chin1881abf2022-12-08 09:41:24 +0000255 bwipe!
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200256endfunc
257
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000258" Test for using a script-local function for 'formatexpr'
259func Test_formatexpr_scriptlocal_func()
260 func! s:Format()
261 let g:FormatArgs = [v:lnum, v:count]
262 endfunc
263 set formatexpr=s:Format()
264 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000265 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000266 new | only
267 call setline(1, range(1, 40))
268 let g:FormatArgs = []
269 normal! 2GVjgq
270 call assert_equal([2, 2], g:FormatArgs)
271 bw!
272 set formatexpr=<SID>Format()
273 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000274 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000275 new | only
276 call setline(1, range(1, 40))
277 let g:FormatArgs = []
278 normal! 4GVjgq
279 call assert_equal([4, 2], g:FormatArgs)
280 bw!
281 let &formatexpr = 's:Format()'
zeertzjq01d4efe2023-01-25 15:31:28 +0000282 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000283 new | only
284 call setline(1, range(1, 40))
285 let g:FormatArgs = []
286 normal! 6GVjgq
287 call assert_equal([6, 2], g:FormatArgs)
288 bw!
289 let &formatexpr = '<SID>Format()'
zeertzjq01d4efe2023-01-25 15:31:28 +0000290 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000291 new | only
292 call setline(1, range(1, 40))
293 let g:FormatArgs = []
294 normal! 8GVjgq
295 call assert_equal([8, 2], g:FormatArgs)
zeertzjq01d4efe2023-01-25 15:31:28 +0000296 bw!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000297 setlocal formatexpr=
zeertzjq01d4efe2023-01-25 15:31:28 +0000298 setglobal formatexpr=s:Format()
299 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
300 call assert_equal('', &formatexpr)
301 new
302 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
303 call setline(1, range(1, 40))
304 let g:FormatArgs = []
305 normal! 10GVjgq
306 call assert_equal([10, 2], g:FormatArgs)
307 bw!
308 setglobal formatexpr=<SID>Format()
309 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
310 call assert_equal('', &formatexpr)
311 new
312 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
313 call setline(1, range(1, 40))
314 let g:FormatArgs = []
315 normal! 12GVjgq
316 call assert_equal([12, 2], g:FormatArgs)
317 bw!
318 let &g:formatexpr = 's:Format()'
319 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
320 call assert_equal('', &formatexpr)
321 new
322 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
323 call setline(1, range(1, 40))
324 let g:FormatArgs = []
325 normal! 14GVjgq
326 call assert_equal([14, 2], g:FormatArgs)
327 bw!
328 let &g:formatexpr = '<SID>Format()'
329 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
330 call assert_equal('', &formatexpr)
331 new
332 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
333 call setline(1, range(1, 40))
334 let g:FormatArgs = []
335 normal! 16GVjgq
336 call assert_equal([16, 2], g:FormatArgs)
337 bw!
338 set formatexpr=
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000339 delfunc s:Format
340 bw!
341endfunc
342
Bram Moolenaar004a6782020-04-11 17:09:31 +0200343" basic test for formatprg
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100344func Test_normal06_formatprg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200345 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200346 CheckNotMSWindows
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100347
348 " uses sed to number non-empty lines
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100349 call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh', 'D')
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100350 call system('chmod +x ./Xsed_format.sh')
351 let text = ['a', '', 'c', '', ' ', 'd', 'e']
352 let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
353
354 10new
355 call setline(1, text)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200356 set formatprg=./Xsed_format.sh
357 norm! gggqG
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100358 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200359 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100360
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100361 call setline(1, text)
362 set formatprg=donothing
363 setlocal formatprg=./Xsed_format.sh
364 norm! gggqG
365 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200366 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100367
Bram Moolenaar004a6782020-04-11 17:09:31 +0200368 " Check for the command-line ranges added to 'formatprg'
369 set formatprg=cat
370 call setline(1, ['one', 'two', 'three', 'four', 'five'])
371 call feedkeys('gggqG', 'xt')
372 call assert_equal('.,$!cat', @:)
373 call feedkeys('2Ggq2j', 'xt')
374 call assert_equal('.,.+2!cat', @:)
375
376 bw!
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200377 " clean up
378 set formatprg=
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100379 setlocal formatprg=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200380endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200381
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100382func Test_normal07_internalfmt()
Christian Brabandtee17b6f2023-09-09 11:23:50 +0200383 " basic test for internal formatter to textwidth of 12
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200384 let list=range(1,11)
385 call map(list, 'v:val." "')
386 10new
387 call setline(1, list)
388 set tw=12
Bram Moolenaar004a6782020-04-11 17:09:31 +0200389 norm! ggVGgq
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200390 call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
391 " clean up
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100392 set tw=0
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200393 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200394endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200395
Bram Moolenaar004a6782020-04-11 17:09:31 +0200396" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100397func Test_normal08_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +0200398 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200399 call Setup_NewWindow()
400 50
401 setl foldenable fdm=marker
402 " First fold
403 norm! V4jzf
404 " check that folds have been created
405 call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
406 " Second fold
407 46
408 norm! V10jzf
409 " check that folds have been created
410 call assert_equal('46/*{{{*/', getline(46))
411 call assert_equal('60/*}}}*/', getline(60))
412 norm! k
413 call assert_equal('45', getline('.'))
414 norm! j
415 call assert_equal('46/*{{{*/', getline('.'))
416 norm! j
417 call assert_equal('61', getline('.'))
418 norm! k
419 " open a fold
420 norm! Vzo
421 norm! k
422 call assert_equal('45', getline('.'))
423 norm! j
424 call assert_equal('46/*{{{*/', getline('.'))
425 norm! j
426 call assert_equal('47', getline('.'))
427 norm! k
428 norm! zcVzO
429 call assert_equal('46/*{{{*/', getline('.'))
430 norm! j
431 call assert_equal('47', getline('.'))
432 norm! j
433 call assert_equal('48', getline('.'))
434 norm! j
435 call assert_equal('49', getline('.'))
436 norm! j
437 call assert_equal('50/*{{{*/', getline('.'))
438 norm! j
439 call assert_equal('51', getline('.'))
440 " delete folds
441 :46
442 " collapse fold
443 norm! V14jzC
444 " delete all folds recursively
445 norm! VzD
446 call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
447
448 " clean up
449 setl nofoldenable fdm=marker
450 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200451endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200452
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000453func Test_normal09a_operatorfunc()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200454 " Test operatorfunc
455 call Setup_NewWindow()
456 " Add some spaces for counting
457 50,60s/$/ /
458 unlet! g:a
459 let g:a=0
460 nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
461 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
462 50
463 norm V2j,,
464 call assert_equal(6, g:a)
465 norm V,,
466 call assert_equal(2, g:a)
467 norm ,,l
468 call assert_equal(0, g:a)
469 50
470 exe "norm 0\<c-v>10j2l,,"
471 call assert_equal(11, g:a)
472 50
473 norm V10j,,
474 call assert_equal(22, g:a)
475
476 " clean up
477 unmap <buffer> ,,
478 set opfunc=
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100479 unlet! g:a
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200480 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200481endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200482
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000483func Test_normal09b_operatorfunc()
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100484 " Test operatorfunc
485 call Setup_NewWindow()
486 " Add some spaces for counting
487 50,60s/$/ /
488 unlet! g:opt
489 set linebreak
490 nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
491 50
492 norm ,,j
493 exe "bd!" g:bufnr
494 call assert_true(&linebreak)
495 call assert_equal(g:opt, &linebreak)
496 set nolinebreak
497 norm ,,j
498 exe "bd!" g:bufnr
499 call assert_false(&linebreak)
500 call assert_equal(g:opt, &linebreak)
501
502 " clean up
503 unmap <buffer> ,,
504 set opfunc=
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200505 call assert_fails('normal Vg@', 'E774:')
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100506 bw!
507 unlet! g:opt
508endfunc
509
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000510func OperatorfuncRedo(_)
511 let g:opfunc_count = v:count
512endfunc
513
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000514func Underscorize(_)
515 normal! '[V']r_
516endfunc
517
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000518func Test_normal09c_operatorfunc()
519 " Test redoing operatorfunc
520 new
521 call setline(1, 'some text')
522 set operatorfunc=OperatorfuncRedo
523 normal v3g@
524 call assert_equal(3, g:opfunc_count)
525 let g:opfunc_count = 0
526 normal .
527 call assert_equal(3, g:opfunc_count)
528
529 bw!
530 unlet g:opfunc_count
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000531
532 " Test redoing Visual mode
533 set operatorfunc=Underscorize
534 new
535 call setline(1, ['first', 'first', 'third', 'third', 'second'])
naohiro ono5c75eed2022-01-03 11:15:47 +0000536 normal! 1GVjg@
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000537 normal! 5G.
538 normal! 3G.
539 call assert_equal(['_____', '_____', '_____', '_____', '______'], getline(1, '$'))
540 bwipe!
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000541 set operatorfunc=
542endfunc
543
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000544" Test for different ways of setting the 'operatorfunc' option
545func Test_opfunc_callback()
546 new
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000547 func OpFunc1(callnr, type)
548 let g:OpFunc1Args = [a:callnr, a:type]
549 endfunc
550 func OpFunc2(type)
551 let g:OpFunc2Args = [a:type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000552 endfunc
553
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000554 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000555 #" Test for using a function name
556 LET &opfunc = 'g:OpFunc2'
557 LET g:OpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000558 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000559 call assert_equal(['char'], g:OpFunc2Args)
560
561 #" Test for using a function()
562 set opfunc=function('g:OpFunc1',\ [10])
563 LET g:OpFunc1Args = []
564 normal! g@l
565 call assert_equal([10, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000566
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000567 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000568 VAR Fn = function('g:OpFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000569 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000570 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000571 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000572 call assert_equal([11, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000573
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000574 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000575 LET Fn = function('g:OpFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000576 LET &operatorfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000577 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000578 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000579 call assert_equal([12, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000580
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000581 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000582 set operatorfunc=funcref('g:OpFunc1',\ [13])
583 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000584 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000585 call assert_equal([13, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000586
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000587 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000588 LET Fn = funcref('g:OpFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000589 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000590 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000591 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000592 call assert_equal([14, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000593
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000594 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000595 LET Fn = funcref('g:OpFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000596 LET &opfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000597 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000598 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000599 call assert_equal([15, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000600
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000601 #" Test for using a lambda function using set
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000602 VAR optval = "LSTART a LMIDDLE OpFunc1(16, a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000603 LET optval = substitute(optval, ' ', '\\ ', 'g')
604 exe "set opfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000605 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000606 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000607 call assert_equal([16, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000608
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000609 #" Test for using a lambda function using LET
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000610 LET &opfunc = LSTART a LMIDDLE OpFunc1(17, a) LEND
611 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000612 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000613 call assert_equal([17, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000614
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000615 #" Set 'operatorfunc' to a string(lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000616 LET &opfunc = 'LSTART a LMIDDLE OpFunc1(18, a) LEND'
617 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000618 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000619 call assert_equal([18, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000620
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000621 #" Set 'operatorfunc' to a variable with a lambda expression
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000622 VAR Lambda = LSTART a LMIDDLE OpFunc1(19, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000623 LET &opfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000624 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000625 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000626 call assert_equal([19, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000627
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000628 #" Set 'operatorfunc' to a string(variable with a lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000629 LET Lambda = LSTART a LMIDDLE OpFunc1(20, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000630 LET &opfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000631 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000632 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000633 call assert_equal([20, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000634
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000635 #" Try to use 'operatorfunc' after the function is deleted
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000636 func g:TmpOpFunc1(type)
637 let g:TmpOpFunc1Args = [21, a:type]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000638 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000639 LET &opfunc = function('g:TmpOpFunc1')
640 delfunc g:TmpOpFunc1
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000641 call test_garbagecollect_now()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000642 LET g:TmpOpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000643 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000644 call assert_equal([], g:TmpOpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000645
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000646 #" Try to use a function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000647 func g:TmpOpFunc2(x, y)
648 let g:TmpOpFunc2Args = [a:x, a:y]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000649 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000650 set opfunc=TmpOpFunc2
651 LET g:TmpOpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000652 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000653 call assert_equal([], g:TmpOpFunc2Args)
654 delfunc TmpOpFunc2
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000655
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000656 #" Try to use a lambda function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000657 LET &opfunc = LSTART a, b LMIDDLE OpFunc1(22, b) LEND
658 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000659 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000660 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000661
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000662 #" Test for clearing the 'operatorfunc' option
663 set opfunc=''
664 set opfunc&
665 call assert_fails("set opfunc=function('abc')", "E700:")
666 call assert_fails("set opfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000667
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000668 #" set 'operatorfunc' to a non-existing function
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000669 LET &opfunc = function('g:OpFunc1', [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000670 call assert_fails("set opfunc=function('NonExistingFunc')", 'E700:')
671 call assert_fails("LET &opfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000672 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000673 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000674 call assert_equal([23, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000675 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000676 call v9.CheckTransLegacySuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000677
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000678 " Test for using a script-local function name
679 func s:OpFunc3(type)
680 let g:OpFunc3Args = [a:type]
681 endfunc
682 set opfunc=s:OpFunc3
683 let g:OpFunc3Args = []
684 normal! g@l
685 call assert_equal(['char'], g:OpFunc3Args)
686
687 let &opfunc = 's:OpFunc3'
688 let g:OpFunc3Args = []
689 normal! g@l
690 call assert_equal(['char'], g:OpFunc3Args)
691 delfunc s:OpFunc3
692
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000693 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000694 set opfunc=(a)\ =>\ OpFunc1(24,\ a)
695 let g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000696 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000697 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000698
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000699 " set 'operatorfunc' to a partial with dict. This used to cause a crash.
700 func SetOpFunc()
701 let operator = {'execute': function('OperatorExecute')}
702 let &opfunc = operator.execute
703 endfunc
704 func OperatorExecute(_) dict
705 endfunc
706 call SetOpFunc()
707 call test_garbagecollect_now()
708 set operatorfunc=
709 delfunc SetOpFunc
710 delfunc OperatorExecute
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000711
712 " Vim9 tests
713 let lines =<< trim END
714 vim9script
715
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000716 def g:Vim9opFunc(val: number, type: string): void
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000717 g:OpFunc1Args = [val, type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000718 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000719
720 # Test for using a def function with opfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000721 set opfunc=function('g:Vim9opFunc',\ [60])
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000722 g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000723 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000724 assert_equal([60, 'char'], g:OpFunc1Args)
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000725
726 # Test for using a global function name
727 &opfunc = g:OpFunc2
728 g:OpFunc2Args = []
729 normal! g@l
730 assert_equal(['char'], g:OpFunc2Args)
731 bw!
732
733 # Test for using a script-local function name
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000734 def LocalOpFunc(type: string): void
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000735 g:LocalOpFuncArgs = [type]
736 enddef
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000737 &opfunc = LocalOpFunc
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000738 g:LocalOpFuncArgs = []
739 normal! g@l
740 assert_equal(['char'], g:LocalOpFuncArgs)
741 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000742 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000743 call v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000744
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000745 " setting 'opfunc' to a script local function outside of a script context
746 " should fail
747 let cleanup =<< trim END
748 call writefile([execute('messages')], 'Xtest.out')
749 qall
750 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100751 call writefile(cleanup, 'Xverify.vim', 'D')
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000752 call RunVim([], [], "-c \"set opfunc=s:abc\" -S Xverify.vim")
753 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
754 call delete('Xtest.out')
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000755
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000756 " cleanup
757 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000758 delfunc OpFunc1
759 delfunc OpFunc2
760 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000761 %bw!
762endfunc
763
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100764func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200765 " Test for expand()
766 10new
767 call setline(1, ['1', 'ifooar,,cbar'])
768 2
769 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200770 call assert_equal('cbar', expand('<cword>'))
771 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
772
773 call setline(1, ['prx = list[idx];'])
774 1
775 let expected = ['', 'prx', 'prx', 'prx',
776 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
777 \ 'idx', 'idx', 'idx', 'idx',
778 \ 'list[idx]',
779 \ '];',
780 \ ]
781 for i in range(1, 16)
782 exe 'norm ' . i . '|'
783 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
784 endfor
785
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200786 " Test for <cexpr> in state.val and ptr->val
787 call setline(1, 'x = state.val;')
788 call cursor(1, 10)
789 call assert_equal('state.val', expand('<cexpr>'))
790 call setline(1, 'x = ptr->val;')
791 call cursor(1, 9)
792 call assert_equal('ptr->val', expand('<cexpr>'))
793
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100794 if executable('echo')
795 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100796 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100797 endif
798
799 " Test expand(`=...`) i.e. backticks expression expansion
800 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100801 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100802
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200803 " clean up
804 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200805endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200806
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200807" Test for expand() in latin1 encoding
808func Test_normal_expand_latin1()
809 new
810 let save_enc = &encoding
811 set encoding=latin1
812 call setline(1, 'val = item->color;')
813 call cursor(1, 11)
814 call assert_equal('color', expand("<cword>"))
815 call assert_equal('item->color', expand("<cexpr>"))
816 let &encoding = save_enc
817 bw!
818endfunc
819
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100820func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200821 " test for 'showcmd'
822 10new
823 exe "norm! ofoobar\<esc>"
824 call assert_equal(2, line('$'))
825 set showcmd
826 exe "norm! ofoobar2\<esc>"
827 call assert_equal(3, line('$'))
828 exe "norm! VAfoobar3\<esc>"
829 call assert_equal(3, line('$'))
830 exe "norm! 0d3\<del>2l"
831 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200832 " test for the visual block size displayed in the status line
833 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
834 call feedkeys("ggl\<C-V>lljj", 'xt')
835 redraw!
836 call assert_match('3x3$', Screenline(&lines))
837 call feedkeys("\<C-V>", 'xt')
838 " test for visually selecting a multi-byte character
839 call setline(1, ["\U2206"])
840 call feedkeys("ggv", 'xt')
841 redraw!
842 call assert_match('1-3$', Screenline(&lines))
843 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200844 " test for visually selecting the end of line
845 call setline(1, ["foobar"])
846 call feedkeys("$vl", 'xt')
847 redraw!
848 call assert_match('2$', Screenline(&lines))
849 call feedkeys("y", 'xt')
850 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200851 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200852endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200853
Bram Moolenaar1671f442020-03-10 07:48:13 +0100854" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100855func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200856 10new
857 call setline(1, range(1,5))
858 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100859 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200860 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100861 call assert_beeps('normal! G2dd')
862 call assert_beeps("normal! g\<C-A>")
863 call assert_beeps("normal! g\<C-X>")
864 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100865 call assert_beeps("normal! vQ\<Esc>")
866 call assert_beeps("normal! 2[[")
867 call assert_beeps("normal! 2]]")
868 call assert_beeps("normal! 2[]")
869 call assert_beeps("normal! 2][")
870 call assert_beeps("normal! 4[z")
871 call assert_beeps("normal! 4]z")
872 call assert_beeps("normal! 4[c")
873 call assert_beeps("normal! 4]c")
874 call assert_beeps("normal! 200%")
875 call assert_beeps("normal! %")
876 call assert_beeps("normal! 2{")
877 call assert_beeps("normal! 2}")
878 call assert_beeps("normal! r\<Right>")
879 call assert_beeps("normal! 8ry")
880 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200881 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200882endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200883
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100884func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200885 " Test for F1
886 call assert_equal(1, winnr())
887 call feedkeys("\<f1>", 'txi')
888 call assert_match('help\.txt', bufname('%'))
889 call assert_equal(2, winnr('$'))
890 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200891endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200892
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100893func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200894 " basic test for Ctrl-F and Ctrl-B
895 call Setup_NewWindow()
896 exe "norm! \<c-f>"
897 call assert_equal('9', getline('.'))
898 exe "norm! 2\<c-f>"
899 call assert_equal('25', getline('.'))
900 exe "norm! 2\<c-b>"
901 call assert_equal('18', getline('.'))
902 1
903 set scrolloff=5
904 exe "norm! 2\<c-f>"
905 call assert_equal('21', getline('.'))
906 exe "norm! \<c-b>"
907 call assert_equal('13', getline('.'))
908 1
909 set scrolloff=99
910 exe "norm! \<c-f>"
911 call assert_equal('13', getline('.'))
912 set scrolloff=0
913 100
914 exe "norm! $\<c-b>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200915 call assert_equal([0, 92, 1, 0, 1], getcurpos())
916 100
917 set nostartofline
918 exe "norm! $\<c-b>"
naohiro ono56200ee2022-01-01 14:59:44 +0000919 call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200920 " cleanup
921 set startofline
922 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200923endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200924
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100925func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200926 10new
927 norm oxxxxxxx
928 exe "norm 2\<c-f>"
929 " check with valgrind that cursor is put back in column 1
930 exe "norm 2\<c-b>"
931 bw!
932endfunc
933
Bram Moolenaar1671f442020-03-10 07:48:13 +0100934" Test for errors with z command
935func Test_normal_z_error()
936 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200937 call assert_beeps('normal! zq')
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000938 call assert_beeps('normal! cz1')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100939endfunc
940
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100941func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200942 " basic test for z commands that scroll the window
943 call Setup_NewWindow()
944 100
945 norm! >>
946 " Test for z<cr>
947 exe "norm! z\<cr>"
948 call assert_equal(' 100', getline('.'))
949 call assert_equal(100, winsaveview()['topline'])
950 call assert_equal([0, 100, 2, 0, 9], getcurpos())
951
952 " Test for zt
953 21
954 norm! >>0zt
955 call assert_equal(' 21', getline('.'))
956 call assert_equal(21, winsaveview()['topline'])
957 call assert_equal([0, 21, 1, 0, 8], getcurpos())
958
959 " Test for zb
960 30
961 norm! >>$ztzb
962 call assert_equal(' 30', getline('.'))
963 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
naohiro ono56200ee2022-01-01 14:59:44 +0000964 call assert_equal([0, 30, 3, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200965
966 " Test for z-
967 1
968 30
969 norm! 0z-
970 call assert_equal(' 30', getline('.'))
971 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
972 call assert_equal([0, 30, 2, 0, 9], getcurpos())
973
974 " Test for z{height}<cr>
975 call assert_equal(10, winheight(0))
976 exe "norm! z12\<cr>"
977 call assert_equal(12, winheight(0))
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000978 exe "norm! z15\<Del>0\<cr>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200979 call assert_equal(10, winheight(0))
980
981 " Test for z.
982 1
983 21
984 norm! 0z.
985 call assert_equal(' 21', getline('.'))
986 call assert_equal(17, winsaveview()['topline'])
987 call assert_equal([0, 21, 2, 0, 9], getcurpos())
988
989 " Test for zz
990 1
991 21
992 norm! 0zz
993 call assert_equal(' 21', getline('.'))
994 call assert_equal(17, winsaveview()['topline'])
995 call assert_equal([0, 21, 1, 0, 8], getcurpos())
996
997 " Test for z+
998 11
999 norm! zt
1000 norm! z+
1001 call assert_equal(' 21', getline('.'))
1002 call assert_equal(21, winsaveview()['topline'])
1003 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1004
1005 " Test for [count]z+
1006 1
1007 norm! 21z+
1008 call assert_equal(' 21', getline('.'))
1009 call assert_equal(21, winsaveview()['topline'])
1010 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1011
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001012 " Test for z+ with [count] greater than buffer size
1013 1
1014 norm! 1000z+
1015 call assert_equal(' 100', getline('.'))
1016 call assert_equal(100, winsaveview()['topline'])
1017 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1018
1019 " Test for z+ from the last buffer line
1020 norm! Gz.z+
1021 call assert_equal(' 100', getline('.'))
1022 call assert_equal(100, winsaveview()['topline'])
1023 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1024
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001025 " Test for z^
1026 norm! 22z+0
1027 norm! z^
1028 call assert_equal(' 21', getline('.'))
1029 call assert_equal(12, winsaveview()['topline'])
1030 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1031
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001032 " Test for z^ from first buffer line
1033 norm! ggz^
1034 call assert_equal('1', getline('.'))
1035 call assert_equal(1, winsaveview()['topline'])
1036 call assert_equal([0, 1, 1, 0, 1], getcurpos())
1037
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001038 " Test for [count]z^
1039 1
1040 norm! 30z^
1041 call assert_equal(' 21', getline('.'))
1042 call assert_equal(12, winsaveview()['topline'])
1043 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1044
1045 " cleanup
1046 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001047endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001048
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001049func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001050 " basic test for z commands that scroll the window
1051 10new
1052 15vsp
1053 set nowrap listchars=
1054 let lineA='abcdefghijklmnopqrstuvwxyz'
1055 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1056 $put =lineA
1057 $put =lineB
1058 1d
1059
Bram Moolenaar1671f442020-03-10 07:48:13 +01001060 " Test for zl and zh with a count
1061 norm! 0z10l
1062 call assert_equal([11, 1], [col('.'), wincol()])
1063 norm! z4h
1064 call assert_equal([11, 5], [col('.'), wincol()])
1065 normal! 2gg
1066
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001067 " Test for zl
1068 1
1069 norm! 5zl
1070 call assert_equal(lineA, getline('.'))
1071 call assert_equal(6, col('.'))
1072 call assert_equal(5, winsaveview()['leftcol'])
1073 norm! yl
1074 call assert_equal('f', @0)
1075
1076 " Test for zh
1077 norm! 2zh
1078 call assert_equal(lineA, getline('.'))
1079 call assert_equal(6, col('.'))
1080 norm! yl
1081 call assert_equal('f', @0)
1082 call assert_equal(3, winsaveview()['leftcol'])
1083
1084 " Test for zL
1085 norm! zL
1086 call assert_equal(11, col('.'))
1087 norm! yl
1088 call assert_equal('k', @0)
1089 call assert_equal(10, winsaveview()['leftcol'])
1090 norm! 2zL
1091 call assert_equal(25, col('.'))
1092 norm! yl
1093 call assert_equal('y', @0)
1094 call assert_equal(24, winsaveview()['leftcol'])
1095
1096 " Test for zH
1097 norm! 2zH
1098 call assert_equal(25, col('.'))
1099 call assert_equal(10, winsaveview()['leftcol'])
1100 norm! yl
1101 call assert_equal('y', @0)
1102
1103 " Test for zs
1104 norm! $zs
1105 call assert_equal(26, col('.'))
1106 call assert_equal(25, winsaveview()['leftcol'])
1107 norm! yl
1108 call assert_equal('z', @0)
1109
1110 " Test for ze
1111 norm! ze
1112 call assert_equal(26, col('.'))
1113 call assert_equal(11, winsaveview()['leftcol'])
1114 norm! yl
1115 call assert_equal('z', @0)
1116
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001117 " Test for zs and ze with folds
1118 %fold
1119 norm! $zs
1120 call assert_equal(26, col('.'))
1121 call assert_equal(0, winsaveview()['leftcol'])
1122 norm! yl
1123 call assert_equal('z', @0)
1124 norm! ze
1125 call assert_equal(26, col('.'))
1126 call assert_equal(0, winsaveview()['leftcol'])
1127 norm! yl
1128 call assert_equal('z', @0)
1129
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001130 " cleanup
1131 set wrap listchars=eol:$
1132 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001133endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001134
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001135func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001136 " basic test for z commands that scroll the window
1137 " using 'sidescrolloff' setting
1138 10new
1139 20vsp
1140 set nowrap listchars= sidescrolloff=5
1141 let lineA='abcdefghijklmnopqrstuvwxyz'
1142 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1143 $put =lineA
1144 $put =lineB
1145 1d
1146
1147 " Test for zl
1148 1
1149 norm! 5zl
1150 call assert_equal(lineA, getline('.'))
1151 call assert_equal(11, col('.'))
1152 call assert_equal(5, winsaveview()['leftcol'])
1153 norm! yl
1154 call assert_equal('k', @0)
1155
1156 " Test for zh
1157 norm! 2zh
1158 call assert_equal(lineA, getline('.'))
1159 call assert_equal(11, col('.'))
1160 norm! yl
1161 call assert_equal('k', @0)
1162 call assert_equal(3, winsaveview()['leftcol'])
1163
1164 " Test for zL
1165 norm! 0zL
1166 call assert_equal(16, col('.'))
1167 norm! yl
1168 call assert_equal('p', @0)
1169 call assert_equal(10, winsaveview()['leftcol'])
1170 norm! 2zL
1171 call assert_equal(26, col('.'))
1172 norm! yl
1173 call assert_equal('z', @0)
1174 call assert_equal(15, winsaveview()['leftcol'])
1175
1176 " Test for zH
1177 norm! 2zH
1178 call assert_equal(15, col('.'))
1179 call assert_equal(0, winsaveview()['leftcol'])
1180 norm! yl
1181 call assert_equal('o', @0)
1182
1183 " Test for zs
1184 norm! $zs
1185 call assert_equal(26, col('.'))
1186 call assert_equal(20, winsaveview()['leftcol'])
1187 norm! yl
1188 call assert_equal('z', @0)
1189
1190 " Test for ze
1191 norm! ze
1192 call assert_equal(26, col('.'))
1193 call assert_equal(11, winsaveview()['leftcol'])
1194 norm! yl
1195 call assert_equal('z', @0)
1196
1197 " cleanup
1198 set wrap listchars=eol:$ sidescrolloff=0
1199 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001200endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001201
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001202" Test for commands that scroll the window horizontally. Test with folds.
1203" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1204func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001205 15new
1206 call setline(1, range(1, 100))
1207 exe "normal! 30ggz\<CR>"
1208 set foldenable
1209 33,36fold
1210 40,43fold
1211 46,49fold
1212 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001213
1214 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001215 " Top of the screen = 30
1216 " Folded lines = 9
1217 " Bottom of the screen = 30 + h + 9 - 1
1218 normal! 4L
1219 call assert_equal(35 + h, line('.'))
1220 normal! 4H
1221 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001222
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001223 " Test for using a large count value
1224 %d
1225 call setline(1, range(1, 4))
1226 norm! 6H
1227 call assert_equal(4, line('.'))
1228
1229 " Test for 'M' with folded lines
1230 %d
1231 call setline(1, range(1, 20))
1232 1,5fold
1233 norm! LM
1234 call assert_equal(12, line('.'))
1235
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001236 " Test for the CTRL-E and CTRL-Y commands with folds
1237 %d
1238 call setline(1, range(1, 10))
1239 3,5fold
1240 exe "normal 6G3\<C-E>"
1241 call assert_equal(6, line('w0'))
1242 exe "normal 2\<C-Y>"
1243 call assert_equal(2, line('w0'))
1244
1245 " Test for CTRL-Y on a folded line
1246 %d
1247 call setline(1, range(1, 100))
1248 exe (h + 2) .. "," .. (h + 4) .. "fold"
1249 exe h + 5
1250 normal z-
1251 exe "normal \<C-Y>\<C-Y>"
1252 call assert_equal(h + 1, line('w$'))
1253
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001254 " Test for CTRL-Y from the first line and CTRL-E from the last line
1255 %d
1256 set scrolloff=2
1257 call setline(1, range(1, 4))
1258 exe "normal gg\<C-Y>"
1259 call assert_equal(1, line('w0'))
1260 call assert_equal(1, line('.'))
1261 exe "normal G4\<C-E>\<C-E>"
1262 call assert_equal(4, line('w$'))
1263 call assert_equal(4, line('.'))
1264 set scrolloff&
1265
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001266 " Using <PageUp> and <PageDown> in an empty buffer should beep
1267 %d
1268 call assert_beeps('exe "normal \<PageUp>"')
1269 call assert_beeps('exe "normal \<C-B>"')
1270 call assert_beeps('exe "normal \<PageDown>"')
1271 call assert_beeps('exe "normal \<C-F>"')
1272
1273 " Test for <C-U> and <C-D> with fold
1274 %d
1275 call setline(1, range(1, 100))
1276 10,35fold
1277 set scroll=10
1278 exe "normal \<C-D>"
1279 call assert_equal(36, line('.'))
1280 exe "normal \<C-D>"
1281 call assert_equal(46, line('.'))
1282 exe "normal \<C-U>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001283 call assert_equal(36, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001284 exe "normal \<C-U>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001285 call assert_equal(1, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001286 exe "normal \<C-U>"
1287 call assert_equal(1, line('.'))
1288 set scroll&
1289
1290 " Test for scrolling to the top of the file with <C-U> and a fold
1291 10
1292 normal ztL
1293 exe "normal \<C-U>\<C-U>"
1294 call assert_equal(1, line('w0'))
1295
1296 " Test for CTRL-D on a folded line
1297 %d
1298 call setline(1, range(1, 100))
1299 50,100fold
1300 75
1301 normal z-
1302 exe "normal \<C-D>"
1303 call assert_equal(50, line('.'))
1304 call assert_equal(100, line('w$'))
1305 normal z.
Luuk van Baalcb204e62024-04-02 20:49:45 +02001306 let lnum = winline()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001307 exe "normal \<C-D>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001308 call assert_equal(lnum, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001309 call assert_equal(50, line('.'))
1310 normal zt
1311 exe "normal \<C-D>"
1312 call assert_equal(50, line('w0'))
1313
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001314 " Test for <S-CR>. Page down.
1315 %d
1316 call setline(1, range(1, 100))
1317 call feedkeys("\<S-CR>", 'xt')
1318 call assert_equal(14, line('w0'))
1319 call assert_equal(28, line('w$'))
1320
1321 " Test for <S-->. Page up.
1322 call feedkeys("\<S-->", 'xt')
1323 call assert_equal(1, line('w0'))
1324 call assert_equal(15, line('w$'))
1325
Bram Moolenaar1671f442020-03-10 07:48:13 +01001326 set foldenable&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00001327 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01001328endfunc
1329
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001330func Test_scroll_in_ex_mode()
1331 " This was using invalid memory because w_botline was invalid.
1332 let lines =<< trim END
1333 diffsplit
1334 norm os00(
1335 call writefile(['done'], 'Xdone')
1336 qa!
1337 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001338 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001339 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1340 call assert_equal(['done'], readfile('Xdone'))
1341
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001342 call delete('Xdone')
1343endfunc
1344
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001345" Test for the 'sidescroll' option
1346func Test_sidescroll_opt()
1347 new
1348 20vnew
1349
1350 " scroll by 2 characters horizontally
1351 set sidescroll=2 nowrap
1352 call setline(1, repeat('a', 40))
1353 normal g$l
1354 call assert_equal(19, screenpos(0, 1, 21).col)
1355 normal l
1356 call assert_equal(20, screenpos(0, 1, 22).col)
1357 normal g0h
1358 call assert_equal(2, screenpos(0, 1, 2).col)
1359 call assert_equal(20, screenpos(0, 1, 20).col)
1360
1361 " when 'sidescroll' is 0, cursor positioned at the center
1362 set sidescroll=0
1363 normal g$l
1364 call assert_equal(11, screenpos(0, 1, 21).col)
1365 normal g0h
1366 call assert_equal(10, screenpos(0, 1, 10).col)
1367
1368 %bw!
1369 set wrap& sidescroll&
1370endfunc
1371
Bram Moolenaar004a6782020-04-11 17:09:31 +02001372" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001373func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001374 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001375 call Setup_NewWindow()
1376 50
1377 setl foldenable fdm=marker foldlevel=5
1378
Bram Moolenaar1671f442020-03-10 07:48:13 +01001379 call assert_beeps('normal! zj')
1380 call assert_beeps('normal! zk')
1381
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001382 " Test for zF
1383 " First fold
1384 norm! 4zF
1385 " check that folds have been created
1386 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
1387
1388 " Test for zd
1389 51
1390 norm! 2zF
1391 call assert_equal(2, foldlevel('.'))
1392 norm! kzd
1393 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
1394 norm! j
1395 call assert_equal(1, foldlevel('.'))
1396
1397 " Test for zD
1398 " also deletes partially selected folds recursively
1399 51
1400 norm! zF
1401 call assert_equal(2, foldlevel('.'))
1402 norm! kV2jzD
1403 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1404
1405 " Test for zE
1406 85
1407 norm! 4zF
1408 86
1409 norm! 2zF
1410 90
1411 norm! 4zF
1412 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
1413 norm! zE
1414 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1415
1416 " Test for zn
1417 50
1418 set foldlevel=0
1419 norm! 2zF
1420 norm! zn
1421 norm! k
1422 call assert_equal('49', getline('.'))
1423 norm! j
1424 call assert_equal('50/*{{{*/', getline('.'))
1425 norm! j
1426 call assert_equal('51/*}}}*/', getline('.'))
1427 norm! j
1428 call assert_equal('52', getline('.'))
1429 call assert_equal(0, &foldenable)
1430
1431 " Test for zN
1432 49
1433 norm! zN
1434 call assert_equal('49', getline('.'))
1435 norm! j
1436 call assert_equal('50/*{{{*/', getline('.'))
1437 norm! j
1438 call assert_equal('52', getline('.'))
1439 call assert_equal(1, &foldenable)
1440
1441 " Test for zi
1442 norm! zi
1443 call assert_equal(0, &foldenable)
1444 norm! zi
1445 call assert_equal(1, &foldenable)
1446 norm! zi
1447 call assert_equal(0, &foldenable)
1448 norm! zi
1449 call assert_equal(1, &foldenable)
1450
1451 " Test for za
1452 50
1453 norm! za
1454 norm! k
1455 call assert_equal('49', getline('.'))
1456 norm! j
1457 call assert_equal('50/*{{{*/', getline('.'))
1458 norm! j
1459 call assert_equal('51/*}}}*/', getline('.'))
1460 norm! j
1461 call assert_equal('52', getline('.'))
1462 50
1463 norm! za
1464 norm! k
1465 call assert_equal('49', getline('.'))
1466 norm! j
1467 call assert_equal('50/*{{{*/', getline('.'))
1468 norm! j
1469 call assert_equal('52', getline('.'))
1470
1471 49
1472 norm! 5zF
1473 norm! k
1474 call assert_equal('48', getline('.'))
1475 norm! j
1476 call assert_equal('49/*{{{*/', getline('.'))
1477 norm! j
1478 call assert_equal('55', getline('.'))
1479 49
1480 norm! za
1481 call assert_equal('49/*{{{*/', getline('.'))
1482 norm! j
1483 call assert_equal('50/*{{{*/', getline('.'))
1484 norm! j
1485 call assert_equal('52', getline('.'))
1486 set nofoldenable
1487 " close fold and set foldenable
1488 norm! za
1489 call assert_equal(1, &foldenable)
1490
1491 50
1492 " have to use {count}za to open all folds and make the cursor visible
1493 norm! 2za
1494 norm! 2k
1495 call assert_equal('48', getline('.'))
1496 norm! j
1497 call assert_equal('49/*{{{*/', getline('.'))
1498 norm! j
1499 call assert_equal('50/*{{{*/', getline('.'))
1500 norm! j
1501 call assert_equal('51/*}}}*/', getline('.'))
1502 norm! j
1503 call assert_equal('52', getline('.'))
1504
1505 " Test for zA
1506 49
1507 set foldlevel=0
1508 50
1509 norm! zA
1510 norm! 2k
1511 call assert_equal('48', getline('.'))
1512 norm! j
1513 call assert_equal('49/*{{{*/', getline('.'))
1514 norm! j
1515 call assert_equal('50/*{{{*/', getline('.'))
1516 norm! j
1517 call assert_equal('51/*}}}*/', getline('.'))
1518 norm! j
1519 call assert_equal('52', getline('.'))
1520
Dominique Pelle923dce22021-11-21 11:36:04 +00001521 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001522 50
1523 set nofoldenable
1524 norm! zA
1525 call assert_equal(1, &foldenable)
1526 norm! k
1527 call assert_equal('48', getline('.'))
1528 norm! j
1529 call assert_equal('49/*{{{*/', getline('.'))
1530 norm! j
1531 call assert_equal('55', getline('.'))
1532
1533 " Test for zc
1534 norm! zE
1535 50
1536 norm! 2zF
1537 49
1538 norm! 5zF
1539 set nofoldenable
1540 50
1541 " There most likely is a bug somewhere:
1542 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1543 " TODO: Should this only close the inner most fold or both folds?
1544 norm! zc
1545 call assert_equal(1, &foldenable)
1546 norm! k
1547 call assert_equal('48', getline('.'))
1548 norm! j
1549 call assert_equal('49/*{{{*/', getline('.'))
1550 norm! j
1551 call assert_equal('55', getline('.'))
1552 set nofoldenable
1553 50
1554 norm! Vjzc
1555 norm! k
1556 call assert_equal('48', getline('.'))
1557 norm! j
1558 call assert_equal('49/*{{{*/', getline('.'))
1559 norm! j
1560 call assert_equal('55', getline('.'))
1561
1562 " Test for zC
1563 set nofoldenable
1564 50
1565 norm! zCk
1566 call assert_equal('48', getline('.'))
1567 norm! j
1568 call assert_equal('49/*{{{*/', getline('.'))
1569 norm! j
1570 call assert_equal('55', getline('.'))
1571
1572 " Test for zx
1573 " 1) close folds at line 49-54
1574 set nofoldenable
1575 48
1576 norm! zx
1577 call assert_equal(1, &foldenable)
1578 norm! j
1579 call assert_equal('49/*{{{*/', getline('.'))
1580 norm! j
1581 call assert_equal('55', getline('.'))
1582
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001583 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001584 51
1585 set nofoldenable
1586 norm! zx
1587 call assert_equal(1, &foldenable)
1588 norm! 3k
1589 call assert_equal('48', getline('.'))
1590 norm! j
1591 call assert_equal('49/*{{{*/', getline('.'))
1592 norm! j
1593 call assert_equal('50/*{{{*/', getline('.'))
1594 norm! j
1595 call assert_equal('51/*}}}*/', getline('.'))
1596 norm! j
1597 call assert_equal('52', getline('.'))
1598 norm! j
1599 call assert_equal('53', getline('.'))
1600 norm! j
1601 call assert_equal('54/*}}}*/', getline('.'))
1602 norm! j
1603 call assert_equal('55', getline('.'))
1604
1605 " 3) close one level of folds
1606 48
1607 set nofoldenable
1608 set foldlevel=1
1609 norm! zx
1610 call assert_equal(1, &foldenable)
1611 call assert_equal('48', getline('.'))
1612 norm! j
1613 call assert_equal('49/*{{{*/', getline('.'))
1614 norm! j
1615 call assert_equal('50/*{{{*/', getline('.'))
1616 norm! j
1617 call assert_equal('52', getline('.'))
1618 norm! j
1619 call assert_equal('53', getline('.'))
1620 norm! j
1621 call assert_equal('54/*}}}*/', getline('.'))
1622 norm! j
1623 call assert_equal('55', getline('.'))
1624
1625 " Test for zX
1626 " Close all folds
1627 set foldlevel=0 nofoldenable
1628 50
1629 norm! zX
1630 call assert_equal(1, &foldenable)
1631 norm! k
1632 call assert_equal('48', getline('.'))
1633 norm! j
1634 call assert_equal('49/*{{{*/', getline('.'))
1635 norm! j
1636 call assert_equal('55', getline('.'))
1637
1638 " Test for zm
1639 50
1640 set nofoldenable foldlevel=2
1641 norm! zm
1642 call assert_equal(1, &foldenable)
1643 call assert_equal(1, &foldlevel)
1644 norm! zm
1645 call assert_equal(0, &foldlevel)
1646 norm! zm
1647 call assert_equal(0, &foldlevel)
1648 norm! k
1649 call assert_equal('48', getline('.'))
1650 norm! j
1651 call assert_equal('49/*{{{*/', getline('.'))
1652 norm! j
1653 call assert_equal('55', getline('.'))
1654
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001655 " Test for zm with a count
1656 50
1657 set foldlevel=2
1658 norm! 3zm
1659 call assert_equal(0, &foldlevel)
1660 call assert_equal(49, foldclosed(line('.')))
1661
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001662 " Test for zM
1663 48
1664 set nofoldenable foldlevel=99
1665 norm! zM
1666 call assert_equal(1, &foldenable)
1667 call assert_equal(0, &foldlevel)
1668 call assert_equal('48', getline('.'))
1669 norm! j
1670 call assert_equal('49/*{{{*/', getline('.'))
1671 norm! j
1672 call assert_equal('55', getline('.'))
1673
1674 " Test for zr
1675 48
1676 set nofoldenable foldlevel=0
1677 norm! zr
1678 call assert_equal(0, &foldenable)
1679 call assert_equal(1, &foldlevel)
1680 set foldlevel=0 foldenable
1681 norm! zr
1682 call assert_equal(1, &foldenable)
1683 call assert_equal(1, &foldlevel)
1684 norm! zr
1685 call assert_equal(2, &foldlevel)
1686 call assert_equal('48', getline('.'))
1687 norm! j
1688 call assert_equal('49/*{{{*/', getline('.'))
1689 norm! j
1690 call assert_equal('50/*{{{*/', getline('.'))
1691 norm! j
1692 call assert_equal('51/*}}}*/', getline('.'))
1693 norm! j
1694 call assert_equal('52', getline('.'))
1695
1696 " Test for zR
1697 48
1698 set nofoldenable foldlevel=0
1699 norm! zR
1700 call assert_equal(0, &foldenable)
1701 call assert_equal(2, &foldlevel)
1702 set foldenable foldlevel=0
1703 norm! zR
1704 call assert_equal(1, &foldenable)
1705 call assert_equal(2, &foldlevel)
1706 call assert_equal('48', getline('.'))
1707 norm! j
1708 call assert_equal('49/*{{{*/', getline('.'))
1709 norm! j
1710 call assert_equal('50/*{{{*/', getline('.'))
1711 norm! j
1712 call assert_equal('51/*}}}*/', getline('.'))
1713 norm! j
1714 call assert_equal('52', getline('.'))
1715 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
1716 48
1717 call assert_equal('48', getline('.'))
1718 norm! j
1719 call assert_equal('49/*{{{*/', getline('.'))
1720 norm! j
1721 call assert_equal('50/*{{{*/', getline('.'))
1722 norm! j
1723 call assert_equal('a /*{{{*/', getline('.'))
1724 norm! j
1725 call assert_equal('51/*}}}*/', getline('.'))
1726 norm! j
1727 call assert_equal('52', getline('.'))
1728 48
1729 norm! zR
1730 call assert_equal(1, &foldenable)
1731 call assert_equal(3, &foldlevel)
1732 call assert_equal('48', getline('.'))
1733 norm! j
1734 call assert_equal('49/*{{{*/', getline('.'))
1735 norm! j
1736 call assert_equal('50/*{{{*/', getline('.'))
1737 norm! j
1738 call assert_equal('a /*{{{*/', getline('.'))
1739 norm! j
1740 call assert_equal('b /*}}}*/', getline('.'))
1741 norm! j
1742 call assert_equal('51/*}}}*/', getline('.'))
1743 norm! j
1744 call assert_equal('52', getline('.'))
1745
1746 " clean up
1747 setl nofoldenable fdm=marker foldlevel=0
1748 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001749endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001750
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001751func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001752 " Reading from redirected file doesn't work on MS-Windows
1753 CheckNotMSWindows
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001754 call writefile(['1a', 'foo', 'bar', '.', 'w! Xn20file2', 'q!'], 'Xn20script', 'D')
1755 call writefile(['1', '2'], 'Xn20file', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001756 call system(GetVimCommand() .. ' -e -s < Xn20script Xn20file')
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001757 let a = readfile('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001758 call assert_equal(['1', 'foo', 'bar', '2'], a)
1759
1760 " clean up
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001761 call delete('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001762 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001763endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001764
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001765func Test_normal21_nv_hat()
1766
1767 " Edit a fresh file and wipe the buffer list so that there is no alternate
1768 " file present. Next, check for the expected command failures.
1769 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001770 call assert_fails(':buffer #', 'E86:')
1771 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001772 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001773
1774 " Test for the expected behavior when switching between two named buffers.
1775 edit Xfoo | edit Xbar
1776 call feedkeys("\<C-^>", 'tx')
1777 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1778 call feedkeys("\<C-^>", 'tx')
1779 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1780
1781 " Test for the expected behavior when only one buffer is named.
1782 enew | let l:nr = bufnr('%')
1783 call feedkeys("\<C-^>", 'tx')
1784 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1785 call feedkeys("\<C-^>", 'tx')
1786 call assert_equal('', bufname('%'))
1787 call assert_equal(l:nr, bufnr('%'))
1788
1789 " Test that no action is taken by "<C-^>" when an operator is pending.
1790 edit Xfoo
1791 call feedkeys("ci\<C-^>", 'tx')
1792 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1793
1794 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001795endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001796
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001797func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001798 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001799 " let shell = &shell
1800 " let &shell = 'sh'
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001801 call writefile(['1', '2'], 'Xn22file', 'D')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001802 let args = ' -N -i NONE --noplugins -X --not-a-term'
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001803 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xn22file')
1804 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001805 call assert_equal([], a)
1806 " Test for ZQ
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001807 call writefile(['1', '2'], 'Xn22file')
1808 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xn22file')
1809 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001810 call assert_equal(['1', '2'], a)
1811
Bram Moolenaar1671f442020-03-10 07:48:13 +01001812 " Unsupported Z command
1813 call assert_beeps('normal! ZW')
1814
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001815 " clean up
Bram Moolenaar0913a102016-09-03 19:11:59 +02001816 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001817endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001818
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001819func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001820 " Test for K command
1821 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001822 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001823 let k = &keywordprg
1824 set keywordprg=:help
1825 1
1826 norm! VK
1827 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1828 call assert_equal('help', &ft)
1829 call assert_match('\*version8.txt\*', getline('.'))
1830 helpclose
1831 norm! 0K
1832 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1833 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001834 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001835 helpclose
1836
Bram Moolenaar426f3752016-11-04 21:22:37 +01001837 set keywordprg=:new
1838 set iskeyword+=%
1839 set iskeyword+=\|
1840 2
1841 norm! K
1842 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1843 bwipe!
1844 3
1845 norm! K
1846 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1847 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001848 if !has('win32')
1849 4
1850 norm! K
1851 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1852 bwipe!
1853 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001854 set iskeyword-=%
1855 set iskeyword-=\|
1856
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001857 " Test for specifying a count to K
1858 1
1859 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1860 set keywordprg=:Kprog
1861 norm! 3K
1862 call assert_equal('3 version8', g:Kprog_Args)
1863 delcom Kprog
1864
Bram Moolenaar0913a102016-09-03 19:11:59 +02001865 " Only expect "man" to work on Unix
1866 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001867 let &keywordprg = k
1868 bw!
1869 return
1870 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001871
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001872 let not_gnu_man = has('mac') || has('bsd')
1873 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001874 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001875 set keywordprg=man\ -P\ cat
1876 else
1877 set keywordprg=man\ --pager=cat
1878 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001879 " Test for using man
1880 2
1881 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001882 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001883 call assert_match("man -P cat 'man'", a)
1884 else
1885 call assert_match("man --pager=cat 'man'", a)
1886 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001887
Bram Moolenaar1671f442020-03-10 07:48:13 +01001888 " Error cases
1889 call setline(1, '#$#')
1890 call assert_fails('normal! ggK', 'E349:')
1891 call setline(1, '---')
1892 call assert_fails('normal! ggv2lK', 'E349:')
1893 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001894 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001895 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001896 norm! V
1897 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001898
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001899 " clean up
1900 let &keywordprg = k
1901 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001902endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001903
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001904func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001905 " Testing for g?? g?g?
1906 new
1907 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1908 1
1909 norm! g??
1910 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1911 norm! g?g?
1912 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1913
1914 " clean up
1915 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001916endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001917
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001918func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001919 CheckFeature quickfix
1920
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001921 " Testing for CTRL-] g CTRL-] g]
1922 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1923 h
1924 " Test for CTRL-]
1925 call search('\<x\>$')
1926 exe "norm! \<c-]>"
1927 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1928 norm! yiW
1929 call assert_equal("*x*", @0)
1930 exe ":norm \<c-o>"
1931
1932 " Test for g_CTRL-]
1933 call search('\<v_u\>$')
1934 exe "norm! g\<c-]>"
1935 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1936 norm! yiW
1937 call assert_equal("*v_u*", @0)
1938 exe ":norm \<c-o>"
1939
1940 " Test for g]
1941 call search('\<i_<Esc>$')
1942 let a = execute(":norm! g]")
1943 call assert_match('i_<Esc>.*insert.txt', a)
1944
1945 if !empty(exepath('cscope')) && has('cscope')
1946 " setting cscopetag changes how g] works
1947 set cst
1948 exe "norm! g]"
1949 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1950 norm! yiW
1951 call assert_equal("*i_<Esc>*", @0)
1952 exe ":norm \<c-o>"
1953 " Test for CTRL-W g]
1954 exe "norm! \<C-W>g]"
1955 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1956 norm! yiW
1957 call assert_equal("*i_<Esc>*", @0)
1958 call assert_equal(3, winnr('$'))
1959 helpclose
1960 set nocst
1961 endif
1962
1963 " Test for CTRL-W g]
1964 let a = execute("norm! \<C-W>g]")
1965 call assert_match('i_<Esc>.*insert.txt', a)
1966
1967 " Test for CTRL-W CTRL-]
1968 exe "norm! \<C-W>\<C-]>"
1969 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1970 norm! yiW
1971 call assert_equal("*i_<Esc>*", @0)
1972 call assert_equal(3, winnr('$'))
1973 helpclose
1974
1975 " Test for CTRL-W g CTRL-]
1976 exe "norm! \<C-W>g\<C-]>"
1977 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1978 norm! yiW
1979 call assert_equal("*i_<Esc>*", @0)
1980 call assert_equal(3, winnr('$'))
1981 helpclose
1982
1983 " clean up
1984 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001985endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001986
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001987func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001988 " Test for ]p ]P [p and [P
1989 new
1990 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1991 1
1992 /Error/y a
1993 2
1994 norm! "a]pj"a[p
1995 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1996 1
1997 /^\s\{4}/
1998 exe "norm! \"a]P3Eldt'"
1999 exe "norm! j\"a[P2Eldt'"
2000 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
2001
2002 " clean up
2003 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002004endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002005
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002006func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002007 " Test for [' [` ]' ]`
2008 call Setup_NewWindow()
2009 1,21s/.\+/ & b/
2010 1
2011 norm! $ma
2012 5
2013 norm! $mb
2014 10
2015 norm! $mc
2016 15
2017 norm! $md
2018 20
2019 norm! $me
2020
2021 " Test for ['
2022 9
2023 norm! 2['
2024 call assert_equal(' 1 b', getline('.'))
2025 call assert_equal(1, line('.'))
2026 call assert_equal(3, col('.'))
2027
2028 " Test for ]'
2029 norm! ]'
2030 call assert_equal(' 5 b', getline('.'))
2031 call assert_equal(5, line('.'))
2032 call assert_equal(3, col('.'))
2033
zeertzjqcf344342022-07-06 12:57:31 +01002034 " No mark before line 1, cursor moves to first non-blank on current line
2035 1
2036 norm! 5|['
2037 call assert_equal(' 1 b', getline('.'))
2038 call assert_equal(1, line('.'))
2039 call assert_equal(3, col('.'))
2040
2041 " No mark after line 21, cursor moves to first non-blank on current line
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002042 21
zeertzjqcf344342022-07-06 12:57:31 +01002043 norm! 5|]'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002044 call assert_equal(' 21 b', getline('.'))
2045 call assert_equal(21, line('.'))
2046 call assert_equal(3, col('.'))
2047
2048 " Test for [`
2049 norm! 2[`
2050 call assert_equal(' 15 b', getline('.'))
2051 call assert_equal(15, line('.'))
2052 call assert_equal(8, col('.'))
2053
2054 " Test for ]`
2055 norm! ]`
2056 call assert_equal(' 20 b', getline('.'))
2057 call assert_equal(20, line('.'))
2058 call assert_equal(8, col('.'))
2059
zeertzjqcf344342022-07-06 12:57:31 +01002060 " No mark before line 1, cursor does not move
2061 1
2062 norm! 5|[`
2063 call assert_equal(' 1 b', getline('.'))
2064 call assert_equal(1, line('.'))
2065 call assert_equal(5, col('.'))
2066
2067 " No mark after line 21, cursor does not move
2068 21
2069 norm! 5|]`
2070 call assert_equal(' 21 b', getline('.'))
2071 call assert_equal(21, line('.'))
2072 call assert_equal(5, col('.'))
2073
2074 " Count too large for [`
2075 " cursor moves to first lowercase mark
2076 norm! 99[`
2077 call assert_equal(' 1 b', getline('.'))
2078 call assert_equal(1, line('.'))
2079 call assert_equal(7, col('.'))
2080
2081 " Count too large for ]`
2082 " cursor moves to last lowercase mark
2083 norm! 99]`
2084 call assert_equal(' 20 b', getline('.'))
2085 call assert_equal(20, line('.'))
2086 call assert_equal(8, col('.'))
2087
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002088 " clean up
2089 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002090endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002091
Bram Moolenaar1671f442020-03-10 07:48:13 +01002092" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002093func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002094 new
2095 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2096
2097 $
2098 norm! d(
2099 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2100 norm! 2d(
2101 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2102 1
2103 norm! 0d)
2104 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2105
2106 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2107 $
2108 norm! $d(
2109 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2110
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002111 " Move to the next sentence from a paragraph macro
2112 %d
2113 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2114 call cursor(1, 1)
2115 normal )
2116 call assert_equal([2, 1], [line('.'), col('.')])
2117 normal )
2118 call assert_equal([2, 12], [line('.'), col('.')])
2119 normal ((
2120 call assert_equal([1, 1], [line('.'), col('.')])
2121
Bram Moolenaar1671f442020-03-10 07:48:13 +01002122 " It is an error if a next sentence is not found
2123 %d
2124 call setline(1, '.SH')
2125 call assert_beeps('normal )')
2126
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002127 " If only dot is present, don't treat that as a sentence
2128 call setline(1, '. This is a sentence.')
2129 normal $((
2130 call assert_equal(3, col('.'))
2131
Bram Moolenaar1671f442020-03-10 07:48:13 +01002132 " Jumping to a fold should open the fold
2133 call setline(1, ['', '', 'one', 'two', 'three'])
2134 set foldenable
2135 2,$fold
2136 call feedkeys(')', 'xt')
2137 call assert_equal(3, line('.'))
2138 call assert_equal(1, foldlevel('.'))
2139 call assert_equal(-1, foldclosed('.'))
2140 set foldenable&
2141
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002142 " clean up
2143 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002144endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002145
Bram Moolenaar1671f442020-03-10 07:48:13 +01002146" Test for { and } paragraph movements
2147func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002148 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002149 A paragraph begins after each empty line, and also at each of a set of
2150 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2151 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2152 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2153 the first column). A section boundary is also a paragraph boundary.
2154 Note that a blank line (only containing white space) is NOT a paragraph
2155 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002156
2157
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002158 Also note that this does not include a '{' or '}' in the first column. When
2159 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2160 paragraph boundary |posix|.
2161 {
2162 This is no paragraph
2163 unless the '{' is set
2164 in 'cpoptions'
2165 }
2166 .IP
2167 The nroff macros IP separates a paragraph
2168 That means, it must be a '.'
2169 followed by IP
2170 .LPIt does not matter, if afterwards some
2171 more characters follow.
2172 .SHAlso section boundaries from the nroff
2173 macros terminate a paragraph. That means
2174 a character like this:
2175 .NH
2176 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002177 [DATA]
2178
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002179 new
2180 call append(0, text)
2181 1
2182 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002183
2184 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002185 .IP
2186 The nroff macros IP separates a paragraph
2187 That means, it must be a '.'
2188 followed by IP
2189 .LPIt does not matter, if afterwards some
2190 more characters follow.
2191 .SHAlso section boundaries from the nroff
2192 macros terminate a paragraph. That means
2193 a character like this:
2194 .NH
2195 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002196
2197 [DATA]
2198 call assert_equal(expected, getline(1, '$'))
2199
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002200 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002201
2202 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002203 .LPIt does not matter, if afterwards some
2204 more characters follow.
2205 .SHAlso section boundaries from the nroff
2206 macros terminate a paragraph. That means
2207 a character like this:
2208 .NH
2209 End of text here
Bram Moolenaar94722c52023-01-28 19:19:03 +00002210
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002211 [DATA]
2212 call assert_equal(expected, getline(1, '$'))
2213
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002214 $
2215 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002216
2217 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002218 .LPIt does not matter, if afterwards some
2219 more characters follow.
2220 .SHAlso section boundaries from the nroff
2221 macros terminate a paragraph. That means
2222 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002223
2224 [DATA]
2225 call assert_equal(expected, getline(1, '$'))
2226
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002227 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002228
2229 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002230 .LPIt does not matter, if afterwards some
2231 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002232
2233 [DATA]
2234 call assert_equal(expected, getline(1, '$'))
2235
dundargocdc4c37b2024-01-12 18:02:10 +01002236 " Test with { in cpoptions
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002237 %d
2238 call append(0, text)
2239 set cpo+={
2240 1
2241 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002242
2243 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002244 {
2245 This is no paragraph
2246 unless the '{' is set
2247 in 'cpoptions'
2248 }
2249 .IP
2250 The nroff macros IP separates a paragraph
2251 That means, it must be a '.'
2252 followed by IP
2253 .LPIt does not matter, if afterwards some
2254 more characters follow.
2255 .SHAlso section boundaries from the nroff
2256 macros terminate a paragraph. That means
2257 a character like this:
2258 .NH
2259 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002260
2261 [DATA]
2262 call assert_equal(expected, getline(1, '$'))
2263
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002264 $
2265 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002266
2267 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002268 {
2269 This is no paragraph
2270 unless the '{' is set
2271 in 'cpoptions'
2272 }
2273 .IP
2274 The nroff macros IP separates a paragraph
2275 That means, it must be a '.'
2276 followed by IP
2277 .LPIt does not matter, if afterwards some
2278 more characters follow.
2279 .SHAlso section boundaries from the nroff
2280 macros terminate a paragraph. That means
2281 a character like this:
2282 .NH
2283 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002284
2285 [DATA]
2286 call assert_equal(expected, getline(1, '$'))
2287
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002288 norm! gg}
2289 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002290
2291 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002292 {
2293 This is no paragraph
2294 unless the '{' is set
2295 in 'cpoptions'
2296 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002297
2298 [DATA]
2299 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002300
Bram Moolenaar1671f442020-03-10 07:48:13 +01002301 " Jumping to a fold should open the fold
2302 %d
2303 call setline(1, ['', 'one', 'two', ''])
2304 set foldenable
2305 2,$fold
2306 call feedkeys('}', 'xt')
2307 call assert_equal(4, line('.'))
2308 call assert_equal(1, foldlevel('.'))
2309 call assert_equal(-1, foldclosed('.'))
2310 set foldenable&
2311
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002312 " clean up
2313 set cpo-={
2314 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002315endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002316
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002317" Test for section movements
2318func Test_normal_section()
2319 new
2320 let lines =<< trim [END]
2321 int foo()
2322 {
2323 if (1)
2324 {
2325 a = 1;
2326 }
2327 }
2328 [END]
2329 call setline(1, lines)
2330
2331 " jumping to a folded line using [[ should open the fold
2332 2,3fold
2333 call cursor(5, 1)
2334 call feedkeys("[[", 'xt')
2335 call assert_equal(2, line('.'))
2336 call assert_equal(-1, foldclosedend(line('.')))
2337
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002338 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002339endfunc
2340
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002341" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002342func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002343 new
2344 call append(0, 'This is a simple test: äüöß')
2345 norm! 1ggVu
2346 call assert_equal('this is a simple test: äüöß', getline('.'))
2347 norm! VU
glepnirbd1232a2024-02-12 22:14:53 +01002348 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002349 norm! guu
glepnirbd1232a2024-02-12 22:14:53 +01002350 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002351 norm! gUgU
glepnirbd1232a2024-02-12 22:14:53 +01002352 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002353 norm! gugu
glepnirbd1232a2024-02-12 22:14:53 +01002354 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002355 norm! gUU
glepnirbd1232a2024-02-12 22:14:53 +01002356 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002357 norm! 010~
glepnirbd1232a2024-02-12 22:14:53 +01002358 call assert_equal('this is a SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002359 norm! V~
glepnirbd1232a2024-02-12 22:14:53 +01002360 call assert_equal('THIS IS A simple test: äüöß', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002361 call assert_beeps('norm! c~')
2362 %d
2363 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002364
zeertzjq8c55d602024-03-13 20:42:26 +01002365 " Test with multiple lines
2366 call setline(1, ['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'])
2367 norm! ggguG
2368 call assert_equal(['aa', 'bbbb', 'cccccc', 'dddddddd'], getline(1, '$'))
2369 norm! GgUgg
2370 call assert_equal(['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'], getline(1, '$'))
2371 %d
2372
Bram Moolenaar1671f442020-03-10 07:48:13 +01002373 " Test for changing case across lines using 'whichwrap'
2374 call setline(1, ['aaaaaa', 'aaaaaa'])
2375 normal! gg10~
2376 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2377 set whichwrap+=~
2378 normal! gg10~
2379 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2380 set whichwrap&
2381
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002382 " try changing the case with a double byte encoding (DBCS)
2383 %bw!
2384 let enc = &enc
2385 set encoding=cp932
2386 call setline(1, "\u8470")
2387 normal ~
2388 normal gU$gu$gUgUg~g~gugu
2389 call assert_equal("\u8470", getline(1))
2390 let &encoding = enc
2391
Bram Moolenaar1671f442020-03-10 07:48:13 +01002392 " clean up
2393 bw!
2394endfunc
2395
2396" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2397" is available but toupper()/tolower() don't do the right thing.
2398func Test_normal_changecase_turkish()
2399 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002400 try
2401 lang tr_TR.UTF-8
2402 set casemap=
2403 let iupper = toupper('i')
2404 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002405 call setline(1, 'iI')
2406 1normal gUU
2407 call assert_equal("\u0130I", getline(1))
2408 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002409
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002410 call setline(1, 'iI')
2411 1normal guu
2412 call assert_equal("i\u0131", getline(1))
2413 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002414 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002415 call setline(1, 'iI')
2416 1normal gUU
2417 call assert_equal("II", getline(1))
2418 call assert_equal("II", toupper("iI"))
2419
2420 call setline(1, 'iI')
2421 1normal guu
2422 call assert_equal("ii", getline(1))
2423 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002424 else
2425 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2426 endif
2427 set casemap&
2428 call setline(1, 'iI')
2429 1normal gUU
2430 call assert_equal("II", getline(1))
2431 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002432
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002433 call setline(1, 'iI')
2434 1normal guu
2435 call assert_equal("ii", getline(1))
2436 call assert_equal("ii", tolower("iI"))
2437
2438 lang en_US.UTF-8
2439 catch /E197:/
2440 " can't use Turkish locale
2441 throw 'Skipped: Turkish locale not available'
2442 endtry
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002443
2444 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002445endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002446
Bram Moolenaar1671f442020-03-10 07:48:13 +01002447" Test for r (replace) command
2448func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002449 new
2450 call append(0, 'This is a simple test: abcd')
2451 exe "norm! 1gg$r\<cr>"
2452 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2453 exe "norm! 1gg2wlr\<cr>"
2454 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2455 exe "norm! 2gg0W5r\<cr>"
2456 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2457 set autoindent
2458 call setline(2, ['simple test: abc', ''])
2459 exe "norm! 2gg0W5r\<cr>"
2460 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2461 exe "norm! 1ggVr\<cr>"
2462 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2463 call setline(1, 'This is a')
2464 exe "norm! 1gg05rf"
2465 call assert_equal('fffffis a', getline(1))
2466
Bram Moolenaar1671f442020-03-10 07:48:13 +01002467 " When replacing characters, copy characters from above and below lines
2468 " using CTRL-Y and CTRL-E.
2469 " Different code paths are used for utf-8 and latin1 encodings
2470 set showmatch
2471 for enc in ['latin1', 'utf-8']
2472 enew!
2473 let &encoding = enc
2474 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2475 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2476 call assert_equal(' {a}x [b]x', getline(2))
2477 endfor
2478 set showmatch&
2479
2480 " r command should fail in operator pending mode
2481 call assert_beeps('normal! cr')
2482
Bram Moolenaar004a6782020-04-11 17:09:31 +02002483 " replace a tab character in visual mode
2484 %d
2485 call setline(1, ["a\tb", "c\td", "e\tf"])
2486 normal gglvjjrx
2487 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2488
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002489 " replace with a multibyte character (with multiple composing characters)
2490 %d
2491 new
2492 call setline(1, 'aaa')
2493 exe "normal $ra\u0328\u0301"
2494 call assert_equal("aaa\u0328\u0301", getline(1))
2495
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002496 " clean up
2497 set noautoindent
2498 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002499endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002500
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002501" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002502func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002503 new
2504 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2505 1
2506 norm! $g*
2507 call assert_equal('x_foo', @/)
2508 call assert_equal('x_foobar.abc', getline('.'))
2509 norm! $g#
2510 call assert_equal('abc', @/)
2511 call assert_equal('abc.x_foo', getline('.'))
2512
2513 " clean up
2514 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002515endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002516
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002517" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2518" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002519func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002520 call Setup_NewWindow()
2521 " Test for g`
2522 clearjumps
2523 norm! ma10j
2524 let a=execute(':jumps')
2525 " empty jumplist
2526 call assert_equal('>', a[-1:])
2527 norm! g`a
2528 call assert_equal('>', a[-1:])
2529 call assert_equal(1, line('.'))
2530 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002531 call cursor(10, 1)
2532 norm! g'a
2533 call assert_equal('>', a[-1:])
2534 call assert_equal(1, line('.'))
zeertzjq30585e02023-03-06 08:10:04 +00002535 let v:errmsg = ''
zeertzjqf86dea82023-03-05 21:15:06 +00002536 call assert_nobeep("normal! g`\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002537 call assert_equal('', v:errmsg)
zeertzjqf86dea82023-03-05 21:15:06 +00002538 call assert_nobeep("normal! g'\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002539 call assert_equal('', v:errmsg)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002540
2541 " Test for g; and g,
2542 norm! g;
2543 " there is only one change in the changelist
2544 " currently, when we setup the window
2545 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002546 call assert_fails(':norm! g;', 'E662:')
2547 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002548 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002549 call append('$', ['a', 'b', 'c', 'd'])
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002550 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002551 call append('$', ['Z', 'Y', 'X', 'W'])
2552 let a = execute(':changes')
2553 call assert_match('2\s\+0\s\+2', a)
2554 call assert_match('101\s\+0\s\+a', a)
2555 call assert_match('105\s\+0\s\+Z', a)
2556 norm! 3g;
2557 call assert_equal(2, line('.'))
2558 norm! 2g,
2559 call assert_equal(105, line('.'))
2560
2561 " Test for g& - global substitute
2562 %d
2563 call setline(1, range(1,10))
2564 call append('$', ['a', 'b', 'c', 'd'])
2565 $s/\w/&&/g
2566 exe "norm! /[1-8]\<cr>"
2567 norm! g&
2568 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2569
Bram Moolenaar1671f442020-03-10 07:48:13 +01002570 " Jumping to a fold using gg should open the fold
2571 set foldenable
2572 set foldopen+=jump
2573 5,8fold
2574 call feedkeys('6gg', 'xt')
2575 call assert_equal(1, foldlevel('.'))
2576 call assert_equal(-1, foldclosed('.'))
2577 set foldopen-=jump
2578 set foldenable&
2579
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002580 " Test for gv
2581 %d
2582 call append('$', repeat(['abcdefgh'], 8))
2583 exe "norm! 2gg02l\<c-v>2j2ly"
2584 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2585 " in visual mode, gv swaps current and last selected region
2586 exe "norm! G0\<c-v>4k4lgvd"
2587 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2588 exe "norm! G0\<c-v>4k4ly"
2589 exe "norm! gvood"
2590 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
Christian Brabandtee17b6f2023-09-09 11:23:50 +02002591 " gv cannot be used in operator pending mode
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002592 call assert_beeps('normal! cgv')
2593 " gv should beep without a previously selected visual area
2594 new
2595 call assert_beeps('normal! gv')
2596 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002597
2598 " Test for gk/gj
2599 %d
2600 15vsp
2601 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002602 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2603 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2604 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002605 $put =lineA
2606 $put =lineB
2607
2608 norm! 3gg0dgk
2609 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2610 set nu
2611 norm! 3gg0gjdgj
2612 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2613
2614 " Test for gJ
2615 norm! 2gggJ
2616 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2617 call assert_equal(16, col('.'))
2618 " shouldn't do anything
2619 norm! 10gJ
2620 call assert_equal(1, col('.'))
2621
2622 " Test for g0 g^ gm g$
2623 exe "norm! 2gg0gji "
2624 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2625 norm! g0yl
2626 call assert_equal(12, col('.'))
2627 call assert_equal(' ', getreg(0))
2628 norm! g$yl
2629 call assert_equal(22, col('.'))
2630 call assert_equal('3', getreg(0))
2631 norm! gmyl
2632 call assert_equal(17, col('.'))
2633 call assert_equal('n', getreg(0))
2634 norm! g^yl
2635 call assert_equal(15, col('.'))
2636 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002637 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002638
Bram Moolenaar74ede802021-05-29 19:18:01 +02002639 " Test for g$ with double-width character half displayed
2640 vsplit
2641 9wincmd |
2642 setlocal nowrap nonumber
2643 call setline(2, 'asdfasdfヨ')
2644 2
2645 normal 0g$
2646 call assert_equal(8, col('.'))
2647 10wincmd |
2648 normal 0g$
2649 call assert_equal(9, col('.'))
2650
2651 setlocal signcolumn=yes
2652 11wincmd |
2653 normal 0g$
2654 call assert_equal(8, col('.'))
2655 12wincmd |
2656 normal 0g$
2657 call assert_equal(9, col('.'))
2658
2659 close
2660
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002661 " Test for g_
2662 call assert_beeps('normal! 100g_')
2663 call setline(2, [' foo ', ' foobar '])
2664 normal! 2ggg_
2665 call assert_equal(5, col('.'))
2666 normal! 2g_
2667 call assert_equal(8, col('.'))
2668
2669 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002670 $put =lineC
2671
2672 " Test for gM
2673 norm! gMyl
2674 call assert_equal(73, col('.'))
2675 call assert_equal('0', getreg(0))
2676 " Test for 20gM
2677 norm! 20gMyl
2678 call assert_equal(29, col('.'))
2679 call assert_equal('S', getreg(0))
2680 " Test for 60gM
2681 norm! 60gMyl
2682 call assert_equal(87, col('.'))
2683 call assert_equal('E', getreg(0))
2684
Bram Moolenaar71c41252021-12-26 15:00:07 +00002685 " Test for gM with Tab characters
2686 call setline('.', "\ta\tb\tc\td\te\tf")
2687 norm! gMyl
2688 call assert_equal(6, col('.'))
2689 call assert_equal("c", getreg(0))
2690
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002691 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002692 call setline('.', lineC)
2693 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002694 set ff=unix
2695 let a=execute(":norm! g\<c-g>")
2696 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2697
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002698 " Test for gI
2699 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002700 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002701
2702 " Test for gi
2703 wincmd c
2704 %d
2705 set tw=0
2706 call setline(1, ['foobar', 'new line'])
2707 norm! A next word
2708 $put ='third line'
2709 norm! gi another word
2710 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002711 call setline(1, 'foobar')
2712 normal! Ggifirst line
2713 call assert_equal('foobarfirst line', getline(1))
2714 " Test gi in 'virtualedit' mode with cursor after the end of the line
2715 set virtualedit=all
2716 call setline(1, 'foo')
2717 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2718 call setline(1, 'foo')
2719 normal! Ggifirst line
2720 call assert_equal('foo first line', getline(1))
2721 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002722
Dominique Pelle923dce22021-11-21 11:36:04 +00002723 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002724 exe "normal! g\<C-\>\<C-G>"
2725 call assert_equal('foo first line', getline('.'))
2726
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002727 " clean up
2728 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002729endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002730
Bram Moolenaarce416b42022-04-03 12:59:34 +01002731func Test_normal_ex_substitute()
2732 " This was hanging on the substitute prompt.
2733 new
2734 call setline(1, 'a')
2735 exe "normal! gggQs/a/b/c\<CR>"
2736 call assert_equal('a', getline(1))
2737 bwipe!
2738endfunc
2739
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002740" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002741func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002742 new
2743
2744 let a = execute(":norm! g\<c-g>")
2745 call assert_equal("\n--No lines in buffer--", a)
2746
Bram Moolenaar1671f442020-03-10 07:48:13 +01002747 " Test for CTRL-G (same as :file)
2748 let a = execute(":norm! \<c-g>")
2749 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2750
Bram Moolenaar05295832018-08-24 22:07:58 +02002751 call setline(1, ['first line', 'second line'])
2752
2753 " Test g CTRL-g with dos, mac and unix file type.
2754 norm! gojll
2755 set ff=dos
2756 let a = execute(":norm! g\<c-g>")
2757 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2758
2759 set ff=mac
2760 let a = execute(":norm! g\<c-g>")
2761 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2762
2763 set ff=unix
2764 let a = execute(":norm! g\<c-g>")
2765 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2766
2767 " Test g CTRL-g in visual mode (v)
2768 let a = execute(":norm! gojllvlg\<c-g>")
2769 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2770
2771 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2772 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2773 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2774
2775 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2776 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2777 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2778
2779 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2780 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2781 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2782
2783 " There should be one byte less with noeol
2784 set bin noeol
2785 let a = execute(":norm! \<Esc>gog\<c-g>")
2786 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2787 set bin & eol&
2788
Bram Moolenaar30276f22019-01-24 17:59:39 +01002789 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002790
Bram Moolenaar30276f22019-01-24 17:59:39 +01002791 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2792 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 +02002793
Bram Moolenaar30276f22019-01-24 17:59:39 +01002794 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2795 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 +02002796
Bram Moolenaar30276f22019-01-24 17:59:39 +01002797 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2798 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 +02002799
Bram Moolenaar30276f22019-01-24 17:59:39 +01002800 set fenc=utf8 bomb
2801 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2802 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 +02002803
Bram Moolenaar30276f22019-01-24 17:59:39 +01002804 set fenc=utf16 bomb
2805 let a = execute(":norm! g\<c-g>")
2806 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 +02002807
Bram Moolenaar30276f22019-01-24 17:59:39 +01002808 set fenc=utf32 bomb
2809 let a = execute(":norm! g\<c-g>")
2810 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 +02002811
Bram Moolenaar30276f22019-01-24 17:59:39 +01002812 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002813
2814 set ff&
2815 bwipe!
2816endfunc
2817
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002818" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002819func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002820 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002821 let a=execute(':norm! 1G0g8')
2822 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002823
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002824 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2825 let a=execute(':norm! 1G$g8')
2826 call assert_equal("\nc3 b6 ", a)
2827
2828 call setline(1, "a\u0302")
2829 let a=execute(':norm! 1G0g8')
2830 call assert_equal("\n61 + cc 82 ", a)
2831
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002832 " clean up
2833 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002834endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002835
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002836" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002837func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002838 new
2839
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002840 " With invalid byte.
2841 call setline(1, "___\xff___")
2842 norm! 1G08g8g
2843 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2844
2845 " With invalid byte before the cursor.
2846 call setline(1, "___\xff___")
2847 norm! 1G$h8g8g
2848 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2849
2850 " With truncated sequence.
2851 call setline(1, "___\xE2\x82___")
2852 norm! 1G08g8g
2853 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2854
2855 " With overlong sequence.
2856 call setline(1, "___\xF0\x82\x82\xAC___")
2857 norm! 1G08g8g
2858 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2859
2860 " With valid utf8.
2861 call setline(1, "café")
2862 norm! 1G08g8
2863 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2864
2865 bw!
2866endfunc
2867
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002868" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002869func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002870 " Cannot capture its output,
2871 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002872 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002873 echo "a\nb\nc\nd"
2874 let b=execute(':norm! g<')
2875 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002876endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002877
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002878" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002879func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002880 new
2881 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002882 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002883 " Test for gp gP
2884 call append(1, range(1,10))
2885 1
2886 norm! 1yy
2887 3
2888 norm! gp
2889 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2890 $
2891 norm! gP
2892 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2893
2894 " Test for go
2895 norm! 26go
2896 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2897 norm! 27go
2898 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2899 norm! 28go
2900 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2901 set ff=dos
2902 norm! 29go
2903 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2904 set ff=unix
2905 norm! gg0
2906 norm! 101go
2907 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2908 norm! 103go
2909 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2910 " count > buffer content
2911 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002912 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002913 " clean up
2914 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002915endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002916
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002917" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002918func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002919 tabnew 1.txt
2920 tabnew 2.txt
2921 tabnew 3.txt
2922 norm! 1gt
2923 call assert_equal(1, tabpagenr())
2924 norm! 3gt
2925 call assert_equal(3, tabpagenr())
2926 norm! 1gT
2927 " count gT goes not to the absolute tabpagenumber
2928 " but, but goes to the count previous tabpagenumber
2929 call assert_equal(2, tabpagenr())
2930 " wrap around
2931 norm! 3gT
2932 call assert_equal(3, tabpagenr())
2933 " gt does not wrap around
2934 norm! 5gt
2935 call assert_equal(3, tabpagenr())
2936
2937 for i in range(3)
2938 tabclose
2939 endfor
2940 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002941 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002942endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002943
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002944" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002945func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002946 new
2947 call setline(1, range(10))
2948 $
2949 setl et sw=2
2950 norm! V10>$
2951 " count is ignored
2952 exe "norm! 10\<home>"
2953 call assert_equal(1, col('.'))
2954 exe "norm! \<home>"
2955 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2956 exe "norm! 5\<c-home>"
2957 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2958 exe "norm! \<c-home>"
2959 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002960 exe "norm! G\<c-kHome>"
2961 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002962
2963 " clean up
2964 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002965endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002966
Bram Moolenaar1671f442020-03-10 07:48:13 +01002967" Test for <End> and <C-End> keys
2968func Test_normal_nvend()
2969 new
2970 call setline(1, map(range(1, 10), '"line" .. v:val'))
2971 exe "normal! \<End>"
2972 call assert_equal(5, col('.'))
2973 exe "normal! 4\<End>"
2974 call assert_equal([4, 5], [line('.'), col('.')])
2975 exe "normal! \<C-End>"
2976 call assert_equal([10, 6], [line('.'), col('.')])
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002977
2978 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01002979endfunc
2980
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002981" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01002982func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002983 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002984 new
2985 set tw=0
2986 call append(0, 'here are some words')
2987 norm! 1gg0elcwZZZ
2988 call assert_equal('hereZZZare some words', getline('.'))
2989 norm! 1gg0elcWYYY
2990 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002991 norm! 2gg0cwfoo
2992 call assert_equal('foo', getline('.'))
2993
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002994 call setline(1, 'one; two')
2995 call cursor(1, 1)
2996 call feedkeys('cwvim', 'xt')
2997 call assert_equal('vim; two', getline(1))
2998 call feedkeys('0cWone', 'xt')
2999 call assert_equal('one two', getline(1))
3000 "When cursor is at the end of a word 'ce' will change until the end of the
3001 "next word, but 'cw' will change only one character
3002 call setline(1, 'one two')
3003 call feedkeys('0ecwce', 'xt')
3004 call assert_equal('once two', getline(1))
3005 call setline(1, 'one two')
3006 call feedkeys('0ecely', 'xt')
3007 call assert_equal('only', getline(1))
3008
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003009 " clean up
3010 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003011endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003012
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003013" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003014func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003015 new
3016 call append(0, 'here are some words')
3017 exe "norm! 1gg0a\<C-\>\<C-N>"
3018 call assert_equal('n', mode())
3019 call assert_equal(1, col('.'))
3020 call assert_equal('', visualmode())
3021 exe "norm! 1gg0viw\<C-\>\<C-N>"
3022 call assert_equal('n', mode())
3023 call assert_equal(4, col('.'))
3024 exe "norm! 1gg0a\<C-\>\<C-G>"
3025 call assert_equal('n', mode())
3026 call assert_equal(1, col('.'))
3027 "imap <buffer> , <c-\><c-n>
3028 set im
3029 exe ":norm! \<c-\>\<c-n>dw"
3030 set noim
3031 call assert_equal('are some words', getline(1))
3032 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02003033 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01003034
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003035 " clean up
3036 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003037endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003038
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003039" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003040func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003041 new
3042 set sts=2 sw=2 ts=8 tw=0
3043 call append(0, ["aaa\tbbb\tccc", '', '', ''])
3044 let a=getline(1)
3045 norm! 2gg0
3046 exe "norm! a\<c-r>=a\<cr>"
3047 norm! 3gg0
3048 exe "norm! a\<c-r>\<c-r>=a\<cr>"
3049 norm! 4gg0
3050 exe "norm! a\<c-r>\<c-o>=a\<cr>"
3051 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
3052
3053 " clean up
3054 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02003055 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003056endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003057
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003058" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003059func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003060 call Setup_NewWindow()
3061 call assert_equal(5, &scroll)
3062 exe "norm! \<c-d>"
3063 call assert_equal('6', getline('.'))
3064 exe "norm! 2\<c-d>"
3065 call assert_equal('8', getline('.'))
3066 call assert_equal(2, &scroll)
3067 set scroll=5
3068 exe "norm! \<c-u>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02003069 call assert_equal('3', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003070 1
3071 set scrolloff=5
3072 exe "norm! \<c-d>"
3073 call assert_equal('10', getline('.'))
3074 exe "norm! \<c-u>"
3075 call assert_equal('5', getline('.'))
3076 1
3077 set scrolloff=99
3078 exe "norm! \<c-d>"
3079 call assert_equal('10', getline('.'))
3080 set scrolloff=0
3081 100
3082 exe "norm! $\<c-u>"
3083 call assert_equal('95', getline('.'))
3084 call assert_equal([0, 95, 1, 0, 1], getcurpos())
3085 100
3086 set nostartofline
3087 exe "norm! $\<c-u>"
3088 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00003089 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003090 " cleanup
3091 set startofline
3092 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003093endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003094
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003095func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003096 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003097 " The ~ register does not exist
3098 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003099 return
3100 endif
3101
3102 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003103 " unfortunately, without a gui, we can't really test much here,
3104 " so simply test that ~p fails (which uses the drop register)
3105 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003106 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003107 call assert_equal([], getreg('~', 1, 1))
3108 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003109 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003110 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003111endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003112
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003113func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003114 new
3115 " How to test this?
3116 " let's just for now test, that the buffer
3117 " does not change
3118 call feedkeys("\<c-s>", 't')
3119 call assert_equal([''], getline(1,'$'))
3120
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003121 " no valid commands
3122 exe "norm! \<char-0x100>"
3123 call assert_equal([''], getline(1,'$'))
3124
3125 exe "norm! ä"
3126 call assert_equal([''], getline(1,'$'))
3127
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003128 " clean up
3129 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003130endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003131
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003132func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003133 " This was causing a crash or ml_get error.
3134 enew!
3135 call setline(1,'xxx')
3136 normal $
3137 new
3138 call setline(1, range(1,2))
3139 2
3140 exe "norm \<C-V>$"
3141 bw!
3142 norm yp
3143 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003144endfunc
3145
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003146func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003147 new
3148 exe "norm! \<c-w>c"
3149 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003150 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003151endfunc
3152
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003153func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003154 new
3155 call setline(1, 'one two three four five six seven eight nine ten')
3156 1
3157 norm! 3d2w
3158 call assert_equal('seven eight nine ten', getline(1))
3159 bw!
3160endfunc
3161
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003162func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003163 CheckFeature timers
3164 CheckFeature cmdline_hist
Bram Moolenaarc255b782022-11-26 19:16:48 +00003165
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003166 func! DoTimerWork(id)
Sean Dewar1fb41032023-08-16 17:15:05 +01003167 call assert_equal(1, getbufinfo('')[0].command)
Bram Moolenaarc255b782022-11-26 19:16:48 +00003168
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003169 " should fail, with E11, but does fail with E23?
3170 "call feedkeys("\<c-^>", 'tm')
3171
Bram Moolenaarc255b782022-11-26 19:16:48 +00003172 " should fail with E11 - "Invalid in command-line window"
Bram Moolenaare2e40752020-09-04 21:18:46 +02003173 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaarc255b782022-11-26 19:16:48 +00003174
3175 " Return from commandline window.
3176 call feedkeys("\<CR>", 't')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003177 endfunc
3178
3179 let oldlang=v:lang
3180 lang C
3181 set updatetime=20
3182 call timer_start(100, 'DoTimerWork')
3183 try
3184 " throws E23, for whatever reason...
3185 call feedkeys('q:', 'x!')
3186 catch /E23/
3187 " no-op
3188 endtry
Bram Moolenaarc255b782022-11-26 19:16:48 +00003189
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003190 " clean up
Bram Moolenaarc255b782022-11-26 19:16:48 +00003191 delfunc DoTimerWork
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003192 set updatetime=4000
3193 exe "lang" oldlang
3194 bw!
3195endfunc
3196
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003197func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003198 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003199 " Don't sleep after the warning message.
3200 call test_settime(1)
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01003201 call writefile(['foo'], 'Xreadonly.log', 'D')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003202 new Xreadonly.log
3203 setl ro
3204 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003205 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003206 call assert_equal(['foo'], getline(1,'$'))
3207 call assert_equal('Xreadonly.log', bufname(''))
3208
3209 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003210 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003211 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003212endfunc
3213
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003214func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003215 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003216 new
3217 call setline(1, 'abcde fghij klmnopq')
3218 norm! 1gg$
3219 set rl
3220 call assert_equal(19, col('.'))
3221 call feedkeys('l', 'tx')
3222 call assert_equal(18, col('.'))
3223 call feedkeys('h', 'tx')
3224 call assert_equal(19, col('.'))
3225 call feedkeys("\<right>", 'tx')
3226 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003227 call feedkeys("\<left>", 'tx')
3228 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003229 call feedkeys("\<s-right>", 'tx')
3230 call assert_equal(13, col('.'))
3231 call feedkeys("\<c-right>", 'tx')
3232 call assert_equal(7, col('.'))
3233 call feedkeys("\<c-left>", 'tx')
3234 call assert_equal(13, col('.'))
3235 call feedkeys("\<s-left>", 'tx')
3236 call assert_equal(19, col('.'))
3237 call feedkeys("<<", 'tx')
3238 call assert_equal(' abcde fghij klmnopq',getline(1))
3239 call feedkeys(">>", 'tx')
3240 call assert_equal('abcde fghij klmnopq',getline(1))
3241
3242 " cleanup
3243 set norl
3244 bw!
3245endfunc
3246
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003247func Test_normal54_Ctrl_bsl()
3248 new
3249 call setline(1, 'abcdefghijklmn')
3250 exe "norm! df\<c-\>\<c-n>"
3251 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3252 exe "norm! df\<c-\>\<c-g>"
3253 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3254 exe "norm! df\<c-\>m"
3255 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003256
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003257 call setline(2, 'abcdefghijklmnāf')
3258 norm! 2gg0
3259 exe "norm! df\<Char-0x101>"
3260 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3261 norm! 1gg0
3262 exe "norm! df\<esc>"
3263 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003264
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003265 " clean up
3266 bw!
3267endfunc
3268
3269func Test_normal_large_count()
3270 " This may fail with 32bit long, how do we detect that?
3271 new
3272 normal o
3273 normal 6666666666dL
3274 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003275endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003276
3277func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003278 new
3279 normal grádv}
3280 call assert_equal('á', getline(1))
3281 normal grád}
3282 call assert_equal('', getline(1))
3283 bwipe!
3284endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003285
3286" Test for the gr (virtual replace) command
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003287func Test_gr_command()
3288 enew!
zeertzjq4f026ea2023-02-26 14:47:24 +00003289 " Test for the bug fixed by 7.4.387
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003290 let save_cpo = &cpo
3291 call append(0, ['First line', 'Second line', 'Third line'])
3292 exe "normal i\<C-G>u"
3293 call cursor(2, 1)
3294 set cpo-=X
3295 normal 4gro
3296 call assert_equal('oooond line', getline(2))
3297 undo
3298 set cpo+=X
3299 normal 4gro
3300 call assert_equal('ooooecond line', getline(2))
3301 let &cpo = save_cpo
zeertzjq4f026ea2023-02-26 14:47:24 +00003302
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003303 normal! ggvegrx
3304 call assert_equal('xxxxx line', getline(1))
3305 exe "normal! gggr\<C-V>122"
3306 call assert_equal('zxxxx line', getline(1))
zeertzjq4f026ea2023-02-26 14:47:24 +00003307
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003308 set virtualedit=all
3309 normal! 15|grl
3310 call assert_equal('zxxxx line l', getline(1))
3311 set virtualedit&
3312 set nomodifiable
3313 call assert_fails('normal! grx', 'E21:')
3314 call assert_fails('normal! gRx', 'E21:')
zeertzjq4f026ea2023-02-26 14:47:24 +00003315 call assert_nobeep("normal! gr\<Esc>")
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003316 set modifiable&
zeertzjq4f026ea2023-02-26 14:47:24 +00003317
3318 call assert_nobeep("normal! gr\<Esc>")
zeertzjqf86dea82023-03-05 21:15:06 +00003319 call assert_nobeep("normal! cgr\<Esc>")
3320 call assert_beeps("normal! cgrx")
zeertzjq4f026ea2023-02-26 14:47:24 +00003321
3322 call assert_equal('zxxxx line l', getline(1))
3323 exe "normal! 2|gr\<C-V>\<Esc>"
3324 call assert_equal("z\<Esc>xx line l", getline(1))
3325
3326 call setline(1, 'abcdef')
3327 exe "normal! 0gr\<C-O>lx"
3328 call assert_equal("\<C-O>def", getline(1))
3329
3330 call setline(1, 'abcdef')
3331 exe "normal! 0gr\<C-G>lx"
3332 call assert_equal("\<C-G>def", getline(1))
3333
3334 bwipe!
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003335endfunc
3336
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003337func Test_nv_hat_count()
3338 %bwipeout!
3339 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003340 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003341
3342 edit Xfoo
3343 let l:foo_nr = bufnr('Xfoo')
3344
3345 edit Xbar
3346 let l:bar_nr = bufnr('Xbar')
3347
3348 " Make sure we are not just using the alternate file.
3349 edit Xbaz
3350
3351 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3352 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3353
3354 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3355 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3356
3357 %bwipeout!
3358endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003359
3360func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003361 " Make sure no buffers are changed.
3362 %bwipe!
3363
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003364 exe "normal \<C-C>"
3365 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003366
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003367 new
3368 cal setline(1, 'hi!')
3369 exe "normal \<C-C>"
3370 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003371
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003372 bwipe!
3373endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003374
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01003375func Test_mode_updated_after_ctrl_c()
3376 CheckScreendump
3377
3378 let buf = RunVimInTerminal('', {'rows': 5})
3379 call term_sendkeys(buf, "i")
3380 call term_sendkeys(buf, "\<C-O>")
3381 " wait a moment so that the "-- (insert) --" message is displayed
3382 call TermWait(buf, 50)
3383 call term_sendkeys(buf, "\<C-C>")
3384 call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
3385
3386 call StopVimInTerminal(buf)
3387endfunc
3388
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003389" Test for '[m', ']m', '[M' and ']M'
3390" Jumping to beginning and end of methods in Java-like languages
3391func Test_java_motion()
3392 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003393 call assert_beeps('normal! [m')
3394 call assert_beeps('normal! ]m')
3395 call assert_beeps('normal! [M')
3396 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003397 let lines =<< trim [CODE]
3398 Piece of Java
3399 {
3400 tt m1 {
3401 t1;
3402 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003403
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003404 tt m2 {
3405 t2;
3406 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003407
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003408 tt m3 {
3409 if (x)
3410 {
3411 t3;
3412 }
3413 } e3
3414 }
3415 [CODE]
3416 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003417
3418 normal gg
3419
3420 normal 2]maA
3421 call assert_equal("\ttt m1 {A", getline('.'))
3422 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3423
3424 normal j]maB
3425 call assert_equal("\ttt m2 {B", getline('.'))
3426 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3427
3428 normal ]maC
3429 call assert_equal("\ttt m3 {C", getline('.'))
3430 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3431
3432 normal [maD
3433 call assert_equal("\ttt m3 {DC", getline('.'))
3434 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3435
3436 normal k2[maE
3437 call assert_equal("\ttt m1 {EA", getline('.'))
3438 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3439
3440 normal 3[maF
3441 call assert_equal("{F", getline('.'))
3442 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3443
3444 normal ]MaG
3445 call assert_equal("\t}G e1", getline('.'))
3446 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3447
3448 normal j2]MaH
3449 call assert_equal("\t}H e3", getline('.'))
3450 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3451
3452 normal ]M]M
3453 normal aI
3454 call assert_equal("}I", getline('.'))
3455 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3456
3457 normal 2[MaJ
3458 call assert_equal("\t}JH e3", getline('.'))
3459 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3460
3461 normal k[MaK
3462 call assert_equal("\t}K e2", getline('.'))
3463 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3464
3465 normal 3[MaL
3466 call assert_equal("{LF", getline('.'))
3467 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3468
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003469 call cursor(2, 1)
3470 call assert_beeps('norm! 5]m')
3471
3472 " jumping to a method in a fold should open the fold
3473 6,10fold
3474 call feedkeys("gg3]m", 'xt')
3475 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3476 call assert_equal(-1, foldclosedend(7))
3477
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003478 bwipe!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003479endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003480
Bram Moolenaar004a6782020-04-11 17:09:31 +02003481" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003482func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003483 call Setup_NewWindow()
3484 " Make long lines that will wrap
3485 %s/$/\=repeat(' foobar', 10)/
3486 20vsp
3487 set wrap
3488 " Test for g$ with count
3489 norm! gg
3490 norm! 0vg$y
3491 call assert_equal(20, col("'>"))
3492 call assert_equal('1 foobar foobar foob', getreg(0))
3493 norm! gg
3494 norm! 0v4g$y
3495 call assert_equal(72, col("'>"))
3496 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3497 norm! gg
3498 norm! 0v6g$y
3499 call assert_equal(40, col("'>"))
3500 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3501 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3502 set nowrap
3503 " clean up
3504 norm! gg
3505 norm! 0vg$y
3506 call assert_equal(20, col("'>"))
3507 call assert_equal('1 foobar foobar foob', getreg(0))
3508 norm! gg
3509 norm! 0v4g$y
3510 call assert_equal(20, col("'>"))
3511 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3512 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3513 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3514 \ '4 foobar foobar foob', getreg(0))
3515 norm! gg
3516 norm! 0v6g$y
3517 call assert_equal(20, col("'>"))
3518 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3519 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3520 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3521 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3522 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3523 \ '6 foobar foobar foob', getreg(0))
3524 " Move to last line, also down movement is not possible, should still move
3525 " the cursor to the last visible char
3526 norm! G
3527 norm! 0v6g$y
3528 call assert_equal(20, col("'>"))
3529 call assert_equal('100 foobar foobar fo', getreg(0))
3530 bw!
3531endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003532
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003533func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003534 " needs 80 column new window
3535 new
3536 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003537 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003538 put =[repeat('x',90)..' {{{1', 'x {{{1']
3539 norm! gk
3540 " In a 80 column wide terminal the window will be only 78 char
3541 " (because Vim will leave space for the other window),
3542 " but if the terminal is larger, it will be 80 chars, so verify the
3543 " cursor column correctly.
3544 call assert_equal(winwidth(0)+1, col('.'))
3545 call assert_equal(winwidth(0)+1, virtcol('.'))
3546 norm! j
3547 call assert_equal(6, col('.'))
3548 call assert_equal(6, virtcol('.'))
3549 norm! gk
3550 call assert_equal(95, col('.'))
3551 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003552 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003553
3554 " needs 80 column new window
3555 new
3556 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003557 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003558 set number
3559 set numberwidth=10
3560 set cpoptions+=n
3561 put =[repeat('0',90), repeat('1',90)]
3562 norm! 075l
3563 call assert_equal(76, col('.'))
3564 norm! gk
3565 call assert_equal(1, col('.'))
3566 norm! gk
3567 call assert_equal(76, col('.'))
3568 norm! gk
3569 call assert_equal(1, col('.'))
3570 norm! gj
3571 call assert_equal(76, col('.'))
3572 norm! gj
3573 call assert_equal(1, col('.'))
3574 norm! gj
3575 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003576 " When 'nowrap' is set, gk and gj behave like k and j
3577 set nowrap
3578 normal! gk
3579 call assert_equal([2, 76], [line('.'), col('.')])
3580 normal! gj
3581 call assert_equal([3, 76], [line('.'), col('.')])
3582 %bw!
3583 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003584endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003585
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003586" Test for using : to run a multi-line Ex command in operator pending mode
3587func Test_normal_yank_with_excmd()
3588 new
3589 call setline(1, ['foo', 'bar', 'baz'])
3590 let @a = ''
3591 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3592 call assert_equal('f', @a)
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003593
3594 bwipe!
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003595endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003596
3597" Test for supplying a count to a normal-mode command across a cursorhold call
3598func Test_normal_cursorhold_with_count()
3599 func s:cHold()
3600 let g:cHold_Called += 1
3601 endfunc
3602 new
3603 augroup normalcHoldTest
3604 au!
3605 au CursorHold <buffer> call s:cHold()
3606 augroup END
3607 let g:cHold_Called = 0
3608 call feedkeys("3\<CursorHold>2ix", 'xt')
3609 call assert_equal(1, g:cHold_Called)
3610 call assert_equal(repeat('x', 32), getline(1))
3611 augroup normalcHoldTest
3612 au!
3613 augroup END
3614 au! normalcHoldTest
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003615
3616 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003617 delfunc s:cHold
3618endfunc
3619
3620" Test for using a count and a command with CTRL-W
3621func Test_wincmd_with_count()
3622 call feedkeys("\<C-W>12n", 'xt')
3623 call assert_equal(12, winheight(0))
3624endfunc
3625
3626" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003627func Test_horiz_motion()
3628 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003629 normal! gg
3630 call assert_beeps('normal! b')
3631 call assert_beeps('normal! B')
3632 call assert_beeps('normal! gE')
3633 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003634 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3635 call setline(1, 'one ,two ,three')
3636 exe "normal! $\<S-BS>"
3637 call assert_equal(11, col('.'))
3638 exe "normal! $\<C-BS>"
3639 call assert_equal(10, col('.'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003640
3641 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003642endfunc
3643
zeertzjq30b6d612023-05-07 17:39:23 +01003644" Test for using a ":" command in operator pending mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003645func Test_normal_colon_op()
3646 new
3647 call setline(1, ['one', 'two'])
3648 call assert_beeps("normal! Gc:d\<CR>")
zeertzjq30b6d612023-05-07 17:39:23 +01003649 call assert_equal(['one'], getline(1, '$'))
3650
3651 call setline(1, ['one…two…three!'])
3652 normal! $
3653 " Using ":" as a movement is characterwise exclusive
3654 call feedkeys("d:normal! F…\<CR>", 'xt')
3655 call assert_equal(['one…two!'], getline(1, '$'))
3656 " Check that redoing a command with 0x80 bytes works
3657 call feedkeys('.', 'xt')
3658 call assert_equal(['one!'], getline(1, '$'))
3659
3660 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3661 " Add this to the command history
3662 call feedkeys(":normal! G0\<CR>", 'xt')
3663 " Use :normal! with control characters in operator pending mode
3664 call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
3665 call assert_equal(['one', 'two', 'five'], getline(1, '$'))
3666 " Check that redoing a command with control characters works
3667 call feedkeys('.', 'xt')
3668 call assert_equal(['five'], getline(1, '$'))
3669
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003670 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003671endfunc
3672
Bram Moolenaar004a6782020-04-11 17:09:31 +02003673" Test for d and D commands
3674func Test_normal_delete_cmd()
3675 new
3676 " D in an empty line
3677 call setline(1, '')
3678 normal D
3679 call assert_equal('', getline(1))
3680 " D in an empty line in virtualedit mode
3681 set virtualedit=all
3682 normal D
3683 call assert_equal('', getline(1))
3684 set virtualedit&
3685 " delete to a readonly register
3686 call setline(1, ['abcd'])
3687 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003688
3689 " D and d with 'nomodifiable'
3690 call setline(1, ['abcd'])
3691 setlocal nomodifiable
3692 call assert_fails('normal D', 'E21:')
3693 call assert_fails('normal d$', 'E21:')
3694
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003695 bwipe!
Bram Moolenaar004a6782020-04-11 17:09:31 +02003696endfunc
3697
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003698" Test for deleting or changing characters across lines with 'whichwrap'
3699" containing 's'. Should count <EOL> as one character.
3700func Test_normal_op_across_lines()
3701 new
3702 set whichwrap&
3703 call setline(1, ['one two', 'three four'])
3704 exe "norm! $3d\<Space>"
3705 call assert_equal(['one twhree four'], getline(1, '$'))
3706
3707 call setline(1, ['one two', 'three four'])
3708 exe "norm! $3c\<Space>x"
3709 call assert_equal(['one twxhree four'], getline(1, '$'))
3710
3711 set whichwrap+=l
3712 call setline(1, ['one two', 'three four'])
3713 exe "norm! $3x"
3714 call assert_equal(['one twhree four'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003715
3716 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003717 set whichwrap&
3718endfunc
3719
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003720" Test for 'w' and 'b' commands
3721func Test_normal_word_move()
3722 new
3723 call setline(1, ['foo bar a', '', 'foo bar b'])
3724 " copy a single character word at the end of a line
3725 normal 1G$yw
3726 call assert_equal('a', @")
3727 " copy a single character word at the end of a file
3728 normal G$yw
3729 call assert_equal('b', @")
3730 " check for a word movement handling an empty line properly
3731 normal 1G$vwy
3732 call assert_equal("a\n\n", @")
3733
3734 " copy using 'b' command
3735 %d
3736 " non-empty blank line at the start of file
3737 call setline(1, [' ', 'foo bar'])
3738 normal 2Gyb
3739 call assert_equal(" \n", @")
3740 " try to copy backwards from the start of the file
3741 call setline(1, ['one two', 'foo bar'])
3742 call assert_beeps('normal ggyb')
3743 " 'b' command should stop at an empty line
3744 call setline(1, ['one two', '', 'foo bar'])
3745 normal 3Gyb
3746 call assert_equal("\n", @")
3747 normal 3Gy2b
3748 call assert_equal("two\n", @")
3749 " 'b' command should not stop at a non-empty blank line
3750 call setline(1, ['one two', ' ', 'foo bar'])
3751 normal 3Gyb
3752 call assert_equal("two\n ", @")
3753
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003754 bwipe!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003755endfunc
3756
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003757" Test for 'scrolloff' with a long line that doesn't fit in the screen
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003758func Test_normal_scrolloff()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003759 10new
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003760 60vnew
3761 call setline(1, ' 1 ' .. repeat('a', 57)
3762 \ .. ' 2 ' .. repeat('b', 57)
3763 \ .. ' 3 ' .. repeat('c', 57)
3764 \ .. ' 4 ' .. repeat('d', 57)
3765 \ .. ' 5 ' .. repeat('e', 57)
3766 \ .. ' 6 ' .. repeat('f', 57)
3767 \ .. ' 7 ' .. repeat('g', 57)
3768 \ .. ' 8 ' .. repeat('h', 57)
3769 \ .. ' 9 ' .. repeat('i', 57)
3770 \ .. '10 ' .. repeat('j', 57)
3771 \ .. '11 ' .. repeat('k', 57)
3772 \ .. '12 ' .. repeat('l', 57)
3773 \ .. '13 ' .. repeat('m', 57)
3774 \ .. '14 ' .. repeat('n', 57)
3775 \ .. '15 ' .. repeat('o', 57)
3776 \ .. '16 ' .. repeat('p', 57)
3777 \ .. '17 ' .. repeat('q', 57)
3778 \ .. '18 ' .. repeat('r', 57)
3779 \ .. '19 ' .. repeat('s', 57)
3780 \ .. '20 ' .. repeat('t', 57)
3781 \ .. '21 ' .. repeat('u', 57)
3782 \ .. '22 ' .. repeat('v', 57)
3783 \ .. '23 ' .. repeat('w', 57)
3784 \ .. '24 ' .. repeat('x', 57)
3785 \ .. '25 ' .. repeat('y', 57)
3786 \ .. '26 ' .. repeat('z', 57)
3787 \ )
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003788 set scrolloff=10
3789 normal gg10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003790 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003791 normal 10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003792 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003793 normal 10gk
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003794 call assert_equal(6, winline())
3795 normal 0
3796 call assert_equal(1, winline())
3797 normal $
3798 call assert_equal(10, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003799
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003800 set scrolloff&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003801 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003802endfunc
3803
3804" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3805func Test_normal_vert_scroll_longline()
3806 10new
3807 80vnew
3808 call setline(1, range(1, 10))
3809 call append(5, repeat('a', 1000))
3810 exe "normal gg\<C-F>"
3811 call assert_equal(6, line('.'))
3812 exe "normal \<C-F>\<C-F>"
3813 call assert_equal(11, line('.'))
3814 call assert_equal(1, winline())
3815 exe "normal \<C-B>"
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003816 call assert_equal(10, line('.'))
Luuk van Baalcb204e62024-04-02 20:49:45 +02003817 call assert_equal(4, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003818 exe "normal \<C-B>\<C-B>"
3819 call assert_equal(5, line('.'))
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003820 call assert_equal(5, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003821
3822 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003823endfunc
3824
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003825" Test for jumping in a file using %
3826func Test_normal_percent_jump()
3827 new
3828 call setline(1, range(1, 100))
3829
3830 " jumping to a folded line should open the fold
3831 25,75fold
3832 call feedkeys('50%', 'xt')
3833 call assert_equal(50, line('.'))
3834 call assert_equal(-1, foldclosedend(50))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003835
3836 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003837endfunc
3838
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003839" Test for << and >> commands to shift text by 'shiftwidth'
3840func Test_normal_shift_rightleft()
3841 new
3842 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3843 set shiftwidth=2 tabstop=8
3844 normal gg6>>
3845 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3846 \ getline(1, '$'))
3847 normal ggVG2>>
3848 call assert_equal([' one', '', "\t ", "\ttwo",
3849 \ "\t three", "\t four"], getline(1, '$'))
3850 normal gg6<<
3851 call assert_equal([' one', '', "\t ", ' two', "\t three",
3852 \ "\t four"], getline(1, '$'))
3853 normal ggVG2<<
3854 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3855 \ getline(1, '$'))
3856 set shiftwidth& tabstop&
3857 bw!
3858endfunc
3859
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003860" Some commands like yy, cc, dd, >>, << and !! accept a count after
3861" typing the first letter of the command.
3862func Test_normal_count_after_operator()
3863 new
3864 setlocal shiftwidth=4 tabstop=8 autoindent
3865 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3866 let @a = ''
3867 normal! j"ay4y
3868 call assert_equal("two\nthree\nfour\nfive\n", @a)
3869 normal! 3G>2>
3870 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3871 \ getline(1, '$'))
3872 exe "normal! 3G0c2cred\nblue"
3873 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3874 \ getline(1, '$'))
3875 exe "normal! gg<8<"
3876 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3877 \ getline(1, '$'))
3878 exe "normal! ggd3d"
3879 call assert_equal(['blue', 'five'], getline(1, '$'))
3880 call setline(1, range(1, 4))
3881 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3882 call assert_equal('".,.+2!', @:)
3883 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3884 call assert_equal('".!', @:)
3885 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3886 call assert_equal('".,$!', @:)
3887 bw!
3888endfunc
3889
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003890func Test_normal_gj_on_extra_wide_char()
3891 new | 25vsp
3892 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3893 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3894 \ ' dreizehn v ierzehn fünfzehn'
3895 put =text
3896 call cursor(2,1)
3897 norm! gj
3898 call assert_equal([0,2,25,0], getpos('.'))
3899 bw!
3900endfunc
3901
Bram Moolenaar03725c52021-11-24 12:17:53 +00003902func Test_normal_count_out_of_range()
3903 new
3904 call setline(1, 'text')
3905 normal 44444444444|
3906 call assert_equal(999999999, v:count)
3907 normal 444444444444|
3908 call assert_equal(999999999, v:count)
3909 normal 4444444444444|
3910 call assert_equal(999999999, v:count)
3911 normal 4444444444444444444|
3912 call assert_equal(999999999, v:count)
3913
3914 normal 9y99999999|
3915 call assert_equal(899999991, v:count)
3916 normal 10y99999999|
3917 call assert_equal(999999999, v:count)
3918 normal 44444444444y44444444444|
3919 call assert_equal(999999999, v:count)
3920 bwipe!
3921endfunc
3922
zeertzjqcdeb6572022-11-15 13:46:12 +00003923" Test that mouse shape is restored to Normal mode after failed "c" operation.
3924func Test_mouse_shape_after_failed_change()
3925 CheckFeature mouseshape
3926 CheckCanRunGui
3927
3928 let lines =<< trim END
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003929 vim9script
zeertzjqcdeb6572022-11-15 13:46:12 +00003930 set mouseshape+=o:busy
3931 setlocal nomodifiable
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003932 var mouse_shapes = []
zeertzjqcdeb6572022-11-15 13:46:12 +00003933
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003934 feedkeys('c')
3935 timer_start(50, (_) => {
3936 mouse_shapes += [getmouseshape()]
3937 timer_start(50, (_) => {
3938 feedkeys('c')
3939 timer_start(50, (_) => {
3940 mouse_shapes += [getmouseshape()]
3941 timer_start(50, (_) => {
3942 writefile(mouse_shapes, 'Xmouseshapes')
3943 quit
3944 })
3945 })
3946 })
3947 })
zeertzjqcdeb6572022-11-15 13:46:12 +00003948 END
3949 call writefile(lines, 'Xmouseshape.vim', 'D')
3950 call RunVim([], [], "-g -S Xmouseshape.vim")
3951 sleep 300m
3952 call assert_equal(['busy', 'arrow'], readfile('Xmouseshapes'))
3953
3954 call delete('Xmouseshapes')
3955endfunc
3956
zeertzjqf86dea82023-03-05 21:15:06 +00003957" Test that mouse shape is restored to Normal mode after cancelling "gr".
3958func Test_mouse_shape_after_cancelling_gr()
3959 CheckFeature mouseshape
3960 CheckCanRunGui
3961
3962 let lines =<< trim END
3963 vim9script
3964 var mouse_shapes = []
3965
3966 feedkeys('gr')
3967 timer_start(50, (_) => {
3968 mouse_shapes += [getmouseshape()]
3969 timer_start(50, (_) => {
3970 feedkeys("\<Esc>")
3971 timer_start(50, (_) => {
3972 mouse_shapes += [getmouseshape()]
3973 timer_start(50, (_) => {
3974 writefile(mouse_shapes, 'Xmouseshapes')
3975 quit
3976 })
3977 })
3978 })
3979 })
3980 END
3981 call writefile(lines, 'Xmouseshape.vim', 'D')
3982 call RunVim([], [], "-g -S Xmouseshape.vim")
3983 sleep 300m
3984 call assert_equal(['beam', 'arrow'], readfile('Xmouseshapes'))
3985
3986 call delete('Xmouseshapes')
3987endfunc
3988
Luuk van Baalaa6ba302023-05-09 16:01:17 +01003989" Test that "j" does not skip lines when scrolling below botline and
3990" 'foldmethod' is not "manual".
3991func Test_normal_j_below_botline()
3992 CheckScreendump
3993
3994 let lines =<< trim END
3995 set number foldmethod=diff scrolloff=0
3996 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
3997 norm Lj
3998 END
3999 call writefile(lines, 'XNormalJBelowBotline', 'D')
4000 let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
4001
4002 call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
4003
4004 call StopVimInTerminal(buf)
4005endfunc
4006
Christian Brabandt2d63e4b2023-08-12 00:03:57 +02004007" Test for r (replace) command with CTRL_V and CTRL_Q
4008func Test_normal_r_ctrl_v_cmd()
4009 new
4010 call append(0, 'This is a simple test: abcd')
4011 exe "norm! 1gg$r\<C-V>\<C-V>"
4012 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4013 exe "norm! 1gg$hr\<C-Q>\<C-Q>"
4014 call assert_equal(['This is a simple test: ab', ''], getline(1,'$'))
4015 exe "norm! 1gg$2hr\<C-V>x7e"
4016 call assert_equal(['This is a simple test: a~', ''], getline(1,'$'))
4017 exe "norm! 1gg$3hr\<C-Q>x7e"
4018 call assert_equal(['This is a simple test: ~~', ''], getline(1,'$'))
4019
4020 if &encoding == 'utf-8'
4021 exe "norm! 1gg$4hr\<C-V>u20ac"
4022 call assert_equal(['This is a simple test:€~~', ''], getline(1,'$'))
4023 exe "norm! 1gg$5hr\<C-Q>u20ac"
4024 call assert_equal(['This is a simple test€€~~', ''], getline(1,'$'))
4025 exe "norm! 1gg0R\<C-V>xff WAS \<esc>"
4026 call assert_equal(['ÿ WAS a simple test€€~~', ''], getline(1,'$'))
4027 exe "norm! 1gg0elR\<C-Q>xffNOT\<esc>"
4028 call assert_equal(['ÿ WASÿNOT simple test€€~~', ''], getline(1,'$'))
4029 endif
4030
4031 call setline(1, 'This is a simple test: abcd')
4032 exe "norm! 1gg$gr\<C-V>\<C-V>"
4033 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4034 exe "norm! 1gg$hgr\<C-Q>\<C-Q>"
4035 call assert_equal(['This is a simple test: ab ', ''], getline(1,'$'))
4036 exe "norm! 1gg$2hgr\<C-V>x7e"
4037 call assert_equal(['This is a simple test: a~ ', ''], getline(1,'$'))
4038 exe "norm! 1gg$3hgr\<C-Q>x7e"
4039 call assert_equal(['This is a simple test: ~~ ', ''], getline(1,'$'))
4040
4041 " clean up
4042 bw!
4043endfunc
4044
zeertzjqb25dbb32023-08-13 18:11:05 +02004045" Test clicking on a TAB or an unprintable character in Normal mode
4046func Test_normal_click_on_ctrl_char()
4047 let save_mouse = &mouse
4048 set mouse=a
4049 new
4050
4051 call setline(1, "a\<Tab>b\<C-K>c")
4052 redraw
4053 call test_setmouse(1, 1)
4054 call feedkeys("\<LeftMouse>", 'xt')
4055 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4056 call test_setmouse(1, 2)
4057 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004058 call assert_equal([0, 1, 2, 0, 2], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004059 call test_setmouse(1, 3)
4060 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004061 call assert_equal([0, 1, 2, 0, 3], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004062 call test_setmouse(1, 7)
4063 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004064 call assert_equal([0, 1, 2, 0, 7], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004065 call test_setmouse(1, 8)
4066 call feedkeys("\<LeftMouse>", 'xt')
4067 call assert_equal([0, 1, 2, 0, 8], getcurpos())
4068 call test_setmouse(1, 9)
4069 call feedkeys("\<LeftMouse>", 'xt')
4070 call assert_equal([0, 1, 3, 0, 9], getcurpos())
4071 call test_setmouse(1, 10)
4072 call feedkeys("\<LeftMouse>", 'xt')
4073 call assert_equal([0, 1, 4, 0, 10], getcurpos())
4074 call test_setmouse(1, 11)
4075 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004076 call assert_equal([0, 1, 4, 0, 11], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004077 call test_setmouse(1, 12)
4078 call feedkeys("\<LeftMouse>", 'xt')
4079 call assert_equal([0, 1, 5, 0, 12], getcurpos())
4080 call test_setmouse(1, 13)
4081 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004082 call assert_equal([0, 1, 5, 0, 13], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004083
4084 bwipe!
4085 let &mouse = save_mouse
4086endfunc
4087
zeertzjq99941602023-08-19 13:08:50 +02004088" Test clicking on a double-width character in Normal mode
4089func Test_normal_click_on_double_width_char()
4090 let save_mouse = &mouse
4091 set mouse=a
4092 new
4093
4094 call setline(1, "口口")
4095 redraw
4096 call test_setmouse(1, 1)
4097 call feedkeys("\<LeftMouse>", 'xt')
4098 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4099 call test_setmouse(1, 2)
4100 call feedkeys("\<LeftMouse>", 'xt')
4101 call assert_equal([0, 1, 1, 0, 2], getcurpos())
4102 call test_setmouse(1, 3)
4103 call feedkeys("\<LeftMouse>", 'xt')
4104 call assert_equal([0, 1, 4, 0, 3], getcurpos())
4105 call test_setmouse(1, 4)
4106 call feedkeys("\<LeftMouse>", 'xt')
4107 call assert_equal([0, 1, 4, 0, 4], getcurpos())
4108
4109 bwipe!
4110 let &mouse = save_mouse
4111endfunc
4112
zeertzjq03cd6972023-09-20 20:08:40 +02004113func Test_normal_click_on_empty_line()
4114 let save_mouse = &mouse
4115 set mouse=a
4116 botright new
4117 call setline(1, ['', '', ''])
4118 let row = win_screenpos(0)[0] + 2
4119 20vsplit
4120 redraw
4121
4122 call test_setmouse(row, 1)
4123 call feedkeys("\<LeftMouse>", 'xt')
4124 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4125 call test_setmouse(row, 2)
4126 call feedkeys("\<LeftMouse>", 'xt')
4127 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4128 call test_setmouse(row, 10)
4129 call feedkeys("\<LeftMouse>", 'xt')
4130 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4131
4132 call test_setmouse(row, 21 + 1)
4133 call feedkeys("\<LeftMouse>", 'xt')
4134 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4135 call test_setmouse(row, 21 + 2)
4136 call feedkeys("\<LeftMouse>", 'xt')
4137 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4138 call test_setmouse(row, 21 + 10)
4139 call feedkeys("\<LeftMouse>", 'xt')
4140 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4141
4142 bwipe!
4143 let &mouse = save_mouse
4144endfunc
4145
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004146func Test_normal33_g_cmd_nonblank()
zeertzjq654bdbb2023-08-20 18:24:20 +02004147 " Test that g<End> goes to the last non-blank char and g$ to the last
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004148 " visible column
4149 20vnew
4150 setlocal nowrap nonumber signcolumn=no
4151 call setline(1, ['fooo fooo fooo fooo fooo fooo fooo fooo '])
zeertzjq654bdbb2023-08-20 18:24:20 +02004152 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004153 call assert_equal(11, col('.'))
4154 normal 0g$
4155 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004156 exe "normal 0g\<kEnd>"
4157 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004158 setlocal wrap
zeertzjq654bdbb2023-08-20 18:24:20 +02004159 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004160 call assert_equal(11, col('.'))
4161 normal 0g$
4162 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004163 exe "normal 0g\<kEnd>"
4164 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004165 bw!
4166endfunc
4167
Christian Brabandt58f9bef2023-11-14 21:02:30 +01004168func Test_normal34_zet_large()
4169 " shouldn't cause overflow
4170 norm! z9765405999999999999
4171endfunc
4172
zeertzjqad493ef2024-03-29 10:23:19 +01004173" Test for { and } paragraph movements in a single line
4174func Test_brace_single_line()
4175 new
4176 call setline(1, ['foobar one two three'])
4177 1
4178 norm! 0}
4179
4180 call assert_equal([0, 1, 20, 0], getpos('.'))
4181 norm! {
4182 call assert_equal([0, 1, 1, 0], getpos('.'))
4183 bw!
4184endfunc
4185
4186" Test for Ctrl-B/Ctrl-U in buffer with a single line
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004187func Test_single_line_scroll()
4188 CheckFeature textprop
Gary Johnson9e6549d2023-12-27 19:12:43 +01004189
4190 new
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004191 call setline(1, ['foobar one two three'])
4192 let vt = 'virt_above'
4193 call prop_type_add(vt, {'highlight': 'IncSearch'})
4194 call prop_add(1, 0, {'type': vt, 'text': '---', 'text_align': 'above'})
zeertzjqad493ef2024-03-29 10:23:19 +01004195 call cursor(1, 1)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004196
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004197 " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004198 set smoothscroll
4199 exe "normal \<C-E>"
4200 call assert_notequal(0, winsaveview().skipcol)
4201 exe "normal \<C-B>"
4202 call assert_equal(0, winsaveview().skipcol)
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004203 exe "normal \<C-E>"
4204 call assert_notequal(0, winsaveview().skipcol)
4205 exe "normal \<C-U>"
4206 call assert_equal(0, winsaveview().skipcol)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004207
4208 set smoothscroll&
Gary Johnson9e6549d2023-12-27 19:12:43 +01004209 bw!
zeertzjqad493ef2024-03-29 10:23:19 +01004210 call prop_type_delete(vt)
Gary Johnson9e6549d2023-12-27 19:12:43 +01004211endfunc
4212
Christian Brabandt5d5cbb22024-01-05 18:19:52 +01004213" vim: shiftwidth=2 sts=2 expandtab nofoldenable