blob: 374696443d0b3c881bfa2aeef9ebf9e55241ecfa [file] [log] [blame]
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001" Test for various Normal mode commands
2
Christian Brabandteb380b92025-07-07 20:53:55 +02003import './util/vim9.vim' as v9
4source util/screendump.vim
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01005
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01006func Setup_NewWindow()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02007 10new
8 call setline(1, range(1,100))
9endfunc
10
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010011func MyFormatExpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020012 " Adds '->$' at lines having numbers followed by trailing whitespace
13 for ln in range(v:lnum, v:lnum+v:count-1)
14 let line = getline(ln)
15 if getline(ln) =~# '\d\s\+$'
16 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
17 endif
18 endfor
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020019endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020020
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010021func CountSpaces(type, ...)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020022 " for testing operatorfunc
23 " will count the number of spaces
24 " and return the result in g:a
25 let sel_save = &selection
26 let &selection = "inclusive"
27 let reg_save = @@
28
29 if a:0 " Invoked from Visual mode, use gv command.
30 silent exe "normal! gvy"
31 elseif a:type == 'line'
32 silent exe "normal! '[V']y"
33 else
34 silent exe "normal! `[v`]y"
35 endif
Bram Moolenaar777e7c22021-10-25 17:07:04 +010036 let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020037 let &selection = sel_save
38 let @@ = reg_save
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020039endfunc
40
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010041func OpfuncDummy(type, ...)
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010042 " for testing operatorfunc
Bram Moolenaar777e7c22021-10-25 17:07:04 +010043 let g:opt = &linebreak
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +010044
45 if a:0 " Invoked from Visual mode, use gv command.
46 silent exe "normal! gvy"
47 elseif a:type == 'line'
48 silent exe "normal! '[V']y"
49 else
50 silent exe "normal! `[v`]y"
51 endif
52 " Create a new dummy window
53 new
Bram Moolenaar777e7c22021-10-25 17:07:04 +010054 let g:bufnr = bufnr('%')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020055endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020056
Bram Moolenaar1671f442020-03-10 07:48:13 +010057func Test_normal00_optrans()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020058 new
59 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
60 1
61 exe "norm! Sfoobar\<esc>"
62 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
63 2
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020064 exe "norm! $vbsone"
65 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 +020066 norm! VS Second line here
67 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
68 %d
69 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
70 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
71
72 1
73 norm! 2D
74 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,'$'))
75 set cpo+=#
76 norm! 4D
77 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
78
79 " clean up
80 set cpo-=#
81 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020082endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020083
Bram Moolenaar1bbb6192018-11-10 16:02:01 +010084func Test_normal01_keymodel()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020085 call Setup_NewWindow()
86 " Test 1: depending on 'keymodel' <s-down> does something different
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020087 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020088 call feedkeys("V\<S-Up>y", 'tx')
89 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020090 set keymodel=startsel
91 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020092 call feedkeys("V\<S-Up>y", 'tx')
93 call assert_equal(['49', '50'], getline("'<", "'>"))
94 " Start visual mode when keymodel = startsel
Bram Moolenaar2931f2a2016-09-09 16:59:08 +020095 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +020096 call feedkeys("\<S-Up>y", 'tx')
97 call assert_equal(['49', '5'], getreg(0, 0, 1))
Bram Moolenaar1671f442020-03-10 07:48:13 +010098 " Use the different Shift special keys
99 50
100 call feedkeys("\<S-Right>\<S-Left>\<S-Up>\<S-Down>\<S-Home>\<S-End>y", 'tx')
101 call assert_equal(['50'], getline("'<", "'>"))
102 call assert_equal(['50', ''], getreg(0, 0, 1))
103
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200104 " Do not start visual mode when keymodel=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200105 set keymodel=
106 50
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200107 call feedkeys("\<S-Up>y$", 'tx')
108 call assert_equal(['42'], getreg(0, 0, 1))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200109 " Stop visual mode when keymodel=stopsel
110 set keymodel=stopsel
111 50
112 call feedkeys("Vkk\<Up>yy", 'tx')
113 call assert_equal(['47'], getreg(0, 0, 1))
114
115 set keymodel=
116 50
117 call feedkeys("Vkk\<Up>yy", 'tx')
118 call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200119
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200120 " Test for using special keys to start visual selection
121 %d
122 call setline(1, ['red fox tail', 'red fox tail', 'red fox tail'])
123 set keymodel=startsel
124 " Test for <S-PageUp> and <S-PageDown>
125 call cursor(1, 1)
126 call feedkeys("\<S-PageDown>y", 'xt')
127 call assert_equal([0, 1, 1, 0], getpos("'<"))
128 call assert_equal([0, 3, 1, 0], getpos("'>"))
129 call feedkeys("Gz\<CR>8|\<S-PageUp>y", 'xt')
Luuk van Baalb9f5b952024-03-26 18:46:45 +0100130 call assert_equal([0, 3, 1, 0], getpos("'<"))
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200131 call assert_equal([0, 3, 8, 0], getpos("'>"))
132 " Test for <S-C-Home> and <S-C-End>
133 call cursor(2, 12)
134 call feedkeys("\<S-C-Home>y", 'xt')
135 call assert_equal([0, 1, 1, 0], getpos("'<"))
136 call assert_equal([0, 2, 12, 0], getpos("'>"))
137 call cursor(1, 4)
138 call feedkeys("\<S-C-End>y", 'xt')
139 call assert_equal([0, 1, 4, 0], getpos("'<"))
140 call assert_equal([0, 3, 13, 0], getpos("'>"))
141 " Test for <S-C-Left> and <S-C-Right>
142 call cursor(2, 5)
143 call feedkeys("\<S-C-Right>y", 'xt')
144 call assert_equal([0, 2, 5, 0], getpos("'<"))
145 call assert_equal([0, 2, 9, 0], getpos("'>"))
146 call cursor(2, 9)
147 call feedkeys("\<S-C-Left>y", 'xt')
148 call assert_equal([0, 2, 5, 0], getpos("'<"))
149 call assert_equal([0, 2, 9, 0], getpos("'>"))
150
151 set keymodel&
152
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200153 " clean up
154 bw!
155endfunc
156
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100157func Test_normal03_join()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200158 " basic join test
159 call Setup_NewWindow()
160 50
161 norm! VJ
162 call assert_equal('50 51', getline('.'))
163 $
164 norm! J
165 call assert_equal('100', getline('.'))
166 $
167 norm! V9-gJ
168 call assert_equal('919293949596979899100', getline('.'))
169 call setline(1, range(1,100))
170 $
171 :j 10
172 call assert_equal('100', getline('.'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200173 call assert_beeps('normal GVJ')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200174 " clean up
175 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200176endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200177
Bram Moolenaar004a6782020-04-11 17:09:31 +0200178" basic filter test
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100179func Test_normal04_filter()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200180 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200181 CheckNotMSWindows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200182 call Setup_NewWindow()
183 1
184 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
185 call assert_equal('| 1', getline('.'))
186 90
187 :sil :!echo one
188 call feedkeys('.', 'tx')
189 call assert_equal('| 90', getline('.'))
190 95
191 set cpo+=!
192 " 2 <CR>, 1: for executing the command,
193 " 2: clear hit-enter-prompt
194 call feedkeys("!!\n", 'tx')
195 call feedkeys(":!echo one\n\n", 'tx')
196 call feedkeys(".", 'tx')
197 call assert_equal('one', getline('.'))
198 set cpo-=!
199 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200200endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200201
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100202func Test_normal05_formatexpr()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200203 " basic formatexpr test
204 call Setup_NewWindow()
205 %d_
206 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
207 1
208 set formatexpr=MyFormatExpr()
209 norm! gqG
210 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
211 set formatexpr=
212 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200213endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200214
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200215func Test_normal05_formatexpr_newbuf()
216 " Edit another buffer in the 'formatexpr' function
217 new
218 func! Format()
219 edit another
220 endfunc
221 set formatexpr=Format()
222 norm gqG
223 bw!
224 set formatexpr=
225endfunc
226
227func Test_normal05_formatexpr_setopt()
228 " Change the 'formatexpr' value in the function
229 new
230 func! Format()
231 set formatexpr=
232 endfunc
233 set formatexpr=Format()
234 norm gqG
235 bw!
236 set formatexpr=
237endfunc
238
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200239" When 'formatexpr' returns non-zero, internal formatting is used.
240func Test_normal_formatexpr_returns_nonzero()
241 new
242 call setline(1, ['one', 'two'])
243 func! Format()
244 return 1
245 endfunc
246 setlocal formatexpr=Format()
247 normal VGgq
248 call assert_equal(['one two'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +0000249
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200250 setlocal formatexpr=
251 delfunc Format
Yee Cheng Chin1881abf2022-12-08 09:41:24 +0000252 bwipe!
Bram Moolenaar2eaeaf32020-05-03 16:04:43 +0200253endfunc
254
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000255" Test for using a script-local function for 'formatexpr'
256func Test_formatexpr_scriptlocal_func()
257 func! s:Format()
258 let g:FormatArgs = [v:lnum, v:count]
259 endfunc
260 set formatexpr=s:Format()
261 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000262 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000263 new | only
264 call setline(1, range(1, 40))
265 let g:FormatArgs = []
266 normal! 2GVjgq
267 call assert_equal([2, 2], g:FormatArgs)
268 bw!
269 set formatexpr=<SID>Format()
270 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +0000271 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000272 new | only
273 call setline(1, range(1, 40))
274 let g:FormatArgs = []
275 normal! 4GVjgq
276 call assert_equal([4, 2], g:FormatArgs)
277 bw!
278 let &formatexpr = 's:Format()'
zeertzjq01d4efe2023-01-25 15:31:28 +0000279 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000280 new | only
281 call setline(1, range(1, 40))
282 let g:FormatArgs = []
283 normal! 6GVjgq
284 call assert_equal([6, 2], g:FormatArgs)
285 bw!
286 let &formatexpr = '<SID>Format()'
zeertzjq01d4efe2023-01-25 15:31:28 +0000287 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000288 new | only
289 call setline(1, range(1, 40))
290 let g:FormatArgs = []
291 normal! 8GVjgq
292 call assert_equal([8, 2], g:FormatArgs)
zeertzjq01d4efe2023-01-25 15:31:28 +0000293 bw!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000294 setlocal formatexpr=
zeertzjq01d4efe2023-01-25 15:31:28 +0000295 setglobal formatexpr=s:Format()
296 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
297 call assert_equal('', &formatexpr)
298 new
299 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
300 call setline(1, range(1, 40))
301 let g:FormatArgs = []
302 normal! 10GVjgq
303 call assert_equal([10, 2], g:FormatArgs)
304 bw!
305 setglobal formatexpr=<SID>Format()
306 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
307 call assert_equal('', &formatexpr)
308 new
309 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
310 call setline(1, range(1, 40))
311 let g:FormatArgs = []
312 normal! 12GVjgq
313 call assert_equal([12, 2], g:FormatArgs)
314 bw!
315 let &g:formatexpr = 's:Format()'
316 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
317 call assert_equal('', &formatexpr)
318 new
319 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
320 call setline(1, range(1, 40))
321 let g:FormatArgs = []
322 normal! 14GVjgq
323 call assert_equal([14, 2], g:FormatArgs)
324 bw!
325 let &g:formatexpr = '<SID>Format()'
326 call assert_equal(expand('<SID>') .. 'Format()', &g:formatexpr)
327 call assert_equal('', &formatexpr)
328 new
329 call assert_equal(expand('<SID>') .. 'Format()', &formatexpr)
330 call setline(1, range(1, 40))
331 let g:FormatArgs = []
332 normal! 16GVjgq
333 call assert_equal([16, 2], g:FormatArgs)
334 bw!
335 set formatexpr=
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000336 delfunc s:Format
337 bw!
338endfunc
339
Bram Moolenaar004a6782020-04-11 17:09:31 +0200340" basic test for formatprg
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100341func Test_normal06_formatprg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200342 " only test on non windows platform
Bram Moolenaar004a6782020-04-11 17:09:31 +0200343 CheckNotMSWindows
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100344
345 " uses sed to number non-empty lines
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100346 call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh', 'D')
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100347 call system('chmod +x ./Xsed_format.sh')
348 let text = ['a', '', 'c', '', ' ', 'd', 'e']
349 let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
350
351 10new
352 call setline(1, text)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200353 set formatprg=./Xsed_format.sh
354 norm! gggqG
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100355 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200356 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100357
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100358 call setline(1, text)
359 set formatprg=donothing
360 setlocal formatprg=./Xsed_format.sh
361 norm! gggqG
362 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar004a6782020-04-11 17:09:31 +0200363 %d
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100364
Bram Moolenaar004a6782020-04-11 17:09:31 +0200365 " Check for the command-line ranges added to 'formatprg'
366 set formatprg=cat
367 call setline(1, ['one', 'two', 'three', 'four', 'five'])
368 call feedkeys('gggqG', 'xt')
369 call assert_equal('.,$!cat', @:)
370 call feedkeys('2Ggq2j', 'xt')
371 call assert_equal('.,.+2!cat', @:)
372
373 bw!
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200374 " clean up
375 set formatprg=
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100376 setlocal formatprg=
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200377endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200378
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100379func Test_normal07_internalfmt()
Christian Brabandtee17b6f2023-09-09 11:23:50 +0200380 " basic test for internal formatter to textwidth of 12
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200381 let list=range(1,11)
382 call map(list, 'v:val." "')
383 10new
384 call setline(1, list)
385 set tw=12
Bram Moolenaar004a6782020-04-11 17:09:31 +0200386 norm! ggVGgq
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200387 call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
388 " clean up
Bram Moolenaar9be7c042017-01-14 14:28:30 +0100389 set tw=0
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200390 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200391endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200392
Bram Moolenaar004a6782020-04-11 17:09:31 +0200393" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100394func Test_normal08_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +0200395 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200396 call Setup_NewWindow()
397 50
398 setl foldenable fdm=marker
399 " First fold
400 norm! V4jzf
401 " check that folds have been created
Riley Bruins0a083062024-06-03 20:40:45 +0200402 call assert_equal(['50/* {{{ */', '51', '52', '53', '54/* }}} */'], getline(50,54))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200403 " Second fold
404 46
405 norm! V10jzf
406 " check that folds have been created
Riley Bruins0a083062024-06-03 20:40:45 +0200407 call assert_equal('46/* {{{ */', getline(46))
408 call assert_equal('60/* }}} */', getline(60))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200409 norm! k
410 call assert_equal('45', getline('.'))
411 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +0200412 call assert_equal('46/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200413 norm! j
414 call assert_equal('61', getline('.'))
415 norm! k
416 " open a fold
417 norm! Vzo
418 norm! k
419 call assert_equal('45', getline('.'))
420 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +0200421 call assert_equal('46/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200422 norm! j
423 call assert_equal('47', getline('.'))
424 norm! k
425 norm! zcVzO
Riley Bruins0a083062024-06-03 20:40:45 +0200426 call assert_equal('46/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200427 norm! j
428 call assert_equal('47', getline('.'))
429 norm! j
430 call assert_equal('48', getline('.'))
431 norm! j
432 call assert_equal('49', getline('.'))
433 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +0200434 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200435 norm! j
436 call assert_equal('51', getline('.'))
437 " delete folds
438 :46
439 " collapse fold
440 norm! V14jzC
441 " delete all folds recursively
442 norm! VzD
443 call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
444
445 " clean up
446 setl nofoldenable fdm=marker
447 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200448endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200449
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000450func Test_normal09a_operatorfunc()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200451 " Test operatorfunc
452 call Setup_NewWindow()
453 " Add some spaces for counting
454 50,60s/$/ /
455 unlet! g:a
456 let g:a=0
457 nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
458 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
459 50
460 norm V2j,,
461 call assert_equal(6, g:a)
462 norm V,,
463 call assert_equal(2, g:a)
464 norm ,,l
465 call assert_equal(0, g:a)
466 50
467 exe "norm 0\<c-v>10j2l,,"
468 call assert_equal(11, g:a)
469 50
470 norm V10j,,
471 call assert_equal(22, g:a)
472
473 " clean up
474 unmap <buffer> ,,
475 set opfunc=
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100476 unlet! g:a
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200477 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200478endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200479
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000480func Test_normal09b_operatorfunc()
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100481 " Test operatorfunc
482 call Setup_NewWindow()
483 " Add some spaces for counting
484 50,60s/$/ /
485 unlet! g:opt
486 set linebreak
487 nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
488 50
489 norm ,,j
490 exe "bd!" g:bufnr
491 call assert_true(&linebreak)
492 call assert_equal(g:opt, &linebreak)
493 set nolinebreak
494 norm ,,j
495 exe "bd!" g:bufnr
496 call assert_false(&linebreak)
497 call assert_equal(g:opt, &linebreak)
498
499 " clean up
500 unmap <buffer> ,,
501 set opfunc=
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200502 call assert_fails('normal Vg@', 'E774:')
Bram Moolenaar4a08b0d2016-11-05 21:55:13 +0100503 bw!
504 unlet! g:opt
505endfunc
506
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000507func OperatorfuncRedo(_)
508 let g:opfunc_count = v:count
509endfunc
510
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000511func Underscorize(_)
512 normal! '[V']r_
513endfunc
514
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000515func Test_normal09c_operatorfunc()
516 " Test redoing operatorfunc
517 new
518 call setline(1, 'some text')
519 set operatorfunc=OperatorfuncRedo
520 normal v3g@
521 call assert_equal(3, g:opfunc_count)
522 let g:opfunc_count = 0
523 normal .
524 call assert_equal(3, g:opfunc_count)
525
526 bw!
527 unlet g:opfunc_count
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000528
529 " Test redoing Visual mode
530 set operatorfunc=Underscorize
531 new
532 call setline(1, ['first', 'first', 'third', 'third', 'second'])
naohiro ono5c75eed2022-01-03 11:15:47 +0000533 normal! 1GVjg@
Bram Moolenaarb3bd1d32022-01-02 13:05:45 +0000534 normal! 5G.
535 normal! 3G.
536 call assert_equal(['_____', '_____', '_____', '_____', '______'], getline(1, '$'))
537 bwipe!
Bram Moolenaar2228cd72021-11-22 14:16:08 +0000538 set operatorfunc=
539endfunc
540
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000541" Test for different ways of setting the 'operatorfunc' option
542func Test_opfunc_callback()
543 new
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000544 func OpFunc1(callnr, type)
545 let g:OpFunc1Args = [a:callnr, a:type]
546 endfunc
547 func OpFunc2(type)
548 let g:OpFunc2Args = [a:type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000549 endfunc
550
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000551 let lines =<< trim END
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000552 #" Test for using a function name
553 LET &opfunc = 'g:OpFunc2'
554 LET g:OpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000555 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000556 call assert_equal(['char'], g:OpFunc2Args)
557
558 #" Test for using a function()
559 set opfunc=function('g:OpFunc1',\ [10])
560 LET g:OpFunc1Args = []
561 normal! g@l
562 call assert_equal([10, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000563
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000564 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000565 VAR Fn = function('g:OpFunc1', [11])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000566 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000567 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000568 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000569 call assert_equal([11, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000570
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000571 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000572 LET Fn = function('g:OpFunc1', [12])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000573 LET &operatorfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000574 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000575 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000576 call assert_equal([12, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000577
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000578 #" Test for using a funcref()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000579 set operatorfunc=funcref('g:OpFunc1',\ [13])
580 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000581 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000582 call assert_equal([13, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000583
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000584 #" Using a funcref variable to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000585 LET Fn = funcref('g:OpFunc1', [14])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000586 LET &opfunc = Fn
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000587 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000588 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000589 call assert_equal([14, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000590
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000591 #" Using a string(funcref_variable) to set 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000592 LET Fn = funcref('g:OpFunc1', [15])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000593 LET &opfunc = string(Fn)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000594 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000595 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000596 call assert_equal([15, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000597
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000598 #" Test for using a lambda function using set
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000599 VAR optval = "LSTART a LMIDDLE OpFunc1(16, a) LEND"
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000600 LET optval = substitute(optval, ' ', '\\ ', 'g')
601 exe "set opfunc=" .. optval
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000602 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000603 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000604 call assert_equal([16, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000605
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000606 #" Test for using a lambda function using LET
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000607 LET &opfunc = LSTART a LMIDDLE OpFunc1(17, a) LEND
608 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000609 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000610 call assert_equal([17, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000611
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000612 #" Set 'operatorfunc' to a string(lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000613 LET &opfunc = 'LSTART a LMIDDLE OpFunc1(18, a) LEND'
614 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000615 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000616 call assert_equal([18, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000617
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000618 #" Set 'operatorfunc' to a variable with a lambda expression
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000619 VAR Lambda = LSTART a LMIDDLE OpFunc1(19, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000620 LET &opfunc = Lambda
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000621 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000622 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000623 call assert_equal([19, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000624
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000625 #" Set 'operatorfunc' to a string(variable with a lambda expression)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000626 LET Lambda = LSTART a LMIDDLE OpFunc1(20, a) LEND
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000627 LET &opfunc = string(Lambda)
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000628 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000629 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000630 call assert_equal([20, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000631
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000632 #" Try to use 'operatorfunc' after the function is deleted
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000633 func g:TmpOpFunc1(type)
634 let g:TmpOpFunc1Args = [21, a:type]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000635 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000636 LET &opfunc = function('g:TmpOpFunc1')
637 delfunc g:TmpOpFunc1
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000638 call test_garbagecollect_now()
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000639 LET g:TmpOpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000640 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000641 call assert_equal([], g:TmpOpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000642
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000643 #" Try to use a function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000644 func g:TmpOpFunc2(x, y)
645 let g:TmpOpFunc2Args = [a:x, a:y]
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000646 endfunc
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000647 set opfunc=TmpOpFunc2
648 LET g:TmpOpFunc2Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000649 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000650 call assert_equal([], g:TmpOpFunc2Args)
651 delfunc TmpOpFunc2
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000652
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000653 #" Try to use a lambda function with two arguments for 'operatorfunc'
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000654 LET &opfunc = LSTART a, b LMIDDLE OpFunc1(22, b) LEND
655 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000656 call assert_fails('normal! g@l', 'E119:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000657 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000658
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000659 #" Test for clearing the 'operatorfunc' option
660 set opfunc=''
661 set opfunc&
662 call assert_fails("set opfunc=function('abc')", "E700:")
663 call assert_fails("set opfunc=funcref('abc')", "E700:")
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000664
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000665 #" set 'operatorfunc' to a non-existing function
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000666 LET &opfunc = function('g:OpFunc1', [23])
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000667 call assert_fails("set opfunc=function('NonExistingFunc')", 'E700:')
668 call assert_fails("LET &opfunc = function('NonExistingFunc')", 'E700:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000669 LET g:OpFunc1Args = []
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000670 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000671 call assert_equal([23, 'char'], g:OpFunc1Args)
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000672 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000673 call v9.CheckTransLegacySuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000674
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000675 " Test for using a script-local function name
676 func s:OpFunc3(type)
677 let g:OpFunc3Args = [a:type]
678 endfunc
679 set opfunc=s:OpFunc3
680 let g:OpFunc3Args = []
681 normal! g@l
682 call assert_equal(['char'], g:OpFunc3Args)
683
684 let &opfunc = 's:OpFunc3'
685 let g:OpFunc3Args = []
686 normal! g@l
687 call assert_equal(['char'], g:OpFunc3Args)
688 delfunc s:OpFunc3
689
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000690 " Using Vim9 lambda expression in legacy context should fail
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000691 set opfunc=(a)\ =>\ OpFunc1(24,\ a)
692 let g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000693 call assert_fails('normal! g@l', 'E117:')
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000694 call assert_equal([], g:OpFunc1Args)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000695
Yegappan Lakshmanan6ae8fae2021-12-12 16:26:44 +0000696 " set 'operatorfunc' to a partial with dict. This used to cause a crash.
697 func SetOpFunc()
698 let operator = {'execute': function('OperatorExecute')}
699 let &opfunc = operator.execute
700 endfunc
701 func OperatorExecute(_) dict
702 endfunc
703 call SetOpFunc()
704 call test_garbagecollect_now()
705 set operatorfunc=
706 delfunc SetOpFunc
707 delfunc OperatorExecute
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000708
709 " Vim9 tests
710 let lines =<< trim END
711 vim9script
712
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000713 def g:Vim9opFunc(val: number, type: string): void
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000714 g:OpFunc1Args = [val, type]
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000715 enddef
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000716
717 # Test for using a def function with opfunc
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000718 set opfunc=function('g:Vim9opFunc',\ [60])
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000719 g:OpFunc1Args = []
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000720 normal! g@l
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000721 assert_equal([60, 'char'], g:OpFunc1Args)
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000722
723 # Test for using a global function name
724 &opfunc = g:OpFunc2
725 g:OpFunc2Args = []
726 normal! g@l
727 assert_equal(['char'], g:OpFunc2Args)
728 bw!
729
730 # Test for using a script-local function name
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000731 def LocalOpFunc(type: string): void
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000732 g:LocalOpFuncArgs = [type]
733 enddef
Bram Moolenaar62b191c2022-02-12 20:34:50 +0000734 &opfunc = LocalOpFunc
Yegappan Lakshmanandb1a4102021-12-17 16:21:20 +0000735 g:LocalOpFuncArgs = []
736 normal! g@l
737 assert_equal(['char'], g:LocalOpFuncArgs)
738 bw!
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000739 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000740 call v9.CheckScriptSuccess(lines)
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000741
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000742 " setting 'opfunc' to a script local function outside of a script context
743 " should fail
744 let cleanup =<< trim END
745 call writefile([execute('messages')], 'Xtest.out')
746 qall
747 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +0100748 call writefile(cleanup, 'Xverify.vim', 'D')
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000749 call RunVim([], [], "-c \"set opfunc=s:abc\" -S Xverify.vim")
750 call assert_match('E81: Using <SID> not in a', readfile('Xtest.out')[0])
751 call delete('Xtest.out')
Yegappan Lakshmanane7f4abd2021-12-24 20:47:38 +0000752
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000753 " cleanup
754 set opfunc&
Yegappan Lakshmanan04ef1fb2021-12-12 20:08:05 +0000755 delfunc OpFunc1
756 delfunc OpFunc2
757 unlet g:OpFunc1Args g:OpFunc2Args
Yegappan Lakshmanan2172bff2021-12-08 10:46:21 +0000758 %bw!
759endfunc
760
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100761func Test_normal10_expand()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200762 " Test for expand()
763 10new
764 call setline(1, ['1', 'ifooar,,cbar'])
765 2
766 norm! $
Bram Moolenaar65f08472017-09-10 18:16:20 +0200767 call assert_equal('cbar', expand('<cword>'))
768 call assert_equal('ifooar,,cbar', expand('<cWORD>'))
769
770 call setline(1, ['prx = list[idx];'])
771 1
772 let expected = ['', 'prx', 'prx', 'prx',
773 \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
774 \ 'idx', 'idx', 'idx', 'idx',
775 \ 'list[idx]',
776 \ '];',
777 \ ]
778 for i in range(1, 16)
779 exe 'norm ' . i . '|'
780 call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
781 endfor
782
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200783 " Test for <cexpr> in state.val and ptr->val
784 call setline(1, 'x = state.val;')
785 call cursor(1, 10)
786 call assert_equal('state.val', expand('<cexpr>'))
787 call setline(1, 'x = ptr->val;')
788 call cursor(1, 9)
789 call assert_equal('ptr->val', expand('<cexpr>'))
790
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100791 if executable('echo')
792 " Test expand(`...`) i.e. backticks command expansion.
Bram Moolenaar077ff432019-10-28 00:42:21 +0100793 call assert_equal('abcde', expand('`echo abcde`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100794 endif
795
796 " Test expand(`=...`) i.e. backticks expression expansion
797 call assert_equal('5', expand('`=2+3`'))
Bram Moolenaar8b633132020-03-20 18:20:51 +0100798 call assert_equal('3.14', expand('`=3.14`'))
Bram Moolenaarae6f8652017-12-20 22:32:20 +0100799
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200800 " clean up
801 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200802endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200803
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200804" Test for expand() in latin1 encoding
805func Test_normal_expand_latin1()
806 new
807 let save_enc = &encoding
808 set encoding=latin1
809 call setline(1, 'val = item->color;')
810 call cursor(1, 11)
811 call assert_equal('color', expand("<cword>"))
812 call assert_equal('item->color', expand("<cexpr>"))
813 let &encoding = save_enc
814 bw!
815endfunc
816
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100817func Test_normal11_showcmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200818 " test for 'showcmd'
819 10new
820 exe "norm! ofoobar\<esc>"
821 call assert_equal(2, line('$'))
822 set showcmd
823 exe "norm! ofoobar2\<esc>"
824 call assert_equal(3, line('$'))
825 exe "norm! VAfoobar3\<esc>"
826 call assert_equal(3, line('$'))
827 exe "norm! 0d3\<del>2l"
828 call assert_equal('obar2foobar3', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +0200829 " test for the visual block size displayed in the status line
830 call setline(1, ['aaaaa', 'bbbbb', 'ccccc'])
831 call feedkeys("ggl\<C-V>lljj", 'xt')
832 redraw!
833 call assert_match('3x3$', Screenline(&lines))
834 call feedkeys("\<C-V>", 'xt')
835 " test for visually selecting a multi-byte character
836 call setline(1, ["\U2206"])
837 call feedkeys("ggv", 'xt')
838 redraw!
839 call assert_match('1-3$', Screenline(&lines))
840 call feedkeys("v", 'xt')
Bram Moolenaard7e5e942020-10-07 16:54:52 +0200841 " test for visually selecting the end of line
842 call setline(1, ["foobar"])
843 call feedkeys("$vl", 'xt')
844 redraw!
845 call assert_match('2$', Screenline(&lines))
846 call feedkeys("y", 'xt')
847 call assert_equal("r\n", @")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200848 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200849endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200850
Bram Moolenaar1671f442020-03-10 07:48:13 +0100851" Test for nv_error and normal command errors
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100852func Test_normal12_nv_error()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200853 10new
854 call setline(1, range(1,5))
855 " should not do anything, just beep
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100856 call assert_beeps('exe "norm! <c-k>"')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200857 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +0100858 call assert_beeps('normal! G2dd')
859 call assert_beeps("normal! g\<C-A>")
860 call assert_beeps("normal! g\<C-X>")
861 call assert_beeps("normal! g\<C-B>")
Bram Moolenaar1671f442020-03-10 07:48:13 +0100862 call assert_beeps("normal! vQ\<Esc>")
863 call assert_beeps("normal! 2[[")
864 call assert_beeps("normal! 2]]")
865 call assert_beeps("normal! 2[]")
866 call assert_beeps("normal! 2][")
867 call assert_beeps("normal! 4[z")
868 call assert_beeps("normal! 4]z")
869 call assert_beeps("normal! 4[c")
870 call assert_beeps("normal! 4]c")
871 call assert_beeps("normal! 200%")
872 call assert_beeps("normal! %")
873 call assert_beeps("normal! 2{")
874 call assert_beeps("normal! 2}")
875 call assert_beeps("normal! r\<Right>")
876 call assert_beeps("normal! 8ry")
877 call assert_beeps('normal! "@')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200878 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200879endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200880
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100881func Test_normal13_help()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200882 " Test for F1
883 call assert_equal(1, winnr())
884 call feedkeys("\<f1>", 'txi')
885 call assert_match('help\.txt', bufname('%'))
886 call assert_equal(2, winnr('$'))
887 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200888endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200889
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100890func Test_normal14_page()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200891 " basic test for Ctrl-F and Ctrl-B
892 call Setup_NewWindow()
893 exe "norm! \<c-f>"
894 call assert_equal('9', getline('.'))
895 exe "norm! 2\<c-f>"
896 call assert_equal('25', getline('.'))
897 exe "norm! 2\<c-b>"
898 call assert_equal('18', getline('.'))
899 1
900 set scrolloff=5
901 exe "norm! 2\<c-f>"
902 call assert_equal('21', getline('.'))
903 exe "norm! \<c-b>"
904 call assert_equal('13', getline('.'))
905 1
906 set scrolloff=99
907 exe "norm! \<c-f>"
908 call assert_equal('13', getline('.'))
909 set scrolloff=0
910 100
911 exe "norm! $\<c-b>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200912 call assert_equal([0, 92, 1, 0, 1], getcurpos())
913 100
914 set nostartofline
915 exe "norm! $\<c-b>"
naohiro ono56200ee2022-01-01 14:59:44 +0000916 call assert_equal([0, 92, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200917 " cleanup
918 set startofline
919 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +0200920endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200921
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100922func Test_normal14_page_eol()
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200923 10new
924 norm oxxxxxxx
925 exe "norm 2\<c-f>"
926 " check with valgrind that cursor is put back in column 1
927 exe "norm 2\<c-b>"
928 bw!
929endfunc
930
Bram Moolenaar1671f442020-03-10 07:48:13 +0100931" Test for errors with z command
932func Test_normal_z_error()
933 call assert_beeps('normal! z2p')
Christian Brabandt2fa93842021-05-30 22:17:25 +0200934 call assert_beeps('normal! zq')
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000935 call assert_beeps('normal! cz1')
Bram Moolenaar1671f442020-03-10 07:48:13 +0100936endfunc
937
Bram Moolenaar1bbb6192018-11-10 16:02:01 +0100938func Test_normal15_z_scroll_vert()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200939 " basic test for z commands that scroll the window
940 call Setup_NewWindow()
941 100
942 norm! >>
943 " Test for z<cr>
944 exe "norm! z\<cr>"
945 call assert_equal(' 100', getline('.'))
946 call assert_equal(100, winsaveview()['topline'])
947 call assert_equal([0, 100, 2, 0, 9], getcurpos())
948
949 " Test for zt
950 21
951 norm! >>0zt
952 call assert_equal(' 21', getline('.'))
953 call assert_equal(21, winsaveview()['topline'])
954 call assert_equal([0, 21, 1, 0, 8], getcurpos())
955
956 " Test for zb
957 30
958 norm! >>$ztzb
959 call assert_equal(' 30', getline('.'))
960 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
naohiro ono56200ee2022-01-01 14:59:44 +0000961 call assert_equal([0, 30, 3, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200962
963 " Test for z-
964 1
965 30
966 norm! 0z-
967 call assert_equal(' 30', getline('.'))
968 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
969 call assert_equal([0, 30, 2, 0, 9], getcurpos())
970
971 " Test for z{height}<cr>
972 call assert_equal(10, winheight(0))
973 exe "norm! z12\<cr>"
974 call assert_equal(12, winheight(0))
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +0000975 exe "norm! z15\<Del>0\<cr>"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200976 call assert_equal(10, winheight(0))
977
978 " Test for z.
979 1
980 21
981 norm! 0z.
982 call assert_equal(' 21', getline('.'))
983 call assert_equal(17, winsaveview()['topline'])
984 call assert_equal([0, 21, 2, 0, 9], getcurpos())
985
986 " Test for zz
987 1
988 21
989 norm! 0zz
990 call assert_equal(' 21', getline('.'))
991 call assert_equal(17, winsaveview()['topline'])
992 call assert_equal([0, 21, 1, 0, 8], getcurpos())
993
994 " Test for z+
995 11
996 norm! zt
997 norm! z+
998 call assert_equal(' 21', getline('.'))
999 call assert_equal(21, winsaveview()['topline'])
1000 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1001
1002 " Test for [count]z+
1003 1
1004 norm! 21z+
1005 call assert_equal(' 21', getline('.'))
1006 call assert_equal(21, winsaveview()['topline'])
1007 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1008
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001009 " Test for z+ with [count] greater than buffer size
1010 1
1011 norm! 1000z+
1012 call assert_equal(' 100', getline('.'))
1013 call assert_equal(100, winsaveview()['topline'])
1014 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1015
1016 " Test for z+ from the last buffer line
1017 norm! Gz.z+
1018 call assert_equal(' 100', getline('.'))
1019 call assert_equal(100, winsaveview()['topline'])
1020 call assert_equal([0, 100, 2, 0, 9], getcurpos())
1021
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001022 " Test for z^
1023 norm! 22z+0
1024 norm! z^
1025 call assert_equal(' 21', getline('.'))
1026 call assert_equal(12, winsaveview()['topline'])
1027 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1028
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001029 " Test for z^ from first buffer line
1030 norm! ggz^
1031 call assert_equal('1', getline('.'))
1032 call assert_equal(1, winsaveview()['topline'])
1033 call assert_equal([0, 1, 1, 0, 1], getcurpos())
1034
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001035 " Test for [count]z^
1036 1
1037 norm! 30z^
1038 call assert_equal(' 21', getline('.'))
1039 call assert_equal(12, winsaveview()['topline'])
1040 call assert_equal([0, 21, 2, 0, 9], getcurpos())
1041
1042 " cleanup
1043 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001044endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001045
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001046func Test_normal16_z_scroll_hor()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001047 " basic test for z commands that scroll the window
1048 10new
1049 15vsp
1050 set nowrap listchars=
1051 let lineA='abcdefghijklmnopqrstuvwxyz'
1052 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1053 $put =lineA
1054 $put =lineB
1055 1d
1056
Bram Moolenaar1671f442020-03-10 07:48:13 +01001057 " Test for zl and zh with a count
1058 norm! 0z10l
1059 call assert_equal([11, 1], [col('.'), wincol()])
1060 norm! z4h
1061 call assert_equal([11, 5], [col('.'), wincol()])
1062 normal! 2gg
1063
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001064 " Test for zl
1065 1
1066 norm! 5zl
1067 call assert_equal(lineA, getline('.'))
1068 call assert_equal(6, col('.'))
1069 call assert_equal(5, winsaveview()['leftcol'])
1070 norm! yl
1071 call assert_equal('f', @0)
1072
1073 " Test for zh
1074 norm! 2zh
1075 call assert_equal(lineA, getline('.'))
1076 call assert_equal(6, col('.'))
1077 norm! yl
1078 call assert_equal('f', @0)
1079 call assert_equal(3, winsaveview()['leftcol'])
1080
1081 " Test for zL
1082 norm! zL
1083 call assert_equal(11, col('.'))
1084 norm! yl
1085 call assert_equal('k', @0)
1086 call assert_equal(10, winsaveview()['leftcol'])
1087 norm! 2zL
1088 call assert_equal(25, col('.'))
1089 norm! yl
1090 call assert_equal('y', @0)
1091 call assert_equal(24, winsaveview()['leftcol'])
1092
1093 " Test for zH
1094 norm! 2zH
1095 call assert_equal(25, col('.'))
1096 call assert_equal(10, winsaveview()['leftcol'])
1097 norm! yl
1098 call assert_equal('y', @0)
1099
1100 " Test for zs
1101 norm! $zs
1102 call assert_equal(26, col('.'))
1103 call assert_equal(25, winsaveview()['leftcol'])
1104 norm! yl
1105 call assert_equal('z', @0)
1106
1107 " Test for ze
1108 norm! ze
1109 call assert_equal(26, col('.'))
1110 call assert_equal(11, winsaveview()['leftcol'])
1111 norm! yl
1112 call assert_equal('z', @0)
1113
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001114 " Test for zs and ze with folds
1115 %fold
1116 norm! $zs
1117 call assert_equal(26, col('.'))
1118 call assert_equal(0, winsaveview()['leftcol'])
1119 norm! yl
1120 call assert_equal('z', @0)
1121 norm! ze
1122 call assert_equal(26, col('.'))
1123 call assert_equal(0, winsaveview()['leftcol'])
1124 norm! yl
1125 call assert_equal('z', @0)
1126
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001127 " cleanup
1128 set wrap listchars=eol:$
1129 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001130endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001131
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001132func Test_normal17_z_scroll_hor2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001133 " basic test for z commands that scroll the window
1134 " using 'sidescrolloff' setting
1135 10new
1136 20vsp
1137 set nowrap listchars= sidescrolloff=5
1138 let lineA='abcdefghijklmnopqrstuvwxyz'
1139 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1140 $put =lineA
1141 $put =lineB
1142 1d
1143
1144 " Test for zl
1145 1
1146 norm! 5zl
1147 call assert_equal(lineA, getline('.'))
1148 call assert_equal(11, col('.'))
1149 call assert_equal(5, winsaveview()['leftcol'])
1150 norm! yl
1151 call assert_equal('k', @0)
1152
1153 " Test for zh
1154 norm! 2zh
1155 call assert_equal(lineA, getline('.'))
1156 call assert_equal(11, col('.'))
1157 norm! yl
1158 call assert_equal('k', @0)
1159 call assert_equal(3, winsaveview()['leftcol'])
1160
1161 " Test for zL
1162 norm! 0zL
1163 call assert_equal(16, col('.'))
1164 norm! yl
1165 call assert_equal('p', @0)
1166 call assert_equal(10, winsaveview()['leftcol'])
1167 norm! 2zL
1168 call assert_equal(26, col('.'))
1169 norm! yl
1170 call assert_equal('z', @0)
1171 call assert_equal(15, winsaveview()['leftcol'])
1172
1173 " Test for zH
1174 norm! 2zH
1175 call assert_equal(15, col('.'))
1176 call assert_equal(0, winsaveview()['leftcol'])
1177 norm! yl
1178 call assert_equal('o', @0)
1179
1180 " Test for zs
1181 norm! $zs
1182 call assert_equal(26, col('.'))
1183 call assert_equal(20, winsaveview()['leftcol'])
1184 norm! yl
1185 call assert_equal('z', @0)
1186
1187 " Test for ze
1188 norm! ze
1189 call assert_equal(26, col('.'))
1190 call assert_equal(11, winsaveview()['leftcol'])
1191 norm! yl
1192 call assert_equal('z', @0)
1193
1194 " cleanup
1195 set wrap listchars=eol:$ sidescrolloff=0
1196 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001197endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001198
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001199" Test for commands that scroll the window horizontally. Test with folds.
1200" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands
1201func Test_vert_scroll_cmds()
Bram Moolenaar1671f442020-03-10 07:48:13 +01001202 15new
1203 call setline(1, range(1, 100))
1204 exe "normal! 30ggz\<CR>"
1205 set foldenable
1206 33,36fold
1207 40,43fold
1208 46,49fold
1209 let h = winheight(0)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001210
1211 " Test for H, M and L commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01001212 " Top of the screen = 30
1213 " Folded lines = 9
1214 " Bottom of the screen = 30 + h + 9 - 1
1215 normal! 4L
1216 call assert_equal(35 + h, line('.'))
1217 normal! 4H
1218 call assert_equal(33, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001219
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001220 " Test for using a large count value
1221 %d
1222 call setline(1, range(1, 4))
1223 norm! 6H
1224 call assert_equal(4, line('.'))
1225
1226 " Test for 'M' with folded lines
1227 %d
1228 call setline(1, range(1, 20))
1229 1,5fold
1230 norm! LM
1231 call assert_equal(12, line('.'))
1232
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001233 " Test for the CTRL-E and CTRL-Y commands with folds
1234 %d
1235 call setline(1, range(1, 10))
1236 3,5fold
1237 exe "normal 6G3\<C-E>"
1238 call assert_equal(6, line('w0'))
1239 exe "normal 2\<C-Y>"
1240 call assert_equal(2, line('w0'))
1241
1242 " Test for CTRL-Y on a folded line
1243 %d
1244 call setline(1, range(1, 100))
1245 exe (h + 2) .. "," .. (h + 4) .. "fold"
1246 exe h + 5
1247 normal z-
1248 exe "normal \<C-Y>\<C-Y>"
1249 call assert_equal(h + 1, line('w$'))
1250
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001251 " Test for CTRL-Y from the first line and CTRL-E from the last line
1252 %d
1253 set scrolloff=2
1254 call setline(1, range(1, 4))
1255 exe "normal gg\<C-Y>"
1256 call assert_equal(1, line('w0'))
1257 call assert_equal(1, line('.'))
1258 exe "normal G4\<C-E>\<C-E>"
1259 call assert_equal(4, line('w$'))
1260 call assert_equal(4, line('.'))
1261 set scrolloff&
1262
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001263 " Using <PageUp> and <PageDown> in an empty buffer should beep
1264 %d
1265 call assert_beeps('exe "normal \<PageUp>"')
1266 call assert_beeps('exe "normal \<C-B>"')
1267 call assert_beeps('exe "normal \<PageDown>"')
1268 call assert_beeps('exe "normal \<C-F>"')
1269
1270 " Test for <C-U> and <C-D> with fold
1271 %d
1272 call setline(1, range(1, 100))
1273 10,35fold
1274 set scroll=10
1275 exe "normal \<C-D>"
1276 call assert_equal(36, line('.'))
1277 exe "normal \<C-D>"
1278 call assert_equal(46, line('.'))
1279 exe "normal \<C-U>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001280 call assert_equal(36, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001281 exe "normal \<C-U>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001282 call assert_equal(1, line('.'))
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001283 exe "normal \<C-U>"
1284 call assert_equal(1, line('.'))
1285 set scroll&
1286
1287 " Test for scrolling to the top of the file with <C-U> and a fold
1288 10
1289 normal ztL
1290 exe "normal \<C-U>\<C-U>"
1291 call assert_equal(1, line('w0'))
1292
1293 " Test for CTRL-D on a folded line
1294 %d
1295 call setline(1, range(1, 100))
1296 50,100fold
1297 75
1298 normal z-
1299 exe "normal \<C-D>"
1300 call assert_equal(50, line('.'))
1301 call assert_equal(100, line('w$'))
1302 normal z.
Luuk van Baalcb204e62024-04-02 20:49:45 +02001303 let lnum = winline()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001304 exe "normal \<C-D>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02001305 call assert_equal(lnum, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001306 call assert_equal(50, line('.'))
1307 normal zt
1308 exe "normal \<C-D>"
1309 call assert_equal(50, line('w0'))
1310
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02001311 " Test for <S-CR>. Page down.
1312 %d
1313 call setline(1, range(1, 100))
1314 call feedkeys("\<S-CR>", 'xt')
1315 call assert_equal(14, line('w0'))
1316 call assert_equal(28, line('w$'))
1317
1318 " Test for <S-->. Page up.
1319 call feedkeys("\<S-->", 'xt')
1320 call assert_equal(1, line('w0'))
1321 call assert_equal(15, line('w$'))
1322
Bram Moolenaar1671f442020-03-10 07:48:13 +01001323 set foldenable&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00001324 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01001325endfunc
1326
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001327func Test_scroll_in_ex_mode()
1328 " This was using invalid memory because w_botline was invalid.
1329 let lines =<< trim END
1330 diffsplit
1331 norm os00(
1332 call writefile(['done'], 'Xdone')
1333 qa!
1334 END
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001335 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001336 call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
1337 call assert_equal(['done'], readfile('Xdone'))
1338
Bram Moolenaar777e7c22021-10-25 17:07:04 +01001339 call delete('Xdone')
1340endfunc
1341
zeertzjqdf098fe2025-01-22 22:27:30 +01001342func Test_scroll_and_paste_in_ex_mode()
1343 " This used to crash because of moving cursor to line 0.
1344 let lines =<< trim END
1345 v/foo/vi|YY9PYQ
1346 v/bar/vi|YY9PYQ
1347 v/bar/exe line('.') == 1 ? "vi|Y\<C-B>9PYQ" : "vi|YQ"
1348 call writefile(['done'], 'Xdone')
1349 qa!
1350 END
1351 call writefile(lines, 'Xscript', 'D')
1352 call assert_equal(1, RunVim([], [], '-u NONE -i NONE -n -X -Z -e -s -S Xscript'))
1353 call assert_equal(['done'], readfile('Xdone'))
1354
1355 call delete('Xdone')
1356endfunc
1357
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001358" Test for the 'sidescroll' option
1359func Test_sidescroll_opt()
1360 new
1361 20vnew
1362
1363 " scroll by 2 characters horizontally
1364 set sidescroll=2 nowrap
1365 call setline(1, repeat('a', 40))
1366 normal g$l
1367 call assert_equal(19, screenpos(0, 1, 21).col)
1368 normal l
1369 call assert_equal(20, screenpos(0, 1, 22).col)
1370 normal g0h
1371 call assert_equal(2, screenpos(0, 1, 2).col)
1372 call assert_equal(20, screenpos(0, 1, 20).col)
1373
1374 " when 'sidescroll' is 0, cursor positioned at the center
1375 set sidescroll=0
1376 normal g$l
1377 call assert_equal(11, screenpos(0, 1, 21).col)
1378 normal g0h
1379 call assert_equal(10, screenpos(0, 1, 10).col)
1380
1381 %bw!
1382 set wrap& sidescroll&
1383endfunc
1384
Bram Moolenaar004a6782020-04-11 17:09:31 +02001385" basic tests for foldopen/folddelete
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001386func Test_normal18_z_fold()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001387 CheckFeature folding
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001388 call Setup_NewWindow()
1389 50
1390 setl foldenable fdm=marker foldlevel=5
1391
Bram Moolenaar1671f442020-03-10 07:48:13 +01001392 call assert_beeps('normal! zj')
1393 call assert_beeps('normal! zk')
1394
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001395 " Test for zF
1396 " First fold
1397 norm! 4zF
1398 " check that folds have been created
Riley Bruins0a083062024-06-03 20:40:45 +02001399 call assert_equal(['50/* {{{ */', '51', '52', '53/* }}} */'], getline(50,53))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001400
1401 " Test for zd
1402 51
1403 norm! 2zF
1404 call assert_equal(2, foldlevel('.'))
1405 norm! kzd
Riley Bruins0a083062024-06-03 20:40:45 +02001406 call assert_equal(['50', '51/* {{{ */', '52/* }}} */', '53'], getline(50,53))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001407 norm! j
1408 call assert_equal(1, foldlevel('.'))
1409
1410 " Test for zD
1411 " also deletes partially selected folds recursively
1412 51
1413 norm! zF
1414 call assert_equal(2, foldlevel('.'))
1415 norm! kV2jzD
1416 call assert_equal(['50', '51', '52', '53'], getline(50,53))
1417
1418 " Test for zE
1419 85
1420 norm! 4zF
1421 86
1422 norm! 2zF
1423 90
1424 norm! 4zF
Riley Bruins0a083062024-06-03 20:40:45 +02001425 call assert_equal(['85/* {{{ */', '86/* {{{ */', '87/* }}} */', '88/* }}} */', '89', '90/* {{{ */', '91', '92', '93/* }}} */'], getline(85,93))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001426 norm! zE
1427 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
1428
1429 " Test for zn
1430 50
1431 set foldlevel=0
1432 norm! 2zF
1433 norm! zn
1434 norm! k
1435 call assert_equal('49', getline('.'))
1436 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001437 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001438 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001439 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001440 norm! j
1441 call assert_equal('52', getline('.'))
1442 call assert_equal(0, &foldenable)
1443
1444 " Test for zN
1445 49
1446 norm! zN
1447 call assert_equal('49', getline('.'))
1448 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001449 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001450 norm! j
1451 call assert_equal('52', getline('.'))
1452 call assert_equal(1, &foldenable)
1453
1454 " Test for zi
1455 norm! zi
1456 call assert_equal(0, &foldenable)
1457 norm! zi
1458 call assert_equal(1, &foldenable)
1459 norm! zi
1460 call assert_equal(0, &foldenable)
1461 norm! zi
1462 call assert_equal(1, &foldenable)
1463
1464 " Test for za
1465 50
1466 norm! za
1467 norm! k
1468 call assert_equal('49', getline('.'))
1469 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001470 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001471 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001472 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001473 norm! j
1474 call assert_equal('52', getline('.'))
1475 50
1476 norm! za
1477 norm! k
1478 call assert_equal('49', getline('.'))
1479 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001480 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001481 norm! j
1482 call assert_equal('52', getline('.'))
1483
1484 49
1485 norm! 5zF
1486 norm! k
1487 call assert_equal('48', getline('.'))
1488 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001489 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001490 norm! j
1491 call assert_equal('55', getline('.'))
1492 49
1493 norm! za
Riley Bruins0a083062024-06-03 20:40:45 +02001494 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001495 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001496 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001497 norm! j
1498 call assert_equal('52', getline('.'))
1499 set nofoldenable
1500 " close fold and set foldenable
1501 norm! za
1502 call assert_equal(1, &foldenable)
1503
1504 50
1505 " have to use {count}za to open all folds and make the cursor visible
1506 norm! 2za
1507 norm! 2k
1508 call assert_equal('48', getline('.'))
1509 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001510 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001511 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001512 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001513 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001514 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001515 norm! j
1516 call assert_equal('52', getline('.'))
1517
1518 " Test for zA
1519 49
1520 set foldlevel=0
1521 50
1522 norm! zA
1523 norm! 2k
1524 call assert_equal('48', getline('.'))
1525 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001526 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001527 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001528 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001529 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001530 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001531 norm! j
1532 call assert_equal('52', getline('.'))
1533
Dominique Pelle923dce22021-11-21 11:36:04 +00001534 " zA on an opened fold when foldenable is not set
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001535 50
1536 set nofoldenable
1537 norm! zA
1538 call assert_equal(1, &foldenable)
1539 norm! k
1540 call assert_equal('48', getline('.'))
1541 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001542 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001543 norm! j
1544 call assert_equal('55', getline('.'))
1545
1546 " Test for zc
1547 norm! zE
1548 50
1549 norm! 2zF
1550 49
1551 norm! 5zF
1552 set nofoldenable
1553 50
1554 " There most likely is a bug somewhere:
1555 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
1556 " TODO: Should this only close the inner most fold or both folds?
1557 norm! zc
1558 call assert_equal(1, &foldenable)
1559 norm! k
1560 call assert_equal('48', getline('.'))
1561 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001562 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001563 norm! j
1564 call assert_equal('55', getline('.'))
1565 set nofoldenable
1566 50
1567 norm! Vjzc
1568 norm! k
1569 call assert_equal('48', getline('.'))
1570 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001571 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001572 norm! j
1573 call assert_equal('55', getline('.'))
1574
1575 " Test for zC
1576 set nofoldenable
1577 50
1578 norm! zCk
1579 call assert_equal('48', getline('.'))
1580 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001581 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001582 norm! j
1583 call assert_equal('55', getline('.'))
1584
1585 " Test for zx
1586 " 1) close folds at line 49-54
1587 set nofoldenable
1588 48
1589 norm! zx
1590 call assert_equal(1, &foldenable)
1591 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001592 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001593 norm! j
1594 call assert_equal('55', getline('.'))
1595
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02001596 " 2) do not close fold under cursor
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001597 51
1598 set nofoldenable
1599 norm! zx
1600 call assert_equal(1, &foldenable)
1601 norm! 3k
1602 call assert_equal('48', getline('.'))
1603 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001604 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001605 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001606 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001607 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001608 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001609 norm! j
1610 call assert_equal('52', getline('.'))
1611 norm! j
1612 call assert_equal('53', getline('.'))
1613 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001614 call assert_equal('54/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001615 norm! j
1616 call assert_equal('55', getline('.'))
1617
1618 " 3) close one level of folds
1619 48
1620 set nofoldenable
1621 set foldlevel=1
1622 norm! zx
1623 call assert_equal(1, &foldenable)
1624 call assert_equal('48', getline('.'))
1625 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001626 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001627 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001628 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001629 norm! j
1630 call assert_equal('52', getline('.'))
1631 norm! j
1632 call assert_equal('53', getline('.'))
1633 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001634 call assert_equal('54/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001635 norm! j
1636 call assert_equal('55', getline('.'))
1637
1638 " Test for zX
1639 " Close all folds
1640 set foldlevel=0 nofoldenable
1641 50
1642 norm! zX
1643 call assert_equal(1, &foldenable)
1644 norm! k
1645 call assert_equal('48', getline('.'))
1646 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001647 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001648 norm! j
1649 call assert_equal('55', getline('.'))
1650
1651 " Test for zm
1652 50
1653 set nofoldenable foldlevel=2
1654 norm! zm
1655 call assert_equal(1, &foldenable)
1656 call assert_equal(1, &foldlevel)
1657 norm! zm
1658 call assert_equal(0, &foldlevel)
1659 norm! zm
1660 call assert_equal(0, &foldlevel)
1661 norm! k
1662 call assert_equal('48', getline('.'))
1663 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001664 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001665 norm! j
1666 call assert_equal('55', getline('.'))
1667
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001668 " Test for zm with a count
1669 50
1670 set foldlevel=2
1671 norm! 3zm
1672 call assert_equal(0, &foldlevel)
1673 call assert_equal(49, foldclosed(line('.')))
1674
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001675 " Test for zM
1676 48
1677 set nofoldenable foldlevel=99
1678 norm! zM
1679 call assert_equal(1, &foldenable)
1680 call assert_equal(0, &foldlevel)
1681 call assert_equal('48', getline('.'))
1682 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001683 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001684 norm! j
1685 call assert_equal('55', getline('.'))
1686
1687 " Test for zr
1688 48
1689 set nofoldenable foldlevel=0
1690 norm! zr
1691 call assert_equal(0, &foldenable)
1692 call assert_equal(1, &foldlevel)
1693 set foldlevel=0 foldenable
1694 norm! zr
1695 call assert_equal(1, &foldenable)
1696 call assert_equal(1, &foldlevel)
1697 norm! zr
1698 call assert_equal(2, &foldlevel)
1699 call assert_equal('48', getline('.'))
1700 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001701 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001702 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001703 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001704 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001705 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001706 norm! j
1707 call assert_equal('52', getline('.'))
1708
1709 " Test for zR
1710 48
1711 set nofoldenable foldlevel=0
1712 norm! zR
1713 call assert_equal(0, &foldenable)
1714 call assert_equal(2, &foldlevel)
1715 set foldenable foldlevel=0
1716 norm! zR
1717 call assert_equal(1, &foldenable)
1718 call assert_equal(2, &foldlevel)
1719 call assert_equal('48', getline('.'))
1720 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001721 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001722 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001723 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001724 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001725 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001726 norm! j
1727 call assert_equal('52', getline('.'))
Riley Bruins0a083062024-06-03 20:40:45 +02001728 call append(50, ['a /* {{{ */', 'b /* }}} */'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001729 48
1730 call assert_equal('48', getline('.'))
1731 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001732 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001733 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001734 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001735 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001736 call assert_equal('a /* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001737 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001738 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001739 norm! j
1740 call assert_equal('52', getline('.'))
1741 48
1742 norm! zR
1743 call assert_equal(1, &foldenable)
1744 call assert_equal(3, &foldlevel)
1745 call assert_equal('48', getline('.'))
1746 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001747 call assert_equal('49/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001748 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001749 call assert_equal('50/* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001750 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001751 call assert_equal('a /* {{{ */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001752 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001753 call assert_equal('b /* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001754 norm! j
Riley Bruins0a083062024-06-03 20:40:45 +02001755 call assert_equal('51/* }}} */', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001756 norm! j
1757 call assert_equal('52', getline('.'))
1758
1759 " clean up
1760 setl nofoldenable fdm=marker foldlevel=0
1761 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001762endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001763
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001764func Test_normal20_exmode()
Bram Moolenaar004a6782020-04-11 17:09:31 +02001765 " Reading from redirected file doesn't work on MS-Windows
1766 CheckNotMSWindows
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001767 call writefile(['1a', 'foo', 'bar', '.', 'w! Xn20file2', 'q!'], 'Xn20script', 'D')
1768 call writefile(['1', '2'], 'Xn20file', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001769 call system(GetVimCommand() .. ' -e -s < Xn20script Xn20file')
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001770 let a = readfile('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001771 call assert_equal(['1', 'foo', 'bar', '2'], a)
1772
1773 " clean up
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001774 call delete('Xn20file2')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001775 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001776endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001777
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001778func Test_normal21_nv_hat()
1779
1780 " Edit a fresh file and wipe the buffer list so that there is no alternate
1781 " file present. Next, check for the expected command failures.
1782 edit Xfoo | %bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02001783 call assert_fails(':buffer #', 'E86:')
1784 call assert_fails(':execute "normal! \<C-^>"', 'E23:')
Bram Moolenaarb7e24832020-06-24 13:37:35 +02001785 call assert_fails("normal i\<C-R>#", 'E23:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001786
1787 " Test for the expected behavior when switching between two named buffers.
1788 edit Xfoo | edit Xbar
1789 call feedkeys("\<C-^>", 'tx')
1790 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1791 call feedkeys("\<C-^>", 'tx')
1792 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1793
1794 " Test for the expected behavior when only one buffer is named.
1795 enew | let l:nr = bufnr('%')
1796 call feedkeys("\<C-^>", 'tx')
1797 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
1798 call feedkeys("\<C-^>", 'tx')
1799 call assert_equal('', bufname('%'))
1800 call assert_equal(l:nr, bufnr('%'))
1801
1802 " Test that no action is taken by "<C-^>" when an operator is pending.
1803 edit Xfoo
1804 call feedkeys("ci\<C-^>", 'tx')
1805 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
1806
1807 %bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001808endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001809
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001810func Test_normal22_zet()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001811 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001812 " let shell = &shell
1813 " let &shell = 'sh'
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01001814 call writefile(['1', '2'], 'Xn22file', 'D')
Bram Moolenaar93344c22019-08-14 21:12:05 +02001815 let args = ' -N -i NONE --noplugins -X --not-a-term'
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001816 call system(GetVimCommand() .. args .. ' -c "%d" -c ":norm! ZZ" Xn22file')
1817 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001818 call assert_equal([], a)
1819 " Test for ZQ
Bram Moolenaarb18b4962022-09-02 21:55:50 +01001820 call writefile(['1', '2'], 'Xn22file')
1821 call system(GetVimCommand() . args . ' -c "%d" -c ":norm! ZQ" Xn22file')
1822 let a = readfile('Xn22file')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001823 call assert_equal(['1', '2'], a)
1824
Bram Moolenaar1671f442020-03-10 07:48:13 +01001825 " Unsupported Z command
1826 call assert_beeps('normal! ZW')
1827
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001828 " clean up
Bram Moolenaar0913a102016-09-03 19:11:59 +02001829 " let &shell = shell
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001830endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001831
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001832func Test_normal23_K()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001833 " Test for K command
1834 new
Bram Moolenaar426f3752016-11-04 21:22:37 +01001835 call append(0, ['version8.txt', 'man', 'aa%bb', 'cc|dd'])
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001836 let k = &keywordprg
1837 set keywordprg=:help
1838 1
1839 norm! VK
1840 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1841 call assert_equal('help', &ft)
1842 call assert_match('\*version8.txt\*', getline('.'))
1843 helpclose
1844 norm! 0K
1845 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1846 call assert_equal('help', &ft)
Bram Moolenaarb1c91982018-05-17 17:04:55 +02001847 call assert_match('\*version8\.\d\*', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001848 helpclose
1849
Bram Moolenaar426f3752016-11-04 21:22:37 +01001850 set keywordprg=:new
1851 set iskeyword+=%
1852 set iskeyword+=\|
1853 2
1854 norm! K
1855 call assert_equal('man', fnamemodify(bufname('%'), ':t'))
1856 bwipe!
1857 3
1858 norm! K
1859 call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
1860 bwipe!
Bram Moolenaareb828d02016-11-05 19:54:01 +01001861 if !has('win32')
1862 4
1863 norm! K
1864 call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
1865 bwipe!
1866 endif
Bram Moolenaar426f3752016-11-04 21:22:37 +01001867 set iskeyword-=%
1868 set iskeyword-=\|
1869
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001870 " Test for specifying a count to K
1871 1
1872 com! -nargs=* Kprog let g:Kprog_Args = <q-args>
1873 set keywordprg=:Kprog
1874 norm! 3K
1875 call assert_equal('3 version8', g:Kprog_Args)
1876 delcom Kprog
1877
Bram Moolenaar0913a102016-09-03 19:11:59 +02001878 " Only expect "man" to work on Unix
1879 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001880 let &keywordprg = k
1881 bw!
1882 return
1883 endif
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001884
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001885 let not_gnu_man = has('mac') || has('bsd')
1886 if not_gnu_man
Dominique Pelle923dce22021-11-21 11:36:04 +00001887 " In macOS and BSD, the option for specifying a pager is different
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001888 set keywordprg=man\ -P\ cat
1889 else
1890 set keywordprg=man\ --pager=cat
1891 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001892 " Test for using man
1893 2
1894 let a = execute('unsilent norm! K')
Bram Moolenaar9134f1e2019-11-29 20:26:13 +01001895 if not_gnu_man
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02001896 call assert_match("man -P cat 'man'", a)
1897 else
1898 call assert_match("man --pager=cat 'man'", a)
1899 endif
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001900
Bram Moolenaar1671f442020-03-10 07:48:13 +01001901 " Error cases
1902 call setline(1, '#$#')
1903 call assert_fails('normal! ggK', 'E349:')
1904 call setline(1, '---')
1905 call assert_fails('normal! ggv2lK', 'E349:')
1906 call setline(1, ['abc', 'xyz'])
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001907 call assert_fails("normal! gg2lv2h\<C-]>", 'E433:')
Bram Moolenaar1671f442020-03-10 07:48:13 +01001908 call assert_beeps("normal! ggVjK")
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02001909 norm! V
1910 call assert_beeps("norm! cK")
Bram Moolenaar1671f442020-03-10 07:48:13 +01001911
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001912 " clean up
1913 let &keywordprg = k
1914 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001915endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001916
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001917func Test_normal24_rot13()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001918 " Testing for g?? g?g?
1919 new
1920 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1921 1
1922 norm! g??
1923 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1924 norm! g?g?
1925 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1926
1927 " clean up
1928 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001929endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001930
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01001931func Test_normal25_tag()
Bram Moolenaar5a4c3082019-12-01 15:23:11 +01001932 CheckFeature quickfix
1933
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001934 " Testing for CTRL-] g CTRL-] g]
1935 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1936 h
1937 " Test for CTRL-]
1938 call search('\<x\>$')
1939 exe "norm! \<c-]>"
1940 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1941 norm! yiW
1942 call assert_equal("*x*", @0)
1943 exe ":norm \<c-o>"
1944
1945 " Test for g_CTRL-]
1946 call search('\<v_u\>$')
1947 exe "norm! g\<c-]>"
1948 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1949 norm! yiW
1950 call assert_equal("*v_u*", @0)
1951 exe ":norm \<c-o>"
1952
1953 " Test for g]
1954 call search('\<i_<Esc>$')
1955 let a = execute(":norm! g]")
1956 call assert_match('i_<Esc>.*insert.txt', a)
1957
1958 if !empty(exepath('cscope')) && has('cscope')
1959 " setting cscopetag changes how g] works
1960 set cst
1961 exe "norm! g]"
1962 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1963 norm! yiW
1964 call assert_equal("*i_<Esc>*", @0)
1965 exe ":norm \<c-o>"
1966 " Test for CTRL-W g]
1967 exe "norm! \<C-W>g]"
1968 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1969 norm! yiW
1970 call assert_equal("*i_<Esc>*", @0)
1971 call assert_equal(3, winnr('$'))
1972 helpclose
1973 set nocst
1974 endif
1975
1976 " Test for CTRL-W g]
1977 let a = execute("norm! \<C-W>g]")
1978 call assert_match('i_<Esc>.*insert.txt', a)
1979
1980 " Test for CTRL-W CTRL-]
1981 exe "norm! \<C-W>\<C-]>"
1982 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1983 norm! yiW
1984 call assert_equal("*i_<Esc>*", @0)
1985 call assert_equal(3, winnr('$'))
1986 helpclose
1987
1988 " Test for CTRL-W g CTRL-]
1989 exe "norm! \<C-W>g\<C-]>"
1990 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1991 norm! yiW
1992 call assert_equal("*i_<Esc>*", @0)
1993 call assert_equal(3, winnr('$'))
1994 helpclose
1995
1996 " clean up
1997 helpclose
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02001998endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001999
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002000func Test_normal26_put()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002001 " Test for ]p ]P [p and [P
2002 new
2003 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
2004 1
2005 /Error/y a
2006 2
2007 norm! "a]pj"a[p
2008 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
2009 1
2010 /^\s\{4}/
2011 exe "norm! \"a]P3Eldt'"
2012 exe "norm! j\"a[P2Eldt'"
2013 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
2014
2015 " clean up
2016 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002017endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002018
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002019func Test_normal27_bracket()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002020 " Test for [' [` ]' ]`
2021 call Setup_NewWindow()
2022 1,21s/.\+/ & b/
2023 1
2024 norm! $ma
2025 5
2026 norm! $mb
2027 10
2028 norm! $mc
2029 15
2030 norm! $md
2031 20
2032 norm! $me
2033
2034 " Test for ['
2035 9
2036 norm! 2['
2037 call assert_equal(' 1 b', getline('.'))
2038 call assert_equal(1, line('.'))
2039 call assert_equal(3, col('.'))
2040
2041 " Test for ]'
2042 norm! ]'
2043 call assert_equal(' 5 b', getline('.'))
2044 call assert_equal(5, line('.'))
2045 call assert_equal(3, col('.'))
2046
zeertzjqcf344342022-07-06 12:57:31 +01002047 " No mark before line 1, cursor moves to first non-blank on current line
2048 1
2049 norm! 5|['
2050 call assert_equal(' 1 b', getline('.'))
2051 call assert_equal(1, line('.'))
2052 call assert_equal(3, col('.'))
2053
2054 " No mark after line 21, cursor moves to first non-blank on current line
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002055 21
zeertzjqcf344342022-07-06 12:57:31 +01002056 norm! 5|]'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002057 call assert_equal(' 21 b', getline('.'))
2058 call assert_equal(21, line('.'))
2059 call assert_equal(3, col('.'))
2060
2061 " Test for [`
2062 norm! 2[`
2063 call assert_equal(' 15 b', getline('.'))
2064 call assert_equal(15, line('.'))
2065 call assert_equal(8, col('.'))
2066
2067 " Test for ]`
2068 norm! ]`
2069 call assert_equal(' 20 b', getline('.'))
2070 call assert_equal(20, line('.'))
2071 call assert_equal(8, col('.'))
2072
zeertzjqcf344342022-07-06 12:57:31 +01002073 " No mark before line 1, cursor does not move
2074 1
2075 norm! 5|[`
2076 call assert_equal(' 1 b', getline('.'))
2077 call assert_equal(1, line('.'))
2078 call assert_equal(5, col('.'))
2079
2080 " No mark after line 21, cursor does not move
2081 21
2082 norm! 5|]`
2083 call assert_equal(' 21 b', getline('.'))
2084 call assert_equal(21, line('.'))
2085 call assert_equal(5, col('.'))
2086
2087 " Count too large for [`
2088 " cursor moves to first lowercase mark
2089 norm! 99[`
2090 call assert_equal(' 1 b', getline('.'))
2091 call assert_equal(1, line('.'))
2092 call assert_equal(7, col('.'))
2093
2094 " Count too large for ]`
2095 " cursor moves to last lowercase mark
2096 norm! 99]`
2097 call assert_equal(' 20 b', getline('.'))
2098 call assert_equal(20, line('.'))
2099 call assert_equal(8, col('.'))
2100
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002101 " clean up
2102 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002103endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002104
Bram Moolenaar1671f442020-03-10 07:48:13 +01002105" Test for ( and ) sentence movements
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002106func Test_normal28_parenthesis()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002107 new
2108 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
2109
2110 $
2111 norm! d(
2112 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
2113 norm! 2d(
2114 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
2115 1
2116 norm! 0d)
2117 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
2118
2119 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
2120 $
2121 norm! $d(
2122 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
2123
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002124 " Move to the next sentence from a paragraph macro
2125 %d
2126 call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.'])
2127 call cursor(1, 1)
2128 normal )
2129 call assert_equal([2, 1], [line('.'), col('.')])
2130 normal )
2131 call assert_equal([2, 12], [line('.'), col('.')])
2132 normal ((
2133 call assert_equal([1, 1], [line('.'), col('.')])
2134
Bram Moolenaar1671f442020-03-10 07:48:13 +01002135 " It is an error if a next sentence is not found
2136 %d
2137 call setline(1, '.SH')
2138 call assert_beeps('normal )')
2139
Bram Moolenaar224a5f12020-04-28 20:29:07 +02002140 " If only dot is present, don't treat that as a sentence
2141 call setline(1, '. This is a sentence.')
2142 normal $((
2143 call assert_equal(3, col('.'))
2144
Bram Moolenaar1671f442020-03-10 07:48:13 +01002145 " Jumping to a fold should open the fold
2146 call setline(1, ['', '', 'one', 'two', 'three'])
2147 set foldenable
2148 2,$fold
2149 call feedkeys(')', 'xt')
2150 call assert_equal(3, line('.'))
2151 call assert_equal(1, foldlevel('.'))
2152 call assert_equal(-1, foldclosed('.'))
2153 set foldenable&
2154
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002155 " clean up
2156 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002157endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002158
Bram Moolenaar1671f442020-03-10 07:48:13 +01002159" Test for { and } paragraph movements
2160func Test_normal29_brace()
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002161 let text =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002162 A paragraph begins after each empty line, and also at each of a set of
2163 paragraph macros, specified by the pairs of characters in the 'paragraphs'
2164 option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to
2165 the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in
2166 the first column). A section boundary is also a paragraph boundary.
2167 Note that a blank line (only containing white space) is NOT a paragraph
2168 boundary.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002169
2170
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002171 Also note that this does not include a '{' or '}' in the first column. When
2172 the '{' flag is in 'cpoptions' then '{' in the first column is used as a
2173 paragraph boundary |posix|.
2174 {
2175 This is no paragraph
2176 unless the '{' is set
2177 in 'cpoptions'
2178 }
2179 .IP
2180 The nroff macros IP separates a paragraph
2181 That means, it must be a '.'
2182 followed by IP
2183 .LPIt does not matter, if afterwards some
2184 more characters follow.
2185 .SHAlso section boundaries from the nroff
2186 macros terminate a paragraph. That means
2187 a character like this:
2188 .NH
2189 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002190 [DATA]
2191
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002192 new
2193 call append(0, text)
2194 1
2195 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002196
2197 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002198 .IP
2199 The nroff macros IP separates a paragraph
2200 That means, it must be a '.'
2201 followed by IP
2202 .LPIt does not matter, if afterwards some
2203 more characters follow.
2204 .SHAlso section boundaries from the nroff
2205 macros terminate a paragraph. That means
2206 a character like this:
2207 .NH
2208 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002209
2210 [DATA]
2211 call assert_equal(expected, getline(1, '$'))
2212
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002213 norm! 0d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002214
2215 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002216 .LPIt does not matter, if afterwards some
2217 more characters follow.
2218 .SHAlso section boundaries from the nroff
2219 macros terminate a paragraph. That means
2220 a character like this:
2221 .NH
2222 End of text here
Bram Moolenaar94722c52023-01-28 19:19:03 +00002223
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002224 [DATA]
2225 call assert_equal(expected, getline(1, '$'))
2226
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002227 $
2228 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002229
2230 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002231 .LPIt does not matter, if afterwards some
2232 more characters follow.
2233 .SHAlso section boundaries from the nroff
2234 macros terminate a paragraph. That means
2235 a character like this:
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002236
2237 [DATA]
2238 call assert_equal(expected, getline(1, '$'))
2239
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002240 norm! d{
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002241
2242 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002243 .LPIt does not matter, if afterwards some
2244 more characters follow.
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002245
2246 [DATA]
2247 call assert_equal(expected, getline(1, '$'))
2248
dundargocdc4c37b2024-01-12 18:02:10 +01002249 " Test with { in cpoptions
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002250 %d
2251 call append(0, text)
2252 set cpo+={
2253 1
2254 norm! 0d2}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002255
2256 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002257 {
2258 This is no paragraph
2259 unless the '{' is set
2260 in 'cpoptions'
2261 }
2262 .IP
2263 The nroff macros IP separates a paragraph
2264 That means, it must be a '.'
2265 followed by IP
2266 .LPIt does not matter, if afterwards some
2267 more characters follow.
2268 .SHAlso section boundaries from the nroff
2269 macros terminate a paragraph. That means
2270 a character like this:
2271 .NH
2272 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002273
2274 [DATA]
2275 call assert_equal(expected, getline(1, '$'))
2276
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002277 $
2278 norm! d}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002279
2280 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002281 {
2282 This is no paragraph
2283 unless the '{' is set
2284 in 'cpoptions'
2285 }
2286 .IP
2287 The nroff macros IP separates a paragraph
2288 That means, it must be a '.'
2289 followed by IP
2290 .LPIt does not matter, if afterwards some
2291 more characters follow.
2292 .SHAlso section boundaries from the nroff
2293 macros terminate a paragraph. That means
2294 a character like this:
2295 .NH
2296 End of text here
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002297
2298 [DATA]
2299 call assert_equal(expected, getline(1, '$'))
2300
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002301 norm! gg}
2302 norm! d5}
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002303
2304 let expected =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02002305 {
2306 This is no paragraph
2307 unless the '{' is set
2308 in 'cpoptions'
2309 }
Bram Moolenaarc79745a2019-05-20 22:12:34 +02002310
2311 [DATA]
2312 call assert_equal(expected, getline(1, '$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002313
Bram Moolenaar1671f442020-03-10 07:48:13 +01002314 " Jumping to a fold should open the fold
2315 %d
2316 call setline(1, ['', 'one', 'two', ''])
2317 set foldenable
2318 2,$fold
2319 call feedkeys('}', 'xt')
2320 call assert_equal(4, line('.'))
2321 call assert_equal(1, foldlevel('.'))
2322 call assert_equal(-1, foldclosed('.'))
2323 set foldenable&
2324
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002325 " clean up
2326 set cpo-={
2327 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002328endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002329
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002330" Test for section movements
2331func Test_normal_section()
2332 new
2333 let lines =<< trim [END]
2334 int foo()
2335 {
2336 if (1)
2337 {
2338 a = 1;
2339 }
2340 }
2341 [END]
2342 call setline(1, lines)
2343
2344 " jumping to a folded line using [[ should open the fold
2345 2,3fold
2346 call cursor(5, 1)
2347 call feedkeys("[[", 'xt')
2348 call assert_equal(2, line('.'))
2349 call assert_equal(-1, foldclosedend(line('.')))
2350
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002351 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02002352endfunc
2353
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002354" Test for changing case using u, U, gu, gU and ~ (tilde) commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002355func Test_normal30_changecase()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002356 new
2357 call append(0, 'This is a simple test: äüöß')
2358 norm! 1ggVu
2359 call assert_equal('this is a simple test: äüöß', getline('.'))
2360 norm! VU
glepnirbd1232a2024-02-12 22:14:53 +01002361 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002362 norm! guu
glepnirbd1232a2024-02-12 22:14:53 +01002363 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002364 norm! gUgU
glepnirbd1232a2024-02-12 22:14:53 +01002365 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002366 norm! gugu
glepnirbd1232a2024-02-12 22:14:53 +01002367 call assert_equal('this is a simple test: äüöß', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002368 norm! gUU
glepnirbd1232a2024-02-12 22:14:53 +01002369 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002370 norm! 010~
glepnirbd1232a2024-02-12 22:14:53 +01002371 call assert_equal('this is a SIMPLE TEST: ÄÜÖẞ', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002372 norm! V~
glepnirbd1232a2024-02-12 22:14:53 +01002373 call assert_equal('THIS IS A simple test: äüöß', getline('.'))
Bram Moolenaard1ad99b2020-10-04 16:16:54 +02002374 call assert_beeps('norm! c~')
2375 %d
2376 call assert_beeps('norm! ~')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002377
zeertzjq8c55d602024-03-13 20:42:26 +01002378 " Test with multiple lines
2379 call setline(1, ['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'])
2380 norm! ggguG
2381 call assert_equal(['aa', 'bbbb', 'cccccc', 'dddddddd'], getline(1, '$'))
2382 norm! GgUgg
2383 call assert_equal(['AA', 'BBBB', 'CCCCCC', 'DDDDDDDD'], getline(1, '$'))
2384 %d
2385
Bram Moolenaar1671f442020-03-10 07:48:13 +01002386 " Test for changing case across lines using 'whichwrap'
2387 call setline(1, ['aaaaaa', 'aaaaaa'])
2388 normal! gg10~
2389 call assert_equal(['AAAAAA', 'aaaaaa'], getline(1, 2))
2390 set whichwrap+=~
2391 normal! gg10~
2392 call assert_equal(['aaaaaa', 'AAAAaa'], getline(1, 2))
2393 set whichwrap&
2394
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02002395 " try changing the case with a double byte encoding (DBCS)
2396 %bw!
2397 let enc = &enc
2398 set encoding=cp932
2399 call setline(1, "\u8470")
2400 normal ~
2401 normal gU$gu$gUgUg~g~gugu
2402 call assert_equal("\u8470", getline(1))
2403 let &encoding = enc
2404
Bram Moolenaar1671f442020-03-10 07:48:13 +01002405 " clean up
2406 bw!
2407endfunc
2408
2409" Turkish ASCII turns to multi-byte. On some systems Turkish locale
2410" is available but toupper()/tolower() don't do the right thing.
2411func Test_normal_changecase_turkish()
2412 new
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002413 try
2414 lang tr_TR.UTF-8
2415 set casemap=
2416 let iupper = toupper('i')
2417 if iupper == "\u0130"
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002418 call setline(1, 'iI')
2419 1normal gUU
2420 call assert_equal("\u0130I", getline(1))
2421 call assert_equal("\u0130I", toupper("iI"))
Bram Moolenaar3317d5e2017-04-08 19:12:06 +02002422
Bram Moolenaar9f4de1f2017-04-08 19:39:43 +02002423 call setline(1, 'iI')
2424 1normal guu
2425 call assert_equal("i\u0131", getline(1))
2426 call assert_equal("i\u0131", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002427 elseif iupper == "I"
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002428 call setline(1, 'iI')
2429 1normal gUU
2430 call assert_equal("II", getline(1))
2431 call assert_equal("II", toupper("iI"))
2432
2433 call setline(1, 'iI')
2434 1normal guu
2435 call assert_equal("ii", getline(1))
2436 call assert_equal("ii", tolower("iI"))
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002437 else
2438 call assert_true(false, "expected toupper('i') to be either 'I' or '\u0130'")
2439 endif
2440 set casemap&
2441 call setline(1, 'iI')
2442 1normal gUU
2443 call assert_equal("II", getline(1))
2444 call assert_equal("II", toupper("iI"))
Bram Moolenaar1cc48202017-04-09 13:41:59 +02002445
Bram Moolenaarf1c118b2018-09-03 22:08:10 +02002446 call setline(1, 'iI')
2447 1normal guu
2448 call assert_equal("ii", getline(1))
2449 call assert_equal("ii", tolower("iI"))
2450
2451 lang en_US.UTF-8
2452 catch /E197:/
2453 " can't use Turkish locale
2454 throw 'Skipped: Turkish locale not available'
2455 endtry
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00002456
2457 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002458endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002459
Bram Moolenaar1671f442020-03-10 07:48:13 +01002460" Test for r (replace) command
2461func Test_normal31_r_cmd()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002462 new
2463 call append(0, 'This is a simple test: abcd')
2464 exe "norm! 1gg$r\<cr>"
2465 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
2466 exe "norm! 1gg2wlr\<cr>"
2467 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
2468 exe "norm! 2gg0W5r\<cr>"
2469 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
2470 set autoindent
2471 call setline(2, ['simple test: abc', ''])
2472 exe "norm! 2gg0W5r\<cr>"
2473 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
2474 exe "norm! 1ggVr\<cr>"
2475 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
2476 call setline(1, 'This is a')
2477 exe "norm! 1gg05rf"
2478 call assert_equal('fffffis a', getline(1))
2479
Bram Moolenaar1671f442020-03-10 07:48:13 +01002480 " When replacing characters, copy characters from above and below lines
2481 " using CTRL-Y and CTRL-E.
2482 " Different code paths are used for utf-8 and latin1 encodings
2483 set showmatch
2484 for enc in ['latin1', 'utf-8']
2485 enew!
2486 let &encoding = enc
2487 call setline(1, [' {a}', 'xxxxxxxxxx', ' [b]'])
2488 exe "norm! 2gg5r\<C-Y>l5r\<C-E>"
2489 call assert_equal(' {a}x [b]x', getline(2))
2490 endfor
2491 set showmatch&
2492
2493 " r command should fail in operator pending mode
2494 call assert_beeps('normal! cr')
2495
Bram Moolenaar004a6782020-04-11 17:09:31 +02002496 " replace a tab character in visual mode
2497 %d
2498 call setline(1, ["a\tb", "c\td", "e\tf"])
2499 normal gglvjjrx
2500 call assert_equal(['axx', 'xxx', 'xxf'], getline(1, '$'))
2501
Bram Moolenaard7e5e942020-10-07 16:54:52 +02002502 " replace with a multibyte character (with multiple composing characters)
2503 %d
2504 new
2505 call setline(1, 'aaa')
2506 exe "normal $ra\u0328\u0301"
2507 call assert_equal("aaa\u0328\u0301", getline(1))
2508
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002509 " clean up
2510 set noautoindent
2511 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002512endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002513
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002514" Test for g*, g#
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002515func Test_normal32_g_cmd1()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002516 new
2517 call append(0, ['abc.x_foo', 'x_foobar.abc'])
2518 1
2519 norm! $g*
2520 call assert_equal('x_foo', @/)
2521 call assert_equal('x_foobar.abc', getline('.'))
2522 norm! $g#
2523 call assert_equal('abc', @/)
2524 call assert_equal('abc.x_foo', getline('.'))
2525
2526 " clean up
2527 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002528endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002529
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002530" Test for g`, g;, g,, g&, gv, gk, gj, gJ, g0, g^, g_, gm, g$, gM, g CTRL-G,
2531" gi and gI commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01002532func Test_normal33_g_cmd2()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002533 call Setup_NewWindow()
2534 " Test for g`
2535 clearjumps
2536 norm! ma10j
2537 let a=execute(':jumps')
2538 " empty jumplist
2539 call assert_equal('>', a[-1:])
2540 norm! g`a
2541 call assert_equal('>', a[-1:])
2542 call assert_equal(1, line('.'))
2543 call assert_equal('1', getline('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002544 call cursor(10, 1)
2545 norm! g'a
2546 call assert_equal('>', a[-1:])
2547 call assert_equal(1, line('.'))
zeertzjq30585e02023-03-06 08:10:04 +00002548 let v:errmsg = ''
zeertzjqf86dea82023-03-05 21:15:06 +00002549 call assert_nobeep("normal! g`\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002550 call assert_equal('', v:errmsg)
zeertzjqf86dea82023-03-05 21:15:06 +00002551 call assert_nobeep("normal! g'\<Esc>")
zeertzjq30585e02023-03-06 08:10:04 +00002552 call assert_equal('', v:errmsg)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002553
2554 " Test for g; and g,
2555 norm! g;
2556 " there is only one change in the changelist
2557 " currently, when we setup the window
2558 call assert_equal(2, line('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02002559 call assert_fails(':norm! g;', 'E662:')
2560 call assert_fails(':norm! g,', 'E663:')
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002561 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002562 call append('$', ['a', 'b', 'c', 'd'])
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01002563 let &ul = &ul
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002564 call append('$', ['Z', 'Y', 'X', 'W'])
2565 let a = execute(':changes')
2566 call assert_match('2\s\+0\s\+2', a)
2567 call assert_match('101\s\+0\s\+a', a)
2568 call assert_match('105\s\+0\s\+Z', a)
2569 norm! 3g;
2570 call assert_equal(2, line('.'))
2571 norm! 2g,
2572 call assert_equal(105, line('.'))
2573
2574 " Test for g& - global substitute
2575 %d
2576 call setline(1, range(1,10))
2577 call append('$', ['a', 'b', 'c', 'd'])
2578 $s/\w/&&/g
2579 exe "norm! /[1-8]\<cr>"
2580 norm! g&
2581 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
2582
Bram Moolenaar1671f442020-03-10 07:48:13 +01002583 " Jumping to a fold using gg should open the fold
2584 set foldenable
2585 set foldopen+=jump
2586 5,8fold
2587 call feedkeys('6gg', 'xt')
2588 call assert_equal(1, foldlevel('.'))
2589 call assert_equal(-1, foldclosed('.'))
2590 set foldopen-=jump
2591 set foldenable&
2592
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002593 " Test for gv
2594 %d
2595 call append('$', repeat(['abcdefgh'], 8))
2596 exe "norm! 2gg02l\<c-v>2j2ly"
2597 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
2598 " in visual mode, gv swaps current and last selected region
2599 exe "norm! G0\<c-v>4k4lgvd"
2600 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
2601 exe "norm! G0\<c-v>4k4ly"
2602 exe "norm! gvood"
2603 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
phaniumcb279922025-06-16 20:19:15 +02002604 " gv works in operator pending mode
2605 call assert_nobeep('normal! cgvxyza')
2606 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'xyza', 'xyza', 'xyza', 'xyza', 'xyza'], getline(1,'$'))
2607 exe "norm! ^\<c-v>Gydgv..cgvbc"
2608 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'bc', 'bc', 'bc', 'bc', 'bc'], getline(1,'$'))
2609 exe "norm! v^GragggUgv"
2610 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'bA', 'AA', 'AA', 'AA', 'Ac'], getline(1,'$'))
2611
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002612 " gv should beep without a previously selected visual area
2613 new
2614 call assert_beeps('normal! gv')
2615 close
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002616
2617 " Test for gk/gj
2618 %d
2619 15vsp
2620 set wrap listchars= sbr=
Bram Moolenaar74ede802021-05-29 19:18:01 +02002621 let lineA = 'abcdefghijklmnopqrstuvwxyz'
2622 let lineB = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2623 let lineC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002624 $put =lineA
2625 $put =lineB
2626
2627 norm! 3gg0dgk
2628 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
2629 set nu
2630 norm! 3gg0gjdgj
2631 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2632
2633 " Test for gJ
2634 norm! 2gggJ
2635 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2636 call assert_equal(16, col('.'))
2637 " shouldn't do anything
2638 norm! 10gJ
2639 call assert_equal(1, col('.'))
2640
2641 " Test for g0 g^ gm g$
2642 exe "norm! 2gg0gji "
2643 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
2644 norm! g0yl
2645 call assert_equal(12, col('.'))
2646 call assert_equal(' ', getreg(0))
2647 norm! g$yl
2648 call assert_equal(22, col('.'))
2649 call assert_equal('3', getreg(0))
2650 norm! gmyl
2651 call assert_equal(17, col('.'))
2652 call assert_equal('n', getreg(0))
2653 norm! g^yl
2654 call assert_equal(15, col('.'))
2655 call assert_equal('l', getreg(0))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002656 call assert_beeps('normal 5g$')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002657
Bram Moolenaar74ede802021-05-29 19:18:01 +02002658 " Test for g$ with double-width character half displayed
2659 vsplit
2660 9wincmd |
2661 setlocal nowrap nonumber
2662 call setline(2, 'asdfasdfヨ')
2663 2
2664 normal 0g$
2665 call assert_equal(8, col('.'))
2666 10wincmd |
2667 normal 0g$
2668 call assert_equal(9, col('.'))
2669
2670 setlocal signcolumn=yes
2671 11wincmd |
2672 normal 0g$
2673 call assert_equal(8, col('.'))
2674 12wincmd |
2675 normal 0g$
2676 call assert_equal(9, col('.'))
2677
2678 close
2679
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002680 " Test for g_
2681 call assert_beeps('normal! 100g_')
2682 call setline(2, [' foo ', ' foobar '])
2683 normal! 2ggg_
2684 call assert_equal(5, col('.'))
2685 normal! 2g_
2686 call assert_equal(8, col('.'))
2687
2688 norm! 2ggdG
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002689 $put =lineC
2690
2691 " Test for gM
2692 norm! gMyl
2693 call assert_equal(73, col('.'))
2694 call assert_equal('0', getreg(0))
2695 " Test for 20gM
2696 norm! 20gMyl
2697 call assert_equal(29, col('.'))
2698 call assert_equal('S', getreg(0))
2699 " Test for 60gM
2700 norm! 60gMyl
2701 call assert_equal(87, col('.'))
2702 call assert_equal('E', getreg(0))
2703
zeertzjq757c37d2025-03-27 18:21:49 +01002704 " Have an odd number of chars in the line
2705 norm! A.
2706 call assert_equal(145, col('.'))
2707 norm! gMyl
2708 call assert_equal(73, col('.'))
2709 call assert_equal('0', getreg(0))
2710
2711 " 'listchars' "eol" should not affect gM behavior
2712 setlocal list listchars=eol:$
2713 norm! $
2714 call assert_equal(145, col('.'))
2715 norm! gMyl
2716 call assert_equal(73, col('.'))
2717 call assert_equal('0', getreg(0))
2718 setlocal nolist
2719
Bram Moolenaar71c41252021-12-26 15:00:07 +00002720 " Test for gM with Tab characters
2721 call setline('.', "\ta\tb\tc\td\te\tf")
2722 norm! gMyl
2723 call assert_equal(6, col('.'))
2724 call assert_equal("c", getreg(0))
2725
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002726 " Test for g Ctrl-G
Bram Moolenaar71c41252021-12-26 15:00:07 +00002727 call setline('.', lineC)
2728 norm! 60gMyl
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002729 set ff=unix
2730 let a=execute(":norm! g\<c-g>")
2731 call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a)
2732
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002733 " Test for gI
2734 norm! gIfoo
Bram Moolenaar8b530c12019-10-28 02:13:05 +01002735 call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002736
2737 " Test for gi
2738 wincmd c
2739 %d
2740 set tw=0
2741 call setline(1, ['foobar', 'new line'])
2742 norm! A next word
2743 $put ='third line'
2744 norm! gi another word
2745 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002746 call setline(1, 'foobar')
2747 normal! Ggifirst line
2748 call assert_equal('foobarfirst line', getline(1))
2749 " Test gi in 'virtualedit' mode with cursor after the end of the line
2750 set virtualedit=all
2751 call setline(1, 'foo')
2752 exe "normal! Abar\<Right>\<Right>\<Right>\<Right>"
2753 call setline(1, 'foo')
2754 normal! Ggifirst line
2755 call assert_equal('foo first line', getline(1))
2756 set virtualedit&
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002757
Dominique Pelle923dce22021-11-21 11:36:04 +00002758 " Test for aborting a g command using CTRL-\ CTRL-G
Bram Moolenaar1671f442020-03-10 07:48:13 +01002759 exe "normal! g\<C-\>\<C-G>"
2760 call assert_equal('foo first line', getline('.'))
2761
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002762 " clean up
2763 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002764endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002765
Bram Moolenaarce416b42022-04-03 12:59:34 +01002766func Test_normal_ex_substitute()
2767 " This was hanging on the substitute prompt.
2768 new
2769 call setline(1, 'a')
2770 exe "normal! gggQs/a/b/c\<CR>"
2771 call assert_equal('a', getline(1))
2772 bwipe!
2773endfunc
2774
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002775" Test for g CTRL-G
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01002776func Test_g_ctrl_g()
Bram Moolenaar05295832018-08-24 22:07:58 +02002777 new
2778
2779 let a = execute(":norm! g\<c-g>")
2780 call assert_equal("\n--No lines in buffer--", a)
2781
Bram Moolenaar1671f442020-03-10 07:48:13 +01002782 " Test for CTRL-G (same as :file)
2783 let a = execute(":norm! \<c-g>")
2784 call assert_equal("\n\n\"[No Name]\" --No lines in buffer--", a)
2785
Bram Moolenaar05295832018-08-24 22:07:58 +02002786 call setline(1, ['first line', 'second line'])
2787
2788 " Test g CTRL-g with dos, mac and unix file type.
2789 norm! gojll
2790 set ff=dos
2791 let a = execute(":norm! g\<c-g>")
2792 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
2793
2794 set ff=mac
2795 let a = execute(":norm! g\<c-g>")
2796 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2797
2798 set ff=unix
2799 let a = execute(":norm! g\<c-g>")
2800 call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
2801
2802 " Test g CTRL-g in visual mode (v)
2803 let a = execute(":norm! gojllvlg\<c-g>")
2804 call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
2805
2806 " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
2807 let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
2808 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2809
2810 " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
2811 let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
2812 call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
2813
2814 " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
2815 let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
2816 call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
2817
2818 " There should be one byte less with noeol
2819 set bin noeol
2820 let a = execute(":norm! \<Esc>gog\<c-g>")
2821 call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
2822 set bin & eol&
2823
Bram Moolenaar30276f22019-01-24 17:59:39 +01002824 call setline(1, ['Français', '日本語'])
Bram Moolenaar05295832018-08-24 22:07:58 +02002825
Bram Moolenaar30276f22019-01-24 17:59:39 +01002826 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2827 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 +02002828
Bram Moolenaar30276f22019-01-24 17:59:39 +01002829 let a = execute(":norm! \<Esc>gojvlg\<c-g>")
2830 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 +02002831
Bram Moolenaar30276f22019-01-24 17:59:39 +01002832 let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
2833 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 +02002834
Bram Moolenaar30276f22019-01-24 17:59:39 +01002835 set fenc=utf8 bomb
2836 let a = execute(":norm! \<Esc>gojlg\<c-g>")
2837 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 +02002838
Bram Moolenaar30276f22019-01-24 17:59:39 +01002839 set fenc=utf16 bomb
2840 let a = execute(":norm! g\<c-g>")
2841 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 +02002842
Bram Moolenaar30276f22019-01-24 17:59:39 +01002843 set fenc=utf32 bomb
2844 let a = execute(":norm! g\<c-g>")
2845 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 +02002846
Bram Moolenaar30276f22019-01-24 17:59:39 +01002847 set fenc& bomb&
Bram Moolenaar05295832018-08-24 22:07:58 +02002848
2849 set ff&
2850 bwipe!
2851endfunc
2852
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002853" Test for g8
Bram Moolenaar1671f442020-03-10 07:48:13 +01002854func Test_normal34_g_cmd3()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002855 new
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002856 let a=execute(':norm! 1G0g8')
2857 call assert_equal("\nNUL", a)
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002858
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002859 call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
2860 let a=execute(':norm! 1G$g8')
2861 call assert_equal("\nc3 b6 ", a)
2862
2863 call setline(1, "a\u0302")
2864 let a=execute(':norm! 1G0g8')
2865 call assert_equal("\n61 + cc 82 ", a)
2866
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002867 " clean up
2868 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002869endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002870
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002871" Test 8g8 which finds invalid utf8 at or after the cursor.
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002872func Test_normal_8g8()
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002873 new
2874
Bram Moolenaar395b6ba2017-04-07 20:09:51 +02002875 " With invalid byte.
2876 call setline(1, "___\xff___")
2877 norm! 1G08g8g
2878 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2879
2880 " With invalid byte before the cursor.
2881 call setline(1, "___\xff___")
2882 norm! 1G$h8g8g
2883 call assert_equal([0, 1, 6, 0, 9], getcurpos())
2884
2885 " With truncated sequence.
2886 call setline(1, "___\xE2\x82___")
2887 norm! 1G08g8g
2888 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2889
2890 " With overlong sequence.
2891 call setline(1, "___\xF0\x82\x82\xAC___")
2892 norm! 1G08g8g
2893 call assert_equal([0, 1, 4, 0, 1], getcurpos())
2894
2895 " With valid utf8.
2896 call setline(1, "café")
2897 norm! 1G08g8
2898 call assert_equal([0, 1, 1, 0, 1], getcurpos())
2899
2900 bw!
2901endfunc
2902
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002903" Test for g<
Bram Moolenaar1671f442020-03-10 07:48:13 +01002904func Test_normal35_g_cmd4()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002905 " Cannot capture its output,
2906 " probably a bug, therefore, test disabled:
Bram Moolenaar31845092016-09-05 22:58:31 +02002907 throw "Skipped: output of g< can't be tested currently"
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002908 echo "a\nb\nc\nd"
2909 let b=execute(':norm! g<')
2910 call assert_true(!empty(b), 'failed `execute(g<)`')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002911endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002912
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002913" Test for gp gP go
Bram Moolenaar1671f442020-03-10 07:48:13 +01002914func Test_normal36_g_cmd5()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002915 new
2916 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02002917 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002918 " Test for gp gP
2919 call append(1, range(1,10))
2920 1
2921 norm! 1yy
2922 3
2923 norm! gp
2924 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2925 $
2926 norm! gP
2927 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2928
2929 " Test for go
2930 norm! 26go
2931 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2932 norm! 27go
2933 call assert_equal([0, 1, 26, 0, 26], getcurpos())
2934 norm! 28go
2935 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2936 set ff=dos
2937 norm! 29go
2938 call assert_equal([0, 2, 1, 0, 1], getcurpos())
2939 set ff=unix
2940 norm! gg0
2941 norm! 101go
2942 call assert_equal([0, 13, 26, 0, 26], getcurpos())
2943 norm! 103go
2944 call assert_equal([0, 14, 1, 0, 1], getcurpos())
2945 " count > buffer content
2946 norm! 120go
naohiro ono56200ee2022-01-01 14:59:44 +00002947 call assert_equal([0, 14, 1, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002948 " clean up
2949 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002950endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002951
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002952" Test for gt and gT
Bram Moolenaar1671f442020-03-10 07:48:13 +01002953func Test_normal37_g_cmd6()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002954 tabnew 1.txt
2955 tabnew 2.txt
2956 tabnew 3.txt
2957 norm! 1gt
2958 call assert_equal(1, tabpagenr())
2959 norm! 3gt
2960 call assert_equal(3, tabpagenr())
2961 norm! 1gT
2962 " count gT goes not to the absolute tabpagenumber
2963 " but, but goes to the count previous tabpagenumber
2964 call assert_equal(2, tabpagenr())
2965 " wrap around
2966 norm! 3gT
2967 call assert_equal(3, tabpagenr())
2968 " gt does not wrap around
2969 norm! 5gt
2970 call assert_equal(3, tabpagenr())
2971
2972 for i in range(3)
2973 tabclose
2974 endfor
2975 " clean up
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +01002976 call assert_fails(':tabclose', 'E784:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02002977endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002978
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002979" Test for <Home> and <C-Home> key
Bram Moolenaar1671f442020-03-10 07:48:13 +01002980func Test_normal38_nvhome()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002981 new
2982 call setline(1, range(10))
2983 $
2984 setl et sw=2
2985 norm! V10>$
2986 " count is ignored
2987 exe "norm! 10\<home>"
2988 call assert_equal(1, col('.'))
2989 exe "norm! \<home>"
2990 call assert_equal([0, 10, 1, 0, 1], getcurpos())
2991 exe "norm! 5\<c-home>"
2992 call assert_equal([0, 5, 1, 0, 1], getcurpos())
2993 exe "norm! \<c-home>"
2994 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01002995 exe "norm! G\<c-kHome>"
2996 call assert_equal([0, 1, 1, 0, 1], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02002997
2998 " clean up
2999 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003000endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003001
Bram Moolenaar1671f442020-03-10 07:48:13 +01003002" Test for <End> and <C-End> keys
3003func Test_normal_nvend()
3004 new
3005 call setline(1, map(range(1, 10), '"line" .. v:val'))
3006 exe "normal! \<End>"
3007 call assert_equal(5, col('.'))
3008 exe "normal! 4\<End>"
3009 call assert_equal([4, 5], [line('.'), col('.')])
3010 exe "normal! \<C-End>"
3011 call assert_equal([10, 6], [line('.'), col('.')])
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003012
3013 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003014endfunc
3015
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003016" Test for cw cW ce
Bram Moolenaar1671f442020-03-10 07:48:13 +01003017func Test_normal39_cw()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003018 " Test for cw and cW on whitespace
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003019 new
3020 set tw=0
3021 call append(0, 'here are some words')
3022 norm! 1gg0elcwZZZ
3023 call assert_equal('hereZZZare some words', getline('.'))
3024 norm! 1gg0elcWYYY
3025 call assert_equal('hereZZZareYYYsome words', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003026 norm! 2gg0cwfoo
3027 call assert_equal('foo', getline('.'))
3028
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003029 call setline(1, 'one; two')
3030 call cursor(1, 1)
3031 call feedkeys('cwvim', 'xt')
3032 call assert_equal('vim; two', getline(1))
3033 call feedkeys('0cWone', 'xt')
3034 call assert_equal('one two', getline(1))
3035 "When cursor is at the end of a word 'ce' will change until the end of the
3036 "next word, but 'cw' will change only one character
3037 call setline(1, 'one two')
3038 call feedkeys('0ecwce', 'xt')
3039 call assert_equal('once two', getline(1))
3040 call setline(1, 'one two')
3041 call feedkeys('0ecely', 'xt')
3042 call assert_equal('only', getline(1))
3043
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003044 " clean up
3045 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003046endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003047
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003048" Test for CTRL-\ commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003049func Test_normal40_ctrl_bsl()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003050 new
3051 call append(0, 'here are some words')
3052 exe "norm! 1gg0a\<C-\>\<C-N>"
3053 call assert_equal('n', mode())
3054 call assert_equal(1, col('.'))
3055 call assert_equal('', visualmode())
3056 exe "norm! 1gg0viw\<C-\>\<C-N>"
3057 call assert_equal('n', mode())
3058 call assert_equal(4, col('.'))
3059 exe "norm! 1gg0a\<C-\>\<C-G>"
3060 call assert_equal('n', mode())
3061 call assert_equal(1, col('.'))
3062 "imap <buffer> , <c-\><c-n>
3063 set im
3064 exe ":norm! \<c-\>\<c-n>dw"
3065 set noim
3066 call assert_equal('are some words', getline(1))
3067 call assert_false(&insertmode)
Yegappan Lakshmanan1a71d312021-07-15 12:49:58 +02003068 call assert_beeps("normal! \<C-\>\<C-A>")
Bram Moolenaar1671f442020-03-10 07:48:13 +01003069
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003070 " clean up
3071 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003072endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003073
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003074" Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= in insert mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003075func Test_normal41_insert_reg()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003076 new
3077 set sts=2 sw=2 ts=8 tw=0
3078 call append(0, ["aaa\tbbb\tccc", '', '', ''])
3079 let a=getline(1)
3080 norm! 2gg0
3081 exe "norm! a\<c-r>=a\<cr>"
3082 norm! 3gg0
3083 exe "norm! a\<c-r>\<c-r>=a\<cr>"
3084 norm! 4gg0
3085 exe "norm! a\<c-r>\<c-o>=a\<cr>"
3086 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
3087
3088 " clean up
3089 set sts=0 sw=8 ts=8
Bram Moolenaar31845092016-09-05 22:58:31 +02003090 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003091endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003092
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003093" Test for Ctrl-D and Ctrl-U
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003094func Test_normal42_halfpage()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003095 call Setup_NewWindow()
3096 call assert_equal(5, &scroll)
3097 exe "norm! \<c-d>"
3098 call assert_equal('6', getline('.'))
3099 exe "norm! 2\<c-d>"
3100 call assert_equal('8', getline('.'))
3101 call assert_equal(2, &scroll)
3102 set scroll=5
3103 exe "norm! \<c-u>"
Luuk van Baalcb204e62024-04-02 20:49:45 +02003104 call assert_equal('3', getline('.'))
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003105 1
3106 set scrolloff=5
3107 exe "norm! \<c-d>"
3108 call assert_equal('10', getline('.'))
3109 exe "norm! \<c-u>"
3110 call assert_equal('5', getline('.'))
3111 1
3112 set scrolloff=99
3113 exe "norm! \<c-d>"
3114 call assert_equal('10', getline('.'))
3115 set scrolloff=0
3116 100
3117 exe "norm! $\<c-u>"
3118 call assert_equal('95', getline('.'))
3119 call assert_equal([0, 95, 1, 0, 1], getcurpos())
3120 100
3121 set nostartofline
3122 exe "norm! $\<c-u>"
3123 call assert_equal('95', getline('.'))
naohiro ono56200ee2022-01-01 14:59:44 +00003124 call assert_equal([0, 95, 2, 0, v:maxcol], getcurpos())
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003125 " cleanup
3126 set startofline
3127 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003128endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003129
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003130func Test_normal45_drop()
Bram Moolenaar29495952018-02-12 22:49:00 +01003131 if !has('dnd')
Bram Moolenaarb48e96f2018-02-13 12:26:14 +01003132 " The ~ register does not exist
3133 call assert_beeps('norm! "~')
Bram Moolenaar29495952018-02-12 22:49:00 +01003134 return
3135 endif
3136
3137 " basic test for drag-n-drop
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003138 " unfortunately, without a gui, we can't really test much here,
3139 " so simply test that ~p fails (which uses the drop register)
3140 new
Bram Moolenaare2e40752020-09-04 21:18:46 +02003141 call assert_fails(':norm! "~p', 'E353:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003142 call assert_equal([], getreg('~', 1, 1))
3143 " the ~ register is read only
Bram Moolenaare2e40752020-09-04 21:18:46 +02003144 call assert_fails(':let @~="1"', 'E354:')
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003145 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003146endfunc
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003147
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003148func Test_normal46_ignore()
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003149 new
3150 " How to test this?
3151 " let's just for now test, that the buffer
3152 " does not change
3153 call feedkeys("\<c-s>", 't')
3154 call assert_equal([''], getline(1,'$'))
3155
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003156 " no valid commands
3157 exe "norm! \<char-0x100>"
3158 call assert_equal([''], getline(1,'$'))
3159
3160 exe "norm! ä"
3161 call assert_equal([''], getline(1,'$'))
3162
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02003163 " clean up
3164 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003165endfunc
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003166
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003167func Test_normal47_visual_buf_wipe()
Bram Moolenaarc4a908e2016-09-08 23:35:30 +02003168 " This was causing a crash or ml_get error.
3169 enew!
3170 call setline(1,'xxx')
3171 normal $
3172 new
3173 call setline(1, range(1,2))
3174 2
3175 exe "norm \<C-V>$"
3176 bw!
3177 norm yp
3178 set nomodified
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003179endfunc
3180
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003181func Test_normal48_wincmd()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003182 new
3183 exe "norm! \<c-w>c"
3184 call assert_equal(1, winnr('$'))
Bram Moolenaare2e40752020-09-04 21:18:46 +02003185 call assert_fails(":norm! \<c-w>c", 'E444:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003186endfunc
3187
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003188func Test_normal49_counts()
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003189 new
3190 call setline(1, 'one two three four five six seven eight nine ten')
3191 1
3192 norm! 3d2w
3193 call assert_equal('seven eight nine ten', getline(1))
3194 bw!
3195endfunc
3196
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003197func Test_normal50_commandline()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003198 CheckFeature timers
3199 CheckFeature cmdline_hist
Bram Moolenaarc255b782022-11-26 19:16:48 +00003200
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003201 func! DoTimerWork(id)
Sean Dewar1fb41032023-08-16 17:15:05 +01003202 call assert_equal(1, getbufinfo('')[0].command)
Bram Moolenaarc255b782022-11-26 19:16:48 +00003203
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003204 " should fail, with E11, but does fail with E23?
3205 "call feedkeys("\<c-^>", 'tm')
3206
Bram Moolenaarc255b782022-11-26 19:16:48 +00003207 " should fail with E11 - "Invalid in command-line window"
Bram Moolenaare2e40752020-09-04 21:18:46 +02003208 call assert_fails(":wincmd p", 'E11:')
Bram Moolenaarc255b782022-11-26 19:16:48 +00003209
3210 " Return from commandline window.
3211 call feedkeys("\<CR>", 't')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003212 endfunc
3213
3214 let oldlang=v:lang
3215 lang C
3216 set updatetime=20
3217 call timer_start(100, 'DoTimerWork')
3218 try
3219 " throws E23, for whatever reason...
3220 call feedkeys('q:', 'x!')
3221 catch /E23/
3222 " no-op
3223 endtry
Bram Moolenaarc255b782022-11-26 19:16:48 +00003224
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003225 " clean up
Bram Moolenaarc255b782022-11-26 19:16:48 +00003226 delfunc DoTimerWork
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003227 set updatetime=4000
3228 exe "lang" oldlang
3229 bw!
3230endfunc
3231
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003232func Test_normal51_FileChangedRO()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003233 CheckFeature autocmd
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003234 " Don't sleep after the warning message.
3235 call test_settime(1)
Bram Moolenaarb152b6a2022-09-29 21:37:33 +01003236 call writefile(['foo'], 'Xreadonly.log', 'D')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003237 new Xreadonly.log
3238 setl ro
3239 au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
Bram Moolenaare2e40752020-09-04 21:18:46 +02003240 call assert_fails(":norm! Af", 'E788:')
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003241 call assert_equal(['foo'], getline(1,'$'))
3242 call assert_equal('Xreadonly.log', bufname(''))
3243
3244 " cleanup
Bram Moolenaare5f2a072017-02-01 22:31:49 +01003245 call test_settime(0)
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003246 bw!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003247endfunc
3248
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003249func Test_normal52_rl()
Bram Moolenaar004a6782020-04-11 17:09:31 +02003250 CheckFeature rightleft
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003251 new
3252 call setline(1, 'abcde fghij klmnopq')
3253 norm! 1gg$
3254 set rl
3255 call assert_equal(19, col('.'))
3256 call feedkeys('l', 'tx')
3257 call assert_equal(18, col('.'))
3258 call feedkeys('h', 'tx')
3259 call assert_equal(19, col('.'))
3260 call feedkeys("\<right>", 'tx')
3261 call assert_equal(18, col('.'))
Bram Moolenaar1671f442020-03-10 07:48:13 +01003262 call feedkeys("\<left>", 'tx')
3263 call assert_equal(19, col('.'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003264 call feedkeys("\<s-right>", 'tx')
3265 call assert_equal(13, col('.'))
3266 call feedkeys("\<c-right>", 'tx')
3267 call assert_equal(7, col('.'))
3268 call feedkeys("\<c-left>", 'tx')
3269 call assert_equal(13, col('.'))
3270 call feedkeys("\<s-left>", 'tx')
3271 call assert_equal(19, col('.'))
3272 call feedkeys("<<", 'tx')
3273 call assert_equal(' abcde fghij klmnopq',getline(1))
3274 call feedkeys(">>", 'tx')
3275 call assert_equal('abcde fghij klmnopq',getline(1))
3276
3277 " cleanup
3278 set norl
3279 bw!
3280endfunc
3281
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003282func Test_normal54_Ctrl_bsl()
3283 new
3284 call setline(1, 'abcdefghijklmn')
3285 exe "norm! df\<c-\>\<c-n>"
3286 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3287 exe "norm! df\<c-\>\<c-g>"
3288 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
3289 exe "norm! df\<c-\>m"
3290 call assert_equal(['abcdefghijklmn'], getline(1,'$'))
Bram Moolenaar30276f22019-01-24 17:59:39 +01003291
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003292 call setline(2, 'abcdefghijklmnāf')
3293 norm! 2gg0
3294 exe "norm! df\<Char-0x101>"
3295 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
3296 norm! 1gg0
3297 exe "norm! df\<esc>"
3298 call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003299
Bram Moolenaarb1e04fc2017-03-29 13:08:35 +02003300 " clean up
3301 bw!
3302endfunc
3303
3304func Test_normal_large_count()
3305 " This may fail with 32bit long, how do we detect that?
3306 new
3307 normal o
3308 normal 6666666666dL
3309 bwipe!
Bram Moolenaar2931f2a2016-09-09 16:59:08 +02003310endfunc
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003311
3312func Test_delete_until_paragraph()
Bram Moolenaarbf3d5802017-03-29 19:48:11 +02003313 new
3314 normal grádv}
3315 call assert_equal('á', getline(1))
3316 normal grád}
3317 call assert_equal('', getline(1))
3318 bwipe!
3319endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003320
3321" Test for the gr (virtual replace) command
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003322func Test_gr_command()
3323 enew!
zeertzjq4f026ea2023-02-26 14:47:24 +00003324 " Test for the bug fixed by 7.4.387
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003325 let save_cpo = &cpo
3326 call append(0, ['First line', 'Second line', 'Third line'])
3327 exe "normal i\<C-G>u"
3328 call cursor(2, 1)
3329 set cpo-=X
3330 normal 4gro
3331 call assert_equal('oooond line', getline(2))
3332 undo
3333 set cpo+=X
3334 normal 4gro
3335 call assert_equal('ooooecond line', getline(2))
3336 let &cpo = save_cpo
zeertzjq4f026ea2023-02-26 14:47:24 +00003337
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003338 normal! ggvegrx
3339 call assert_equal('xxxxx line', getline(1))
3340 exe "normal! gggr\<C-V>122"
3341 call assert_equal('zxxxx line', getline(1))
zeertzjq4f026ea2023-02-26 14:47:24 +00003342
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003343 set virtualedit=all
3344 normal! 15|grl
3345 call assert_equal('zxxxx line l', getline(1))
3346 set virtualedit&
3347 set nomodifiable
3348 call assert_fails('normal! grx', 'E21:')
3349 call assert_fails('normal! gRx', 'E21:')
zeertzjq4f026ea2023-02-26 14:47:24 +00003350 call assert_nobeep("normal! gr\<Esc>")
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003351 set modifiable&
zeertzjq4f026ea2023-02-26 14:47:24 +00003352
3353 call assert_nobeep("normal! gr\<Esc>")
zeertzjqf86dea82023-03-05 21:15:06 +00003354 call assert_nobeep("normal! cgr\<Esc>")
3355 call assert_beeps("normal! cgrx")
zeertzjq4f026ea2023-02-26 14:47:24 +00003356
3357 call assert_equal('zxxxx line l', getline(1))
3358 exe "normal! 2|gr\<C-V>\<Esc>"
3359 call assert_equal("z\<Esc>xx line l", getline(1))
3360
3361 call setline(1, 'abcdef')
3362 exe "normal! 0gr\<C-O>lx"
3363 call assert_equal("\<C-O>def", getline(1))
3364
3365 call setline(1, 'abcdef')
3366 exe "normal! 0gr\<C-G>lx"
3367 call assert_equal("\<C-G>def", getline(1))
3368
3369 bwipe!
Bram Moolenaarfb094e12017-11-05 20:59:28 +01003370endfunc
3371
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003372func Test_nv_hat_count()
3373 %bwipeout!
3374 let l:nr = bufnr('%') + 1
Bram Moolenaare2e40752020-09-04 21:18:46 +02003375 call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92:')
Bram Moolenaar1bbb6192018-11-10 16:02:01 +01003376
3377 edit Xfoo
3378 let l:foo_nr = bufnr('Xfoo')
3379
3380 edit Xbar
3381 let l:bar_nr = bufnr('Xbar')
3382
3383 " Make sure we are not just using the alternate file.
3384 edit Xbaz
3385
3386 call feedkeys(l:foo_nr . "\<C-^>", 'tx')
3387 call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t'))
3388
3389 call feedkeys(l:bar_nr . "\<C-^>", 'tx')
3390 call assert_equal('Xbar', fnamemodify(bufname('%'), ':t'))
3391
3392 %bwipeout!
3393endfunc
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003394
3395func Test_message_when_using_ctrl_c()
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003396 " Make sure no buffers are changed.
3397 %bwipe!
3398
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003399 exe "normal \<C-C>"
3400 call assert_match("Type :qa and press <Enter> to exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003401
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003402 new
3403 cal setline(1, 'hi!')
3404 exe "normal \<C-C>"
3405 call assert_match("Type :qa! and press <Enter> to abandon all changes and exit Vim", Screenline(&lines))
Bram Moolenaar553e5a52019-03-25 23:16:34 +01003406
Bram Moolenaara84a3dd2019-03-25 22:21:24 +01003407 bwipe!
3408endfunc
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003409
Bram Moolenaar7a1d3282022-06-16 13:04:45 +01003410func Test_mode_updated_after_ctrl_c()
3411 CheckScreendump
3412
3413 let buf = RunVimInTerminal('', {'rows': 5})
3414 call term_sendkeys(buf, "i")
3415 call term_sendkeys(buf, "\<C-O>")
3416 " wait a moment so that the "-- (insert) --" message is displayed
3417 call TermWait(buf, 50)
3418 call term_sendkeys(buf, "\<C-C>")
3419 call VerifyScreenDump(buf, 'Test_mode_updated_1', {})
3420
3421 call StopVimInTerminal(buf)
3422endfunc
3423
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003424" Test for '[m', ']m', '[M' and ']M'
3425" Jumping to beginning and end of methods in Java-like languages
3426func Test_java_motion()
3427 new
Bram Moolenaar1671f442020-03-10 07:48:13 +01003428 call assert_beeps('normal! [m')
3429 call assert_beeps('normal! ]m')
3430 call assert_beeps('normal! [M')
3431 call assert_beeps('normal! ]M')
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003432 let lines =<< trim [CODE]
3433 Piece of Java
3434 {
3435 tt m1 {
3436 t1;
3437 } e1
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003438
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003439 tt m2 {
3440 t2;
3441 } e2
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003442
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003443 tt m3 {
3444 if (x)
3445 {
3446 t3;
3447 }
3448 } e3
3449 }
3450 [CODE]
3451 call setline(1, lines)
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003452
3453 normal gg
3454
3455 normal 2]maA
3456 call assert_equal("\ttt m1 {A", getline('.'))
3457 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3458
3459 normal j]maB
3460 call assert_equal("\ttt m2 {B", getline('.'))
3461 call assert_equal([7, 9, 16], [line('.'), col('.'), virtcol('.')])
3462
3463 normal ]maC
3464 call assert_equal("\ttt m3 {C", getline('.'))
3465 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3466
3467 normal [maD
3468 call assert_equal("\ttt m3 {DC", getline('.'))
3469 call assert_equal([11, 9, 16], [line('.'), col('.'), virtcol('.')])
3470
3471 normal k2[maE
3472 call assert_equal("\ttt m1 {EA", getline('.'))
3473 call assert_equal([3, 9, 16], [line('.'), col('.'), virtcol('.')])
3474
3475 normal 3[maF
3476 call assert_equal("{F", getline('.'))
3477 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3478
3479 normal ]MaG
3480 call assert_equal("\t}G e1", getline('.'))
3481 call assert_equal([5, 3, 10], [line('.'), col('.'), virtcol('.')])
3482
3483 normal j2]MaH
3484 call assert_equal("\t}H e3", getline('.'))
3485 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3486
3487 normal ]M]M
3488 normal aI
3489 call assert_equal("}I", getline('.'))
3490 call assert_equal([17, 2, 2], [line('.'), col('.'), virtcol('.')])
3491
3492 normal 2[MaJ
3493 call assert_equal("\t}JH e3", getline('.'))
3494 call assert_equal([16, 3, 10], [line('.'), col('.'), virtcol('.')])
3495
3496 normal k[MaK
3497 call assert_equal("\t}K e2", getline('.'))
3498 call assert_equal([9, 3, 10], [line('.'), col('.'), virtcol('.')])
3499
3500 normal 3[MaL
3501 call assert_equal("{LF", getline('.'))
3502 call assert_equal([2, 2, 2], [line('.'), col('.'), virtcol('.')])
3503
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003504 call cursor(2, 1)
3505 call assert_beeps('norm! 5]m')
3506
3507 " jumping to a method in a fold should open the fold
3508 6,10fold
3509 call feedkeys("gg3]m", 'xt')
3510 call assert_equal([7, 8, 15], [line('.'), col('.'), virtcol('.')])
3511 call assert_equal(-1, foldclosedend(7))
3512
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003513 bwipe!
Bram Moolenaarc6b37db2019-04-27 18:00:34 +02003514endfunc
Bram Moolenaard5c82342019-07-27 18:44:57 +02003515
Bram Moolenaar004a6782020-04-11 17:09:31 +02003516" Tests for g cmds
Bram Moolenaar1671f442020-03-10 07:48:13 +01003517func Test_normal_gdollar_cmd()
Bram Moolenaard5c82342019-07-27 18:44:57 +02003518 call Setup_NewWindow()
3519 " Make long lines that will wrap
3520 %s/$/\=repeat(' foobar', 10)/
3521 20vsp
3522 set wrap
3523 " Test for g$ with count
3524 norm! gg
3525 norm! 0vg$y
3526 call assert_equal(20, col("'>"))
3527 call assert_equal('1 foobar foobar foob', getreg(0))
3528 norm! gg
3529 norm! 0v4g$y
3530 call assert_equal(72, col("'>"))
3531 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0))
3532 norm! gg
3533 norm! 0v6g$y
3534 call assert_equal(40, col("'>"))
3535 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3536 \ '2 foobar foobar foobar foobar foobar foo', getreg(0))
3537 set nowrap
3538 " clean up
3539 norm! gg
3540 norm! 0vg$y
3541 call assert_equal(20, col("'>"))
3542 call assert_equal('1 foobar foobar foob', getreg(0))
3543 norm! gg
3544 norm! 0v4g$y
3545 call assert_equal(20, col("'>"))
3546 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3547 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3548 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3549 \ '4 foobar foobar foob', getreg(0))
3550 norm! gg
3551 norm! 0v6g$y
3552 call assert_equal(20, col("'>"))
3553 call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3554 \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3555 \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3556 \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3557 \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n"..
3558 \ '6 foobar foobar foob', getreg(0))
3559 " Move to last line, also down movement is not possible, should still move
3560 " the cursor to the last visible char
3561 norm! G
3562 norm! 0v6g$y
3563 call assert_equal(20, col("'>"))
3564 call assert_equal('100 foobar foobar fo', getreg(0))
3565 bw!
3566endfunc
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003567
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003568func Test_normal_gk_gj()
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003569 " needs 80 column new window
3570 new
3571 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003572 call assert_beeps('normal gk')
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003573 put =[repeat('x',90)..' {{{1', 'x {{{1']
3574 norm! gk
3575 " In a 80 column wide terminal the window will be only 78 char
3576 " (because Vim will leave space for the other window),
3577 " but if the terminal is larger, it will be 80 chars, so verify the
3578 " cursor column correctly.
3579 call assert_equal(winwidth(0)+1, col('.'))
3580 call assert_equal(winwidth(0)+1, virtcol('.'))
3581 norm! j
3582 call assert_equal(6, col('.'))
3583 call assert_equal(6, virtcol('.'))
3584 norm! gk
3585 call assert_equal(95, col('.'))
3586 call assert_equal(95, virtcol('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003587 %bw!
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003588
3589 " needs 80 column new window
3590 new
3591 vert 80new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003592 call assert_beeps('normal gj')
Bram Moolenaarceba3dd2019-10-12 16:12:54 +02003593 set number
3594 set numberwidth=10
3595 set cpoptions+=n
3596 put =[repeat('0',90), repeat('1',90)]
3597 norm! 075l
3598 call assert_equal(76, col('.'))
3599 norm! gk
3600 call assert_equal(1, col('.'))
3601 norm! gk
3602 call assert_equal(76, col('.'))
3603 norm! gk
3604 call assert_equal(1, col('.'))
3605 norm! gj
3606 call assert_equal(76, col('.'))
3607 norm! gj
3608 call assert_equal(1, col('.'))
3609 norm! gj
3610 call assert_equal(76, col('.'))
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003611 " When 'nowrap' is set, gk and gj behave like k and j
3612 set nowrap
3613 normal! gk
3614 call assert_equal([2, 76], [line('.'), col('.')])
3615 normal! gj
3616 call assert_equal([3, 76], [line('.'), col('.')])
3617 %bw!
3618 set cpoptions& number& numberwidth& wrap&
Bram Moolenaar03ac52f2019-09-24 22:47:46 +02003619endfunc
Bram Moolenaarf0cee192020-02-16 13:33:56 +01003620
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003621" Test for using : to run a multi-line Ex command in operator pending mode
3622func Test_normal_yank_with_excmd()
3623 new
3624 call setline(1, ['foo', 'bar', 'baz'])
3625 let @a = ''
3626 call feedkeys("\"ay:if v:true\<CR>normal l\<CR>endif\<CR>", 'xt')
3627 call assert_equal('f', @a)
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003628
3629 bwipe!
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003630endfunc
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003631
3632" Test for supplying a count to a normal-mode command across a cursorhold call
3633func Test_normal_cursorhold_with_count()
3634 func s:cHold()
3635 let g:cHold_Called += 1
3636 endfunc
3637 new
3638 augroup normalcHoldTest
3639 au!
3640 au CursorHold <buffer> call s:cHold()
3641 augroup END
3642 let g:cHold_Called = 0
3643 call feedkeys("3\<CursorHold>2ix", 'xt')
3644 call assert_equal(1, g:cHold_Called)
3645 call assert_equal(repeat('x', 32), getline(1))
3646 augroup normalcHoldTest
3647 au!
3648 augroup END
3649 au! normalcHoldTest
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003650
3651 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003652 delfunc s:cHold
3653endfunc
3654
3655" Test for using a count and a command with CTRL-W
3656func Test_wincmd_with_count()
3657 call feedkeys("\<C-W>12n", 'xt')
3658 call assert_equal(12, winheight(0))
3659endfunc
3660
3661" Test for 'b', 'B' 'ge' and 'gE' commands
Bram Moolenaar1671f442020-03-10 07:48:13 +01003662func Test_horiz_motion()
3663 new
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003664 normal! gg
3665 call assert_beeps('normal! b')
3666 call assert_beeps('normal! B')
3667 call assert_beeps('normal! gE')
3668 call assert_beeps('normal! ge')
Bram Moolenaar1671f442020-03-10 07:48:13 +01003669 " <S-Backspace> moves one word left and <C-Backspace> moves one WORD left
3670 call setline(1, 'one ,two ,three')
3671 exe "normal! $\<S-BS>"
3672 call assert_equal(11, col('.'))
3673 exe "normal! $\<C-BS>"
3674 call assert_equal(10, col('.'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003675
3676 bwipe!
Bram Moolenaar1671f442020-03-10 07:48:13 +01003677endfunc
3678
zeertzjq30b6d612023-05-07 17:39:23 +01003679" Test for using a ":" command in operator pending mode
Bram Moolenaar1671f442020-03-10 07:48:13 +01003680func Test_normal_colon_op()
3681 new
3682 call setline(1, ['one', 'two'])
3683 call assert_beeps("normal! Gc:d\<CR>")
zeertzjq30b6d612023-05-07 17:39:23 +01003684 call assert_equal(['one'], getline(1, '$'))
3685
3686 call setline(1, ['one…two…three!'])
3687 normal! $
3688 " Using ":" as a movement is characterwise exclusive
3689 call feedkeys("d:normal! F…\<CR>", 'xt')
3690 call assert_equal(['one…two!'], getline(1, '$'))
3691 " Check that redoing a command with 0x80 bytes works
3692 call feedkeys('.', 'xt')
3693 call assert_equal(['one!'], getline(1, '$'))
3694
3695 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3696 " Add this to the command history
3697 call feedkeys(":normal! G0\<CR>", 'xt')
3698 " Use :normal! with control characters in operator pending mode
3699 call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
3700 call assert_equal(['one', 'two', 'five'], getline(1, '$'))
3701 " Check that redoing a command with control characters works
3702 call feedkeys('.', 'xt')
3703 call assert_equal(['five'], getline(1, '$'))
3704
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003705 bwipe!
Bram Moolenaarf5f1e102020-03-08 05:13:15 +01003706endfunc
3707
Bram Moolenaar004a6782020-04-11 17:09:31 +02003708" Test for d and D commands
3709func Test_normal_delete_cmd()
3710 new
3711 " D in an empty line
3712 call setline(1, '')
3713 normal D
3714 call assert_equal('', getline(1))
3715 " D in an empty line in virtualedit mode
3716 set virtualedit=all
3717 normal D
3718 call assert_equal('', getline(1))
3719 set virtualedit&
3720 " delete to a readonly register
3721 call setline(1, ['abcd'])
3722 call assert_beeps('normal ":d2l')
Bram Moolenaar6fd367a2021-03-13 13:14:04 +01003723
3724 " D and d with 'nomodifiable'
3725 call setline(1, ['abcd'])
3726 setlocal nomodifiable
3727 call assert_fails('normal D', 'E21:')
3728 call assert_fails('normal d$', 'E21:')
3729
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003730 bwipe!
Bram Moolenaar004a6782020-04-11 17:09:31 +02003731endfunc
3732
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003733" Test for deleting or changing characters across lines with 'whichwrap'
3734" containing 's'. Should count <EOL> as one character.
3735func Test_normal_op_across_lines()
3736 new
3737 set whichwrap&
3738 call setline(1, ['one two', 'three four'])
3739 exe "norm! $3d\<Space>"
3740 call assert_equal(['one twhree four'], getline(1, '$'))
3741
3742 call setline(1, ['one two', 'three four'])
3743 exe "norm! $3c\<Space>x"
3744 call assert_equal(['one twxhree four'], getline(1, '$'))
3745
3746 set whichwrap+=l
3747 call setline(1, ['one two', 'three four'])
3748 exe "norm! $3x"
3749 call assert_equal(['one twhree four'], getline(1, '$'))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003750
3751 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003752 set whichwrap&
3753endfunc
3754
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003755" Test for 'w' and 'b' commands
3756func Test_normal_word_move()
3757 new
3758 call setline(1, ['foo bar a', '', 'foo bar b'])
3759 " copy a single character word at the end of a line
3760 normal 1G$yw
3761 call assert_equal('a', @")
3762 " copy a single character word at the end of a file
3763 normal G$yw
3764 call assert_equal('b', @")
3765 " check for a word movement handling an empty line properly
3766 normal 1G$vwy
3767 call assert_equal("a\n\n", @")
3768
3769 " copy using 'b' command
3770 %d
3771 " non-empty blank line at the start of file
3772 call setline(1, [' ', 'foo bar'])
3773 normal 2Gyb
3774 call assert_equal(" \n", @")
3775 " try to copy backwards from the start of the file
3776 call setline(1, ['one two', 'foo bar'])
3777 call assert_beeps('normal ggyb')
3778 " 'b' command should stop at an empty line
3779 call setline(1, ['one two', '', 'foo bar'])
3780 normal 3Gyb
3781 call assert_equal("\n", @")
3782 normal 3Gy2b
3783 call assert_equal("two\n", @")
3784 " 'b' command should not stop at a non-empty blank line
3785 call setline(1, ['one two', ' ', 'foo bar'])
3786 normal 3Gyb
3787 call assert_equal("two\n ", @")
3788
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003789 bwipe!
Bram Moolenaar224a5f12020-04-28 20:29:07 +02003790endfunc
3791
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003792" Test for 'scrolloff' with a long line that doesn't fit in the screen
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003793func Test_normal_scrolloff()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003794 10new
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003795 60vnew
3796 call setline(1, ' 1 ' .. repeat('a', 57)
3797 \ .. ' 2 ' .. repeat('b', 57)
3798 \ .. ' 3 ' .. repeat('c', 57)
3799 \ .. ' 4 ' .. repeat('d', 57)
3800 \ .. ' 5 ' .. repeat('e', 57)
3801 \ .. ' 6 ' .. repeat('f', 57)
3802 \ .. ' 7 ' .. repeat('g', 57)
3803 \ .. ' 8 ' .. repeat('h', 57)
3804 \ .. ' 9 ' .. repeat('i', 57)
3805 \ .. '10 ' .. repeat('j', 57)
3806 \ .. '11 ' .. repeat('k', 57)
3807 \ .. '12 ' .. repeat('l', 57)
3808 \ .. '13 ' .. repeat('m', 57)
3809 \ .. '14 ' .. repeat('n', 57)
3810 \ .. '15 ' .. repeat('o', 57)
3811 \ .. '16 ' .. repeat('p', 57)
3812 \ .. '17 ' .. repeat('q', 57)
3813 \ .. '18 ' .. repeat('r', 57)
3814 \ .. '19 ' .. repeat('s', 57)
3815 \ .. '20 ' .. repeat('t', 57)
3816 \ .. '21 ' .. repeat('u', 57)
3817 \ .. '22 ' .. repeat('v', 57)
3818 \ .. '23 ' .. repeat('w', 57)
3819 \ .. '24 ' .. repeat('x', 57)
3820 \ .. '25 ' .. repeat('y', 57)
3821 \ .. '26 ' .. repeat('z', 57)
3822 \ )
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003823 set scrolloff=10
3824 normal gg10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003825 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003826 normal 10gj
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003827 call assert_equal(6, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003828 normal 10gk
Bram Moolenaar4b6172e2022-10-13 20:23:28 +01003829 call assert_equal(6, winline())
3830 normal 0
3831 call assert_equal(1, winline())
3832 normal $
3833 call assert_equal(10, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003834
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003835 set scrolloff&
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003836 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003837endfunc
3838
3839" Test for vertical scrolling with CTRL-F and CTRL-B with a long line
3840func Test_normal_vert_scroll_longline()
3841 10new
3842 80vnew
3843 call setline(1, range(1, 10))
3844 call append(5, repeat('a', 1000))
3845 exe "normal gg\<C-F>"
3846 call assert_equal(6, line('.'))
3847 exe "normal \<C-F>\<C-F>"
3848 call assert_equal(11, line('.'))
3849 call assert_equal(1, winline())
3850 exe "normal \<C-B>"
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02003851 call assert_equal(11, line('.'))
3852 call assert_equal(5, winline())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003853 exe "normal \<C-B>\<C-B>"
3854 call assert_equal(5, line('.'))
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01003855 call assert_equal(5, winline())
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003856
3857 bwipe!
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003858endfunc
3859
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003860" Test for jumping in a file using %
3861func Test_normal_percent_jump()
3862 new
3863 call setline(1, range(1, 100))
3864
3865 " jumping to a folded line should open the fold
3866 25,75fold
3867 call feedkeys('50%', 'xt')
3868 call assert_equal(50, line('.'))
3869 call assert_equal(-1, foldclosedend(50))
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003870
3871 bwipe!
Bram Moolenaar8a9bc952020-10-02 18:48:07 +02003872endfunc
3873
Bram Moolenaar3e72dca2021-05-29 16:30:12 +02003874" Test for << and >> commands to shift text by 'shiftwidth'
3875func Test_normal_shift_rightleft()
3876 new
3877 call setline(1, ['one', '', "\t", ' two', "\tthree", ' four'])
3878 set shiftwidth=2 tabstop=8
3879 normal gg6>>
3880 call assert_equal([' one', '', "\t ", ' two', "\t three", "\tfour"],
3881 \ getline(1, '$'))
3882 normal ggVG2>>
3883 call assert_equal([' one', '', "\t ", "\ttwo",
3884 \ "\t three", "\t four"], getline(1, '$'))
3885 normal gg6<<
3886 call assert_equal([' one', '', "\t ", ' two', "\t three",
3887 \ "\t four"], getline(1, '$'))
3888 normal ggVG2<<
3889 call assert_equal(['one', '', "\t", ' two', "\tthree", ' four'],
3890 \ getline(1, '$'))
3891 set shiftwidth& tabstop&
3892 bw!
3893endfunc
3894
Yegappan Lakshmanan2ac71842021-05-31 19:23:01 +02003895" Some commands like yy, cc, dd, >>, << and !! accept a count after
3896" typing the first letter of the command.
3897func Test_normal_count_after_operator()
3898 new
3899 setlocal shiftwidth=4 tabstop=8 autoindent
3900 call setline(1, ['one', 'two', 'three', 'four', 'five'])
3901 let @a = ''
3902 normal! j"ay4y
3903 call assert_equal("two\nthree\nfour\nfive\n", @a)
3904 normal! 3G>2>
3905 call assert_equal(['one', 'two', ' three', ' four', 'five'],
3906 \ getline(1, '$'))
3907 exe "normal! 3G0c2cred\nblue"
3908 call assert_equal(['one', 'two', ' red', ' blue', 'five'],
3909 \ getline(1, '$'))
3910 exe "normal! gg<8<"
3911 call assert_equal(['one', 'two', 'red', 'blue', 'five'],
3912 \ getline(1, '$'))
3913 exe "normal! ggd3d"
3914 call assert_equal(['blue', 'five'], getline(1, '$'))
3915 call setline(1, range(1, 4))
3916 call feedkeys("gg!3!\<C-B>\"\<CR>", 'xt')
3917 call assert_equal('".,.+2!', @:)
3918 call feedkeys("gg!1!\<C-B>\"\<CR>", 'xt')
3919 call assert_equal('".!', @:)
3920 call feedkeys("gg!9!\<C-B>\"\<CR>", 'xt')
3921 call assert_equal('".,$!', @:)
3922 bw!
3923endfunc
3924
Christian Brabandtaaec1d42021-11-04 13:28:29 +00003925func Test_normal_gj_on_extra_wide_char()
3926 new | 25vsp
3927 let text='1 foooooooo ar e ins‍zwe1 foooooooo ins‍zwei' .
3928 \ ' i drei vier fünf sechs sieben acht un zehn elf zwöfl' .
3929 \ ' dreizehn v ierzehn fünfzehn'
3930 put =text
3931 call cursor(2,1)
3932 norm! gj
3933 call assert_equal([0,2,25,0], getpos('.'))
3934 bw!
3935endfunc
3936
Bram Moolenaar03725c52021-11-24 12:17:53 +00003937func Test_normal_count_out_of_range()
3938 new
3939 call setline(1, 'text')
3940 normal 44444444444|
3941 call assert_equal(999999999, v:count)
3942 normal 444444444444|
3943 call assert_equal(999999999, v:count)
3944 normal 4444444444444|
3945 call assert_equal(999999999, v:count)
3946 normal 4444444444444444444|
3947 call assert_equal(999999999, v:count)
3948
3949 normal 9y99999999|
3950 call assert_equal(899999991, v:count)
3951 normal 10y99999999|
3952 call assert_equal(999999999, v:count)
3953 normal 44444444444y44444444444|
3954 call assert_equal(999999999, v:count)
3955 bwipe!
3956endfunc
3957
zeertzjqcdeb6572022-11-15 13:46:12 +00003958" Test that mouse shape is restored to Normal mode after failed "c" operation.
3959func Test_mouse_shape_after_failed_change()
3960 CheckFeature mouseshape
3961 CheckCanRunGui
3962
3963 let lines =<< trim END
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003964 vim9script
zeertzjqcdeb6572022-11-15 13:46:12 +00003965 set mouseshape+=o:busy
3966 setlocal nomodifiable
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003967 var mouse_shapes = []
zeertzjqcdeb6572022-11-15 13:46:12 +00003968
Yee Cheng Chin1881abf2022-12-08 09:41:24 +00003969 feedkeys('c')
3970 timer_start(50, (_) => {
3971 mouse_shapes += [getmouseshape()]
3972 timer_start(50, (_) => {
3973 feedkeys('c')
3974 timer_start(50, (_) => {
3975 mouse_shapes += [getmouseshape()]
3976 timer_start(50, (_) => {
3977 writefile(mouse_shapes, 'Xmouseshapes')
3978 quit
3979 })
3980 })
3981 })
3982 })
zeertzjqcdeb6572022-11-15 13:46:12 +00003983 END
3984 call writefile(lines, 'Xmouseshape.vim', 'D')
3985 call RunVim([], [], "-g -S Xmouseshape.vim")
Yee Cheng Chin24078e32024-11-12 20:26:48 +01003986 call WaitForAssert({-> assert_equal(['busy', 'arrow'], readfile('Xmouseshapes'))}, 300)
zeertzjqcdeb6572022-11-15 13:46:12 +00003987
3988 call delete('Xmouseshapes')
3989endfunc
3990
zeertzjqf86dea82023-03-05 21:15:06 +00003991" Test that mouse shape is restored to Normal mode after cancelling "gr".
3992func Test_mouse_shape_after_cancelling_gr()
3993 CheckFeature mouseshape
3994 CheckCanRunGui
3995
3996 let lines =<< trim END
3997 vim9script
3998 var mouse_shapes = []
3999
4000 feedkeys('gr')
4001 timer_start(50, (_) => {
4002 mouse_shapes += [getmouseshape()]
4003 timer_start(50, (_) => {
4004 feedkeys("\<Esc>")
4005 timer_start(50, (_) => {
4006 mouse_shapes += [getmouseshape()]
4007 timer_start(50, (_) => {
4008 writefile(mouse_shapes, 'Xmouseshapes')
4009 quit
4010 })
4011 })
4012 })
4013 })
4014 END
4015 call writefile(lines, 'Xmouseshape.vim', 'D')
4016 call RunVim([], [], "-g -S Xmouseshape.vim")
Yee Cheng Chin24078e32024-11-12 20:26:48 +01004017 call WaitForAssert({-> assert_equal(['beam', 'arrow'], readfile('Xmouseshapes'))}, 300)
zeertzjqf86dea82023-03-05 21:15:06 +00004018
4019 call delete('Xmouseshapes')
4020endfunc
4021
Luuk van Baalaa6ba302023-05-09 16:01:17 +01004022" Test that "j" does not skip lines when scrolling below botline and
4023" 'foldmethod' is not "manual".
4024func Test_normal_j_below_botline()
4025 CheckScreendump
4026
4027 let lines =<< trim END
4028 set number foldmethod=diff scrolloff=0
4029 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
4030 norm Lj
4031 END
4032 call writefile(lines, 'XNormalJBelowBotline', 'D')
4033 let buf = RunVimInTerminal('-S XNormalJBelowBotline', #{rows: 19, cols: 40})
4034
4035 call VerifyScreenDump(buf, 'Test_normal_j_below_botline', {})
4036
4037 call StopVimInTerminal(buf)
4038endfunc
4039
Christian Brabandt2d63e4b2023-08-12 00:03:57 +02004040" Test for r (replace) command with CTRL_V and CTRL_Q
4041func Test_normal_r_ctrl_v_cmd()
4042 new
4043 call append(0, 'This is a simple test: abcd')
4044 exe "norm! 1gg$r\<C-V>\<C-V>"
4045 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4046 exe "norm! 1gg$hr\<C-Q>\<C-Q>"
4047 call assert_equal(['This is a simple test: ab', ''], getline(1,'$'))
4048 exe "norm! 1gg$2hr\<C-V>x7e"
4049 call assert_equal(['This is a simple test: a~', ''], getline(1,'$'))
4050 exe "norm! 1gg$3hr\<C-Q>x7e"
4051 call assert_equal(['This is a simple test: ~~', ''], getline(1,'$'))
4052
4053 if &encoding == 'utf-8'
4054 exe "norm! 1gg$4hr\<C-V>u20ac"
4055 call assert_equal(['This is a simple test:€~~', ''], getline(1,'$'))
4056 exe "norm! 1gg$5hr\<C-Q>u20ac"
4057 call assert_equal(['This is a simple test€€~~', ''], getline(1,'$'))
4058 exe "norm! 1gg0R\<C-V>xff WAS \<esc>"
4059 call assert_equal(['ÿ WAS a simple test€€~~', ''], getline(1,'$'))
4060 exe "norm! 1gg0elR\<C-Q>xffNOT\<esc>"
4061 call assert_equal(['ÿ WASÿNOT simple test€€~~', ''], getline(1,'$'))
4062 endif
4063
4064 call setline(1, 'This is a simple test: abcd')
4065 exe "norm! 1gg$gr\<C-V>\<C-V>"
4066 call assert_equal(['This is a simple test: abc', ''], getline(1,'$'))
4067 exe "norm! 1gg$hgr\<C-Q>\<C-Q>"
4068 call assert_equal(['This is a simple test: ab ', ''], getline(1,'$'))
4069 exe "norm! 1gg$2hgr\<C-V>x7e"
4070 call assert_equal(['This is a simple test: a~ ', ''], getline(1,'$'))
4071 exe "norm! 1gg$3hgr\<C-Q>x7e"
4072 call assert_equal(['This is a simple test: ~~ ', ''], getline(1,'$'))
4073
4074 " clean up
4075 bw!
4076endfunc
4077
zeertzjqb25dbb32023-08-13 18:11:05 +02004078" Test clicking on a TAB or an unprintable character in Normal mode
4079func Test_normal_click_on_ctrl_char()
4080 let save_mouse = &mouse
4081 set mouse=a
4082 new
4083
4084 call setline(1, "a\<Tab>b\<C-K>c")
4085 redraw
4086 call test_setmouse(1, 1)
4087 call feedkeys("\<LeftMouse>", 'xt')
4088 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4089 call test_setmouse(1, 2)
4090 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004091 call assert_equal([0, 1, 2, 0, 2], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004092 call test_setmouse(1, 3)
4093 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004094 call assert_equal([0, 1, 2, 0, 3], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004095 call test_setmouse(1, 7)
4096 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004097 call assert_equal([0, 1, 2, 0, 7], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004098 call test_setmouse(1, 8)
4099 call feedkeys("\<LeftMouse>", 'xt')
4100 call assert_equal([0, 1, 2, 0, 8], getcurpos())
4101 call test_setmouse(1, 9)
4102 call feedkeys("\<LeftMouse>", 'xt')
4103 call assert_equal([0, 1, 3, 0, 9], getcurpos())
4104 call test_setmouse(1, 10)
4105 call feedkeys("\<LeftMouse>", 'xt')
4106 call assert_equal([0, 1, 4, 0, 10], getcurpos())
4107 call test_setmouse(1, 11)
4108 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004109 call assert_equal([0, 1, 4, 0, 11], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004110 call test_setmouse(1, 12)
4111 call feedkeys("\<LeftMouse>", 'xt')
4112 call assert_equal([0, 1, 5, 0, 12], getcurpos())
4113 call test_setmouse(1, 13)
4114 call feedkeys("\<LeftMouse>", 'xt')
zeertzjqe500ae82023-08-17 22:35:26 +02004115 call assert_equal([0, 1, 5, 0, 13], getcurpos())
zeertzjqb25dbb32023-08-13 18:11:05 +02004116
4117 bwipe!
4118 let &mouse = save_mouse
4119endfunc
4120
zeertzjq99941602023-08-19 13:08:50 +02004121" Test clicking on a double-width character in Normal mode
4122func Test_normal_click_on_double_width_char()
4123 let save_mouse = &mouse
4124 set mouse=a
4125 new
4126
4127 call setline(1, "口口")
4128 redraw
4129 call test_setmouse(1, 1)
4130 call feedkeys("\<LeftMouse>", 'xt')
4131 call assert_equal([0, 1, 1, 0, 1], getcurpos())
4132 call test_setmouse(1, 2)
4133 call feedkeys("\<LeftMouse>", 'xt')
4134 call assert_equal([0, 1, 1, 0, 2], getcurpos())
4135 call test_setmouse(1, 3)
4136 call feedkeys("\<LeftMouse>", 'xt')
4137 call assert_equal([0, 1, 4, 0, 3], getcurpos())
4138 call test_setmouse(1, 4)
4139 call feedkeys("\<LeftMouse>", 'xt')
4140 call assert_equal([0, 1, 4, 0, 4], getcurpos())
4141
4142 bwipe!
4143 let &mouse = save_mouse
4144endfunc
4145
zeertzjq03cd6972023-09-20 20:08:40 +02004146func Test_normal_click_on_empty_line()
4147 let save_mouse = &mouse
4148 set mouse=a
4149 botright new
4150 call setline(1, ['', '', ''])
4151 let row = win_screenpos(0)[0] + 2
4152 20vsplit
4153 redraw
4154
4155 call test_setmouse(row, 1)
4156 call feedkeys("\<LeftMouse>", 'xt')
4157 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4158 call test_setmouse(row, 2)
4159 call feedkeys("\<LeftMouse>", 'xt')
4160 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4161 call test_setmouse(row, 10)
4162 call feedkeys("\<LeftMouse>", 'xt')
4163 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4164
4165 call test_setmouse(row, 21 + 1)
4166 call feedkeys("\<LeftMouse>", 'xt')
4167 call assert_equal([0, 3, 1, 0, 1], getcurpos())
4168 call test_setmouse(row, 21 + 2)
4169 call feedkeys("\<LeftMouse>", 'xt')
4170 call assert_equal([0, 3, 1, 0, 2], getcurpos())
4171 call test_setmouse(row, 21 + 10)
4172 call feedkeys("\<LeftMouse>", 'xt')
4173 call assert_equal([0, 3, 1, 0, 10], getcurpos())
4174
4175 bwipe!
4176 let &mouse = save_mouse
4177endfunc
4178
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004179func Test_normal33_g_cmd_nonblank()
zeertzjq654bdbb2023-08-20 18:24:20 +02004180 " Test that g<End> goes to the last non-blank char and g$ to the last
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004181 " visible column
4182 20vnew
4183 setlocal nowrap nonumber signcolumn=no
4184 call setline(1, ['fooo fooo fooo fooo fooo fooo fooo fooo '])
zeertzjq654bdbb2023-08-20 18:24:20 +02004185 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004186 call assert_equal(11, col('.'))
4187 normal 0g$
4188 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004189 exe "normal 0g\<kEnd>"
4190 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004191 setlocal wrap
zeertzjq654bdbb2023-08-20 18:24:20 +02004192 exe "normal 0g\<End>"
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004193 call assert_equal(11, col('.'))
4194 normal 0g$
4195 call assert_equal(20, col('.'))
zeertzjq654bdbb2023-08-20 18:24:20 +02004196 exe "normal 0g\<kEnd>"
4197 call assert_equal(11, col('.'))
Christian Brabandtb5f6fe92023-08-19 15:53:16 +02004198 bw!
4199endfunc
4200
Christian Brabandt58f9bef2023-11-14 21:02:30 +01004201func Test_normal34_zet_large()
4202 " shouldn't cause overflow
4203 norm! z9765405999999999999
4204endfunc
4205
zeertzjqad493ef2024-03-29 10:23:19 +01004206" Test for { and } paragraph movements in a single line
4207func Test_brace_single_line()
4208 new
4209 call setline(1, ['foobar one two three'])
4210 1
4211 norm! 0}
4212
4213 call assert_equal([0, 1, 20, 0], getpos('.'))
4214 norm! {
4215 call assert_equal([0, 1, 1, 0], getpos('.'))
4216 bw!
4217endfunc
4218
4219" Test for Ctrl-B/Ctrl-U in buffer with a single line
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004220func Test_single_line_scroll()
4221 CheckFeature textprop
Gary Johnson9e6549d2023-12-27 19:12:43 +01004222
4223 new
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004224 call setline(1, ['foobar one two three'])
4225 let vt = 'virt_above'
4226 call prop_type_add(vt, {'highlight': 'IncSearch'})
4227 call prop_add(1, 0, {'type': vt, 'text': '---', 'text_align': 'above'})
zeertzjqad493ef2024-03-29 10:23:19 +01004228 call cursor(1, 1)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004229
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004230 " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004231 set smoothscroll
4232 exe "normal \<C-E>"
4233 call assert_notequal(0, winsaveview().skipcol)
4234 exe "normal \<C-B>"
4235 call assert_equal(0, winsaveview().skipcol)
Luuk van Baal5a2e3ec2024-03-28 10:07:29 +01004236 exe "normal \<C-E>"
4237 call assert_notequal(0, winsaveview().skipcol)
4238 exe "normal \<C-U>"
4239 call assert_equal(0, winsaveview().skipcol)
Luuk van Baalb9f5b952024-03-26 18:46:45 +01004240
4241 set smoothscroll&
Gary Johnson9e6549d2023-12-27 19:12:43 +01004242 bw!
zeertzjqad493ef2024-03-29 10:23:19 +01004243 call prop_type_delete(vt)
Gary Johnson9e6549d2023-12-27 19:12:43 +01004244endfunc
4245
Luuk van Baalbd28cae2024-04-03 22:50:40 +02004246" Test for zb in buffer with a single line and filler lines
4247func Test_single_line_filler_zb()
4248 call setline(1, ['', 'foobar one two three'])
4249 diffthis
4250 new
4251 call setline(1, ['foobar one two three'])
4252 diffthis
4253
4254 " zb scrolls to reveal filler lines at the start of the buffer.
4255 exe "normal \<C-E>zb"
4256 call assert_equal(1, winsaveview().topfill)
4257
4258 bw!
4259endfunc
4260
Luuk van Baal78c51502024-04-09 21:30:19 +02004261" Test for Ctrl-U not getting stuck at end of buffer with 'scrolloff'.
4262func Test_halfpage_scrolloff_eob()
4263 set scrolloff=5
4264
4265 call setline(1, range(1, 100))
4266 exe "norm! Gzz\<C-U>zz"
4267 call assert_notequal(100, line('.'))
4268
4269 set scrolloff&
4270 bwipe!
4271endfunc
4272
Luuk van Baalaa8e22b2024-04-10 17:33:43 +02004273" Test for Ctrl-U/D moving the cursor at the buffer boundaries.
4274func Test_halfpage_cursor_startend()
4275 call setline(1, range(1, 100))
4276 exe "norm! jztj\<C-U>"
4277 call assert_equal(1, line('.'))
4278 exe "norm! G\<C-Y>k\<C-D>"
4279 call assert_equal(100, line('.'))
4280 bwipe!
4281endfunc
4282
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02004283" Test for Ctrl-F/B moving the cursor to the window boundaries.
4284func Test_page_cursor_topbot()
4285 10new
4286 call setline(1, range(1, 100))
4287 exe "norm! gg2\<C-F>"
4288 call assert_equal(17, line('.'))
4289 exe "norm! \<C-B>"
4290 call assert_equal(18, line('.'))
4291 exe "norm! \<C-B>\<C-F>"
4292 call assert_equal(9, line('.'))
Luuk van Baal8ccb8902024-07-04 17:35:56 +02004293 " Not when already at the start of the buffer.
4294 exe "norm! ggj\<C-B>"
4295 call assert_equal(2, line('.'))
Luuk van Baal4b6b0c42024-04-20 17:38:20 +02004296 bwipe!
4297endfunc
4298
Luuk van Baal58448e02024-05-11 11:27:52 +02004299" Test for Ctrl-D with long line
4300func Test_halfpage_longline()
4301 10new
zeertzjqfa117382024-09-29 10:14:32 +02004302 40vsplit
Luuk van Baal58448e02024-05-11 11:27:52 +02004303 call setline(1, ['long'->repeat(1000), 'short'])
4304 exe "norm! \<C-D>"
4305 call assert_equal(2, line('.'))
4306 bwipe!
4307endfunc
Christian Brabandteff20eb2024-05-15 21:35:36 +02004308
4309" Test for Ctrl-E with long line and very narrow window,
zeertzjq8feed3a2024-09-29 10:37:47 +02004310" used to cause an infinite loop
Christian Brabandteff20eb2024-05-15 21:35:36 +02004311func Test_scroll_longline_no_loop()
4312 4vnew
4313 setl smoothscroll number showbreak=> scrolloff=2
4314 call setline(1, repeat(['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'], 3))
4315 exe "normal! \<C-E>"
4316 bwipe!
4317endfunc
Christian Brabandtf8702ae2024-08-28 20:39:24 +02004318
4319" Test for go command
4320func Test_normal_go()
4321 new
4322 call setline(1, ['one two three four'])
4323 call cursor(1, 5)
4324 norm! dvgo
4325 call assert_equal('wo three four', getline(1))
4326 norm! ...
4327 call assert_equal('three four', getline(1))
4328
4329 bwipe!
4330endfunc
zeertzjqdf098fe2025-01-22 22:27:30 +01004331
Luuk van Baalc9825032025-04-13 17:45:34 +02004332" Test for Ctrl-D with 'scrolloff' and narrow window does not get stuck.
4333func Test_scroll_longline_scrolloff()
4334 11new
4335 36vsplit
4336 set scrolloff=5
4337
4338 call setline(1, ['']->repeat(5))
4339 call setline(6, ['foo'->repeat(20)]->repeat(2))
4340 call setline(8, ['bar'->repeat(30)])
4341 call setline(9, ['']->repeat(5))
4342 exe "normal! \<C-D>"
4343 call assert_equal(6, line('w0'))
4344 exe "normal! \<C-D>"
4345 call assert_equal(7, line('w0'))
4346
4347 set scrolloff&
4348 bwipe!
4349endfunc
4350
Luuk van Baalacf0ebe2025-05-12 20:45:41 +02004351" Benchmark test for Ctrl-F with 'nosmoothscroll'
4352func Test_scroll_longline_benchmark()
4353 call setline(1, ['foo'->repeat(20000)] + [''])
4354 let start = reltime()
4355 exe "normal! \<C-F>"
4356 call assert_inrange(0, 0.1, reltimefloat(reltime(start)))
4357 bwipe!
4358endfunc
4359
Luuk van Baalc6c72d12025-05-14 20:21:55 +02004360" Test Ctrl-B with 'nosmoothscroll' not stuck with line exactly window width.
4361func Test_scroll_longline_winwidth()
4362 10new
4363 call setline(1, ['']->repeat(20) + ['A'->repeat(20 * winwidth(0))] + ['']->repeat(20))
4364 exe "normal! G3\<C-B>"
4365 call assert_equal(22, line('w0'))
4366 exe "normal! \<C-B>"
4367 call assert_equal(21, line('w0'))
4368 exe "normal! \<C-B>"
4369 call assert_equal(11, line('w0'))
4370 exe "normal! \<C-B>"
4371 call assert_equal(3, line('w0'))
4372 exe "normal! \<C-B>"
4373 call assert_equal(1, line('w0'))
4374 bwipe!
4375endfunc
4376
Emir SARI8fe9e552025-06-25 20:22:43 +02004377func Test_pos_percentage_in_turkish_locale()
Emir SARI8fe9e552025-06-25 20:22:43 +02004378 CheckRunVimInTerminal
Christian Brabandt22318932025-06-26 23:04:37 +02004379 CheckNotMac
Emir SARI8fe9e552025-06-25 20:22:43 +02004380 defer execute(':lang C')
4381
4382 try
4383 let dir = expand('$VIMRUNTIME/lang/tr/')
4384 let target = expand('$VIMRUNTIME/lang/tr/LC_MESSAGES/')
4385 let tr = '../po/tr.mo'
4386 call mkdir(dir, 'R')
4387 call mkdir(target, '')
4388 call filecopy(tr, target .. 'vim.mo')
4389 lang tr_TR.UTF-8
4390 let buf = RunVimInTerminal('', {'rows': 5})
4391 call term_sendkeys(buf, ":lang tr_TR.UTF-8\<cr>")
4392 call term_sendkeys(buf, ":put =range(1,40)\<cr>")
4393 call term_sendkeys(buf, ":5\<cr>")
4394 call WaitForAssert({-> assert_match('%8$', term_getline(buf, 5))})
4395
4396 call StopVimInTerminal(buf)
4397 catch /E197:/
4398 " can't use Turkish locale
4399 throw 'Skipped: Turkish locale not available'
4400 endtry
4401endfunc
4402
Christian Brabandt5d5cbb22024-01-05 18:19:52 +01004403" vim: shiftwidth=2 sts=2 expandtab nofoldenable