blob: 34561ffbabbf0941c4d0c986b40d4cd2cb523d05 [file] [log] [blame]
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001" Test for various Normal mode commands
2
3func! Setup_NewWindow()
4 10new
5 call setline(1, range(1,100))
6endfunc
7
8func! MyFormatExpr()
9 " Adds '->$' at lines having numbers followed by trailing whitespace
10 for ln in range(v:lnum, v:lnum+v:count-1)
11 let line = getline(ln)
12 if getline(ln) =~# '\d\s\+$'
13 call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
14 endif
15 endfor
16endfu
17
18function! CountSpaces(type, ...)
19 " for testing operatorfunc
20 " will count the number of spaces
21 " and return the result in g:a
22 let sel_save = &selection
23 let &selection = "inclusive"
24 let reg_save = @@
25
26 if a:0 " Invoked from Visual mode, use gv command.
27 silent exe "normal! gvy"
28 elseif a:type == 'line'
29 silent exe "normal! '[V']y"
30 else
31 silent exe "normal! `[v`]y"
32 endif
33 let g:a=strlen(substitute(@@, '[^ ]', '', 'g'))
34 let &selection = sel_save
35 let @@ = reg_save
36endfunction
37
38fun! Test_normal00_optrans()
39 " Attention: This needs to be the very first test,
40 " it will fail, if it runs later, don't know why!
41 " Test for S s and alike comamnds, that are internally handled aliased
42 new
43 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
44 1
45 exe "norm! Sfoobar\<esc>"
46 call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
47 2
48 " Test does not work
49 " TODO: Why does it not work?
50 " Adds an additional linebreak if used in visual mode...
51 " When run in the test, this returns:
52 " ,--------
53 " |foobar
54 " |2 This is
55 " |the second
56 " |one
57 " |3 this is the third line
58 " `-----------
59 " instead of
60 " ,--------
61 " |foobar
62 " |2 This is the second one
63 " |3 this is the third line
64 " `-----------
65 exe "norm! $vbsone"
66 call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$'))
67 " When run in the test, this returns:
68 " ,--------
69 " |foobar
70 " |Second line
71 " |here
72 " |3 this is the third line
73 " `-----------
74 " instead of
75 " ,--------
76 " |foobar
77 " |Second line here
78 " |3 this is the third line
79 " `-----------
80 norm! VS Second line here
81 call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
82 %d
83 call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
84 call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
85
86 1
87 norm! 2D
88 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,'$'))
89 set cpo+=#
90 norm! 4D
91 call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
92
93 " clean up
94 set cpo-=#
95 bw!
96endfu
97
98func! Test_normal01_keymodel()
99 call Setup_NewWindow()
100 " Test 1: depending on 'keymodel' <s-down> does something different
101 :50
102 call feedkeys("V\<S-Up>y", 'tx')
103 call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
104 :set keymodel=startsel
105 :50
106 call feedkeys("V\<S-Up>y", 'tx')
107 call assert_equal(['49', '50'], getline("'<", "'>"))
108 " Start visual mode when keymodel = startsel
109 :50
110 call feedkeys("\<S-Up>y", 'tx')
111 call assert_equal(['49', '5'], getreg(0, 0, 1))
112 " Do not start visual mode when keymodel=
113 :set keymodel=
114 :50
115 call feedkeys("\<S-Up>y$", 'tx')
116 call assert_equal(['42'], getreg(0, 0, 1))
117
118 " clean up
119 bw!
120endfunc
121
122func! Test_normal02_selectmode()
123 " some basic select mode tests
124 call Setup_NewWindow()
125 50
126 norm! gHy
127 call assert_equal('y51', getline('.'))
128 call setline(1, range(1,100))
129 50
130 exe ":norm! V9jo\<c-g>y"
131 call assert_equal('y60', getline('.'))
132 " clean up
133 bw!
134endfu
135
136func! Test_normal03_join()
137 " basic join test
138 call Setup_NewWindow()
139 50
140 norm! VJ
141 call assert_equal('50 51', getline('.'))
142 $
143 norm! J
144 call assert_equal('100', getline('.'))
145 $
146 norm! V9-gJ
147 call assert_equal('919293949596979899100', getline('.'))
148 call setline(1, range(1,100))
149 $
150 :j 10
151 call assert_equal('100', getline('.'))
152 " clean up
153 bw!
154endfu
155
156func! Test_normal04_filter()
157 " basic filter test
158 " only test on non windows platform
159 if has("win32") || has("win64") || has("win95")
160 return
161 endif
162 call Setup_NewWindow()
163 1
164 call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
165 call assert_equal('| 1', getline('.'))
166 90
167 :sil :!echo one
168 call feedkeys('.', 'tx')
169 call assert_equal('| 90', getline('.'))
170 95
171 set cpo+=!
172 " 2 <CR>, 1: for executing the command,
173 " 2: clear hit-enter-prompt
174 call feedkeys("!!\n", 'tx')
175 call feedkeys(":!echo one\n\n", 'tx')
176 call feedkeys(".", 'tx')
177 call assert_equal('one', getline('.'))
178 set cpo-=!
179 bw!
180endfu
181
182func! Test_normal05_formatexpr()
183 " basic formatexpr test
184 call Setup_NewWindow()
185 %d_
186 call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
187 1
188 set formatexpr=MyFormatExpr()
189 norm! gqG
190 call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
191 set formatexpr=
192 bw!
193endfu
194
Bram Moolenaard77f9d52016-09-04 15:13:39 +0200195func Test_normal05_formatexpr_newbuf()
196 " Edit another buffer in the 'formatexpr' function
197 new
198 func! Format()
199 edit another
200 endfunc
201 set formatexpr=Format()
202 norm gqG
203 bw!
204 set formatexpr=
205endfunc
206
207func Test_normal05_formatexpr_setopt()
208 " Change the 'formatexpr' value in the function
209 new
210 func! Format()
211 set formatexpr=
212 endfunc
213 set formatexpr=Format()
214 norm gqG
215 bw!
216 set formatexpr=
217endfunc
218
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200219func! Test_normal06_formatprg()
220 " basic test for formatprg
221 " only test on non windows platform
222 if has("win32") || has("win64") || has("win95")
223 return
224 else
225 " uses sed to number non-empty lines
226 call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh')
227 call system('chmod +x ./Xsed_format.sh')
228 endif
229 call Setup_NewWindow()
230 %d
231 call setline(1, ['a', '', 'c', '', ' ', 'd', 'e'])
232 set formatprg=./Xsed_format.sh
233 norm! gggqG
234 call assert_equal(['1 a', '', '3 c', '', '5 ', '6 d', '7 e'], getline(1, '$'))
235 " clean up
236 set formatprg=
237 call delete('Xsed_format.sh')
238 bw!
239endfu
240
241func! Test_normal07_internalfmt()
242 " basic test for internal formmatter to textwidth of 12
243 let list=range(1,11)
244 call map(list, 'v:val." "')
245 10new
246 call setline(1, list)
247 set tw=12
248 norm! gggqG
249 call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
250 " clean up
251 set formatprg=
252 bw!
253endfu
254
255func! Test_normal08_fold()
256 " basic tests for foldopen/folddelete
257 if !has("folding")
258 return
259 endif
260 call Setup_NewWindow()
261 50
262 setl foldenable fdm=marker
263 " First fold
264 norm! V4jzf
265 " check that folds have been created
266 call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
267 " Second fold
268 46
269 norm! V10jzf
270 " check that folds have been created
271 call assert_equal('46/*{{{*/', getline(46))
272 call assert_equal('60/*}}}*/', getline(60))
273 norm! k
274 call assert_equal('45', getline('.'))
275 norm! j
276 call assert_equal('46/*{{{*/', getline('.'))
277 norm! j
278 call assert_equal('61', getline('.'))
279 norm! k
280 " open a fold
281 norm! Vzo
282 norm! k
283 call assert_equal('45', getline('.'))
284 norm! j
285 call assert_equal('46/*{{{*/', getline('.'))
286 norm! j
287 call assert_equal('47', getline('.'))
288 norm! k
289 norm! zcVzO
290 call assert_equal('46/*{{{*/', getline('.'))
291 norm! j
292 call assert_equal('47', getline('.'))
293 norm! j
294 call assert_equal('48', getline('.'))
295 norm! j
296 call assert_equal('49', getline('.'))
297 norm! j
298 call assert_equal('50/*{{{*/', getline('.'))
299 norm! j
300 call assert_equal('51', getline('.'))
301 " delete folds
302 :46
303 " collapse fold
304 norm! V14jzC
305 " delete all folds recursively
306 norm! VzD
307 call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
308
309 " clean up
310 setl nofoldenable fdm=marker
311 bw!
312endfu
313
314func! Test_normal09_operatorfunc()
315 " Test operatorfunc
316 call Setup_NewWindow()
317 " Add some spaces for counting
318 50,60s/$/ /
319 unlet! g:a
320 let g:a=0
321 nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
322 vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
323 50
324 norm V2j,,
325 call assert_equal(6, g:a)
326 norm V,,
327 call assert_equal(2, g:a)
328 norm ,,l
329 call assert_equal(0, g:a)
330 50
331 exe "norm 0\<c-v>10j2l,,"
332 call assert_equal(11, g:a)
333 50
334 norm V10j,,
335 call assert_equal(22, g:a)
336
337 " clean up
338 unmap <buffer> ,,
339 set opfunc=
340 bw!
341endfu
342
343func! Test_normal10_expand()
344 " Test for expand()
345 10new
346 call setline(1, ['1', 'ifooar,,cbar'])
347 2
348 norm! $
349 let a=expand('<cword>')
350 let b=expand('<cWORD>')
351 call assert_equal('cbar', a)
352 call assert_equal('ifooar,,cbar', b)
353 " clean up
354 bw!
355endfu
356
357func! Test_normal11_showcmd()
358 " test for 'showcmd'
359 10new
360 exe "norm! ofoobar\<esc>"
361 call assert_equal(2, line('$'))
362 set showcmd
363 exe "norm! ofoobar2\<esc>"
364 call assert_equal(3, line('$'))
365 exe "norm! VAfoobar3\<esc>"
366 call assert_equal(3, line('$'))
367 exe "norm! 0d3\<del>2l"
368 call assert_equal('obar2foobar3', getline('.'))
369 bw!
370endfu
371
372func! Test_normal12_nv_error()
373 " Test for nv_error
374 10new
375 call setline(1, range(1,5))
376 " should not do anything, just beep
377 exe "norm! <c-k>"
378 call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
379 bw!
380endfu
381
382func! Test_normal13_help()
383 " Test for F1
384 call assert_equal(1, winnr())
385 call feedkeys("\<f1>", 'txi')
386 call assert_match('help\.txt', bufname('%'))
387 call assert_equal(2, winnr('$'))
388 bw!
389endfu
390
391func! Test_normal14_page()
392 " basic test for Ctrl-F and Ctrl-B
393 call Setup_NewWindow()
394 exe "norm! \<c-f>"
395 call assert_equal('9', getline('.'))
396 exe "norm! 2\<c-f>"
397 call assert_equal('25', getline('.'))
398 exe "norm! 2\<c-b>"
399 call assert_equal('18', getline('.'))
400 1
401 set scrolloff=5
402 exe "norm! 2\<c-f>"
403 call assert_equal('21', getline('.'))
404 exe "norm! \<c-b>"
405 call assert_equal('13', getline('.'))
406 1
407 set scrolloff=99
408 exe "norm! \<c-f>"
409 call assert_equal('13', getline('.'))
410 set scrolloff=0
411 100
412 exe "norm! $\<c-b>"
413 call assert_equal('92', getline('.'))
414 call assert_equal([0, 92, 1, 0, 1], getcurpos())
415 100
416 set nostartofline
417 exe "norm! $\<c-b>"
418 call assert_equal('92', getline('.'))
419 call assert_equal([0, 92, 2, 0, 2147483647], getcurpos())
420 " cleanup
421 set startofline
422 bw!
423endfu
424
Bram Moolenaarbc54f3f2016-09-04 14:34:28 +0200425func! Test_normal14_page_eol()
426 10new
427 norm oxxxxxxx
428 exe "norm 2\<c-f>"
429 " check with valgrind that cursor is put back in column 1
430 exe "norm 2\<c-b>"
431 bw!
432endfunc
433
Bram Moolenaar87bc3f72016-09-03 17:33:54 +0200434func! Test_normal15_z_scroll_vert()
435 " basic test for z commands that scroll the window
436 call Setup_NewWindow()
437 100
438 norm! >>
439 " Test for z<cr>
440 exe "norm! z\<cr>"
441 call assert_equal(' 100', getline('.'))
442 call assert_equal(100, winsaveview()['topline'])
443 call assert_equal([0, 100, 2, 0, 9], getcurpos())
444
445 " Test for zt
446 21
447 norm! >>0zt
448 call assert_equal(' 21', getline('.'))
449 call assert_equal(21, winsaveview()['topline'])
450 call assert_equal([0, 21, 1, 0, 8], getcurpos())
451
452 " Test for zb
453 30
454 norm! >>$ztzb
455 call assert_equal(' 30', getline('.'))
456 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
457 call assert_equal([0, 30, 3, 0, 2147483647], getcurpos())
458
459 " Test for z-
460 1
461 30
462 norm! 0z-
463 call assert_equal(' 30', getline('.'))
464 call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
465 call assert_equal([0, 30, 2, 0, 9], getcurpos())
466
467 " Test for z{height}<cr>
468 call assert_equal(10, winheight(0))
469 exe "norm! z12\<cr>"
470 call assert_equal(12, winheight(0))
471 exe "norm! z10\<cr>"
472 call assert_equal(10, winheight(0))
473
474 " Test for z.
475 1
476 21
477 norm! 0z.
478 call assert_equal(' 21', getline('.'))
479 call assert_equal(17, winsaveview()['topline'])
480 call assert_equal([0, 21, 2, 0, 9], getcurpos())
481
482 " Test for zz
483 1
484 21
485 norm! 0zz
486 call assert_equal(' 21', getline('.'))
487 call assert_equal(17, winsaveview()['topline'])
488 call assert_equal([0, 21, 1, 0, 8], getcurpos())
489
490 " Test for z+
491 11
492 norm! zt
493 norm! z+
494 call assert_equal(' 21', getline('.'))
495 call assert_equal(21, winsaveview()['topline'])
496 call assert_equal([0, 21, 2, 0, 9], getcurpos())
497
498 " Test for [count]z+
499 1
500 norm! 21z+
501 call assert_equal(' 21', getline('.'))
502 call assert_equal(21, winsaveview()['topline'])
503 call assert_equal([0, 21, 2, 0, 9], getcurpos())
504
505 " Test for z^
506 norm! 22z+0
507 norm! z^
508 call assert_equal(' 21', getline('.'))
509 call assert_equal(12, winsaveview()['topline'])
510 call assert_equal([0, 21, 2, 0, 9], getcurpos())
511
512 " Test for [count]z^
513 1
514 norm! 30z^
515 call assert_equal(' 21', getline('.'))
516 call assert_equal(12, winsaveview()['topline'])
517 call assert_equal([0, 21, 2, 0, 9], getcurpos())
518
519 " cleanup
520 bw!
521endfu
522
523func! Test_normal16_z_scroll_hor()
524 " basic test for z commands that scroll the window
525 10new
526 15vsp
527 set nowrap listchars=
528 let lineA='abcdefghijklmnopqrstuvwxyz'
529 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
530 $put =lineA
531 $put =lineB
532 1d
533
534 " Test for zl
535 1
536 norm! 5zl
537 call assert_equal(lineA, getline('.'))
538 call assert_equal(6, col('.'))
539 call assert_equal(5, winsaveview()['leftcol'])
540 norm! yl
541 call assert_equal('f', @0)
542
543 " Test for zh
544 norm! 2zh
545 call assert_equal(lineA, getline('.'))
546 call assert_equal(6, col('.'))
547 norm! yl
548 call assert_equal('f', @0)
549 call assert_equal(3, winsaveview()['leftcol'])
550
551 " Test for zL
552 norm! zL
553 call assert_equal(11, col('.'))
554 norm! yl
555 call assert_equal('k', @0)
556 call assert_equal(10, winsaveview()['leftcol'])
557 norm! 2zL
558 call assert_equal(25, col('.'))
559 norm! yl
560 call assert_equal('y', @0)
561 call assert_equal(24, winsaveview()['leftcol'])
562
563 " Test for zH
564 norm! 2zH
565 call assert_equal(25, col('.'))
566 call assert_equal(10, winsaveview()['leftcol'])
567 norm! yl
568 call assert_equal('y', @0)
569
570 " Test for zs
571 norm! $zs
572 call assert_equal(26, col('.'))
573 call assert_equal(25, winsaveview()['leftcol'])
574 norm! yl
575 call assert_equal('z', @0)
576
577 " Test for ze
578 norm! ze
579 call assert_equal(26, col('.'))
580 call assert_equal(11, winsaveview()['leftcol'])
581 norm! yl
582 call assert_equal('z', @0)
583
584 " cleanup
585 set wrap listchars=eol:$
586 bw!
587endfu
588
589func! Test_normal17_z_scroll_hor2()
590 " basic test for z commands that scroll the window
591 " using 'sidescrolloff' setting
592 10new
593 20vsp
594 set nowrap listchars= sidescrolloff=5
595 let lineA='abcdefghijklmnopqrstuvwxyz'
596 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
597 $put =lineA
598 $put =lineB
599 1d
600
601 " Test for zl
602 1
603 norm! 5zl
604 call assert_equal(lineA, getline('.'))
605 call assert_equal(11, col('.'))
606 call assert_equal(5, winsaveview()['leftcol'])
607 norm! yl
608 call assert_equal('k', @0)
609
610 " Test for zh
611 norm! 2zh
612 call assert_equal(lineA, getline('.'))
613 call assert_equal(11, col('.'))
614 norm! yl
615 call assert_equal('k', @0)
616 call assert_equal(3, winsaveview()['leftcol'])
617
618 " Test for zL
619 norm! 0zL
620 call assert_equal(16, col('.'))
621 norm! yl
622 call assert_equal('p', @0)
623 call assert_equal(10, winsaveview()['leftcol'])
624 norm! 2zL
625 call assert_equal(26, col('.'))
626 norm! yl
627 call assert_equal('z', @0)
628 call assert_equal(15, winsaveview()['leftcol'])
629
630 " Test for zH
631 norm! 2zH
632 call assert_equal(15, col('.'))
633 call assert_equal(0, winsaveview()['leftcol'])
634 norm! yl
635 call assert_equal('o', @0)
636
637 " Test for zs
638 norm! $zs
639 call assert_equal(26, col('.'))
640 call assert_equal(20, winsaveview()['leftcol'])
641 norm! yl
642 call assert_equal('z', @0)
643
644 " Test for ze
645 norm! ze
646 call assert_equal(26, col('.'))
647 call assert_equal(11, winsaveview()['leftcol'])
648 norm! yl
649 call assert_equal('z', @0)
650
651 " cleanup
652 set wrap listchars=eol:$ sidescrolloff=0
653 bw!
654endfu
655
656func! Test_normal18_z_fold()
657 " basic tests for foldopen/folddelete
658 if !has("folding")
659 return
660 endif
661 call Setup_NewWindow()
662 50
663 setl foldenable fdm=marker foldlevel=5
664
665 " Test for zF
666 " First fold
667 norm! 4zF
668 " check that folds have been created
669 call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
670
671 " Test for zd
672 51
673 norm! 2zF
674 call assert_equal(2, foldlevel('.'))
675 norm! kzd
676 call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
677 norm! j
678 call assert_equal(1, foldlevel('.'))
679
680 " Test for zD
681 " also deletes partially selected folds recursively
682 51
683 norm! zF
684 call assert_equal(2, foldlevel('.'))
685 norm! kV2jzD
686 call assert_equal(['50', '51', '52', '53'], getline(50,53))
687
688 " Test for zE
689 85
690 norm! 4zF
691 86
692 norm! 2zF
693 90
694 norm! 4zF
695 call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
696 norm! zE
697 call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
698
699 " Test for zn
700 50
701 set foldlevel=0
702 norm! 2zF
703 norm! zn
704 norm! k
705 call assert_equal('49', getline('.'))
706 norm! j
707 call assert_equal('50/*{{{*/', getline('.'))
708 norm! j
709 call assert_equal('51/*}}}*/', getline('.'))
710 norm! j
711 call assert_equal('52', getline('.'))
712 call assert_equal(0, &foldenable)
713
714 " Test for zN
715 49
716 norm! zN
717 call assert_equal('49', getline('.'))
718 norm! j
719 call assert_equal('50/*{{{*/', getline('.'))
720 norm! j
721 call assert_equal('52', getline('.'))
722 call assert_equal(1, &foldenable)
723
724 " Test for zi
725 norm! zi
726 call assert_equal(0, &foldenable)
727 norm! zi
728 call assert_equal(1, &foldenable)
729 norm! zi
730 call assert_equal(0, &foldenable)
731 norm! zi
732 call assert_equal(1, &foldenable)
733
734 " Test for za
735 50
736 norm! za
737 norm! k
738 call assert_equal('49', getline('.'))
739 norm! j
740 call assert_equal('50/*{{{*/', getline('.'))
741 norm! j
742 call assert_equal('51/*}}}*/', getline('.'))
743 norm! j
744 call assert_equal('52', getline('.'))
745 50
746 norm! za
747 norm! k
748 call assert_equal('49', getline('.'))
749 norm! j
750 call assert_equal('50/*{{{*/', getline('.'))
751 norm! j
752 call assert_equal('52', getline('.'))
753
754 49
755 norm! 5zF
756 norm! k
757 call assert_equal('48', getline('.'))
758 norm! j
759 call assert_equal('49/*{{{*/', getline('.'))
760 norm! j
761 call assert_equal('55', getline('.'))
762 49
763 norm! za
764 call assert_equal('49/*{{{*/', getline('.'))
765 norm! j
766 call assert_equal('50/*{{{*/', getline('.'))
767 norm! j
768 call assert_equal('52', getline('.'))
769 set nofoldenable
770 " close fold and set foldenable
771 norm! za
772 call assert_equal(1, &foldenable)
773
774 50
775 " have to use {count}za to open all folds and make the cursor visible
776 norm! 2za
777 norm! 2k
778 call assert_equal('48', getline('.'))
779 norm! j
780 call assert_equal('49/*{{{*/', getline('.'))
781 norm! j
782 call assert_equal('50/*{{{*/', getline('.'))
783 norm! j
784 call assert_equal('51/*}}}*/', getline('.'))
785 norm! j
786 call assert_equal('52', getline('.'))
787
788 " Test for zA
789 49
790 set foldlevel=0
791 50
792 norm! zA
793 norm! 2k
794 call assert_equal('48', getline('.'))
795 norm! j
796 call assert_equal('49/*{{{*/', getline('.'))
797 norm! j
798 call assert_equal('50/*{{{*/', getline('.'))
799 norm! j
800 call assert_equal('51/*}}}*/', getline('.'))
801 norm! j
802 call assert_equal('52', getline('.'))
803
804 " zA on a opened fold when foldenale is not set
805 50
806 set nofoldenable
807 norm! zA
808 call assert_equal(1, &foldenable)
809 norm! k
810 call assert_equal('48', getline('.'))
811 norm! j
812 call assert_equal('49/*{{{*/', getline('.'))
813 norm! j
814 call assert_equal('55', getline('.'))
815
816 " Test for zc
817 norm! zE
818 50
819 norm! 2zF
820 49
821 norm! 5zF
822 set nofoldenable
823 50
824 " There most likely is a bug somewhere:
825 " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
826 " TODO: Should this only close the inner most fold or both folds?
827 norm! zc
828 call assert_equal(1, &foldenable)
829 norm! k
830 call assert_equal('48', getline('.'))
831 norm! j
832 call assert_equal('49/*{{{*/', getline('.'))
833 norm! j
834 call assert_equal('55', getline('.'))
835 set nofoldenable
836 50
837 norm! Vjzc
838 norm! k
839 call assert_equal('48', getline('.'))
840 norm! j
841 call assert_equal('49/*{{{*/', getline('.'))
842 norm! j
843 call assert_equal('55', getline('.'))
844
845 " Test for zC
846 set nofoldenable
847 50
848 norm! zCk
849 call assert_equal('48', getline('.'))
850 norm! j
851 call assert_equal('49/*{{{*/', getline('.'))
852 norm! j
853 call assert_equal('55', getline('.'))
854
855 " Test for zx
856 " 1) close folds at line 49-54
857 set nofoldenable
858 48
859 norm! zx
860 call assert_equal(1, &foldenable)
861 norm! j
862 call assert_equal('49/*{{{*/', getline('.'))
863 norm! j
864 call assert_equal('55', getline('.'))
865
866 " 2) do not close fold under curser
867 51
868 set nofoldenable
869 norm! zx
870 call assert_equal(1, &foldenable)
871 norm! 3k
872 call assert_equal('48', getline('.'))
873 norm! j
874 call assert_equal('49/*{{{*/', getline('.'))
875 norm! j
876 call assert_equal('50/*{{{*/', getline('.'))
877 norm! j
878 call assert_equal('51/*}}}*/', getline('.'))
879 norm! j
880 call assert_equal('52', getline('.'))
881 norm! j
882 call assert_equal('53', getline('.'))
883 norm! j
884 call assert_equal('54/*}}}*/', getline('.'))
885 norm! j
886 call assert_equal('55', getline('.'))
887
888 " 3) close one level of folds
889 48
890 set nofoldenable
891 set foldlevel=1
892 norm! zx
893 call assert_equal(1, &foldenable)
894 call assert_equal('48', getline('.'))
895 norm! j
896 call assert_equal('49/*{{{*/', getline('.'))
897 norm! j
898 call assert_equal('50/*{{{*/', getline('.'))
899 norm! j
900 call assert_equal('52', getline('.'))
901 norm! j
902 call assert_equal('53', getline('.'))
903 norm! j
904 call assert_equal('54/*}}}*/', getline('.'))
905 norm! j
906 call assert_equal('55', getline('.'))
907
908 " Test for zX
909 " Close all folds
910 set foldlevel=0 nofoldenable
911 50
912 norm! zX
913 call assert_equal(1, &foldenable)
914 norm! k
915 call assert_equal('48', getline('.'))
916 norm! j
917 call assert_equal('49/*{{{*/', getline('.'))
918 norm! j
919 call assert_equal('55', getline('.'))
920
921 " Test for zm
922 50
923 set nofoldenable foldlevel=2
924 norm! zm
925 call assert_equal(1, &foldenable)
926 call assert_equal(1, &foldlevel)
927 norm! zm
928 call assert_equal(0, &foldlevel)
929 norm! zm
930 call assert_equal(0, &foldlevel)
931 norm! k
932 call assert_equal('48', getline('.'))
933 norm! j
934 call assert_equal('49/*{{{*/', getline('.'))
935 norm! j
936 call assert_equal('55', getline('.'))
937
938 " Test for zM
939 48
940 set nofoldenable foldlevel=99
941 norm! zM
942 call assert_equal(1, &foldenable)
943 call assert_equal(0, &foldlevel)
944 call assert_equal('48', getline('.'))
945 norm! j
946 call assert_equal('49/*{{{*/', getline('.'))
947 norm! j
948 call assert_equal('55', getline('.'))
949
950 " Test for zr
951 48
952 set nofoldenable foldlevel=0
953 norm! zr
954 call assert_equal(0, &foldenable)
955 call assert_equal(1, &foldlevel)
956 set foldlevel=0 foldenable
957 norm! zr
958 call assert_equal(1, &foldenable)
959 call assert_equal(1, &foldlevel)
960 norm! zr
961 call assert_equal(2, &foldlevel)
962 call assert_equal('48', getline('.'))
963 norm! j
964 call assert_equal('49/*{{{*/', getline('.'))
965 norm! j
966 call assert_equal('50/*{{{*/', getline('.'))
967 norm! j
968 call assert_equal('51/*}}}*/', getline('.'))
969 norm! j
970 call assert_equal('52', getline('.'))
971
972 " Test for zR
973 48
974 set nofoldenable foldlevel=0
975 norm! zR
976 call assert_equal(0, &foldenable)
977 call assert_equal(2, &foldlevel)
978 set foldenable foldlevel=0
979 norm! zR
980 call assert_equal(1, &foldenable)
981 call assert_equal(2, &foldlevel)
982 call assert_equal('48', getline('.'))
983 norm! j
984 call assert_equal('49/*{{{*/', getline('.'))
985 norm! j
986 call assert_equal('50/*{{{*/', getline('.'))
987 norm! j
988 call assert_equal('51/*}}}*/', getline('.'))
989 norm! j
990 call assert_equal('52', getline('.'))
991 call append(50, ['a /*{{{*/', 'b /*}}}*/'])
992 48
993 call assert_equal('48', getline('.'))
994 norm! j
995 call assert_equal('49/*{{{*/', getline('.'))
996 norm! j
997 call assert_equal('50/*{{{*/', getline('.'))
998 norm! j
999 call assert_equal('a /*{{{*/', getline('.'))
1000 norm! j
1001 call assert_equal('51/*}}}*/', getline('.'))
1002 norm! j
1003 call assert_equal('52', getline('.'))
1004 48
1005 norm! zR
1006 call assert_equal(1, &foldenable)
1007 call assert_equal(3, &foldlevel)
1008 call assert_equal('48', getline('.'))
1009 norm! j
1010 call assert_equal('49/*{{{*/', getline('.'))
1011 norm! j
1012 call assert_equal('50/*{{{*/', getline('.'))
1013 norm! j
1014 call assert_equal('a /*{{{*/', getline('.'))
1015 norm! j
1016 call assert_equal('b /*}}}*/', getline('.'))
1017 norm! j
1018 call assert_equal('51/*}}}*/', getline('.'))
1019 norm! j
1020 call assert_equal('52', getline('.'))
1021
1022 " clean up
1023 setl nofoldenable fdm=marker foldlevel=0
1024 bw!
1025endfu
1026
1027func! Test_normal19_z_spell()
1028 if !has("spell") || !has('syntax')
1029 return
1030 endif
1031 new
1032 call append(0, ['1 good', '2 goood', '3 goood'])
1033 set spell spellfile=./Xspellfile.add spelllang=en
1034 let oldlang=v:lang
1035 lang C
1036
1037 " Test for zg
1038 1
1039 norm! ]s
1040 call assert_equal('2 goood', getline('.'))
1041 norm! zg
1042 1
1043 let a=execute('unsilent :norm! ]s')
1044 call assert_equal('1 good', getline('.'))
1045 call assert_equal('search hit BOTTOM, continuing at TOP', a[1:])
1046 let cnt=readfile('./Xspellfile.add')
1047 call assert_equal('goood', cnt[0])
1048
1049 " Test for zw
1050 2
1051 norm! $zw
1052 1
1053 norm! ]s
1054 call assert_equal('2 goood', getline('.'))
1055 let cnt=readfile('./Xspellfile.add')
1056 call assert_equal('#oood', cnt[0])
1057 call assert_equal('goood/!', cnt[1])
1058
1059 " Test for zg in visual mode
1060 let a=execute('unsilent :norm! V$zg')
1061 call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
1062 1
1063 norm! ]s
1064 call assert_equal('3 goood', getline('.'))
1065 let cnt=readfile('./Xspellfile.add')
1066 call assert_equal('2 goood', cnt[2])
1067 " Remove "2 good" from spellfile
1068 2
1069 let a=execute('unsilent norm! V$zw')
1070 call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
1071 let cnt=readfile('./Xspellfile.add')
1072 call assert_equal('2 goood/!', cnt[3])
1073
1074 " Test for zG
1075 let a=execute('unsilent norm! V$zG')
1076 call assert_match("Word '2 goood' added to .*", a)
1077 let fname=matchstr(a, 'to\s\+\zs\f\+$')
1078 let cnt=readfile(fname)
1079 call assert_equal('2 goood', cnt[0])
1080
1081 " Test for zW
1082 let a=execute('unsilent norm! V$zW')
1083 call assert_match("Word '2 goood' added to .*", a)
1084 let cnt=readfile(fname)
1085 call assert_equal('# goood', cnt[0])
1086 call assert_equal('2 goood/!', cnt[1])
1087
1088 " Test for zuW
1089 let a=execute('unsilent norm! V$zuW')
1090 call assert_match("Word '2 goood' removed from .*", a)
1091 let cnt=readfile(fname)
1092 call assert_equal('# goood', cnt[0])
1093 call assert_equal('# goood/!', cnt[1])
1094
1095 " Test for zuG
1096 let a=execute('unsilent norm! $zG')
1097 call assert_match("Word 'goood' added to .*", a)
1098 let cnt=readfile(fname)
1099 call assert_equal('# goood', cnt[0])
1100 call assert_equal('# goood/!', cnt[1])
1101 call assert_equal('goood', cnt[2])
1102 let a=execute('unsilent norm! $zuG')
1103 let cnt=readfile(fname)
1104 call assert_match("Word 'goood' removed from .*", a)
1105 call assert_equal('# goood', cnt[0])
1106 call assert_equal('# goood/!', cnt[1])
1107 call assert_equal('#oood', cnt[2])
1108 " word not found in wordlist
1109 let a=execute('unsilent norm! V$zuG')
1110 let cnt=readfile(fname)
1111 call assert_match("", a)
1112 call assert_equal('# goood', cnt[0])
1113 call assert_equal('# goood/!', cnt[1])
1114 call assert_equal('#oood', cnt[2])
1115
1116 " Test for zug
1117 call delete('./Xspellfile.add')
1118 2
1119 let a=execute('unsilent norm! $zg')
1120 let cnt=readfile('./Xspellfile.add')
1121 call assert_equal('goood', cnt[0])
1122 let a=execute('unsilent norm! $zug')
1123 call assert_match("Word 'goood' removed from \./Xspellfile.add", a)
1124 let cnt=readfile('./Xspellfile.add')
1125 call assert_equal('#oood', cnt[0])
1126 " word not in wordlist
1127 let a=execute('unsilent norm! V$zug')
1128 call assert_match('', a)
1129 let cnt=readfile('./Xspellfile.add')
1130 call assert_equal('#oood', cnt[0])
1131
1132 " Test for zuw
1133 call delete('./Xspellfile.add')
1134 2
1135 let a=execute('unsilent norm! Vzw')
1136 let cnt=readfile('./Xspellfile.add')
1137 call assert_equal('2 goood/!', cnt[0])
1138 let a=execute('unsilent norm! Vzuw')
1139 call assert_match("Word '2 goood' removed from \./Xspellfile.add", a)
1140 let cnt=readfile('./Xspellfile.add')
1141 call assert_equal('# goood/!', cnt[0])
1142 " word not in wordlist
1143 let a=execute('unsilent norm! $zug')
1144 call assert_match('', a)
1145 let cnt=readfile('./Xspellfile.add')
1146 call assert_equal('# goood/!', cnt[0])
1147
1148 " add second entry to spellfile setting
1149 set spellfile=./Xspellfile.add,./Xspellfile2.add
1150 call delete('./Xspellfile.add')
1151 2
1152 let a=execute('unsilent norm! $2zg')
1153 let cnt=readfile('./Xspellfile2.add')
1154 call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
1155 call assert_equal('goood', cnt[0])
1156
1157 " clean up
1158 exe "lang" oldlang
1159 call delete("./Xspellfile.add")
1160 call delete("./Xspellfile2.add")
1161
1162 " zux -> no-op
1163 2
1164 norm! $zux
1165 call assert_equal([], glob('Xspellfile.add',0,1))
1166 call assert_equal([], glob('Xspellfile2.add',0,1))
1167
1168 set spellfile=
1169 bw!
1170endfu
1171
1172func! Test_normal20_exmode()
Bram Moolenaar0913a102016-09-03 19:11:59 +02001173 if !has("unix")
1174 " Reading from redirected file doesn't work on MS-Windows
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001175 return
1176 endif
1177 call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
1178 call writefile(['1', '2'], 'Xfile')
1179 call system(v:progpath .' -e -s < Xscript Xfile')
1180 let a=readfile('Xfile2')
1181 call assert_equal(['1', 'foo', 'bar', '2'], a)
1182
1183 " clean up
1184 for file in ['Xfile', 'Xfile2', 'Xscript']
1185 call delete(file)
1186 endfor
1187 bw!
1188endfu
1189
1190func! Test_normal21_nv_hat()
1191 set hidden
1192 e Xfoobar
1193 e Xfile2
1194 call feedkeys("\<c-^>", 't')
1195 call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
1196 call feedkeys("f\<c-^>", 't')
1197 call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
1198 " clean up
1199 set nohidden
1200 bw!
1201endfu
1202
1203func! Test_normal22_zet()
1204 " Test for ZZ
Bram Moolenaar0913a102016-09-03 19:11:59 +02001205 " let shell = &shell
1206 " let &shell = 'sh'
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001207 call writefile(['1', '2'], 'Xfile')
1208 let args = ' -u NONE -N -U NONE -i NONE --noplugins -X --not-a-term'
1209 call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile')
1210 let a = readfile('Xfile')
1211 call assert_equal([], a)
1212 " Test for ZQ
1213 call writefile(['1', '2'], 'Xfile')
1214 call system(v:progpath . args . ' -c "%d" -c ":norm! ZQ" Xfile')
1215 let a = readfile('Xfile')
1216 call assert_equal(['1', '2'], a)
1217
1218 " clean up
1219 for file in ['Xfile']
1220 call delete(file)
1221 endfor
Bram Moolenaar0913a102016-09-03 19:11:59 +02001222 " let &shell = shell
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001223endfu
1224
1225func! Test_normal23_K()
1226 " Test for K command
1227 new
1228 call append(0, ['version8.txt', 'man'])
1229 let k = &keywordprg
1230 set keywordprg=:help
1231 1
1232 norm! VK
1233 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1234 call assert_equal('help', &ft)
1235 call assert_match('\*version8.txt\*', getline('.'))
1236 helpclose
1237 norm! 0K
1238 call assert_equal('version8.txt', fnamemodify(bufname('%'), ':t'))
1239 call assert_equal('help', &ft)
1240 call assert_match('\*version8\.0\*', getline('.'))
1241 helpclose
1242
Bram Moolenaar0913a102016-09-03 19:11:59 +02001243 " Only expect "man" to work on Unix
1244 if !has("unix")
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001245 let &keywordprg = k
1246 bw!
1247 return
1248 endif
1249 set keywordprg=man\ --pager=cat
1250 " Test for using man
1251 2
1252 let a = execute('unsilent norm! K')
1253 call assert_match("man --pager=cat 'man'", a)
1254
1255 " clean up
1256 let &keywordprg = k
1257 bw!
1258endfu
1259
1260func! Test_normal24_rot13()
1261 " This test uses multi byte characters
1262 if !has("multi_byte")
1263 return
1264 endif
1265 " Testing for g?? g?g?
1266 new
1267 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1268 1
1269 norm! g??
1270 call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
1271 norm! g?g?
1272 call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
1273
1274 " clean up
1275 bw!
1276endfu
1277
1278func! Test_normal25_tag()
1279 " Testing for CTRL-] g CTRL-] g]
1280 " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
1281 h
1282 " Test for CTRL-]
1283 call search('\<x\>$')
1284 exe "norm! \<c-]>"
1285 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1286 norm! yiW
1287 call assert_equal("*x*", @0)
1288 exe ":norm \<c-o>"
1289
1290 " Test for g_CTRL-]
1291 call search('\<v_u\>$')
1292 exe "norm! g\<c-]>"
1293 call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
1294 norm! yiW
1295 call assert_equal("*v_u*", @0)
1296 exe ":norm \<c-o>"
1297
1298 " Test for g]
1299 call search('\<i_<Esc>$')
1300 let a = execute(":norm! g]")
1301 call assert_match('i_<Esc>.*insert.txt', a)
1302
1303 if !empty(exepath('cscope')) && has('cscope')
1304 " setting cscopetag changes how g] works
1305 set cst
1306 exe "norm! g]"
1307 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1308 norm! yiW
1309 call assert_equal("*i_<Esc>*", @0)
1310 exe ":norm \<c-o>"
1311 " Test for CTRL-W g]
1312 exe "norm! \<C-W>g]"
1313 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1314 norm! yiW
1315 call assert_equal("*i_<Esc>*", @0)
1316 call assert_equal(3, winnr('$'))
1317 helpclose
1318 set nocst
1319 endif
1320
1321 " Test for CTRL-W g]
1322 let a = execute("norm! \<C-W>g]")
1323 call assert_match('i_<Esc>.*insert.txt', a)
1324
1325 " Test for CTRL-W CTRL-]
1326 exe "norm! \<C-W>\<C-]>"
1327 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1328 norm! yiW
1329 call assert_equal("*i_<Esc>*", @0)
1330 call assert_equal(3, winnr('$'))
1331 helpclose
1332
1333 " Test for CTRL-W g CTRL-]
1334 exe "norm! \<C-W>g\<C-]>"
1335 call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
1336 norm! yiW
1337 call assert_equal("*i_<Esc>*", @0)
1338 call assert_equal(3, winnr('$'))
1339 helpclose
1340
1341 " clean up
1342 helpclose
1343endfu
1344
1345func! Test_normal26_put()
1346 " Test for ]p ]P [p and [P
1347 new
1348 call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
1349 1
1350 /Error/y a
1351 2
1352 norm! "a]pj"a[p
1353 call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
1354 1
1355 /^\s\{4}/
1356 exe "norm! \"a]P3Eldt'"
1357 exe "norm! j\"a[P2Eldt'"
1358 call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
1359
1360 " clean up
1361 bw!
1362endfu
1363
1364func! Test_normal27_bracket()
1365 " Test for [' [` ]' ]`
1366 call Setup_NewWindow()
1367 1,21s/.\+/ & b/
1368 1
1369 norm! $ma
1370 5
1371 norm! $mb
1372 10
1373 norm! $mc
1374 15
1375 norm! $md
1376 20
1377 norm! $me
1378
1379 " Test for ['
1380 9
1381 norm! 2['
1382 call assert_equal(' 1 b', getline('.'))
1383 call assert_equal(1, line('.'))
1384 call assert_equal(3, col('.'))
1385
1386 " Test for ]'
1387 norm! ]'
1388 call assert_equal(' 5 b', getline('.'))
1389 call assert_equal(5, line('.'))
1390 call assert_equal(3, col('.'))
1391
1392 " No mark after line 21, cursor moves to first non blank on current line
1393 21
1394 norm! $]'
1395 call assert_equal(' 21 b', getline('.'))
1396 call assert_equal(21, line('.'))
1397 call assert_equal(3, col('.'))
1398
1399 " Test for [`
1400 norm! 2[`
1401 call assert_equal(' 15 b', getline('.'))
1402 call assert_equal(15, line('.'))
1403 call assert_equal(8, col('.'))
1404
1405 " Test for ]`
1406 norm! ]`
1407 call assert_equal(' 20 b', getline('.'))
1408 call assert_equal(20, line('.'))
1409 call assert_equal(8, col('.'))
1410
1411 " clean up
1412 bw!
1413endfu
1414
1415func! Test_normal28_parenthesis()
1416 " basic testing for ( and )
1417 new
1418 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
1419
1420 $
1421 norm! d(
1422 call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
1423 norm! 2d(
1424 call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
1425 1
1426 norm! 0d)
1427 call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
1428
1429 call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
1430 $
1431 norm! $d(
1432 call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
1433
1434 " clean up
1435 bw!
1436endfu
1437
1438fun! Test_normal29_brace()
1439 " basic test for { and } movements
1440 let text= ['A paragraph begins after each empty line, and also at each of a set of',
1441 \ 'paragraph macros, specified by the pairs of characters in the ''paragraphs''',
1442 \ 'option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to',
1443 \ 'the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in',
1444 \ 'the first column). A section boundary is also a paragraph boundary.',
1445 \ 'Note that a blank line (only containing white space) is NOT a paragraph',
1446 \ 'boundary.',
1447 \ '',
1448 \ '',
1449 \ 'Also note that this does not include a ''{'' or ''}'' in the first column. When',
1450 \ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a',
1451 \ 'paragraph boundary |posix|.',
1452 \ '{',
1453 \ 'This is no paragaraph',
1454 \ 'unless the ''{'' is set',
1455 \ 'in ''cpoptions''',
1456 \ '}',
1457 \ '.IP',
1458 \ 'The nroff macros IP seperates a paragraph',
1459 \ 'That means, it must be a ''.''',
1460 \ 'followed by IP',
1461 \ '.LPIt does not matter, if afterwards some',
1462 \ 'more characters follow.',
1463 \ '.SHAlso section boundaries from the nroff',
1464 \ 'macros terminate a paragraph. That means',
1465 \ 'a character like this:',
1466 \ '.NH',
1467 \ 'End of text here']
1468 new
1469 call append(0, text)
1470 1
1471 norm! 0d2}
1472 call assert_equal(['.IP',
1473 \ 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
1474 \ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff',
1475 \ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
1476 norm! 0d}
1477 call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
1478 \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
1479 \ 'a character like this:', '.NH', 'End of text here', ''], getline(1, '$'))
1480 $
1481 norm! d{
1482 call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
1483 \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', 'a character like this:', ''], getline(1, '$'))
1484 norm! d{
1485 call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', ''], getline(1,'$'))
1486 " Test with { in cpooptions
1487 %d
1488 call append(0, text)
1489 set cpo+={
1490 1
1491 norm! 0d2}
1492 call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
1493 \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
1494 \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
1495 \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
1496 \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
1497 $
1498 norm! d}
1499 call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
1500 \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
1501 \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
1502 \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
1503 \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
1504 norm! gg}
1505 norm! d5}
1506 call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
1507
1508 " clean up
1509 set cpo-={
1510 bw!
1511endfu
1512
1513fun! Test_normal30_changecase()
1514 " This test uses multi byte characters
1515 if !has("multi_byte")
1516 return
1517 endif
1518 new
1519 call append(0, 'This is a simple test: äüöß')
1520 norm! 1ggVu
1521 call assert_equal('this is a simple test: äüöß', getline('.'))
1522 norm! VU
1523 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
1524 norm! guu
1525 call assert_equal('this is a simple test: äüöss', getline('.'))
1526 norm! gUgU
1527 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
1528 norm! gugu
1529 call assert_equal('this is a simple test: äüöss', getline('.'))
1530 norm! gUU
1531 call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
1532 norm! 010~
1533 call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
1534 norm! V~
1535 call assert_equal('THIS IS A simple test: äüöss', getline('.'))
1536
1537 " clean up
1538 bw!
1539endfu
1540
1541fun! Test_normal31_r_cmd()
1542 " Test for r command
1543 new
1544 call append(0, 'This is a simple test: abcd')
1545 exe "norm! 1gg$r\<cr>"
1546 call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
1547 exe "norm! 1gg2wlr\<cr>"
1548 call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
1549 exe "norm! 2gg0W5r\<cr>"
1550 call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
1551 set autoindent
1552 call setline(2, ['simple test: abc', ''])
1553 exe "norm! 2gg0W5r\<cr>"
1554 call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
1555 exe "norm! 1ggVr\<cr>"
1556 call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
1557 call setline(1, 'This is a')
1558 exe "norm! 1gg05rf"
1559 call assert_equal('fffffis a', getline(1))
1560
1561 " clean up
1562 set noautoindent
1563 bw!
1564endfu
1565
1566func! Test_normal32_g_cmd1()
1567 " Test for g*, g#
1568 new
1569 call append(0, ['abc.x_foo', 'x_foobar.abc'])
1570 1
1571 norm! $g*
1572 call assert_equal('x_foo', @/)
1573 call assert_equal('x_foobar.abc', getline('.'))
1574 norm! $g#
1575 call assert_equal('abc', @/)
1576 call assert_equal('abc.x_foo', getline('.'))
1577
1578 " clean up
1579 bw!
1580endfu
1581
1582fun! Test_normal33_g_cmd2()
1583 if !has("jumplist")
1584 return
1585 endif
1586 " Tests for g cmds
1587 call Setup_NewWindow()
1588 " Test for g`
1589 clearjumps
1590 norm! ma10j
1591 let a=execute(':jumps')
1592 " empty jumplist
1593 call assert_equal('>', a[-1:])
1594 norm! g`a
1595 call assert_equal('>', a[-1:])
1596 call assert_equal(1, line('.'))
1597 call assert_equal('1', getline('.'))
1598
1599 " Test for g; and g,
1600 norm! g;
1601 " there is only one change in the changelist
1602 " currently, when we setup the window
1603 call assert_equal(2, line('.'))
1604 call assert_fails(':norm! g;', 'E662')
1605 call assert_fails(':norm! g,', 'E663')
1606 let &ul=&ul
1607 call append('$', ['a', 'b', 'c', 'd'])
1608 let &ul=&ul
1609 call append('$', ['Z', 'Y', 'X', 'W'])
1610 let a = execute(':changes')
1611 call assert_match('2\s\+0\s\+2', a)
1612 call assert_match('101\s\+0\s\+a', a)
1613 call assert_match('105\s\+0\s\+Z', a)
1614 norm! 3g;
1615 call assert_equal(2, line('.'))
1616 norm! 2g,
1617 call assert_equal(105, line('.'))
1618
1619 " Test for g& - global substitute
1620 %d
1621 call setline(1, range(1,10))
1622 call append('$', ['a', 'b', 'c', 'd'])
1623 $s/\w/&&/g
1624 exe "norm! /[1-8]\<cr>"
1625 norm! g&
1626 call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
1627
1628 " Test for gv
1629 %d
1630 call append('$', repeat(['abcdefgh'], 8))
1631 exe "norm! 2gg02l\<c-v>2j2ly"
1632 call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
1633 " in visual mode, gv swaps current and last selected region
1634 exe "norm! G0\<c-v>4k4lgvd"
1635 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
1636 exe "norm! G0\<c-v>4k4ly"
1637 exe "norm! gvood"
1638 call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
1639
1640 " Test for gk/gj
1641 %d
1642 15vsp
1643 set wrap listchars= sbr=
1644 let lineA='abcdefghijklmnopqrstuvwxyz'
1645 let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1646 $put =lineA
1647 $put =lineB
1648
1649 norm! 3gg0dgk
1650 call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
1651 set nu
1652 norm! 3gg0gjdgj
1653 call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
1654
1655 " Test for gJ
1656 norm! 2gggJ
1657 call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
1658 call assert_equal(16, col('.'))
1659 " shouldn't do anything
1660 norm! 10gJ
1661 call assert_equal(1, col('.'))
1662
1663 " Test for g0 g^ gm g$
1664 exe "norm! 2gg0gji "
1665 call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
1666 norm! g0yl
1667 call assert_equal(12, col('.'))
1668 call assert_equal(' ', getreg(0))
1669 norm! g$yl
1670 call assert_equal(22, col('.'))
1671 call assert_equal('3', getreg(0))
1672 norm! gmyl
1673 call assert_equal(17, col('.'))
1674 call assert_equal('n', getreg(0))
1675 norm! g^yl
1676 call assert_equal(15, col('.'))
1677 call assert_equal('l', getreg(0))
1678
1679 " Test for g Ctrl-G
Bram Moolenaar0913a102016-09-03 19:11:59 +02001680 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001681 let a=execute(":norm! g\<c-g>")
1682 call assert_match('Col 15 of 43; Line 2 of 2; Word 2 of 2; Byte 16 of 45', a)
1683
1684 " Test for gI
1685 norm! gIfoo
1686 call assert_equal(['', 'fooabcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
1687
1688 " Test for gi
1689 wincmd c
1690 %d
1691 set tw=0
1692 call setline(1, ['foobar', 'new line'])
1693 norm! A next word
1694 $put ='third line'
1695 norm! gi another word
1696 call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
1697
1698 " clean up
1699 bw!
1700endfu
1701
1702fun! Test_normal34_g_cmd3()
1703 if !has("multi_byte")
1704 return
1705 endif
1706 " Test for g8
1707 new
1708 call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
1709 let a=execute(':norm! 1gg$g8')
1710 call assert_equal('c3 b6 ', a[1:])
1711
1712 " Test for gp gP
1713 call append(1, range(1,10))
1714 " clean up
1715 bw!
1716endfu
1717
1718fun! Test_normal35_g_cmd4()
1719 " Test for g<
1720 " Cannot capture its output,
1721 " probably a bug, therefore, test disabled:
1722 return
1723 echo "a\nb\nc\nd"
1724 let b=execute(':norm! g<')
1725 call assert_true(!empty(b), 'failed `execute(g<)`')
1726endfu
1727
1728fun! Test_normal36_g_cmd5()
1729 new
1730 call append(0, 'abcdefghijklmnopqrstuvwxyz')
Bram Moolenaar0913a102016-09-03 19:11:59 +02001731 set ff=unix
Bram Moolenaar87bc3f72016-09-03 17:33:54 +02001732 " Test for gp gP
1733 call append(1, range(1,10))
1734 1
1735 norm! 1yy
1736 3
1737 norm! gp
1738 call assert_equal([0, 5, 1, 0, 1], getcurpos())
1739 $
1740 norm! gP
1741 call assert_equal([0, 14, 1, 0, 1], getcurpos())
1742
1743 " Test for go
1744 norm! 26go
1745 call assert_equal([0, 1, 26, 0, 26], getcurpos())
1746 norm! 27go
1747 call assert_equal([0, 1, 26, 0, 26], getcurpos())
1748 norm! 28go
1749 call assert_equal([0, 2, 1, 0, 1], getcurpos())
1750 set ff=dos
1751 norm! 29go
1752 call assert_equal([0, 2, 1, 0, 1], getcurpos())
1753 set ff=unix
1754 norm! gg0
1755 norm! 101go
1756 call assert_equal([0, 13, 26, 0, 26], getcurpos())
1757 norm! 103go
1758 call assert_equal([0, 14, 1, 0, 1], getcurpos())
1759 " count > buffer content
1760 norm! 120go
1761 call assert_equal([0, 14, 1, 0, 2147483647], getcurpos())
1762 " clean up
1763 bw!
1764endfu
1765
1766fun! Test_normal37_g_cmd6()
1767 " basic test for gt and gT
1768 tabnew 1.txt
1769 tabnew 2.txt
1770 tabnew 3.txt
1771 norm! 1gt
1772 call assert_equal(1, tabpagenr())
1773 norm! 3gt
1774 call assert_equal(3, tabpagenr())
1775 norm! 1gT
1776 " count gT goes not to the absolute tabpagenumber
1777 " but, but goes to the count previous tabpagenumber
1778 call assert_equal(2, tabpagenr())
1779 " wrap around
1780 norm! 3gT
1781 call assert_equal(3, tabpagenr())
1782 " gt does not wrap around
1783 norm! 5gt
1784 call assert_equal(3, tabpagenr())
1785
1786 for i in range(3)
1787 tabclose
1788 endfor
1789 " clean up
1790 call assert_fails(':tabclose', 'E784')
1791endfu
1792
1793fun! Test_normal38_nvhome()
1794 " Test for <Home> and <C-Home> key
1795 new
1796 call setline(1, range(10))
1797 $
1798 setl et sw=2
1799 norm! V10>$
1800 " count is ignored
1801 exe "norm! 10\<home>"
1802 call assert_equal(1, col('.'))
1803 exe "norm! \<home>"
1804 call assert_equal([0, 10, 1, 0, 1], getcurpos())
1805 exe "norm! 5\<c-home>"
1806 call assert_equal([0, 5, 1, 0, 1], getcurpos())
1807 exe "norm! \<c-home>"
1808 call assert_equal([0, 1, 1, 0, 1], getcurpos())
1809
1810 " clean up
1811 bw!
1812endfu
1813
1814fun! Test_normal39_cw()
1815 " Test for cw and cW on whitespace
1816 " and cpo+=w setting
1817 new
1818 set tw=0
1819 call append(0, 'here are some words')
1820 norm! 1gg0elcwZZZ
1821 call assert_equal('hereZZZare some words', getline('.'))
1822 norm! 1gg0elcWYYY
1823 call assert_equal('hereZZZareYYYsome words', getline('.'))
1824 set cpo+=w
1825 call setline(1, 'here are some words')
1826 norm! 1gg0elcwZZZ
1827 call assert_equal('hereZZZ are some words', getline('.'))
1828 norm! 1gg2elcWYYY
1829 call assert_equal('hereZZZ areYYY some words', getline('.'))
1830 set cpo-=w
1831 norm! 2gg0cwfoo
1832 call assert_equal('foo', getline('.'))
1833
1834 " clean up
1835 bw!
1836endfu
1837
1838fun! Test_normal40_ctrl_bsl()
1839 " Basic test for CTRL-\ commands
1840 new
1841 call append(0, 'here are some words')
1842 exe "norm! 1gg0a\<C-\>\<C-N>"
1843 call assert_equal('n', mode())
1844 call assert_equal(1, col('.'))
1845 call assert_equal('', visualmode())
1846 exe "norm! 1gg0viw\<C-\>\<C-N>"
1847 call assert_equal('n', mode())
1848 call assert_equal(4, col('.'))
1849 exe "norm! 1gg0a\<C-\>\<C-G>"
1850 call assert_equal('n', mode())
1851 call assert_equal(1, col('.'))
1852 "imap <buffer> , <c-\><c-n>
1853 set im
1854 exe ":norm! \<c-\>\<c-n>dw"
1855 set noim
1856 call assert_equal('are some words', getline(1))
1857 call assert_false(&insertmode)
1858
1859 " clean up
1860 bw!
1861endfu
1862
1863fun! Test_normal41_insert_reg()
1864 " Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>=
1865 " in insert mode
1866 new
1867 set sts=2 sw=2 ts=8 tw=0
1868 call append(0, ["aaa\tbbb\tccc", '', '', ''])
1869 let a=getline(1)
1870 norm! 2gg0
1871 exe "norm! a\<c-r>=a\<cr>"
1872 norm! 3gg0
1873 exe "norm! a\<c-r>\<c-r>=a\<cr>"
1874 norm! 4gg0
1875 exe "norm! a\<c-r>\<c-o>=a\<cr>"
1876 call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
1877
1878 " clean up
1879 set sts=0 sw=8 ts=8
1880 "bw!
1881endfu
1882
1883func! Test_normal42_halfpage()
1884 " basic test for Ctrl-D and Ctrl-U
1885 call Setup_NewWindow()
1886 call assert_equal(5, &scroll)
1887 exe "norm! \<c-d>"
1888 call assert_equal('6', getline('.'))
1889 exe "norm! 2\<c-d>"
1890 call assert_equal('8', getline('.'))
1891 call assert_equal(2, &scroll)
1892 set scroll=5
1893 exe "norm! \<c-u>"
1894 call assert_equal('3', getline('.'))
1895 1
1896 set scrolloff=5
1897 exe "norm! \<c-d>"
1898 call assert_equal('10', getline('.'))
1899 exe "norm! \<c-u>"
1900 call assert_equal('5', getline('.'))
1901 1
1902 set scrolloff=99
1903 exe "norm! \<c-d>"
1904 call assert_equal('10', getline('.'))
1905 set scrolloff=0
1906 100
1907 exe "norm! $\<c-u>"
1908 call assert_equal('95', getline('.'))
1909 call assert_equal([0, 95, 1, 0, 1], getcurpos())
1910 100
1911 set nostartofline
1912 exe "norm! $\<c-u>"
1913 call assert_equal('95', getline('.'))
1914 call assert_equal([0, 95, 2, 0, 2147483647], getcurpos())
1915 " cleanup
1916 set startofline
1917 bw!
1918endfu
1919
1920fun! Test_normal43_textobject1()
1921 " basic tests for text object aw
1922 new
1923 call append(0, ['foobar,eins,foobar', 'foo,zwei,foo '])
1924 " diw
1925 norm! 1gg0diw
1926 call assert_equal([',eins,foobar', 'foo,zwei,foo ', ''], getline(1,'$'))
1927 " daw
1928 norm! 2ggEdaw
1929 call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$'))
1930 %d
1931 call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "])
1932 " diW
1933 norm! 2ggwd2iW
1934 call assert_equal(['foo eins foobar', 'foo foo ', ''], getline(1,'$'))
1935 " daW
1936 norm! 1ggd2aW
1937 call assert_equal(['foobar', 'foo foo ', ''], getline(1,'$'))
1938
1939 %d
1940 call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "])
1941 " aw in visual line mode switches to characterwise mode
1942 norm! 2gg$Vawd
1943 call assert_equal(['foo eins foobar', 'foo zwei foo'], getline(1,'$'))
1944 norm! 1gg$Viwd
1945 call assert_equal(['foo eins ', 'foo zwei foo'], getline(1,'$'))
1946
1947 " clean up
1948 bw!
1949endfu
1950
1951func! Test_normal44_textobjects2()
1952 " basic testing for is and as text objects
1953 new
1954 call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
1955 " Test for dis - does not remove trailing whitespace
1956 norm! 1gg0dis
1957 call assert_equal([' With some sentences!', '', 'Even with a question? And one more. And no sentence here', ''], getline(1,'$'))
1958 " Test for das - removes leading whitespace
1959 norm! 3ggf?ldas
1960 call assert_equal([' With some sentences!', '', 'Even with a question? And no sentence here', ''], getline(1,'$'))
1961 " when used in visual mode, is made characterwise
1962 norm! 3gg$Visy
1963 call assert_equal('v', visualmode())
1964 " reset visualmode()
1965 norm! 3ggVy
1966 norm! 3gg$Vasy
1967 call assert_equal('v', visualmode())
1968 " basic testing for textobjects a< and at
1969 %d
1970 call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' '])
1971 " a<
1972 norm! 1gg0da<
1973 call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
1974 norm! 1pj
1975 call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
1976 " at
1977 norm! d2at
1978 call assert_equal([' '], getline(1,'$'))
1979 %d
1980 call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' '])
1981 " i<
1982 norm! 1gg0di<
1983 call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
1984 norm! 1Pj
1985 call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
1986 norm! d2it
1987 call assert_equal(['<div></div>',' '], getline(1,'$'))
1988 " basic testing for a[ and i[ text object
1989 %d
1990 call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
1991 norm! 3gg0di[
1992 call assert_equal([' ', '[', ']'], getline(1,'$'))
1993 call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
1994 norm! 3gg0ftd2a[
1995 call assert_equal([' '], getline(1,'$'))
1996 %d
1997 " Test for i" when cursor is in front of a quoted object
1998 call append(0, 'foo "bar"')
1999 norm! 1gg0di"
2000 call assert_equal(['foo ""', ''], getline(1,'$'))
2001
2002 " clean up
2003 bw!
2004endfu
2005
2006func! Test_normal45_drop()
2007 if !has("dnd")
2008 return
2009 endif
2010 " basic test for :drop command
2011 " unfortunately, without a gui, we can't really test much here,
2012 " so simply test that ~p fails (which uses the drop register)
2013 new
2014 call assert_fails(':norm! "~p', 'E353')
2015 call assert_equal([], getreg('~', 1, 1))
2016 " the ~ register is read only
2017 call assert_fails(':let @~="1"', 'E354')
2018 bw!
2019endfu
2020
2021func! Test_normal46_ignore()
2022 new
2023 " How to test this?
2024 " let's just for now test, that the buffer
2025 " does not change
2026 call feedkeys("\<c-s>", 't')
2027 call assert_equal([''], getline(1,'$'))
2028
2029 " clean up
2030 bw!
2031endfu