xref: /vim-8.2.3635/src/testdir/test_fold.vim (revision 8ea05de6)
1" Test for folding
2
3source check.vim
4source view_util.vim
5source screendump.vim
6
7func PrepIndent(arg)
8  return [a:arg] + repeat(["\t".a:arg], 5)
9endfu
10
11func Test_address_fold()
12  new
13  call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
14	      \ 'after fold 1', 'after fold 2', 'after fold 3'])
15  setl fen fdm=marker
16  " The next commands should all copy the same part of the buffer,
17  " regardless of the addressing type, since the part to be copied
18  " is folded away
19  :1y
20  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
21  :.y
22  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
23  :.+y
24  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
25  :.,.y
26  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
27  :sil .1,.y
28  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
29  " use silent to make E493 go away
30  :sil .+,.y
31  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
32  :,y
33  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
34  :,+y
35  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/','after fold 1'], getreg(0,1,1))
36  " using .+3 as second address should copy the whole folded line + the next 3
37  " lines
38  :.,+3y
39  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/',
40	      \ 'after fold 1', 'after fold 2', 'after fold 3'], getreg(0,1,1))
41  :sil .,-2y
42  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
43
44  " now test again with folding disabled
45  set nofoldenable
46  :1y
47  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
48  :.y
49  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
50  :.+y
51  call assert_equal(['1'], getreg(0,1,1))
52  :.,.y
53  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
54  " use silent to make E493 go away
55  :sil .1,.y
56  call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
57  " use silent to make E493 go away
58  :sil .+,.y
59  call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
60  :,y
61  call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
62  :,+y
63  call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
64  " using .+3 as second address should copy the whole folded line + the next 3
65  " lines
66  :.,+3y
67  call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3'], getreg(0,1,1))
68  :7
69  :sil .,-2y
70  call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1))
71
72  quit!
73endfunc
74
75func Test_indent_fold()
76    new
77    call setline(1, ['', 'a', '    b', '    c'])
78    setl fen fdm=indent
79    2
80    norm! >>
81    let a=map(range(1,4), 'foldclosed(v:val)')
82    call assert_equal([-1,-1,-1,-1], a)
83    bw!
84endfunc
85
86func Test_indent_fold2()
87    new
88    call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
89    setl fen fdm=marker
90    2
91    norm! >>
92    let a=map(range(1,5), 'v:val->foldclosed()')
93    call assert_equal([-1,-1,-1,4,4], a)
94    bw!
95endfunc
96
97func Test_manual_fold_with_filter()
98  CheckExecutable cat
99  for type in ['manual', 'marker']
100    exe 'set foldmethod=' . type
101    new
102    call setline(1, range(1, 20))
103    4,$fold
104    %foldopen
105    10,$fold
106    %foldopen
107    " This filter command should not have an effect
108    1,8! cat
109    call feedkeys('5ggzdzMGdd', 'xt')
110    call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
111
112    bwipe!
113    set foldmethod&
114  endfor
115endfunc
116
117func Test_indent_fold_with_read()
118  new
119  set foldmethod=indent
120  call setline(1, repeat(["\<Tab>a"], 4))
121  for n in range(1, 4)
122    call assert_equal(1, foldlevel(n))
123  endfor
124
125  call writefile(["a", "", "\<Tab>a"], 'Xfile')
126  foldopen
127  2read Xfile
128  %foldclose
129  call assert_equal(1, foldlevel(1))
130  call assert_equal(2, foldclosedend(1))
131  call assert_equal(0, foldlevel(3))
132  call assert_equal(0, foldlevel(4))
133  call assert_equal(1, foldlevel(5))
134  call assert_equal(7, 5->foldclosedend())
135
136  bwipe!
137  set foldmethod&
138  call delete('Xfile')
139endfunc
140
141func Test_combining_folds_indent()
142  new
143  let one = "\<Tab>a"
144  let zero = 'a'
145  call setline(1, [one, one, zero, zero, zero, one, one, one])
146  set foldmethod=indent
147  3,5d
148  %foldclose
149  call assert_equal(5, foldclosedend(1))
150
151  set foldmethod&
152  bwipe!
153endfunc
154
155func Test_combining_folds_marker()
156  new
157  call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
158  set foldmethod=marker
159  3,5d
160  %foldclose
161  call assert_equal(2, foldclosedend(1))
162
163  set foldmethod&
164  bwipe!
165endfunc
166
167func Test_folds_marker_in_comment()
168  new
169  call setline(1, ['" foo', 'bar', 'baz'])
170  setl fen fdm=marker
171  setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
172  norm! zf2j
173  setl nofen
174  :1y
175  call assert_equal(['" foo{{{'], getreg(0,1,1))
176  :+2y
177  call assert_equal(['baz"}}}'], getreg(0,1,1))
178
179  set foldmethod&
180  bwipe!
181endfunc
182
183func s:TestFoldExpr(lnum)
184  let thisline = getline(a:lnum)
185  if thisline == 'a'
186    return 1
187  elseif thisline == 'b'
188    return 0
189  elseif thisline == 'c'
190    return '<1'
191  elseif thisline == 'd'
192    return '>1'
193  endif
194  return 0
195endfunction
196
197func Test_update_folds_expr_read()
198  new
199  call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
200  set foldmethod=expr
201  set foldexpr=s:TestFoldExpr(v:lnum)
202  2
203  foldopen
204  call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
205  read Xfile
206  %foldclose
207  call assert_equal(2, foldclosedend(1))
208  call assert_equal(0, foldlevel(3))
209  call assert_equal(0, 4->foldlevel())
210  call assert_equal(6, foldclosedend(5))
211  call assert_equal(10, foldclosedend(7))
212  call assert_equal(14, foldclosedend(11))
213
214  call delete('Xfile')
215  bwipe!
216  set foldmethod& foldexpr&
217endfunc
218
219func Check_foldlevels(expected)
220  call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
221endfunc
222
223func Test_move_folds_around_manual()
224  new
225  let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
226  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
227  let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
228  " all folds closed
229  set foldenable foldlevel=0 fdm=indent
230  " needs a forced redraw
231  redraw!
232  set fdm=manual
233  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
234  call assert_equal(input, getline(1, '$'))
235  7,12m0
236  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
237  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
238  10,12m0
239  call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] +  PrepIndent("c"), getline(1, '$'))
240  call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
241  " moving should not close the folds
242  %d
243  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
244  set fdm=indent
245  redraw!
246  set fdm=manual
247  call cursor(2, 1)
248  %foldopen
249  7,12m0
250  let folds=repeat([-1], 18)
251  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
252  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
253  norm! zM
254  " folds are not corrupted and all have been closed
255  call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
256  %d
257  call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
258  set fdm=indent
259  redraw!
260  set fdm=manual
261  %foldopen
262  3m4
263  %foldclose
264  call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
265  call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
266  %d
267  call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
268  set fdm=indent foldlevel=0
269  set fdm=manual
270  %foldopen
271  3m1
272  %foldclose
273  call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
274  call assert_equal(0, foldlevel(2))
275  call assert_equal(5, foldclosedend(3))
276  call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
277  2,6m$
278  %foldclose
279  call assert_equal(5, foldclosedend(2))
280  call assert_equal(0, foldlevel(6))
281  call assert_equal(9, foldclosedend(7))
282  call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
283
284  %d
285  " Ensure moving around the edges still works.
286  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
287  set fdm=indent foldlevel=0
288  set fdm=manual
289  %foldopen
290  6m$
291  " The first fold has been truncated to the 5'th line.
292  " Second fold has been moved up because the moved line is now below it.
293  call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
294
295  %delete
296  set fdm=indent foldlevel=0
297  call setline(1, [
298	\ "a",
299	\ "\ta",
300	\ "\t\ta",
301	\ "\t\ta",
302	\ "\t\ta",
303	\ "a",
304	\ "a"])
305  set fdm=manual
306  %foldopen!
307  4,5m6
308  call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
309
310  %delete
311  set fdm=indent
312  call setline(1, [
313	\ "\ta",
314	\ "\t\ta",
315	\ "\t\ta",
316	\ "\t\ta",
317	\ "\ta",
318	\ "\t\ta",
319	\ "\t\ta",
320	\ "\t\ta",
321	\ "\ta",
322	\ "\t\ta",
323	\ "\t\ta",
324	\ "\t\ta",
325	\ "\t\ta",
326	\ "\ta",
327	\ "a"])
328  set fdm=manual
329  %foldopen!
330  13m7
331  call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
332
333  bw!
334endfunc
335
336func Test_move_folds_around_indent()
337  new
338  let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
339  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
340  let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
341  " all folds closed
342  set fdm=indent
343  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
344  call assert_equal(input, getline(1, '$'))
345  7,12m0
346  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
347  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
348  10,12m0
349  call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] +  PrepIndent("c"), getline(1, '$'))
350  call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
351  " moving should not close the folds
352  %d
353  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
354  set fdm=indent
355  call cursor(2, 1)
356  %foldopen
357  7,12m0
358  let folds=repeat([-1], 18)
359  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
360  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
361  norm! zM
362  " folds are not corrupted and all have been closed
363  call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
364  %d
365  call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
366  set fdm=indent
367  %foldopen
368  3m4
369  %foldclose
370  call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
371  call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
372  %d
373  call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
374  set fdm=indent foldlevel=0
375  %foldopen
376  3m1
377  %foldclose
378  call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
379  call assert_equal(1, foldlevel(2))
380  call assert_equal(5, foldclosedend(3))
381  call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
382  2,6m$
383  %foldclose
384  call assert_equal(9, foldclosedend(2))
385  call assert_equal(1, foldlevel(6))
386  call assert_equal(9, foldclosedend(7))
387  call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
388  " Ensure moving around the edges still works.
389  %d
390  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
391  set fdm=indent foldlevel=0
392  %foldopen
393  6m$
394  " The first fold has been truncated to the 5'th line.
395  " Second fold has been moved up because the moved line is now below it.
396  call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
397  bw!
398endfunc
399
400func Test_folddoopen_folddoclosed()
401  new
402  call setline(1, range(1, 9))
403  set foldmethod=manual
404  1,3 fold
405  6,8 fold
406
407  " Test without range.
408  folddoopen   s/$/o/
409  folddoclosed s/$/c/
410  call assert_equal(['1c', '2c', '3c',
411  \                  '4o', '5o',
412  \                  '6c', '7c', '8c',
413  \                  '9o'], getline(1, '$'))
414
415  " Test with range.
416  call setline(1, range(1, 9))
417  1,8 folddoopen   s/$/o/
418  4,$ folddoclosed s/$/c/
419  call assert_equal(['1',  '2', '3',
420  \                  '4o', '5o',
421  \                  '6c', '7c', '8c',
422  \                  '9'], getline(1, '$'))
423
424  set foldmethod&
425  bw!
426endfunc
427
428func Test_fold_error()
429  new
430  call setline(1, [1, 2])
431
432  for fm in ['indent', 'expr', 'syntax', 'diff']
433    exe 'set foldmethod=' . fm
434    call assert_fails('norm zf', 'E350:')
435    call assert_fails('norm zd', 'E351:')
436    call assert_fails('norm zE', 'E352:')
437  endfor
438
439  set foldmethod=manual
440  call assert_fails('norm zd', 'E490:')
441  call assert_fails('norm zo', 'E490:')
442  call assert_fails('3fold',   'E16:')
443
444  set foldmethod=marker
445  set nomodifiable
446  call assert_fails('1,2fold', 'E21:')
447
448  set modifiable&
449  set foldmethod&
450  bw!
451endfunc
452
453func Test_foldtext_recursive()
454  new
455  call setline(1, ['{{{', 'some text', '}}}'])
456  setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart)
457  " This was crashing because of endless recursion.
458  2foldclose
459  redraw
460  call assert_equal(1, foldlevel(2))
461  call assert_equal(1, foldclosed(2))
462  call assert_equal(3, foldclosedend(2))
463  bwipe!
464endfunc
465
466" Various fold related tests
467
468" Basic test if a fold can be created, opened, moving to the end and closed
469func Test_fold_manual()
470  enew!
471  set fdm=manual
472
473  let content = ['1 aa', '2 bb', '3 cc']
474  call append(0, content)
475  call cursor(1, 1)
476  normal zf2j
477  call assert_equal('1 aa', getline(foldclosed('.')))
478  normal zo
479  call assert_equal(-1, foldclosed('.'))
480  normal ]z
481  call assert_equal('3 cc', getline('.'))
482  normal zc
483  call assert_equal('1 aa', getline(foldclosed('.')))
484
485  set fdm&
486  enew!
487endfunc
488
489" test folding with markers.
490func Test_fold_marker()
491  enew!
492  set fdm=marker fdl=1 fdc=3
493
494  let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
495  call append(0, content)
496  call cursor(2, 1)
497  call assert_equal(2, foldlevel('.'))
498  normal [z
499  call assert_equal(1, foldlevel('.'))
500  exe "normal jo{{ \<Esc>r{jj"
501  call assert_equal(1, foldlevel('.'))
502  normal kYpj
503  call assert_equal(0, foldlevel('.'))
504
505  set fdm& fdl& fdc&
506  enew!
507endfunc
508
509" test create fold markers with C filetype
510func Test_fold_create_marker_in_C()
511  enew!
512  set fdm=marker fdl=9
513  set filetype=c
514
515  let content =<< trim [CODE]
516    /*
517     * comment
518     *
519     *
520     */
521    int f(int* p) {
522        *p = 3;
523        return 0;
524    }
525  [CODE]
526
527  for c in range(len(content) - 1)
528    bw!
529    call append(0, content)
530    call cursor(c + 1, 1)
531    norm! zfG
532    call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1))
533  endfor
534
535  set fdm& fdl&
536  enew!
537endfunc
538
539" test folding with indent
540func Test_fold_indent()
541  enew!
542  set fdm=indent sw=2
543
544  let content = ['1 aa', '2 bb', '3 cc']
545  call append(0, content)
546  call cursor(2, 1)
547  exe "normal i  \<Esc>jI    "
548  call assert_equal(2, foldlevel('.'))
549  normal k
550  call assert_equal(1, foldlevel('.'))
551
552  set fdm& sw&
553  enew!
554endfunc
555
556" test syntax folding
557func Test_fold_syntax()
558  CheckFeature syntax
559
560  enew!
561  set fdm=syntax fdl=0
562
563  syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
564  syn region Fd1 start="ee" end="ff" fold contained
565  syn region Fd2 start="gg" end="hh" fold contained
566  syn region Fd3 start="commentstart" end="commentend" fold contained
567  let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
568	      \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
569  call append(0, content)
570  normal Gzk
571  call assert_equal('9 ii', getline('.'))
572  normal k
573  call assert_equal('3 cc', getline('.'))
574  exe "normal jAcommentstart   \<Esc>Acommentend"
575  set fdl=1
576  normal 3j
577  call assert_equal('7 gg', getline('.'))
578  set fdl=0
579  exe "normal zO\<C-L>j"
580  call assert_equal('8 hh', getline('.'))
581  syn clear Fd1 Fd2 Fd3 Hup
582
583  set fdm& fdl&
584  enew!
585endfunc
586
587func Flvl()
588  let l = getline(v:lnum)
589  if l =~ "bb$"
590    return 2
591  elseif l =~ "gg$"
592    return "s1"
593  elseif l =~ "ii$"
594    return ">2"
595  elseif l =~ "kk$"
596    return "0"
597  endif
598  return "="
599endfun
600
601" test expression folding
602func Test_fold_expr()
603  enew!
604  set fdm=expr fde=Flvl()
605
606  let content = ['1 aa',
607	      \ '2 bb',
608	      \ '3 cc',
609	      \ '4 dd {{{commentstart  commentend',
610	      \ '5 ee {{{ }}}',
611	      \ '{{{',
612	      \ '6 ff }}}',
613	      \ '6 ff }}}',
614	      \ '  7 gg',
615	      \ '    8 hh',
616	      \ '9 ii',
617	      \ 'a jj',
618	      \ 'b kk']
619  call append(0, content)
620  call cursor(1, 1)
621  exe "normal /bb$\<CR>"
622  call assert_equal(2, foldlevel('.'))
623  exe "normal /hh$\<CR>"
624  call assert_equal(1, foldlevel('.'))
625  exe "normal /ii$\<CR>"
626  call assert_equal(2, foldlevel('.'))
627  exe "normal /kk$\<CR>"
628  call assert_equal(0, foldlevel('.'))
629
630  set fdm& fde&
631  enew!
632endfunc
633
634" Bug with fdm=indent and moving folds
635" Moving a fold a few times, messes up the folds below the moved fold.
636" Fixed by 7.4.700
637func Test_fold_move()
638  enew!
639  set fdm=indent sw=2 fdl=0
640
641  let content = ['', '', 'Line1', '  Line2', '  Line3',
642	      \ 'Line4', '  Line5', '  Line6',
643	      \ 'Line7', '  Line8', '  Line9']
644  call append(0, content)
645  normal zM
646  call cursor(4, 1)
647  move 2
648  move 1
649  call assert_equal(7, foldclosed(7))
650  call assert_equal(8, foldclosedend(7))
651  call assert_equal(0, foldlevel(9))
652  call assert_equal(10, foldclosed(10))
653  call assert_equal(11, foldclosedend(10))
654  call assert_equal('+--  2 lines: Line2', foldtextresult(2))
655  call assert_equal('+--  2 lines: Line8', 10->foldtextresult())
656
657  set fdm& sw& fdl&
658  enew!
659endfunc
660
661" test for patch 7.3.637
662" Cannot catch the error caused by a foldopen when there is no fold.
663func Test_foldopen_exception()
664  enew!
665  let a = 'No error caught'
666  try
667    foldopen
668  catch
669    let a = matchstr(v:exception,'^[^ ]*')
670  endtry
671  call assert_equal('Vim(foldopen):E490:', a)
672
673  let a = 'No error caught'
674  try
675    foobar
676  catch
677    let a = matchstr(v:exception,'^[^ ]*')
678  endtry
679  call assert_match('E492:', a)
680endfunc
681
682func Test_fold_last_line_with_pagedown()
683  enew!
684  set fdm=manual
685
686  let expect = '+-- 11 lines: 9---'
687  let content = range(1,19)
688  call append(0, content)
689  normal dd9G
690  normal zfG
691  normal zt
692  call assert_equal('9', getline(foldclosed('.')))
693  call assert_equal('19', getline(foldclosedend('.')))
694  call assert_equal(expect, ScreenLines(1, len(expect))[0])
695  call feedkeys("\<C-F>", 'xt')
696  call assert_equal(expect, ScreenLines(1, len(expect))[0])
697  call feedkeys("\<C-F>", 'xt')
698  call assert_equal(expect, ScreenLines(1, len(expect))[0])
699  call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt')
700  call assert_equal(expect, ScreenLines(1, len(expect))[0])
701
702  set fdm&
703  enew!
704endfunc
705
706func Test_folds_with_rnu()
707  CheckScreendump
708
709  call writefile([
710	\ 'set fdm=marker rnu foldcolumn=2',
711	\ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])',
712	\ ], 'Xtest_folds_with_rnu')
713  let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {})
714
715  call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {})
716  call term_sendkeys(buf, "j")
717  call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {})
718
719  " clean up
720  call StopVimInTerminal(buf)
721  call delete('Xtest_folds_with_rnu')
722endfunc
723
724func Test_folds_marker_in_comment2()
725  new
726  call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit'])
727  setl fen fdm=marker
728  setl commentstring=<!--%s-->
729  setl comments=s:<!--,m:\ \ \ \ ,e:-->
730  norm! zf2j
731  setl nofen
732  :1y
733  call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1))
734  :+2y
735  call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1))
736
737  set foldmethod&
738  bwipe!
739endfunc
740
741func Test_fold_delete_with_marker()
742  new
743  call setline(1, ['func Func() {{{1', 'endfunc'])
744  1,2yank
745  new
746  set fdm=marker
747  call setline(1, 'x')
748  normal! Vp
749  normal! zd
750  call assert_equal(['func Func() ', 'endfunc'], getline(1, '$'))
751
752  set fdm&
753  bwipe!
754  bwipe!
755endfunc
756
757func Test_fold_delete_with_marker_and_whichwrap()
758  new
759  let content1 = ['']
760  let content2 = ['folded line 1 "{{{1', '  test', '  test2', '  test3', '', 'folded line 2 "{{{1', '  test', '  test2', '  test3']
761  call setline(1, content1 + content2)
762  set fdm=marker ww+=l
763  normal! x
764  call assert_equal(content2, getline(1, '$'))
765  set fdm& ww&
766  bwipe!
767endfunc
768
769func Test_fold_delete_first_line()
770  new
771  call setline(1, [
772	\ '" x {{{1',
773	\ '" a',
774	\ '" aa',
775	\ '" x {{{1',
776	\ '" b',
777	\ '" bb',
778	\ '" x {{{1',
779	\ '" c',
780	\ '" cc',
781	\ ])
782  set foldmethod=marker
783  1
784  normal dj
785  call assert_equal([
786	\ '" x {{{1',
787	\ '" c',
788	\ '" cc',
789	\ ], getline(1,'$'))
790  bwipe!
791  set foldmethod&
792endfunc
793
794" Test for errors in 'foldexpr'
795func Test_fold_expr_error()
796  new
797  call setline(1, ['one', 'two', 'three'])
798
799  " Return a list from the expression
800  set foldexpr=[]
801  set foldmethod=expr
802  for i in range(3)
803    call assert_equal(0, foldlevel(i))
804  endfor
805
806  " expression error
807  set foldexpr=[{]
808  set foldmethod=expr
809  for i in range(3)
810    call assert_equal(0, foldlevel(i))
811  endfor
812
813  set foldmethod& foldexpr&
814  close!
815endfunc
816
817func Test_undo_fold_deletion()
818  new
819  set fdm=marker
820  let lines =<< trim END
821      " {{{
822      " }}}1
823      " {{{
824  END
825  call setline(1, lines)
826  3d
827  g/"/d
828  undo
829  redo
830  eval getline(1, '$')->assert_equal([''])
831
832  set fdm&vim
833  bwipe!
834endfunc
835
836" this was crashing
837func Test_move_no_folds()
838  new
839  fold
840  setlocal fdm=expr
841  normal zj
842  bwipe!
843endfunc
844
845" this was crashing
846func Test_fold_create_delete_create()
847  new
848  fold
849  fold
850  normal zd
851  fold
852  bwipe!
853endfunc
854
855" vim: shiftwidth=2 sts=2 expandtab
856