blob: 3c78e62c3e795a307c00eedfef4f2621b6fd0020 [file] [log] [blame]
Bram Moolenaarded27822017-01-02 14:27:34 +01001" Test for folding
2
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02003source check.vim
Bram Moolenaar907dad72018-07-10 15:07:15 +02004source view_util.vim
Bram Moolenaar7701f302018-10-02 21:20:32 +02005source screendump.vim
Bram Moolenaar907dad72018-07-10 15:07:15 +02006
Bram Moolenaar94be6192017-04-22 22:40:11 +02007func PrepIndent(arg)
Bram Moolenaar88d298a2017-03-14 21:53:58 +01008 return [a:arg] + repeat(["\t".a:arg], 5)
9endfu
10
Bram Moolenaar94be6192017-04-22 22:40:11 +020011func Test_address_fold()
Bram Moolenaarded27822017-01-02 14:27:34 +010012 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
Bram Moolenaar518c9b12017-03-21 11:48:39 +010016 " The next commands should all copy the same part of the buffer,
17 " regardless of the addressing type, since the part to be copied
Bram Moolenaarded27822017-01-02 14:27:34 +010018 " 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!
Bram Moolenaar1159b162017-02-28 21:53:56 +010073endfunc
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010074
Bram Moolenaar9954dc32022-11-11 22:58:36 +000075func Test_address_offsets()
76 " check the help for :range-closed-fold
77 enew
78 call setline(1, [
79 \ '1 one',
80 \ '2 two',
81 \ '3 three',
82 \ '4 four FOLDED',
83 \ '5 five FOLDED',
84 \ '6 six',
85 \ '7 seven',
86 \ '8 eight',
87 \])
88 set foldmethod=manual
89 normal 4Gvjzf
90 3,4+2yank
91 call assert_equal([
92 \ '3 three',
93 \ '4 four FOLDED',
94 \ '5 five FOLDED',
95 \ '6 six',
96 \ '7 seven',
97 \ ], getreg(0,1,1))
98
99 enew!
100 call setline(1, [
101 \ '1 one',
102 \ '2 two',
103 \ '3 three FOLDED',
104 \ '4 four FOLDED',
105 \ '5 five FOLDED',
106 \ '6 six FOLDED',
107 \ '7 seven',
108 \ '8 eight',
109 \])
110 normal 3Gv3jzf
111 2,4-1yank
112 call assert_equal([
113 \ '2 two',
114 \ '3 three FOLDED',
115 \ '4 four FOLDED',
116 \ '5 five FOLDED',
117 \ '6 six FOLDED',
118 \ ], getreg(0,1,1))
119
120 bwipe!
121endfunc
122
Bram Moolenaar94be6192017-04-22 22:40:11 +0200123func Test_indent_fold()
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +0100124 new
125 call setline(1, ['', 'a', ' b', ' c'])
126 setl fen fdm=indent
127 2
128 norm! >>
129 let a=map(range(1,4), 'foldclosed(v:val)')
130 call assert_equal([-1,-1,-1,-1], a)
131 bw!
Bram Moolenaar1159b162017-02-28 21:53:56 +0100132endfunc
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +0100133
Bram Moolenaar94be6192017-04-22 22:40:11 +0200134func Test_indent_fold2()
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +0100135 new
136 call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
137 setl fen fdm=marker
138 2
139 norm! >>
Bram Moolenaara4208962019-08-24 20:50:19 +0200140 let a=map(range(1,5), 'v:val->foldclosed()')
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +0100141 call assert_equal([-1,-1,-1,4,4], a)
142 bw!
Bram Moolenaar1159b162017-02-28 21:53:56 +0100143endfunc
144
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200145" Test for fold indent with indents greater than 'foldnestmax'
146func Test_indent_fold_max()
147 new
148 setlocal foldmethod=indent
149 setlocal shiftwidth=2
150 " 'foldnestmax' default value is 20
151 call setline(1, "\t\t\t\t\t\ta")
152 call assert_equal(20, foldlevel(1))
153 setlocal foldnestmax=10
154 call assert_equal(10, foldlevel(1))
155 setlocal foldnestmax=-1
156 call assert_equal(0, foldlevel(1))
157 bw!
158endfunc
159
zeertzjq07146ad2022-12-19 15:51:44 +0000160func Test_indent_fold_tabstop()
161 call setline(1, ['0', ' 1', ' 1', "\t2", "\t2"])
162 setlocal shiftwidth=4
163 setlocal foldcolumn=1
164 setlocal foldlevel=2
165 setlocal foldmethod=indent
166 redraw
167 call assert_equal('2 2', ScreenLines(5, 10)[0])
168 vsplit
169 windo diffthis
170 botright new
171 " This 'tabstop' value should not be used for folding in other buffers.
172 setlocal tabstop=4
173 diffoff!
174 redraw
175 call assert_equal('2 2', ScreenLines(5, 10)[0])
176
177 bwipe!
178 bwipe!
179endfunc
180
Bram Moolenaar1159b162017-02-28 21:53:56 +0100181func Test_manual_fold_with_filter()
Bram Moolenaaraeb313f2020-11-27 19:13:28 +0100182 CheckExecutable cat
Bram Moolenaar3f3897e2017-03-04 15:28:53 +0100183 for type in ['manual', 'marker']
184 exe 'set foldmethod=' . type
185 new
186 call setline(1, range(1, 20))
187 4,$fold
188 %foldopen
189 10,$fold
190 %foldopen
191 " This filter command should not have an effect
192 1,8! cat
193 call feedkeys('5ggzdzMGdd', 'xt')
194 call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
195
196 bwipe!
197 set foldmethod&
198 endfor
Bram Moolenaar1159b162017-02-28 21:53:56 +0100199endfunc
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100200
Bram Moolenaar94be6192017-04-22 22:40:11 +0200201func Test_indent_fold_with_read()
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100202 new
203 set foldmethod=indent
204 call setline(1, repeat(["\<Tab>a"], 4))
205 for n in range(1, 4)
206 call assert_equal(1, foldlevel(n))
207 endfor
208
Bram Moolenaar70e67252022-09-27 19:34:35 +0100209 call writefile(["a", "", "\<Tab>a"], 'Xinfofile', 'D')
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100210 foldopen
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100211 2read Xinfofile
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100212 %foldclose
213 call assert_equal(1, foldlevel(1))
214 call assert_equal(2, foldclosedend(1))
215 call assert_equal(0, foldlevel(3))
216 call assert_equal(0, foldlevel(4))
217 call assert_equal(1, foldlevel(5))
Bram Moolenaara4208962019-08-24 20:50:19 +0200218 call assert_equal(7, 5->foldclosedend())
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100219
220 bwipe!
221 set foldmethod&
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100222endfunc
223
224func Test_combining_folds_indent()
225 new
226 let one = "\<Tab>a"
227 let zero = 'a'
228 call setline(1, [one, one, zero, zero, zero, one, one, one])
229 set foldmethod=indent
230 3,5d
231 %foldclose
232 call assert_equal(5, foldclosedend(1))
233
234 set foldmethod&
235 bwipe!
236endfunc
237
238func Test_combining_folds_marker()
239 new
240 call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
241 set foldmethod=marker
242 3,5d
243 %foldclose
244 call assert_equal(2, foldclosedend(1))
245
246 set foldmethod&
247 bwipe!
248endfunc
249
Bram Moolenaar025a6b72017-03-12 20:37:21 +0100250func Test_folds_marker_in_comment()
251 new
252 call setline(1, ['" foo', 'bar', 'baz'])
253 setl fen fdm=marker
254 setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
255 norm! zf2j
256 setl nofen
257 :1y
258 call assert_equal(['" foo{{{'], getreg(0,1,1))
259 :+2y
260 call assert_equal(['baz"}}}'], getreg(0,1,1))
261
262 set foldmethod&
263 bwipe!
264endfunc
265
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100266func s:TestFoldExpr(lnum)
267 let thisline = getline(a:lnum)
268 if thisline == 'a'
269 return 1
270 elseif thisline == 'b'
271 return 0
272 elseif thisline == 'c'
273 return '<1'
274 elseif thisline == 'd'
275 return '>1'
276 endif
277 return 0
278endfunction
279
280func Test_update_folds_expr_read()
281 new
282 call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
283 set foldmethod=expr
284 set foldexpr=s:TestFoldExpr(v:lnum)
285 2
286 foldopen
Bram Moolenaar70e67252022-09-27 19:34:35 +0100287 call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xupfofile', 'D')
Bram Moolenaarb18b4962022-09-02 21:55:50 +0100288 read Xupfofile
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100289 %foldclose
290 call assert_equal(2, foldclosedend(1))
291 call assert_equal(0, foldlevel(3))
Bram Moolenaara4208962019-08-24 20:50:19 +0200292 call assert_equal(0, 4->foldlevel())
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100293 call assert_equal(6, foldclosedend(5))
294 call assert_equal(10, foldclosedend(7))
295 call assert_equal(14, foldclosedend(11))
296
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100297 bwipe!
298 set foldmethod& foldexpr&
299endfunc
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100300
zeertzjq93c15732022-05-21 16:34:38 +0100301" Test for what patch 8.1.0535 fixes.
302func Test_foldexpr_no_interrupt_addsub()
303 new
304 func! FoldFunc()
305 call setpos('.', getcurpos())
306 return '='
307 endfunc
308
309 set foldmethod=expr
310 set foldexpr=FoldFunc()
311 call setline(1, '1.2')
312
313 exe "norm! $\<C-A>"
314 call assert_equal('1.3', getline(1))
315
316 bwipe!
317 delfunc FoldFunc
318 set foldmethod& foldexpr&
319endfunc
320
Bram Moolenaar87b4e5c2022-10-01 15:32:46 +0100321" Fold function defined in another script
322func Test_foldexpr_compiled()
323 new
324 let lines =<< trim END
325 vim9script
326 def FoldFunc(): number
327 return v:lnum
328 enddef
329
330 set foldmethod=expr
331 set foldexpr=s:FoldFunc()
332 END
333 call writefile(lines, 'XfoldExpr', 'D')
334 source XfoldExpr
335
336 call setline(1, ['one', 'two', 'three'])
337 redraw
338 call assert_equal(1, foldlevel(1))
339 call assert_equal(2, foldlevel(2))
340 call assert_equal(3, foldlevel(3))
341
342 bwipe!
343 set foldmethod& foldexpr&
344endfunc
345
Bram Moolenaar94be6192017-04-22 22:40:11 +0200346func Check_foldlevels(expected)
347 call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
348endfunc
349
350func Test_move_folds_around_manual()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100351 new
352 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
353 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
354 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
355 " all folds closed
356 set foldenable foldlevel=0 fdm=indent
357 " needs a forced redraw
358 redraw!
359 set fdm=manual
360 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
361 call assert_equal(input, getline(1, '$'))
362 7,12m0
363 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
364 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
365 10,12m0
366 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
367 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)'))
368 " moving should not close the folds
369 %d
370 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
371 set fdm=indent
372 redraw!
373 set fdm=manual
374 call cursor(2, 1)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100375 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100376 7,12m0
377 let folds=repeat([-1], 18)
378 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
379 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
380 norm! zM
381 " folds are not corrupted and all have been closed
382 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)'))
383 %d
384 call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
385 set fdm=indent
386 redraw!
387 set fdm=manual
388 %foldopen
389 3m4
390 %foldclose
391 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
392 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
393 %d
394 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
395 set fdm=indent foldlevel=0
396 set fdm=manual
397 %foldopen
398 3m1
399 %foldclose
400 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
401 call assert_equal(0, foldlevel(2))
402 call assert_equal(5, foldclosedend(3))
403 call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
404 2,6m$
405 %foldclose
406 call assert_equal(5, foldclosedend(2))
407 call assert_equal(0, foldlevel(6))
408 call assert_equal(9, foldclosedend(7))
409 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
Bram Moolenaar495b7dd2017-09-16 17:19:22 +0200410
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100411 %d
412 " Ensure moving around the edges still works.
413 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
414 set fdm=indent foldlevel=0
415 set fdm=manual
416 %foldopen
417 6m$
418 " The first fold has been truncated to the 5'th line.
419 " Second fold has been moved up because the moved line is now below it.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200420 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
421
422 %delete
423 set fdm=indent foldlevel=0
424 call setline(1, [
425 \ "a",
426 \ "\ta",
427 \ "\t\ta",
428 \ "\t\ta",
429 \ "\t\ta",
430 \ "a",
431 \ "a"])
432 set fdm=manual
433 %foldopen!
434 4,5m6
435 call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
436
437 %delete
438 set fdm=indent
439 call setline(1, [
440 \ "\ta",
441 \ "\t\ta",
442 \ "\t\ta",
443 \ "\t\ta",
444 \ "\ta",
445 \ "\t\ta",
446 \ "\t\ta",
447 \ "\t\ta",
448 \ "\ta",
449 \ "\t\ta",
450 \ "\t\ta",
451 \ "\t\ta",
452 \ "\t\ta",
453 \ "\ta",
454 \ "a"])
455 set fdm=manual
456 %foldopen!
457 13m7
458 call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
Bram Moolenaar94722c52023-01-28 19:19:03 +0000459
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100460 bw!
461endfunc
462
Bram Moolenaar94be6192017-04-22 22:40:11 +0200463func Test_move_folds_around_indent()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100464 new
465 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
466 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
467 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
468 " all folds closed
469 set fdm=indent
470 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
471 call assert_equal(input, getline(1, '$'))
472 7,12m0
473 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
474 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
475 10,12m0
476 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
477 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)'))
478 " moving should not close the folds
479 %d
480 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
481 set fdm=indent
482 call cursor(2, 1)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100483 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100484 7,12m0
485 let folds=repeat([-1], 18)
486 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
487 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
488 norm! zM
489 " folds are not corrupted and all have been closed
490 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)'))
491 %d
492 call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
493 set fdm=indent
494 %foldopen
495 3m4
496 %foldclose
497 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
498 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
499 %d
500 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
501 set fdm=indent foldlevel=0
502 %foldopen
503 3m1
504 %foldclose
505 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
506 call assert_equal(1, foldlevel(2))
507 call assert_equal(5, foldclosedend(3))
508 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
509 2,6m$
510 %foldclose
511 call assert_equal(9, foldclosedend(2))
512 call assert_equal(1, foldlevel(6))
513 call assert_equal(9, foldclosedend(7))
514 call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100515 " Ensure moving around the edges still works.
516 %d
517 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
518 set fdm=indent foldlevel=0
519 %foldopen
520 6m$
521 " The first fold has been truncated to the 5'th line.
522 " Second fold has been moved up because the moved line is now below it.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200523 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100524 bw!
525endfunc
Bram Moolenaar518c9b12017-03-21 11:48:39 +0100526
527func Test_folddoopen_folddoclosed()
528 new
529 call setline(1, range(1, 9))
530 set foldmethod=manual
531 1,3 fold
532 6,8 fold
533
534 " Test without range.
535 folddoopen s/$/o/
536 folddoclosed s/$/c/
537 call assert_equal(['1c', '2c', '3c',
538 \ '4o', '5o',
539 \ '6c', '7c', '8c',
540 \ '9o'], getline(1, '$'))
541
542 " Test with range.
543 call setline(1, range(1, 9))
544 1,8 folddoopen s/$/o/
545 4,$ folddoclosed s/$/c/
546 call assert_equal(['1', '2', '3',
547 \ '4o', '5o',
548 \ '6c', '7c', '8c',
549 \ '9'], getline(1, '$'))
550
551 set foldmethod&
552 bw!
553endfunc
554
555func Test_fold_error()
556 new
557 call setline(1, [1, 2])
558
559 for fm in ['indent', 'expr', 'syntax', 'diff']
560 exe 'set foldmethod=' . fm
561 call assert_fails('norm zf', 'E350:')
562 call assert_fails('norm zd', 'E351:')
563 call assert_fails('norm zE', 'E352:')
564 endfor
565
566 set foldmethod=manual
567 call assert_fails('norm zd', 'E490:')
568 call assert_fails('norm zo', 'E490:')
569 call assert_fails('3fold', 'E16:')
570
571 set foldmethod=marker
572 set nomodifiable
573 call assert_fails('1,2fold', 'E21:')
574
575 set modifiable&
576 set foldmethod&
577 bw!
578endfunc
Bram Moolenaar495b7dd2017-09-16 17:19:22 +0200579
580func Test_foldtext_recursive()
581 new
582 call setline(1, ['{{{', 'some text', '}}}'])
583 setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart)
584 " This was crashing because of endless recursion.
585 2foldclose
586 redraw
587 call assert_equal(1, foldlevel(2))
588 call assert_equal(1, foldclosed(2))
589 call assert_equal(3, foldclosedend(2))
590 bwipe!
591endfunc
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100592
593" Various fold related tests
594
595" Basic test if a fold can be created, opened, moving to the end and closed
596func Test_fold_manual()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200597 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100598 set fdm=manual
599
600 let content = ['1 aa', '2 bb', '3 cc']
601 call append(0, content)
602 call cursor(1, 1)
603 normal zf2j
604 call assert_equal('1 aa', getline(foldclosed('.')))
605 normal zo
606 call assert_equal(-1, foldclosed('.'))
607 normal ]z
608 call assert_equal('3 cc', getline('.'))
609 normal zc
610 call assert_equal('1 aa', getline(foldclosed('.')))
611
Bram Moolenaar68ffe8c2021-04-05 12:47:25 +0200612 " Create a fold inside a closed fold after setting 'foldlevel'
613 %d _
614 call setline(1, range(1, 5))
615 1,5fold
616 normal zR
617 2,4fold
618 set foldlevel=1
619 3fold
620 call assert_equal([1, 3, 3, 3, 1], map(range(1, 5), {->foldlevel(v:val)}))
621 set foldlevel&
622
623 " Create overlapping folds (at the start and at the end)
624 normal zE
625 2,3fold
626 normal zR
627 3,4fold
628 call assert_equal([0, 2, 2, 1, 0], map(range(1, 5), {->foldlevel(v:val)}))
629 normal zE
630 3,4fold
631 normal zR
632 2,3fold
633 call assert_equal([0, 1, 2, 2, 0], map(range(1, 5), {->foldlevel(v:val)}))
634
635 " Create a nested fold across two non-adjoining folds
636 %d _
637 call setline(1, range(1, 7))
638 1,2fold
639 normal zR
640 4,5fold
641 normal zR
642 6,7fold
643 normal zR
644 1,5fold
645 call assert_equal([2, 2, 1, 2, 2, 1, 1],
646 \ map(range(1, 7), {->foldlevel(v:val)}))
647
648 " A newly created nested fold should be closed
649 %d _
650 call setline(1, range(1, 6))
651 1,6fold
652 normal zR
653 3,4fold
654 normal zR
655 2,5fold
656 call assert_equal([1, 2, 3, 3, 2, 1], map(range(1, 6), {->foldlevel(v:val)}))
657 call assert_equal(2, foldclosed(4))
658 call assert_equal(5, foldclosedend(4))
659
660 " Test zO, zC and zA on a line with no folds.
661 normal zE
662 call assert_fails('normal zO', 'E490:')
663 call assert_fails('normal zC', 'E490:')
664 call assert_fails('normal zA', 'E490:')
665
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100666 set fdm&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200667 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100668endfunc
669
670" test folding with markers.
671func Test_fold_marker()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200672 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100673 set fdm=marker fdl=1 fdc=3
674
675 let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
676 call append(0, content)
677 call cursor(2, 1)
678 call assert_equal(2, foldlevel('.'))
679 normal [z
680 call assert_equal(1, foldlevel('.'))
681 exe "normal jo{{ \<Esc>r{jj"
682 call assert_equal(1, foldlevel('.'))
683 normal kYpj
684 call assert_equal(0, foldlevel('.'))
685
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200686 " Use only closing fold marker (without and with a count)
687 set fdl&
688 %d _
689 call setline(1, ['one }}}', 'two'])
690 call assert_equal([0, 0], [foldlevel(1), foldlevel(2)])
691 %d _
692 call setline(1, ['one }}}4', 'two'])
693 call assert_equal([4, 3], [foldlevel(1), foldlevel(2)])
694
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100695 set fdm& fdl& fdc&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200696 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100697endfunc
698
Bram Moolenaar4af72592018-12-09 15:00:52 +0100699" test create fold markers with C filetype
700func Test_fold_create_marker_in_C()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200701 bw!
Bram Moolenaar4af72592018-12-09 15:00:52 +0100702 set fdm=marker fdl=9
703 set filetype=c
704
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200705 let content =<< trim [CODE]
706 /*
707 * comment
Bram Moolenaar94722c52023-01-28 19:19:03 +0000708 *
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200709 *
710 */
711 int f(int* p) {
712 *p = 3;
713 return 0;
714 }
715 [CODE]
716
Bram Moolenaar4af72592018-12-09 15:00:52 +0100717 for c in range(len(content) - 1)
718 bw!
719 call append(0, content)
720 call cursor(c + 1, 1)
721 norm! zfG
722 call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1))
723 endfor
724
725 set fdm& fdl&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200726 bw!
Bram Moolenaar4af72592018-12-09 15:00:52 +0100727endfunc
728
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100729" test folding with indent
730func Test_fold_indent()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200731 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100732 set fdm=indent sw=2
733
734 let content = ['1 aa', '2 bb', '3 cc']
735 call append(0, content)
736 call cursor(2, 1)
737 exe "normal i \<Esc>jI "
738 call assert_equal(2, foldlevel('.'))
739 normal k
740 call assert_equal(1, foldlevel('.'))
741
742 set fdm& sw&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200743 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100744endfunc
745
746" test syntax folding
747func Test_fold_syntax()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200748 CheckFeature syntax
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100749
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200750 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100751 set fdm=syntax fdl=0
752
753 syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
754 syn region Fd1 start="ee" end="ff" fold contained
755 syn region Fd2 start="gg" end="hh" fold contained
756 syn region Fd3 start="commentstart" end="commentend" fold contained
757 let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
758 \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
759 call append(0, content)
760 normal Gzk
761 call assert_equal('9 ii', getline('.'))
762 normal k
763 call assert_equal('3 cc', getline('.'))
764 exe "normal jAcommentstart \<Esc>Acommentend"
765 set fdl=1
766 normal 3j
767 call assert_equal('7 gg', getline('.'))
768 set fdl=0
769 exe "normal zO\<C-L>j"
770 call assert_equal('8 hh', getline('.'))
771 syn clear Fd1 Fd2 Fd3 Hup
772
773 set fdm& fdl&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200774 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100775endfunc
776
777func Flvl()
778 let l = getline(v:lnum)
779 if l =~ "bb$"
780 return 2
781 elseif l =~ "gg$"
782 return "s1"
783 elseif l =~ "ii$"
784 return ">2"
785 elseif l =~ "kk$"
786 return "0"
787 endif
788 return "="
789endfun
790
791" test expression folding
792func Test_fold_expr()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200793 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100794 set fdm=expr fde=Flvl()
795
796 let content = ['1 aa',
797 \ '2 bb',
798 \ '3 cc',
799 \ '4 dd {{{commentstart commentend',
800 \ '5 ee {{{ }}}',
801 \ '{{{',
802 \ '6 ff }}}',
803 \ '6 ff }}}',
804 \ ' 7 gg',
805 \ ' 8 hh',
806 \ '9 ii',
807 \ 'a jj',
808 \ 'b kk']
809 call append(0, content)
810 call cursor(1, 1)
811 exe "normal /bb$\<CR>"
812 call assert_equal(2, foldlevel('.'))
813 exe "normal /hh$\<CR>"
814 call assert_equal(1, foldlevel('.'))
815 exe "normal /ii$\<CR>"
816 call assert_equal(2, foldlevel('.'))
817 exe "normal /kk$\<CR>"
818 call assert_equal(0, foldlevel('.'))
819
820 set fdm& fde&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200821 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100822endfunc
823
824" Bug with fdm=indent and moving folds
825" Moving a fold a few times, messes up the folds below the moved fold.
826" Fixed by 7.4.700
827func Test_fold_move()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200828 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100829 set fdm=indent sw=2 fdl=0
830
831 let content = ['', '', 'Line1', ' Line2', ' Line3',
832 \ 'Line4', ' Line5', ' Line6',
833 \ 'Line7', ' Line8', ' Line9']
834 call append(0, content)
835 normal zM
836 call cursor(4, 1)
837 move 2
838 move 1
839 call assert_equal(7, foldclosed(7))
840 call assert_equal(8, foldclosedend(7))
841 call assert_equal(0, foldlevel(9))
842 call assert_equal(10, foldclosed(10))
843 call assert_equal(11, foldclosedend(10))
844 call assert_equal('+-- 2 lines: Line2', foldtextresult(2))
Bram Moolenaara4208962019-08-24 20:50:19 +0200845 call assert_equal('+-- 2 lines: Line8', 10->foldtextresult())
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100846
847 set fdm& sw& fdl&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200848 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100849endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100850
851" test for patch 7.3.637
852" Cannot catch the error caused by a foldopen when there is no fold.
853func Test_foldopen_exception()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200854 new
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100855 let a = 'No error caught'
856 try
857 foldopen
858 catch
859 let a = matchstr(v:exception,'^[^ ]*')
860 endtry
861 call assert_equal('Vim(foldopen):E490:', a)
862
863 let a = 'No error caught'
864 try
865 foobar
866 catch
867 let a = matchstr(v:exception,'^[^ ]*')
868 endtry
869 call assert_match('E492:', a)
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200870 bw!
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100871endfunc
Bram Moolenaar907dad72018-07-10 15:07:15 +0200872
873func Test_fold_last_line_with_pagedown()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200874 new
Bram Moolenaar907dad72018-07-10 15:07:15 +0200875 set fdm=manual
876
877 let expect = '+-- 11 lines: 9---'
878 let content = range(1,19)
879 call append(0, content)
880 normal dd9G
881 normal zfG
882 normal zt
883 call assert_equal('9', getline(foldclosed('.')))
884 call assert_equal('19', getline(foldclosedend('.')))
885 call assert_equal(expect, ScreenLines(1, len(expect))[0])
886 call feedkeys("\<C-F>", 'xt')
887 call assert_equal(expect, ScreenLines(1, len(expect))[0])
888 call feedkeys("\<C-F>", 'xt')
889 call assert_equal(expect, ScreenLines(1, len(expect))[0])
890 call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt')
891 call assert_equal(expect, ScreenLines(1, len(expect))[0])
892
893 set fdm&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200894 bw!
Bram Moolenaar907dad72018-07-10 15:07:15 +0200895endfunc
Bram Moolenaar7701f302018-10-02 21:20:32 +0200896
897func Test_folds_with_rnu()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200898 CheckScreendump
Bram Moolenaar7701f302018-10-02 21:20:32 +0200899
900 call writefile([
901 \ 'set fdm=marker rnu foldcolumn=2',
902 \ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])',
Bram Moolenaar70e67252022-09-27 19:34:35 +0100903 \ ], 'Xtest_folds_with_rnu', 'D')
Bram Moolenaar7701f302018-10-02 21:20:32 +0200904 let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {})
905
906 call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {})
907 call term_sendkeys(buf, "j")
908 call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {})
909
910 " clean up
911 call StopVimInTerminal(buf)
Bram Moolenaar7701f302018-10-02 21:20:32 +0200912endfunc
Bram Moolenaar53932812018-12-07 21:08:49 +0100913
914func Test_folds_marker_in_comment2()
915 new
916 call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit'])
917 setl fen fdm=marker
918 setl commentstring=<!--%s-->
919 setl comments=s:<!--,m:\ \ \ \ ,e:-->
920 norm! zf2j
921 setl nofen
922 :1y
923 call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1))
924 :+2y
925 call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1))
926
927 set foldmethod&
928 bwipe!
929endfunc
Bram Moolenaar9a4a8c42019-08-19 22:48:30 +0200930
931func Test_fold_delete_with_marker()
932 new
933 call setline(1, ['func Func() {{{1', 'endfunc'])
934 1,2yank
935 new
936 set fdm=marker
937 call setline(1, 'x')
938 normal! Vp
939 normal! zd
940 call assert_equal(['func Func() ', 'endfunc'], getline(1, '$'))
941
942 set fdm&
943 bwipe!
944 bwipe!
945endfunc
Bram Moolenaar7a9bd7c2019-09-17 22:42:55 +0200946
947func Test_fold_delete_with_marker_and_whichwrap()
948 new
949 let content1 = ['']
950 let content2 = ['folded line 1 "{{{1', ' test', ' test2', ' test3', '', 'folded line 2 "{{{1', ' test', ' test2', ' test3']
951 call setline(1, content1 + content2)
952 set fdm=marker ww+=l
953 normal! x
954 call assert_equal(content2, getline(1, '$'))
955 set fdm& ww&
956 bwipe!
957endfunc
Bram Moolenaar3b681232019-12-13 19:35:55 +0100958
959func Test_fold_delete_first_line()
960 new
961 call setline(1, [
962 \ '" x {{{1',
963 \ '" a',
964 \ '" aa',
965 \ '" x {{{1',
966 \ '" b',
967 \ '" bb',
968 \ '" x {{{1',
969 \ '" c',
970 \ '" cc',
971 \ ])
972 set foldmethod=marker
973 1
974 normal dj
975 call assert_equal([
976 \ '" x {{{1',
977 \ '" c',
978 \ '" cc',
979 \ ], getline(1,'$'))
980 bwipe!
981 set foldmethod&
982endfunc
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +0200983
Bram Moolenaar68ffe8c2021-04-05 12:47:25 +0200984" Add a test for deleting the outer fold of a nested fold and promoting the
985" inner folds to one level up with already a fold at that level following the
986" nested fold.
987func Test_fold_delete_recursive_fold()
988 new
989 call setline(1, range(1, 7))
990 2,3fold
991 normal zR
992 4,5fold
993 normal zR
994 1,5fold
995 normal zR
996 6,7fold
997 normal zR
998 normal 1Gzd
999 normal 1Gzj
1000 call assert_equal(2, line('.'))
1001 normal zj
1002 call assert_equal(4, line('.'))
1003 normal zj
1004 call assert_equal(6, line('.'))
1005 bw!
1006endfunc
1007
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +02001008" Test for errors in 'foldexpr'
1009func Test_fold_expr_error()
1010 new
1011 call setline(1, ['one', 'two', 'three'])
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001012 " In a window with no folds, foldlevel() should return 0
1013 call assert_equal(0, foldlevel(1))
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +02001014
1015 " Return a list from the expression
1016 set foldexpr=[]
1017 set foldmethod=expr
1018 for i in range(3)
1019 call assert_equal(0, foldlevel(i))
1020 endfor
1021
1022 " expression error
1023 set foldexpr=[{]
1024 set foldmethod=expr
1025 for i in range(3)
1026 call assert_equal(0, foldlevel(i))
1027 endfor
1028
1029 set foldmethod& foldexpr&
1030 close!
1031endfunc
1032
Bram Moolenaarda697642020-09-17 19:36:04 +02001033func Test_undo_fold_deletion()
1034 new
1035 set fdm=marker
1036 let lines =<< trim END
1037 " {{{
1038 " }}}1
1039 " {{{
1040 END
1041 call setline(1, lines)
1042 3d
1043 g/"/d
1044 undo
1045 redo
1046 eval getline(1, '$')->assert_equal([''])
1047
1048 set fdm&vim
1049 bwipe!
1050endfunc
1051
Bram Moolenaarc136a352020-11-03 20:05:40 +01001052" this was crashing
1053func Test_move_no_folds()
1054 new
1055 fold
1056 setlocal fdm=expr
1057 normal zj
1058 bwipe!
1059endfunc
1060
Bram Moolenaar5e1f22f2020-11-10 18:23:52 +01001061" this was crashing
1062func Test_fold_create_delete_create()
1063 new
1064 fold
1065 fold
1066 normal zd
1067 fold
1068 bwipe!
1069endfunc
1070
Bram Moolenaar6a78f322020-12-21 14:01:41 +01001071" this was crashing
1072func Test_fold_create_delete()
1073 new
1074 norm zFzFzdzj
1075 bwipe!
1076endfunc
1077
Bram Moolenaare71996b2021-01-21 17:03:07 +01001078func Test_fold_relative_move()
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001079 new
Bram Moolenaare71996b2021-01-21 17:03:07 +01001080 set fdm=indent sw=2 wrap tw=80
1081
Bram Moolenaar3c49e742021-04-04 21:26:04 +02001082 let longtext = repeat('x', &columns + 1)
1083 let content = [ ' foo', ' ' .. longtext, ' baz',
1084 \ longtext,
1085 \ ' foo', ' ' .. longtext, ' baz'
Bram Moolenaare71996b2021-01-21 17:03:07 +01001086 \ ]
1087 call append(0, content)
1088
1089 normal zM
1090
Bram Moolenaar3c49e742021-04-04 21:26:04 +02001091 for lnum in range(1, 3)
1092 call cursor(lnum, 1)
1093 call assert_true(foldclosed(line('.')))
1094 normal gj
1095 call assert_equal(2, winline())
1096 endfor
Bram Moolenaare71996b2021-01-21 17:03:07 +01001097
1098 call cursor(2, 1)
1099 call assert_true(foldclosed(line('.')))
1100 normal 2gj
1101 call assert_equal(3, winline())
1102
Bram Moolenaar3c49e742021-04-04 21:26:04 +02001103 for lnum in range(5, 7)
1104 call cursor(lnum, 1)
1105 call assert_true(foldclosed(line('.')))
1106 normal gk
1107 call assert_equal(3, winline())
1108 endfor
Bram Moolenaare71996b2021-01-21 17:03:07 +01001109
1110 call cursor(6, 1)
1111 call assert_true(foldclosed(line('.')))
1112 normal 2gk
1113 call assert_equal(2, winline())
1114
1115 set fdm& sw& wrap& tw&
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001116 bw!
Bram Moolenaare71996b2021-01-21 17:03:07 +01001117endfunc
1118
Bram Moolenaar4fa11752021-03-03 13:26:02 +01001119" Test for using multibyte characters as 'foldopen', 'foldclose' and
1120" 'foldsetp' items in 'fillchars'
1121func s:mbyte_fillchar_tests(fo, fc, fs)
1122 setlocal foldcolumn=3
1123
1124 normal zE
1125 1,2fold
1126 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
1127 \ ScreenLines([1, 2], 10))
1128 1,2foldopen
1129 call assert_equal([a:fo .. ' one ', a:fs .. ' two '],
1130 \ ScreenLines([1, 2], 7))
1131 1,2foldclose
1132 redraw!
1133 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
1134 \ ScreenLines([1, 2], 10))
1135
1136 " Two level fold
1137 normal zE
1138 2,3fold
1139 1,4fold
1140 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
1141 \ ScreenLines([1, 2], 10))
1142 1,4foldopen
1143 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
1144 \ ScreenLines([1, 2], 10))
1145 1,4foldopen
1146 call assert_equal([a:fo .. ' one ', a:fs .. a:fo .. ' two ',
1147 \ a:fs .. a:fs .. ' three '], ScreenLines([1, 3], 10))
1148 2,3foldclose
1149 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
1150 \ ScreenLines([1, 2], 10))
1151 1,4foldclose
1152 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
1153 \ ScreenLines([1, 2], 10))
1154
1155 " Three level fold
1156 normal zE
1157 3,4fold
1158 2,5fold
1159 1,6fold
1160 call assert_equal([a:fc .. ' +-- 6 '], ScreenLines(1, 10))
1161 " open all the folds
1162 normal zR
1163 call assert_equal([
1164 \ a:fo .. ' one ',
1165 \ a:fs .. a:fo .. ' two ',
1166 \ '2' .. a:fo .. ' three ',
1167 \ '23 four ',
1168 \ a:fs .. a:fs .. ' five ',
1169 \ a:fs .. ' six ',
1170 \ ], ScreenLines([1, 6], 10))
1171 " close the innermost fold
1172 3,4foldclose
1173 call assert_equal([
1174 \ a:fo .. ' one ',
1175 \ a:fs .. a:fo .. ' two ',
1176 \ a:fs .. a:fs .. a:fc .. '+---- ',
1177 \ a:fs .. a:fs .. ' five ',
1178 \ a:fs .. ' six ',
1179 \ ], ScreenLines([1, 5], 10))
1180 " close the next fold
1181 2,5foldclose
1182 call assert_equal([
1183 \ a:fo .. ' one ',
1184 \ a:fs .. a:fc .. ' +--- 4',
1185 \ a:fs .. ' six ',
1186 \ ], ScreenLines([1, 3], 10))
1187
1188 " set the fold column size to 2
1189 setlocal fdc=2
1190 normal zR
1191 call assert_equal([
1192 \ a:fo .. ' one ',
1193 \ a:fo .. ' two ',
1194 \ a:fo .. ' three',
1195 \ '3 four ',
1196 \ '2 five ',
1197 \ a:fs .. ' six ',
1198 \ ], ScreenLines([1, 6], 7))
1199
1200 " set the fold column size to 1
1201 setlocal fdc=1
1202 normal zR
1203 call assert_equal([
1204 \ a:fo .. 'one ',
1205 \ a:fo .. 'two ',
1206 \ a:fo .. 'three ',
1207 \ '3four ',
1208 \ '2five ',
1209 \ a:fs .. 'six ',
1210 \ ], ScreenLines([1, 6], 7))
1211
Bram Moolenaar008bff92021-03-04 21:55:58 +01001212 " Enable number and sign columns and place some signs
1213 setlocal fdc=3
1214 setlocal number
1215 setlocal signcolumn=auto
1216 sign define S1 text=->
1217 sign place 10 line=3 name=S1
1218 call assert_equal([
1219 \ a:fo .. ' 1 one ',
1220 \ a:fs .. a:fo .. ' 2 two ',
1221 \ '2' .. a:fo .. ' -> 3 three',
1222 \ '23 4 four ',
1223 \ a:fs .. a:fs .. ' 5 five ',
1224 \ a:fs .. ' 6 six '
1225 \ ], ScreenLines([1, 6], 14))
1226
1227 " Test with 'rightleft'
1228 if has('rightleft')
1229 setlocal rightleft
1230 let lines = ScreenLines([1, 6], winwidth(0))
1231 call assert_equal('o 1 ' .. a:fo,
1232 \ strcharpart(lines[0], strchars(lines[0]) - 10, 10))
1233 call assert_equal('t 2 ' .. a:fo .. a:fs,
1234 \ strcharpart(lines[1], strchars(lines[1]) - 10, 10))
1235 call assert_equal('t 3 >- ' .. a:fo .. '2',
1236 \ strcharpart(lines[2], strchars(lines[2]) - 10, 10))
1237 call assert_equal('f 4 32',
1238 \ strcharpart(lines[3], strchars(lines[3]) - 10, 10))
1239 call assert_equal('f 5 ' .. a:fs .. a:fs,
1240 \ strcharpart(lines[4], strchars(lines[4]) - 10, 10))
1241 call assert_equal('s 6 ' .. a:fs,
1242 \ strcharpart(lines[5], strchars(lines[5]) - 10, 10))
1243 setlocal norightleft
1244 endif
1245
1246 sign unplace *
1247 sign undefine S1
1248 setlocal number& signcolumn&
1249
1250 " Add a test with more than 9 folds (and then delete some folds)
1251 normal zE
1252 for i in range(1, 10)
1253 normal zfGzo
1254 endfor
1255 normal zR
1256 call assert_equal([
1257 \ a:fo .. a:fo .. ' one ',
1258 \ '9> two '
1259 \ ], ScreenLines([1, 2], 7))
1260 normal 1Gzd
1261 call assert_equal([
1262 \ a:fo .. a:fo .. ' one ',
1263 \ '89 two '
1264 \ ], ScreenLines([1, 2], 7))
1265 normal 1Gzdzdzdzdzdzdzd
1266 call assert_equal([
1267 \ a:fo .. a:fo .. ' one ',
1268 \ a:fs .. a:fs .. ' two '
1269 \ ], ScreenLines([1, 2], 7))
1270
1271 setlocal foldcolumn& number& signcolumn&
Bram Moolenaar4fa11752021-03-03 13:26:02 +01001272endfunc
1273
1274func Test_foldcolumn_multibyte_char()
1275 new
1276 call setline(1, ['one', 'two', 'three', 'four', 'five', 'six'])
1277 setlocal foldenable foldmethod=manual
1278
1279 " First test with the default setting
1280 call s:mbyte_fillchar_tests('-', '+', '|')
1281
1282 " Use multi-byte characters
1283 set fillchars+=foldopen:▾,foldsep:│,foldclose:▸
1284 call s:mbyte_fillchar_tests('▾', '▸', '│')
1285
Bram Moolenaar196a1f72021-03-21 14:39:19 +01001286 " Use a mix of multi-byte and single-byte characters
1287 set fillchars+=foldopen:¬,foldsep:\|,foldclose:+
1288 call s:mbyte_fillchar_tests('¬', '+', '|')
1289 set fillchars+=foldopen:+,foldsep:\|,foldclose:¬
1290 call s:mbyte_fillchar_tests('+', '¬', '|')
1291
Bram Moolenaar4fa11752021-03-03 13:26:02 +01001292 bw!
1293 set foldenable& fdc& fdm& fillchars&
1294endfunc
1295
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001296" Test for calling foldlevel() from a fold expression
1297let g:FoldLevels = []
1298func FoldExpr1(lnum)
1299 let f = [a:lnum]
1300 for i in range(1, line('$'))
1301 call add(f, foldlevel(i))
1302 endfor
1303 call add(g:FoldLevels, f)
1304 return getline(a:lnum)[0] == "\t"
1305endfunc
1306
1307func Test_foldexpr_foldlevel()
1308 new
1309 call setline(1, ['one', "\ttwo", "\tthree"])
1310 setlocal foldmethod=expr
1311 setlocal foldexpr=FoldExpr1(v:lnum)
1312 setlocal foldenable
1313 setlocal foldcolumn=3
1314 redraw!
1315 call assert_equal([[1, -1, -1, -1], [2, -1, -1, -1], [3, 0, 1, -1]],
1316 \ g:FoldLevels)
1317 set foldmethod& foldexpr& foldenable& foldcolumn&
1318 bw!
1319endfunc
1320
1321" Test for returning different values from a fold expression
1322func FoldExpr2(lnum)
1323 if a:lnum == 1 || a:lnum == 4
1324 return -2
1325 elseif a:lnum == 2
1326 return 'a1'
1327 elseif a:lnum == 3
1328 return 's4'
1329 endif
1330 return '='
1331endfunc
1332
1333func Test_foldexpr_2()
1334 new
1335 call setline(1, ['one', 'two', 'three', 'four'])
1336 setlocal foldexpr=FoldExpr2(v:lnum)
1337 setlocal foldmethod=expr
1338 call assert_equal([0, 1, 1, 0], [foldlevel(1), foldlevel(2), foldlevel(3),
1339 \ foldlevel(4)])
1340 bw!
1341endfunc
1342
1343" Test for the 'foldclose' option
1344func Test_foldclose_opt()
1345 CheckScreendump
1346
1347 let lines =<< trim END
1348 set foldmethod=manual foldclose=all foldopen=all
1349 call setline(1, ['one', 'two', 'three', 'four'])
1350 2,3fold
1351 func XsaveFoldLevels()
1352 redraw!
1353 call writefile([json_encode([foldclosed(1), foldclosed(2), foldclosed(3),
1354 \ foldclosed(4)])], 'Xoutput', 'a')
1355 endfunc
1356 END
Bram Moolenaar70e67252022-09-27 19:34:35 +01001357 call writefile(lines, 'Xscript', 'D')
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001358 let rows = 10
1359 let buf = RunVimInTerminal('-S Xscript', {'rows': rows})
1360 call term_wait(buf)
1361 call term_sendkeys(buf, ":set noruler\n")
1362 call term_wait(buf)
1363 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1364 call term_sendkeys(buf, "2G")
1365 call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
1366 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1367 call term_sendkeys(buf, "4G")
1368 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1369 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1370 call term_sendkeys(buf, "3G")
1371 call WaitForAssert({-> assert_equal('three', term_getline(buf, 3))})
1372 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1373 call term_sendkeys(buf, "1G")
1374 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1375 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
Bram Moolenaar68ffe8c2021-04-05 12:47:25 +02001376 call term_sendkeys(buf, "2G")
1377 call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
1378 call term_sendkeys(buf, "k")
1379 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001380
1381 " clean up
1382 call StopVimInTerminal(buf)
1383
1384 call assert_equal(['[-1,2,2,-1]', '[-1,-1,-1,-1]', '[-1,2,2,-1]',
1385 \ '[-1,-1,-1,-1]', '[-1,2,2,-1]'], readfile('Xoutput'))
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001386 call delete('Xoutput')
1387endfunc
1388
1389" Test for foldtextresult()
1390func Test_foldtextresult()
1391 new
1392 call assert_equal('', foldtextresult(-1))
1393 call assert_equal('', foldtextresult(0))
1394 call assert_equal('', foldtextresult(1))
1395 call setline(1, ['one', 'two', 'three', 'four'])
1396 2,3fold
1397 call assert_equal('', foldtextresult(1))
1398 call assert_equal('+-- 2 lines: two', foldtextresult(2))
1399 setlocal foldtext=
1400 call assert_equal('+-- 2 lines folded ', foldtextresult(2))
1401
1402 " Fold text for a C comment fold
1403 %d _
1404 setlocal foldtext&
1405 call setline(1, ['', '/*', ' * Comment', ' */', ''])
1406 2,4fold
1407 call assert_equal('+-- 3 lines: Comment', foldtextresult(2))
1408
1409 bw!
1410endfunc
1411
1412" Test for merging two recursive folds when an intermediate line with no fold
1413" is removed
dundargocc57b5bc2022-11-02 13:30:51 +00001414func Test_fold_merge_recursive()
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001415 new
1416 call setline(1, [' one', ' two', 'xxxx', ' three',
1417 \ ' four', "\tfive"])
1418 setlocal foldmethod=indent shiftwidth=2
1419 3d_
1420 %foldclose
1421 call assert_equal([1, 5], [foldclosed(5), foldclosedend(1)])
1422 bw!
1423endfunc
1424
1425" Test for moving a line which is the start of a fold from a recursive fold to
1426" outside. The fold length should reduce.
1427func Test_fold_move_foldlevel()
1428 new
1429 call setline(1, ['a{{{', 'b{{{', 'c{{{', 'd}}}', 'e}}}', 'f}}}', 'g'])
1430 setlocal foldmethod=marker
1431 normal zR
1432 call assert_equal([3, 2, 1], [foldlevel(4), foldlevel(5), foldlevel(6)])
1433 3move 7
1434 call assert_equal([2, 1, 0], [foldlevel(3), foldlevel(4), foldlevel(5)])
1435 call assert_equal(1, foldlevel(7))
1436
1437 " Move a line from outside a fold to inside the fold.
1438 %d _
1439 call setline(1, ['a', 'b{{{', 'c}}}'])
1440 normal zR
1441 1move 2
1442 call assert_equal([1, 1, 1], [foldlevel(1), foldlevel(2), foldlevel(3)])
1443
1444 " Move the start of one fold to inside another fold
1445 %d _
1446 call setline(1, ['a', 'b{{{', 'c}}}', 'd{{{', 'e}}}'])
1447 normal zR
1448 call assert_equal([0, 1, 1, 1, 1], [foldlevel(1), foldlevel(2),
1449 \ foldlevel(3), foldlevel(4), foldlevel(5)])
1450 1,2move 4
1451 call assert_equal([0, 1, 1, 2, 2], [foldlevel(1), foldlevel(2),
1452 \ foldlevel(3), foldlevel(4), foldlevel(5)])
1453
1454 bw!
1455endfunc
1456
Bram Moolenaar68ffe8c2021-04-05 12:47:25 +02001457" Test for using zj and zk to move downwards and upwards to the start and end
1458" of the next fold.
1459" Test for using [z and ]z in a closed fold to jump to the beginning and end
1460" of the fold.
1461func Test_fold_jump()
1462 new
1463 call setline(1, ["\t1", "\t2", "\t\t3", "\t\t4", "\t\t\t5", "\t\t\t6", "\t\t7", "\t\t8", "\t9", "\t10"])
1464 setlocal foldmethod=indent
1465 normal zR
1466 normal zj
1467 call assert_equal(3, line('.'))
1468 normal zj
1469 call assert_equal(5, line('.'))
1470 call assert_beeps('normal zj')
1471 call assert_equal(5, line('.'))
1472 call assert_beeps('normal 9Gzj')
1473 call assert_equal(9, line('.'))
1474 normal Gzk
1475 call assert_equal(8, line('.'))
1476 normal zk
1477 call assert_equal(6, line('.'))
1478 call assert_beeps('normal zk')
1479 call assert_equal(6, line('.'))
1480 call assert_beeps('normal 2Gzk')
1481 call assert_equal(2, line('.'))
1482
1483 " Using [z or ]z in a closed fold should not move the cursor
1484 %d _
1485 call setline(1, ["1", "\t2", "\t3", "\t4", "\t5", "\t6", "7"])
1486 normal zR4Gzc
1487 call assert_equal(4, line('.'))
1488 call assert_beeps('normal [z')
1489 call assert_equal(4, line('.'))
1490 call assert_beeps('normal ]z')
1491 call assert_equal(4, line('.'))
1492 bw!
1493endfunc
1494
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001495" Test for using a script-local function for 'foldexpr'
1496func Test_foldexpr_scriptlocal_func()
1497 func! s:FoldFunc()
1498 let g:FoldLnum = v:lnum
1499 endfunc
1500 new | only
1501 call setline(1, 'abc')
1502 let g:FoldLnum = 0
1503 set foldmethod=expr foldexpr=s:FoldFunc()
1504 redraw!
1505 call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +00001506 call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001507 call assert_equal(1, g:FoldLnum)
1508 set foldmethod& foldexpr=
1509 bw!
1510 new | only
1511 call setline(1, 'abc')
1512 let g:FoldLnum = 0
1513 set foldmethod=expr foldexpr=<SID>FoldFunc()
1514 redraw!
1515 call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
zeertzjq01d4efe2023-01-25 15:31:28 +00001516 call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001517 call assert_equal(1, g:FoldLnum)
zeertzjq01d4efe2023-01-25 15:31:28 +00001518 bw!
1519 call setline(1, 'abc')
1520 setlocal foldmethod& foldexpr&
1521 setglobal foldmethod=expr foldexpr=s:FoldFunc()
1522 call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
1523 call assert_equal('0', &foldexpr)
1524 enew!
1525 call setline(1, 'abc')
1526 redraw!
1527 call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
1528 call assert_equal(1, g:FoldLnum)
1529 bw!
1530 call setline(1, 'abc')
1531 setlocal foldmethod& foldexpr&
1532 setglobal foldmethod=expr foldexpr=<SID>FoldFunc()
1533 call assert_equal(expand('<SID>') .. 'FoldFunc()', &g:foldexpr)
1534 call assert_equal('0', &foldexpr)
1535 enew!
1536 call setline(1, 'abc')
1537 redraw!
1538 call assert_equal(expand('<SID>') .. 'FoldFunc()', &foldexpr)
1539 call assert_equal(1, g:FoldLnum)
1540 set foldmethod& foldexpr&
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001541 delfunc s:FoldFunc
1542 bw!
1543endfunc
1544
Yegappan Lakshmanan27708e62021-12-26 21:54:43 +00001545" Test for using a script-local function for 'foldtext'
1546func Test_foldtext_scriptlocal_func()
1547 func! s:FoldText()
1548 let g:FoldTextArgs = [v:foldstart, v:foldend]
1549 return foldtext()
1550 endfunc
1551 new | only
1552 call setline(1, range(50))
1553 let g:FoldTextArgs = []
Yegappan Lakshmanan27708e62021-12-26 21:54:43 +00001554 set foldtext=s:FoldText()
1555 norm! 4Gzf4j
1556 redraw!
1557 call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
zeertzjq01d4efe2023-01-25 15:31:28 +00001558 call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
Yegappan Lakshmanan27708e62021-12-26 21:54:43 +00001559 call assert_equal([4, 8], g:FoldTextArgs)
1560 set foldtext&
1561 bw!
1562 new | only
1563 call setline(1, range(50))
1564 let g:FoldTextArgs = []
Yegappan Lakshmanan27708e62021-12-26 21:54:43 +00001565 set foldtext=<SID>FoldText()
1566 norm! 8Gzf4j
1567 redraw!
1568 call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
zeertzjq01d4efe2023-01-25 15:31:28 +00001569 call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
Yegappan Lakshmanan27708e62021-12-26 21:54:43 +00001570 call assert_equal([8, 12], g:FoldTextArgs)
1571 set foldtext&
1572 bw!
zeertzjq01d4efe2023-01-25 15:31:28 +00001573 call setline(1, range(50))
1574 let g:FoldTextArgs = []
1575 setlocal foldtext&
1576 setglobal foldtext=s:FoldText()
1577 call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
1578 call assert_equal('foldtext()', &foldtext)
1579 enew!
1580 call setline(1, range(50))
1581 norm! 12Gzf4j
1582 redraw!
1583 call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
1584 call assert_equal([12, 16], g:FoldTextArgs)
1585 set foldtext&
1586 bw!
1587 call setline(1, range(50))
1588 let g:FoldTextArgs = []
1589 setlocal foldtext&
1590 setglobal foldtext=<SID>FoldText()
1591 call assert_equal(expand('<SID>') .. 'FoldText()', &g:foldtext)
1592 call assert_equal('foldtext()', &foldtext)
1593 enew!
1594 call setline(1, range(50))
1595 norm! 16Gzf4j
1596 redraw!
1597 call assert_equal(expand('<SID>') .. 'FoldText()', &foldtext)
1598 call assert_equal([16, 20], g:FoldTextArgs)
1599 set foldtext&
1600 bw!
Yegappan Lakshmanan27708e62021-12-26 21:54:43 +00001601 delfunc s:FoldText
1602endfunc
1603
Brandon Simmons2c407072022-04-23 13:50:17 +01001604" Make sure a fold containing a nested fold is split correctly when using
1605" foldmethod=indent
1606func Test_fold_split()
1607 new
1608 let lines =<< trim END
1609 line 1
1610 line 2
1611 line 3
1612 line 4
1613 line 5
1614 END
1615 call setline(1, lines)
1616 setlocal sw=2
1617 setlocal foldmethod=indent foldenable
1618 call assert_equal([0, 1, 1, 2, 2], range(1, 5)->map('foldlevel(v:val)'))
1619 call append(2, 'line 2.5')
1620 call assert_equal([0, 1, 0, 1, 2, 2], range(1, 6)->map('foldlevel(v:val)'))
Yegappan Lakshmananee47eac2022-06-29 12:55:36 +01001621 3d
1622 call assert_equal([0, 1, 1, 2, 2], range(1, 5)->map('foldlevel(v:val)'))
Brandon Simmons2c407072022-04-23 13:50:17 +01001623 bw!
1624endfunc
1625
Brandon Simmonsd98e75e2022-05-10 19:13:23 +01001626" Make sure that when you append under a blank line that is under a fold with
1627" the same indent level as your appended line, the fold expands across the
1628" blank line
1629func Test_indent_append_under_blank_line()
1630 new
1631 let lines =<< trim END
1632 line 1
1633 line 2
1634 line 3
1635 END
1636 call setline(1, lines)
1637 setlocal sw=2
1638 setlocal foldmethod=indent foldenable
1639 call assert_equal([0, 1, 1], range(1, 3)->map('foldlevel(v:val)'))
1640 call append(3, '')
1641 call append(4, ' line 5')
1642 call assert_equal([0, 1, 1, 1, 1], range(1, 5)->map('foldlevel(v:val)'))
1643 bw!
1644endfunc
1645
Brandon Simmons3fcccf92022-05-20 18:25:21 +01001646" Make sure that when you delete 1 line of a fold whose length is 2 lines, the
1647" fold can't be closed since its length (1) is now less than foldminlines.
1648func Test_indent_one_line_fold_close()
1649 let lines =<< trim END
1650 line 1
1651 line 2
1652 line 3
1653 END
1654
1655 new
1656 setlocal sw=2 foldmethod=indent
1657 call setline(1, lines)
1658 " open all folds, delete line, then close all folds
1659 normal zR
1660 3delete
1661 normal zM
1662 call assert_equal(-1, foldclosed(2)) " the fold should not be closed
1663
1664 " Now do the same, but delete line 2 this time; this covers different code.
1665 " (Combining this code with the above code doesn't expose both bugs.)
1666 1,$delete
1667 call setline(1, lines)
1668 normal zR
1669 2delete
1670 normal zM
1671 call assert_equal(-1, foldclosed(2))
1672 bw!
1673endfunc
1674
Brandon Simmonse8c4a642022-05-23 15:33:08 +01001675" Make sure that when appending [an indented line then a blank line] right
1676" before a single indented line, the resulting extended fold can be closed
1677func Test_indent_append_blank_small_fold_close()
1678 new
1679 setlocal sw=2 foldmethod=indent
1680 " at first, the fold at the second line can't be closed since it's smaller
1681 " than foldminlines
1682 let lines =<< trim END
1683 line 1
1684 line 4
1685 END
1686 call setline(1, lines)
1687 call append(1, [' line 2', ''])
1688 " close all folds
1689 normal zM
1690 call assert_notequal(-1, foldclosed(2)) " the fold should be closed now
1691 bw!
1692endfunc
1693
Bram Moolenaarf00112d2022-11-11 01:20:35 +00001694func Test_sort_closed_fold()
1695 CheckExecutable sort
1696
1697 call setline(1, [
1698 \ 'Section 1',
1699 \ ' how',
1700 \ ' now',
1701 \ ' brown',
1702 \ ' cow',
1703 \ 'Section 2',
1704 \ ' how',
1705 \ ' now',
1706 \ ' brown',
1707 \ ' cow',
1708 \])
1709 setlocal foldmethod=indent sw=3
1710 normal 2G
1711
1712 " The "!!" expands to ".,.+3" and must only sort four lines
1713 call feedkeys("!!sort\<CR>", 'xt')
1714 call assert_equal([
1715 \ 'Section 1',
1716 \ ' brown',
1717 \ ' cow',
1718 \ ' how',
1719 \ ' now',
1720 \ 'Section 2',
1721 \ ' how',
1722 \ ' now',
1723 \ ' brown',
1724 \ ' cow',
1725 \ ], getline(1, 10))
1726
1727 bwipe!
1728endfunc
1729
Bram Moolenaar232bdaa2023-01-13 14:17:58 +00001730func Test_indent_with_L_command()
1731 " The "L" command moved the cursor to line zero, causing the text saved for
1732 " undo to use line number -1, which caused trouble for undo later.
1733 new
1734 sil! norm 8R V{zf8=Lu
1735 bwipe!
1736endfunc
1737
Brandon Simmonsda3dd7d2023-01-17 19:48:07 +00001738" Make sure that when there is a fold at the bottom of the buffer and a newline
1739" character is appended to the line, the fold gets expanded (instead of the new
1740" line not being part of the fold).
1741func Test_expand_fold_at_bottom_of_buffer()
1742 new
1743 " create a fold on the only line
1744 fold
1745 execute "normal A\<CR>"
1746 call assert_equal([1, 1], range(1, 2)->map('foldlevel(v:val)'))
1747
1748 bwipe!
1749endfunc
1750
Luuk van Baal441a7a92023-02-18 20:15:44 +00001751func Test_fold_screenrow_motion()
1752 call setline(1, repeat(['aaaa'], 5))
1753 1,4fold
1754 norm Ggkzo
1755 call assert_equal(1, line('.'))
1756endfunc
1757
zeertzjq58e1e012023-06-04 18:46:28 +01001758" This was using freed memory
1759func Test_foldcolumn_linebreak_control_char()
1760 CheckFeature linebreak
1761
1762 5vnew
1763 setlocal foldcolumn=1 linebreak
1764 call setline(1, "aaa\<C-A>b")
1765 redraw
1766 call assert_equal([' aaa^', ' Ab '], ScreenLines([1, 2], 5))
1767 call assert_equal(screenattr(1, 5), screenattr(2, 2))
1768
1769 bwipe!
1770endfunc
1771
zeertzjqa991ce92023-10-06 19:16:36 +02001772" This used to cause invalid memory access
1773func Test_foldexpr_return_empty_string()
1774 new
1775 setlocal foldexpr='' foldmethod=expr
1776 redraw
1777
1778 bwipe!
1779endfunc
1780
Shota Nozaki0689b872024-01-03 19:18:43 +01001781" Make sure that when ending a fold that hasn't been started, it does not
1782" start a new fold.
1783func Test_foldexpr_end_fold()
1784 new
1785 setlocal foldmethod=expr
1786 let &l:foldexpr = 'v:lnum == 2 ? "<2" : "="'
1787 call setline(1, range(1, 3))
1788 redraw
1789 call assert_equal([0, 0, 0], range(1, 3)->map('foldlevel(v:val)'))
1790
1791 bwipe!
1792endfunc
1793
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +02001794" vim: shiftwidth=2 sts=2 expandtab