xref: /vim-8.2.3635/src/testdir/test_fold.vim (revision 68ffe8ca)
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
97" Test for fold indent with indents greater than 'foldnestmax'
98func Test_indent_fold_max()
99  new
100  setlocal foldmethod=indent
101  setlocal shiftwidth=2
102  " 'foldnestmax' default value is 20
103  call setline(1, "\t\t\t\t\t\ta")
104  call assert_equal(20, foldlevel(1))
105  setlocal foldnestmax=10
106  call assert_equal(10, foldlevel(1))
107  setlocal foldnestmax=-1
108  call assert_equal(0, foldlevel(1))
109  bw!
110endfunc
111
112func Test_manual_fold_with_filter()
113  CheckExecutable cat
114  for type in ['manual', 'marker']
115    exe 'set foldmethod=' . type
116    new
117    call setline(1, range(1, 20))
118    4,$fold
119    %foldopen
120    10,$fold
121    %foldopen
122    " This filter command should not have an effect
123    1,8! cat
124    call feedkeys('5ggzdzMGdd', 'xt')
125    call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
126
127    bwipe!
128    set foldmethod&
129  endfor
130endfunc
131
132func Test_indent_fold_with_read()
133  new
134  set foldmethod=indent
135  call setline(1, repeat(["\<Tab>a"], 4))
136  for n in range(1, 4)
137    call assert_equal(1, foldlevel(n))
138  endfor
139
140  call writefile(["a", "", "\<Tab>a"], 'Xfile')
141  foldopen
142  2read Xfile
143  %foldclose
144  call assert_equal(1, foldlevel(1))
145  call assert_equal(2, foldclosedend(1))
146  call assert_equal(0, foldlevel(3))
147  call assert_equal(0, foldlevel(4))
148  call assert_equal(1, foldlevel(5))
149  call assert_equal(7, 5->foldclosedend())
150
151  bwipe!
152  set foldmethod&
153  call delete('Xfile')
154endfunc
155
156func Test_combining_folds_indent()
157  new
158  let one = "\<Tab>a"
159  let zero = 'a'
160  call setline(1, [one, one, zero, zero, zero, one, one, one])
161  set foldmethod=indent
162  3,5d
163  %foldclose
164  call assert_equal(5, foldclosedend(1))
165
166  set foldmethod&
167  bwipe!
168endfunc
169
170func Test_combining_folds_marker()
171  new
172  call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
173  set foldmethod=marker
174  3,5d
175  %foldclose
176  call assert_equal(2, foldclosedend(1))
177
178  set foldmethod&
179  bwipe!
180endfunc
181
182func Test_folds_marker_in_comment()
183  new
184  call setline(1, ['" foo', 'bar', 'baz'])
185  setl fen fdm=marker
186  setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
187  norm! zf2j
188  setl nofen
189  :1y
190  call assert_equal(['" foo{{{'], getreg(0,1,1))
191  :+2y
192  call assert_equal(['baz"}}}'], getreg(0,1,1))
193
194  set foldmethod&
195  bwipe!
196endfunc
197
198func s:TestFoldExpr(lnum)
199  let thisline = getline(a:lnum)
200  if thisline == 'a'
201    return 1
202  elseif thisline == 'b'
203    return 0
204  elseif thisline == 'c'
205    return '<1'
206  elseif thisline == 'd'
207    return '>1'
208  endif
209  return 0
210endfunction
211
212func Test_update_folds_expr_read()
213  new
214  call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
215  set foldmethod=expr
216  set foldexpr=s:TestFoldExpr(v:lnum)
217  2
218  foldopen
219  call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
220  read Xfile
221  %foldclose
222  call assert_equal(2, foldclosedend(1))
223  call assert_equal(0, foldlevel(3))
224  call assert_equal(0, 4->foldlevel())
225  call assert_equal(6, foldclosedend(5))
226  call assert_equal(10, foldclosedend(7))
227  call assert_equal(14, foldclosedend(11))
228
229  call delete('Xfile')
230  bwipe!
231  set foldmethod& foldexpr&
232endfunc
233
234func Check_foldlevels(expected)
235  call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
236endfunc
237
238func Test_move_folds_around_manual()
239  new
240  let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
241  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
242  let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
243  " all folds closed
244  set foldenable foldlevel=0 fdm=indent
245  " needs a forced redraw
246  redraw!
247  set fdm=manual
248  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
249  call assert_equal(input, getline(1, '$'))
250  7,12m0
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  10,12m0
254  call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] +  PrepIndent("c"), getline(1, '$'))
255  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)'))
256  " moving should not close the folds
257  %d
258  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
259  set fdm=indent
260  redraw!
261  set fdm=manual
262  call cursor(2, 1)
263  %foldopen
264  7,12m0
265  let folds=repeat([-1], 18)
266  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
267  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
268  norm! zM
269  " folds are not corrupted and all have been closed
270  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)'))
271  %d
272  call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
273  set fdm=indent
274  redraw!
275  set fdm=manual
276  %foldopen
277  3m4
278  %foldclose
279  call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
280  call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
281  %d
282  call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
283  set fdm=indent foldlevel=0
284  set fdm=manual
285  %foldopen
286  3m1
287  %foldclose
288  call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
289  call assert_equal(0, foldlevel(2))
290  call assert_equal(5, foldclosedend(3))
291  call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
292  2,6m$
293  %foldclose
294  call assert_equal(5, foldclosedend(2))
295  call assert_equal(0, foldlevel(6))
296  call assert_equal(9, foldclosedend(7))
297  call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
298
299  %d
300  " Ensure moving around the edges still works.
301  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
302  set fdm=indent foldlevel=0
303  set fdm=manual
304  %foldopen
305  6m$
306  " The first fold has been truncated to the 5'th line.
307  " Second fold has been moved up because the moved line is now below it.
308  call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
309
310  %delete
311  set fdm=indent foldlevel=0
312  call setline(1, [
313	\ "a",
314	\ "\ta",
315	\ "\t\ta",
316	\ "\t\ta",
317	\ "\t\ta",
318	\ "a",
319	\ "a"])
320  set fdm=manual
321  %foldopen!
322  4,5m6
323  call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
324
325  %delete
326  set fdm=indent
327  call setline(1, [
328	\ "\ta",
329	\ "\t\ta",
330	\ "\t\ta",
331	\ "\t\ta",
332	\ "\ta",
333	\ "\t\ta",
334	\ "\t\ta",
335	\ "\t\ta",
336	\ "\ta",
337	\ "\t\ta",
338	\ "\t\ta",
339	\ "\t\ta",
340	\ "\t\ta",
341	\ "\ta",
342	\ "a"])
343  set fdm=manual
344  %foldopen!
345  13m7
346  call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
347
348  bw!
349endfunc
350
351func Test_move_folds_around_indent()
352  new
353  let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
354  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
355  let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
356  " all folds closed
357  set fdm=indent
358  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
359  call assert_equal(input, getline(1, '$'))
360  7,12m0
361  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
362  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
363  10,12m0
364  call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] +  PrepIndent("c"), getline(1, '$'))
365  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)'))
366  " moving should not close the folds
367  %d
368  call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
369  set fdm=indent
370  call cursor(2, 1)
371  %foldopen
372  7,12m0
373  let folds=repeat([-1], 18)
374  call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
375  call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
376  norm! zM
377  " folds are not corrupted and all have been closed
378  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)'))
379  %d
380  call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
381  set fdm=indent
382  %foldopen
383  3m4
384  %foldclose
385  call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
386  call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
387  %d
388  call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
389  set fdm=indent foldlevel=0
390  %foldopen
391  3m1
392  %foldclose
393  call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
394  call assert_equal(1, foldlevel(2))
395  call assert_equal(5, foldclosedend(3))
396  call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
397  2,6m$
398  %foldclose
399  call assert_equal(9, foldclosedend(2))
400  call assert_equal(1, foldlevel(6))
401  call assert_equal(9, foldclosedend(7))
402  call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
403  " Ensure moving around the edges still works.
404  %d
405  call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
406  set fdm=indent foldlevel=0
407  %foldopen
408  6m$
409  " The first fold has been truncated to the 5'th line.
410  " Second fold has been moved up because the moved line is now below it.
411  call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
412  bw!
413endfunc
414
415func Test_folddoopen_folddoclosed()
416  new
417  call setline(1, range(1, 9))
418  set foldmethod=manual
419  1,3 fold
420  6,8 fold
421
422  " Test without range.
423  folddoopen   s/$/o/
424  folddoclosed s/$/c/
425  call assert_equal(['1c', '2c', '3c',
426  \                  '4o', '5o',
427  \                  '6c', '7c', '8c',
428  \                  '9o'], getline(1, '$'))
429
430  " Test with range.
431  call setline(1, range(1, 9))
432  1,8 folddoopen   s/$/o/
433  4,$ folddoclosed s/$/c/
434  call assert_equal(['1',  '2', '3',
435  \                  '4o', '5o',
436  \                  '6c', '7c', '8c',
437  \                  '9'], getline(1, '$'))
438
439  set foldmethod&
440  bw!
441endfunc
442
443func Test_fold_error()
444  new
445  call setline(1, [1, 2])
446
447  for fm in ['indent', 'expr', 'syntax', 'diff']
448    exe 'set foldmethod=' . fm
449    call assert_fails('norm zf', 'E350:')
450    call assert_fails('norm zd', 'E351:')
451    call assert_fails('norm zE', 'E352:')
452  endfor
453
454  set foldmethod=manual
455  call assert_fails('norm zd', 'E490:')
456  call assert_fails('norm zo', 'E490:')
457  call assert_fails('3fold',   'E16:')
458
459  set foldmethod=marker
460  set nomodifiable
461  call assert_fails('1,2fold', 'E21:')
462
463  set modifiable&
464  set foldmethod&
465  bw!
466endfunc
467
468func Test_foldtext_recursive()
469  new
470  call setline(1, ['{{{', 'some text', '}}}'])
471  setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart)
472  " This was crashing because of endless recursion.
473  2foldclose
474  redraw
475  call assert_equal(1, foldlevel(2))
476  call assert_equal(1, foldclosed(2))
477  call assert_equal(3, foldclosedend(2))
478  bwipe!
479endfunc
480
481" Various fold related tests
482
483" Basic test if a fold can be created, opened, moving to the end and closed
484func Test_fold_manual()
485  new
486  set fdm=manual
487
488  let content = ['1 aa', '2 bb', '3 cc']
489  call append(0, content)
490  call cursor(1, 1)
491  normal zf2j
492  call assert_equal('1 aa', getline(foldclosed('.')))
493  normal zo
494  call assert_equal(-1, foldclosed('.'))
495  normal ]z
496  call assert_equal('3 cc', getline('.'))
497  normal zc
498  call assert_equal('1 aa', getline(foldclosed('.')))
499
500  " Create a fold inside a closed fold after setting 'foldlevel'
501  %d _
502  call setline(1, range(1, 5))
503  1,5fold
504  normal zR
505  2,4fold
506  set foldlevel=1
507  3fold
508  call assert_equal([1, 3, 3, 3, 1], map(range(1, 5), {->foldlevel(v:val)}))
509  set foldlevel&
510
511  " Create overlapping folds (at the start and at the end)
512  normal zE
513  2,3fold
514  normal zR
515  3,4fold
516  call assert_equal([0, 2, 2, 1, 0], map(range(1, 5), {->foldlevel(v:val)}))
517  normal zE
518  3,4fold
519  normal zR
520  2,3fold
521  call assert_equal([0, 1, 2, 2, 0], map(range(1, 5), {->foldlevel(v:val)}))
522
523  " Create a nested fold across two non-adjoining folds
524  %d _
525  call setline(1, range(1, 7))
526  1,2fold
527  normal zR
528  4,5fold
529  normal zR
530  6,7fold
531  normal zR
532  1,5fold
533  call assert_equal([2, 2, 1, 2, 2, 1, 1],
534        \ map(range(1, 7), {->foldlevel(v:val)}))
535
536  " A newly created nested fold should be closed
537  %d _
538  call setline(1, range(1, 6))
539  1,6fold
540  normal zR
541  3,4fold
542  normal zR
543  2,5fold
544  call assert_equal([1, 2, 3, 3, 2, 1], map(range(1, 6), {->foldlevel(v:val)}))
545  call assert_equal(2, foldclosed(4))
546  call assert_equal(5, foldclosedend(4))
547
548  " Test zO, zC and zA on a line with no folds.
549  normal zE
550  call assert_fails('normal zO', 'E490:')
551  call assert_fails('normal zC', 'E490:')
552  call assert_fails('normal zA', 'E490:')
553
554  set fdm&
555  bw!
556endfunc
557
558" test folding with markers.
559func Test_fold_marker()
560  new
561  set fdm=marker fdl=1 fdc=3
562
563  let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
564  call append(0, content)
565  call cursor(2, 1)
566  call assert_equal(2, foldlevel('.'))
567  normal [z
568  call assert_equal(1, foldlevel('.'))
569  exe "normal jo{{ \<Esc>r{jj"
570  call assert_equal(1, foldlevel('.'))
571  normal kYpj
572  call assert_equal(0, foldlevel('.'))
573
574  " Use only closing fold marker (without and with a count)
575  set fdl&
576  %d _
577  call setline(1, ['one }}}', 'two'])
578  call assert_equal([0, 0], [foldlevel(1), foldlevel(2)])
579  %d _
580  call setline(1, ['one }}}4', 'two'])
581  call assert_equal([4, 3], [foldlevel(1), foldlevel(2)])
582
583  set fdm& fdl& fdc&
584  bw!
585endfunc
586
587" test create fold markers with C filetype
588func Test_fold_create_marker_in_C()
589  bw!
590  set fdm=marker fdl=9
591  set filetype=c
592
593  let content =<< trim [CODE]
594    /*
595     * comment
596     *
597     *
598     */
599    int f(int* p) {
600        *p = 3;
601        return 0;
602    }
603  [CODE]
604
605  for c in range(len(content) - 1)
606    bw!
607    call append(0, content)
608    call cursor(c + 1, 1)
609    norm! zfG
610    call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1))
611  endfor
612
613  set fdm& fdl&
614  bw!
615endfunc
616
617" test folding with indent
618func Test_fold_indent()
619  new
620  set fdm=indent sw=2
621
622  let content = ['1 aa', '2 bb', '3 cc']
623  call append(0, content)
624  call cursor(2, 1)
625  exe "normal i  \<Esc>jI    "
626  call assert_equal(2, foldlevel('.'))
627  normal k
628  call assert_equal(1, foldlevel('.'))
629
630  set fdm& sw&
631  bw!
632endfunc
633
634" test syntax folding
635func Test_fold_syntax()
636  CheckFeature syntax
637
638  new
639  set fdm=syntax fdl=0
640
641  syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
642  syn region Fd1 start="ee" end="ff" fold contained
643  syn region Fd2 start="gg" end="hh" fold contained
644  syn region Fd3 start="commentstart" end="commentend" fold contained
645  let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
646	      \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
647  call append(0, content)
648  normal Gzk
649  call assert_equal('9 ii', getline('.'))
650  normal k
651  call assert_equal('3 cc', getline('.'))
652  exe "normal jAcommentstart   \<Esc>Acommentend"
653  set fdl=1
654  normal 3j
655  call assert_equal('7 gg', getline('.'))
656  set fdl=0
657  exe "normal zO\<C-L>j"
658  call assert_equal('8 hh', getline('.'))
659  syn clear Fd1 Fd2 Fd3 Hup
660
661  set fdm& fdl&
662  bw!
663endfunc
664
665func Flvl()
666  let l = getline(v:lnum)
667  if l =~ "bb$"
668    return 2
669  elseif l =~ "gg$"
670    return "s1"
671  elseif l =~ "ii$"
672    return ">2"
673  elseif l =~ "kk$"
674    return "0"
675  endif
676  return "="
677endfun
678
679" test expression folding
680func Test_fold_expr()
681  new
682  set fdm=expr fde=Flvl()
683
684  let content = ['1 aa',
685	      \ '2 bb',
686	      \ '3 cc',
687	      \ '4 dd {{{commentstart  commentend',
688	      \ '5 ee {{{ }}}',
689	      \ '{{{',
690	      \ '6 ff }}}',
691	      \ '6 ff }}}',
692	      \ '  7 gg',
693	      \ '    8 hh',
694	      \ '9 ii',
695	      \ 'a jj',
696	      \ 'b kk']
697  call append(0, content)
698  call cursor(1, 1)
699  exe "normal /bb$\<CR>"
700  call assert_equal(2, foldlevel('.'))
701  exe "normal /hh$\<CR>"
702  call assert_equal(1, foldlevel('.'))
703  exe "normal /ii$\<CR>"
704  call assert_equal(2, foldlevel('.'))
705  exe "normal /kk$\<CR>"
706  call assert_equal(0, foldlevel('.'))
707
708  set fdm& fde&
709  bw!
710endfunc
711
712" Bug with fdm=indent and moving folds
713" Moving a fold a few times, messes up the folds below the moved fold.
714" Fixed by 7.4.700
715func Test_fold_move()
716  new
717  set fdm=indent sw=2 fdl=0
718
719  let content = ['', '', 'Line1', '  Line2', '  Line3',
720	      \ 'Line4', '  Line5', '  Line6',
721	      \ 'Line7', '  Line8', '  Line9']
722  call append(0, content)
723  normal zM
724  call cursor(4, 1)
725  move 2
726  move 1
727  call assert_equal(7, foldclosed(7))
728  call assert_equal(8, foldclosedend(7))
729  call assert_equal(0, foldlevel(9))
730  call assert_equal(10, foldclosed(10))
731  call assert_equal(11, foldclosedend(10))
732  call assert_equal('+--  2 lines: Line2', foldtextresult(2))
733  call assert_equal('+--  2 lines: Line8', 10->foldtextresult())
734
735  set fdm& sw& fdl&
736  bw!
737endfunc
738
739" test for patch 7.3.637
740" Cannot catch the error caused by a foldopen when there is no fold.
741func Test_foldopen_exception()
742  new
743  let a = 'No error caught'
744  try
745    foldopen
746  catch
747    let a = matchstr(v:exception,'^[^ ]*')
748  endtry
749  call assert_equal('Vim(foldopen):E490:', a)
750
751  let a = 'No error caught'
752  try
753    foobar
754  catch
755    let a = matchstr(v:exception,'^[^ ]*')
756  endtry
757  call assert_match('E492:', a)
758  bw!
759endfunc
760
761func Test_fold_last_line_with_pagedown()
762  new
763  set fdm=manual
764
765  let expect = '+-- 11 lines: 9---'
766  let content = range(1,19)
767  call append(0, content)
768  normal dd9G
769  normal zfG
770  normal zt
771  call assert_equal('9', getline(foldclosed('.')))
772  call assert_equal('19', getline(foldclosedend('.')))
773  call assert_equal(expect, ScreenLines(1, len(expect))[0])
774  call feedkeys("\<C-F>", 'xt')
775  call assert_equal(expect, ScreenLines(1, len(expect))[0])
776  call feedkeys("\<C-F>", 'xt')
777  call assert_equal(expect, ScreenLines(1, len(expect))[0])
778  call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt')
779  call assert_equal(expect, ScreenLines(1, len(expect))[0])
780
781  set fdm&
782  bw!
783endfunc
784
785func Test_folds_with_rnu()
786  CheckScreendump
787
788  call writefile([
789	\ 'set fdm=marker rnu foldcolumn=2',
790	\ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])',
791	\ ], 'Xtest_folds_with_rnu')
792  let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {})
793
794  call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {})
795  call term_sendkeys(buf, "j")
796  call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {})
797
798  " clean up
799  call StopVimInTerminal(buf)
800  call delete('Xtest_folds_with_rnu')
801endfunc
802
803func Test_folds_marker_in_comment2()
804  new
805  call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit'])
806  setl fen fdm=marker
807  setl commentstring=<!--%s-->
808  setl comments=s:<!--,m:\ \ \ \ ,e:-->
809  norm! zf2j
810  setl nofen
811  :1y
812  call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1))
813  :+2y
814  call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1))
815
816  set foldmethod&
817  bwipe!
818endfunc
819
820func Test_fold_delete_with_marker()
821  new
822  call setline(1, ['func Func() {{{1', 'endfunc'])
823  1,2yank
824  new
825  set fdm=marker
826  call setline(1, 'x')
827  normal! Vp
828  normal! zd
829  call assert_equal(['func Func() ', 'endfunc'], getline(1, '$'))
830
831  set fdm&
832  bwipe!
833  bwipe!
834endfunc
835
836func Test_fold_delete_with_marker_and_whichwrap()
837  new
838  let content1 = ['']
839  let content2 = ['folded line 1 "{{{1', '  test', '  test2', '  test3', '', 'folded line 2 "{{{1', '  test', '  test2', '  test3']
840  call setline(1, content1 + content2)
841  set fdm=marker ww+=l
842  normal! x
843  call assert_equal(content2, getline(1, '$'))
844  set fdm& ww&
845  bwipe!
846endfunc
847
848func Test_fold_delete_first_line()
849  new
850  call setline(1, [
851	\ '" x {{{1',
852	\ '" a',
853	\ '" aa',
854	\ '" x {{{1',
855	\ '" b',
856	\ '" bb',
857	\ '" x {{{1',
858	\ '" c',
859	\ '" cc',
860	\ ])
861  set foldmethod=marker
862  1
863  normal dj
864  call assert_equal([
865	\ '" x {{{1',
866	\ '" c',
867	\ '" cc',
868	\ ], getline(1,'$'))
869  bwipe!
870  set foldmethod&
871endfunc
872
873" Add a test for deleting the outer fold of a nested fold and promoting the
874" inner folds to one level up with already a fold at that level following the
875" nested fold.
876func Test_fold_delete_recursive_fold()
877  new
878  call setline(1, range(1, 7))
879  2,3fold
880  normal zR
881  4,5fold
882  normal zR
883  1,5fold
884  normal zR
885  6,7fold
886  normal zR
887  normal 1Gzd
888  normal 1Gzj
889  call assert_equal(2, line('.'))
890  normal zj
891  call assert_equal(4, line('.'))
892  normal zj
893  call assert_equal(6, line('.'))
894  bw!
895endfunc
896
897" Test for errors in 'foldexpr'
898func Test_fold_expr_error()
899  new
900  call setline(1, ['one', 'two', 'three'])
901  " In a window with no folds, foldlevel() should return 0
902  call assert_equal(0, foldlevel(1))
903
904  " Return a list from the expression
905  set foldexpr=[]
906  set foldmethod=expr
907  for i in range(3)
908    call assert_equal(0, foldlevel(i))
909  endfor
910
911  " expression error
912  set foldexpr=[{]
913  set foldmethod=expr
914  for i in range(3)
915    call assert_equal(0, foldlevel(i))
916  endfor
917
918  set foldmethod& foldexpr&
919  close!
920endfunc
921
922func Test_undo_fold_deletion()
923  new
924  set fdm=marker
925  let lines =<< trim END
926      " {{{
927      " }}}1
928      " {{{
929  END
930  call setline(1, lines)
931  3d
932  g/"/d
933  undo
934  redo
935  eval getline(1, '$')->assert_equal([''])
936
937  set fdm&vim
938  bwipe!
939endfunc
940
941" this was crashing
942func Test_move_no_folds()
943  new
944  fold
945  setlocal fdm=expr
946  normal zj
947  bwipe!
948endfunc
949
950" this was crashing
951func Test_fold_create_delete_create()
952  new
953  fold
954  fold
955  normal zd
956  fold
957  bwipe!
958endfunc
959
960" this was crashing
961func Test_fold_create_delete()
962  new
963  norm zFzFzdzj
964  bwipe!
965endfunc
966
967func Test_fold_relative_move()
968  new
969  set fdm=indent sw=2 wrap tw=80
970
971  let longtext = repeat('x', &columns + 1)
972  let content = [ '  foo', '  ' .. longtext, '  baz',
973              \   longtext,
974              \   '  foo', '  ' .. longtext, '  baz'
975              \ ]
976  call append(0, content)
977
978  normal zM
979
980  for lnum in range(1, 3)
981    call cursor(lnum, 1)
982    call assert_true(foldclosed(line('.')))
983    normal gj
984    call assert_equal(2, winline())
985  endfor
986
987  call cursor(2, 1)
988  call assert_true(foldclosed(line('.')))
989  normal 2gj
990  call assert_equal(3, winline())
991
992  for lnum in range(5, 7)
993    call cursor(lnum, 1)
994    call assert_true(foldclosed(line('.')))
995    normal gk
996    call assert_equal(3, winline())
997  endfor
998
999  call cursor(6, 1)
1000  call assert_true(foldclosed(line('.')))
1001  normal 2gk
1002  call assert_equal(2, winline())
1003
1004  set fdm& sw& wrap& tw&
1005  bw!
1006endfunc
1007
1008" Test for using multibyte characters as 'foldopen', 'foldclose' and
1009" 'foldsetp' items in 'fillchars'
1010func s:mbyte_fillchar_tests(fo, fc, fs)
1011  setlocal foldcolumn=3
1012
1013  normal zE
1014  1,2fold
1015  call assert_equal([a:fc .. '  +--  2 ', '   three  '],
1016        \ ScreenLines([1, 2], 10))
1017  1,2foldopen
1018  call assert_equal([a:fo .. '  one ', a:fs .. '  two '],
1019        \ ScreenLines([1, 2], 7))
1020  1,2foldclose
1021  redraw!
1022  call assert_equal([a:fc .. '  +--  2 ', '   three  '],
1023        \  ScreenLines([1, 2], 10))
1024
1025  " Two level fold
1026  normal zE
1027  2,3fold
1028  1,4fold
1029  call assert_equal([a:fc .. '  +--  4 ', '   five   '],
1030        \ ScreenLines([1, 2], 10))
1031  1,4foldopen
1032  call assert_equal([a:fo .. '  one    ', a:fs .. a:fc .. ' +---  2'],
1033        \ ScreenLines([1, 2], 10))
1034  1,4foldopen
1035  call assert_equal([a:fo .. '  one    ', a:fs .. a:fo .. ' two    ',
1036        \ a:fs .. a:fs .. ' three  '], ScreenLines([1, 3], 10))
1037  2,3foldclose
1038  call assert_equal([a:fo .. '  one    ', a:fs .. a:fc .. ' +---  2'],
1039        \ ScreenLines([1, 2], 10))
1040  1,4foldclose
1041  call assert_equal([a:fc .. '  +--  4 ', '   five   '],
1042        \ ScreenLines([1, 2], 10))
1043
1044  " Three level fold
1045  normal zE
1046  3,4fold
1047  2,5fold
1048  1,6fold
1049  call assert_equal([a:fc .. '  +--  6 '], ScreenLines(1, 10))
1050  " open all the folds
1051  normal zR
1052  call assert_equal([
1053        \ a:fo .. '  one    ',
1054        \ a:fs .. a:fo .. ' two    ',
1055        \ '2' .. a:fo .. ' three  ',
1056        \ '23 four   ',
1057        \ a:fs .. a:fs .. ' five   ',
1058        \ a:fs .. '  six    ',
1059        \ ], ScreenLines([1, 6], 10))
1060  " close the innermost fold
1061  3,4foldclose
1062  call assert_equal([
1063        \ a:fo .. '  one    ',
1064        \ a:fs .. a:fo .. ' two    ',
1065        \ a:fs .. a:fs .. a:fc .. '+----  ',
1066        \ a:fs .. a:fs .. ' five   ',
1067        \ a:fs .. '  six    ',
1068        \ ], ScreenLines([1, 5], 10))
1069  " close the next fold
1070  2,5foldclose
1071  call assert_equal([
1072        \ a:fo .. '  one    ',
1073        \ a:fs .. a:fc .. ' +---  4',
1074        \ a:fs .. '  six    ',
1075        \ ], ScreenLines([1, 3], 10))
1076
1077  " set the fold column size to 2
1078  setlocal fdc=2
1079  normal zR
1080  call assert_equal([
1081        \ a:fo .. ' one  ',
1082        \ a:fo .. ' two  ',
1083        \ a:fo .. ' three',
1084        \ '3 four ',
1085        \ '2 five ',
1086        \ a:fs .. ' six  ',
1087        \ ], ScreenLines([1, 6], 7))
1088
1089  " set the fold column size to 1
1090  setlocal fdc=1
1091  normal zR
1092  call assert_equal([
1093        \ a:fo .. 'one   ',
1094        \ a:fo .. 'two   ',
1095        \ a:fo .. 'three ',
1096        \ '3four  ',
1097        \ '2five  ',
1098        \ a:fs .. 'six   ',
1099        \ ], ScreenLines([1, 6], 7))
1100
1101  " Enable number and sign columns and place some signs
1102  setlocal fdc=3
1103  setlocal number
1104  setlocal signcolumn=auto
1105  sign define S1 text=->
1106  sign place 10 line=3 name=S1
1107  call assert_equal([
1108        \ a:fo .. '      1 one  ',
1109        \ a:fs .. a:fo .. '     2 two  ',
1110        \ '2' .. a:fo .. ' ->  3 three',
1111        \ '23     4 four ',
1112        \ a:fs .. a:fs .. '     5 five ',
1113        \ a:fs .. '      6 six  '
1114        \ ], ScreenLines([1, 6], 14))
1115
1116  " Test with 'rightleft'
1117  if has('rightleft')
1118    setlocal rightleft
1119    let lines = ScreenLines([1, 6], winwidth(0))
1120    call assert_equal('o 1      ' .. a:fo,
1121          \  strcharpart(lines[0], strchars(lines[0]) - 10, 10))
1122    call assert_equal('t 2     ' .. a:fo .. a:fs,
1123          \  strcharpart(lines[1], strchars(lines[1]) - 10, 10))
1124    call assert_equal('t 3  >- ' .. a:fo .. '2',
1125          \  strcharpart(lines[2], strchars(lines[2]) - 10, 10))
1126    call assert_equal('f 4     32',
1127          \  strcharpart(lines[3], strchars(lines[3]) - 10, 10))
1128    call assert_equal('f 5     ' .. a:fs .. a:fs,
1129          \  strcharpart(lines[4], strchars(lines[4]) - 10, 10))
1130    call assert_equal('s 6      ' .. a:fs,
1131          \  strcharpart(lines[5], strchars(lines[5]) - 10, 10))
1132    setlocal norightleft
1133  endif
1134
1135  sign unplace *
1136  sign undefine S1
1137  setlocal number& signcolumn&
1138
1139  " Add a test with more than 9 folds (and then delete some folds)
1140  normal zE
1141  for i in range(1, 10)
1142    normal zfGzo
1143  endfor
1144  normal zR
1145  call assert_equal([
1146        \ a:fo .. a:fo .. ' one ',
1147        \ '9> two '
1148        \ ], ScreenLines([1, 2], 7))
1149  normal 1Gzd
1150  call assert_equal([
1151        \ a:fo .. a:fo .. ' one ',
1152        \ '89 two '
1153        \ ], ScreenLines([1, 2], 7))
1154  normal 1Gzdzdzdzdzdzdzd
1155  call assert_equal([
1156        \ a:fo .. a:fo .. ' one ',
1157        \ a:fs .. a:fs .. ' two '
1158        \ ], ScreenLines([1, 2], 7))
1159
1160  setlocal foldcolumn& number& signcolumn&
1161endfunc
1162
1163func Test_foldcolumn_multibyte_char()
1164  new
1165  call setline(1, ['one', 'two', 'three', 'four', 'five', 'six'])
1166  setlocal foldenable foldmethod=manual
1167
1168  " First test with the default setting
1169  call s:mbyte_fillchar_tests('-', '+', '|')
1170
1171  " Use multi-byte characters
1172  set fillchars+=foldopen:▾,foldsep:│,foldclose:▸
1173  call s:mbyte_fillchar_tests('▾', '▸', '│')
1174
1175  " Use a mix of multi-byte and single-byte characters
1176  set fillchars+=foldopen:¬,foldsep:\|,foldclose:+
1177  call s:mbyte_fillchar_tests('¬', '+', '|')
1178  set fillchars+=foldopen:+,foldsep:\|,foldclose:¬
1179  call s:mbyte_fillchar_tests('+', '¬', '|')
1180
1181  bw!
1182  set foldenable& fdc& fdm& fillchars&
1183endfunc
1184
1185" Test for calling foldlevel() from a fold expression
1186let g:FoldLevels = []
1187func FoldExpr1(lnum)
1188  let f = [a:lnum]
1189  for i in range(1, line('$'))
1190    call add(f, foldlevel(i))
1191  endfor
1192  call add(g:FoldLevels, f)
1193  return getline(a:lnum)[0] == "\t"
1194endfunc
1195
1196func Test_foldexpr_foldlevel()
1197  new
1198  call setline(1, ['one', "\ttwo", "\tthree"])
1199  setlocal foldmethod=expr
1200  setlocal foldexpr=FoldExpr1(v:lnum)
1201  setlocal foldenable
1202  setlocal foldcolumn=3
1203  redraw!
1204  call assert_equal([[1, -1, -1, -1], [2, -1, -1, -1], [3, 0, 1, -1]],
1205        \ g:FoldLevels)
1206  set foldmethod& foldexpr& foldenable& foldcolumn&
1207  bw!
1208endfunc
1209
1210" Test for returning different values from a fold expression
1211func FoldExpr2(lnum)
1212  if a:lnum == 1 || a:lnum == 4
1213    return -2
1214  elseif a:lnum == 2
1215    return 'a1'
1216  elseif a:lnum == 3
1217    return 's4'
1218  endif
1219  return '='
1220endfunc
1221
1222func Test_foldexpr_2()
1223  new
1224  call setline(1, ['one', 'two', 'three', 'four'])
1225  setlocal foldexpr=FoldExpr2(v:lnum)
1226  setlocal foldmethod=expr
1227  call assert_equal([0, 1, 1, 0], [foldlevel(1), foldlevel(2), foldlevel(3),
1228        \ foldlevel(4)])
1229  bw!
1230endfunc
1231
1232" Test for the 'foldclose' option
1233func Test_foldclose_opt()
1234  CheckScreendump
1235
1236  let lines =<< trim END
1237    set foldmethod=manual foldclose=all foldopen=all
1238    call setline(1, ['one', 'two', 'three', 'four'])
1239    2,3fold
1240    func XsaveFoldLevels()
1241      redraw!
1242      call writefile([json_encode([foldclosed(1), foldclosed(2), foldclosed(3),
1243        \ foldclosed(4)])], 'Xoutput', 'a')
1244    endfunc
1245  END
1246  call writefile(lines, 'Xscript')
1247  let rows = 10
1248  let buf = RunVimInTerminal('-S Xscript', {'rows': rows})
1249  call term_wait(buf)
1250  call term_sendkeys(buf, ":set noruler\n")
1251  call term_wait(buf)
1252  call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1253  call term_sendkeys(buf, "2G")
1254  call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
1255  call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1256  call term_sendkeys(buf, "4G")
1257  call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1258  call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1259  call term_sendkeys(buf, "3G")
1260  call WaitForAssert({-> assert_equal('three', term_getline(buf, 3))})
1261  call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1262  call term_sendkeys(buf, "1G")
1263  call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1264  call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1265  call term_sendkeys(buf, "2G")
1266  call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
1267  call term_sendkeys(buf, "k")
1268  call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1269
1270  " clean up
1271  call StopVimInTerminal(buf)
1272
1273  call assert_equal(['[-1,2,2,-1]', '[-1,-1,-1,-1]', '[-1,2,2,-1]',
1274        \ '[-1,-1,-1,-1]', '[-1,2,2,-1]'], readfile('Xoutput'))
1275  call delete('Xscript')
1276  call delete('Xoutput')
1277endfunc
1278
1279" Test for foldtextresult()
1280func Test_foldtextresult()
1281  new
1282  call assert_equal('', foldtextresult(-1))
1283  call assert_equal('', foldtextresult(0))
1284  call assert_equal('', foldtextresult(1))
1285  call setline(1, ['one', 'two', 'three', 'four'])
1286  2,3fold
1287  call assert_equal('', foldtextresult(1))
1288  call assert_equal('+--  2 lines: two', foldtextresult(2))
1289  setlocal foldtext=
1290  call assert_equal('+--  2 lines folded ', foldtextresult(2))
1291
1292  " Fold text for a C comment fold
1293  %d _
1294  setlocal foldtext&
1295  call setline(1, ['', '/*', ' * Comment', ' */', ''])
1296  2,4fold
1297  call assert_equal('+--  3 lines: Comment', foldtextresult(2))
1298
1299  bw!
1300endfunc
1301
1302" Test for merging two recursive folds when an intermediate line with no fold
1303" is removed
1304func Test_fold_merge_recrusive()
1305  new
1306  call setline(1, ['  one', '    two', 'xxxx', '    three',
1307        \ '      four', "\tfive"])
1308  setlocal foldmethod=indent shiftwidth=2
1309  3d_
1310  %foldclose
1311  call assert_equal([1, 5], [foldclosed(5), foldclosedend(1)])
1312  bw!
1313endfunc
1314
1315" Test for moving a line which is the start of a fold from a recursive fold to
1316" outside. The fold length should reduce.
1317func Test_fold_move_foldlevel()
1318  new
1319  call setline(1, ['a{{{', 'b{{{', 'c{{{', 'd}}}', 'e}}}', 'f}}}', 'g'])
1320  setlocal foldmethod=marker
1321  normal zR
1322  call assert_equal([3, 2, 1], [foldlevel(4), foldlevel(5), foldlevel(6)])
1323  3move 7
1324  call assert_equal([2, 1, 0], [foldlevel(3), foldlevel(4), foldlevel(5)])
1325  call assert_equal(1, foldlevel(7))
1326
1327  " Move a line from outside a fold to inside the fold.
1328  %d _
1329  call setline(1, ['a', 'b{{{', 'c}}}'])
1330  normal zR
1331  1move 2
1332  call assert_equal([1, 1, 1], [foldlevel(1), foldlevel(2), foldlevel(3)])
1333
1334  " Move the start of one fold to inside another fold
1335  %d _
1336  call setline(1, ['a', 'b{{{', 'c}}}', 'd{{{', 'e}}}'])
1337  normal zR
1338  call assert_equal([0, 1, 1, 1, 1], [foldlevel(1), foldlevel(2),
1339        \ foldlevel(3), foldlevel(4), foldlevel(5)])
1340  1,2move 4
1341  call assert_equal([0, 1, 1, 2, 2], [foldlevel(1), foldlevel(2),
1342        \ foldlevel(3), foldlevel(4), foldlevel(5)])
1343
1344  bw!
1345endfunc
1346
1347" Test for using zj and zk to move downwards and upwards to the start and end
1348" of the next fold.
1349" Test for using [z and ]z in a closed fold to jump to the beginning and end
1350" of the fold.
1351func Test_fold_jump()
1352  new
1353  call setline(1, ["\t1", "\t2", "\t\t3", "\t\t4", "\t\t\t5", "\t\t\t6", "\t\t7", "\t\t8", "\t9", "\t10"])
1354  setlocal foldmethod=indent
1355  normal zR
1356  normal zj
1357  call assert_equal(3, line('.'))
1358  normal zj
1359  call assert_equal(5, line('.'))
1360  call assert_beeps('normal zj')
1361  call assert_equal(5, line('.'))
1362  call assert_beeps('normal 9Gzj')
1363  call assert_equal(9, line('.'))
1364  normal Gzk
1365  call assert_equal(8, line('.'))
1366  normal zk
1367  call assert_equal(6, line('.'))
1368  call assert_beeps('normal zk')
1369  call assert_equal(6, line('.'))
1370  call assert_beeps('normal 2Gzk')
1371  call assert_equal(2, line('.'))
1372
1373  " Using [z or ]z in a closed fold should not move the cursor
1374  %d _
1375  call setline(1, ["1", "\t2", "\t3", "\t4", "\t5", "\t6", "7"])
1376  normal zR4Gzc
1377  call assert_equal(4, line('.'))
1378  call assert_beeps('normal [z')
1379  call assert_equal(4, line('.'))
1380  call assert_beeps('normal ]z')
1381  call assert_equal(4, line('.'))
1382  bw!
1383endfunc
1384
1385" vim: shiftwidth=2 sts=2 expandtab
1386