blob: 920dcc406de327a33f44cd0ed23f12e78cf3e871 [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 Moolenaar94be6192017-04-22 22:40:11 +020075func Test_indent_fold()
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010076 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!
Bram Moolenaar1159b162017-02-28 21:53:56 +010084endfunc
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010085
Bram Moolenaar94be6192017-04-22 22:40:11 +020086func Test_indent_fold2()
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010087 new
88 call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
89 setl fen fdm=marker
90 2
91 norm! >>
Bram Moolenaara4208962019-08-24 20:50:19 +020092 let a=map(range(1,5), 'v:val->foldclosed()')
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010093 call assert_equal([-1,-1,-1,4,4], a)
94 bw!
Bram Moolenaar1159b162017-02-28 21:53:56 +010095endfunc
96
97func Test_manual_fold_with_filter()
Bram Moolenaaraeb313f2020-11-27 19:13:28 +010098 CheckExecutable cat
Bram Moolenaar3f3897e2017-03-04 15:28:53 +010099 for type in ['manual', 'marker']
100 exe 'set foldmethod=' . type
101 new
102 call setline(1, range(1, 20))
103 4,$fold
104 %foldopen
105 10,$fold
106 %foldopen
107 " This filter command should not have an effect
108 1,8! cat
109 call feedkeys('5ggzdzMGdd', 'xt')
110 call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
111
112 bwipe!
113 set foldmethod&
114 endfor
Bram Moolenaar1159b162017-02-28 21:53:56 +0100115endfunc
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100116
Bram Moolenaar94be6192017-04-22 22:40:11 +0200117func Test_indent_fold_with_read()
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100118 new
119 set foldmethod=indent
120 call setline(1, repeat(["\<Tab>a"], 4))
121 for n in range(1, 4)
122 call assert_equal(1, foldlevel(n))
123 endfor
124
125 call writefile(["a", "", "\<Tab>a"], 'Xfile')
126 foldopen
127 2read Xfile
128 %foldclose
129 call assert_equal(1, foldlevel(1))
130 call assert_equal(2, foldclosedend(1))
131 call assert_equal(0, foldlevel(3))
132 call assert_equal(0, foldlevel(4))
133 call assert_equal(1, foldlevel(5))
Bram Moolenaara4208962019-08-24 20:50:19 +0200134 call assert_equal(7, 5->foldclosedend())
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100135
136 bwipe!
137 set foldmethod&
138 call delete('Xfile')
139endfunc
140
141func Test_combining_folds_indent()
142 new
143 let one = "\<Tab>a"
144 let zero = 'a'
145 call setline(1, [one, one, zero, zero, zero, one, one, one])
146 set foldmethod=indent
147 3,5d
148 %foldclose
149 call assert_equal(5, foldclosedend(1))
150
151 set foldmethod&
152 bwipe!
153endfunc
154
155func Test_combining_folds_marker()
156 new
157 call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
158 set foldmethod=marker
159 3,5d
160 %foldclose
161 call assert_equal(2, foldclosedend(1))
162
163 set foldmethod&
164 bwipe!
165endfunc
166
Bram Moolenaar025a6b72017-03-12 20:37:21 +0100167func Test_folds_marker_in_comment()
168 new
169 call setline(1, ['" foo', 'bar', 'baz'])
170 setl fen fdm=marker
171 setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
172 norm! zf2j
173 setl nofen
174 :1y
175 call assert_equal(['" foo{{{'], getreg(0,1,1))
176 :+2y
177 call assert_equal(['baz"}}}'], getreg(0,1,1))
178
179 set foldmethod&
180 bwipe!
181endfunc
182
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100183func s:TestFoldExpr(lnum)
184 let thisline = getline(a:lnum)
185 if thisline == 'a'
186 return 1
187 elseif thisline == 'b'
188 return 0
189 elseif thisline == 'c'
190 return '<1'
191 elseif thisline == 'd'
192 return '>1'
193 endif
194 return 0
195endfunction
196
197func Test_update_folds_expr_read()
198 new
199 call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
200 set foldmethod=expr
201 set foldexpr=s:TestFoldExpr(v:lnum)
202 2
203 foldopen
204 call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
205 read Xfile
206 %foldclose
207 call assert_equal(2, foldclosedend(1))
208 call assert_equal(0, foldlevel(3))
Bram Moolenaara4208962019-08-24 20:50:19 +0200209 call assert_equal(0, 4->foldlevel())
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100210 call assert_equal(6, foldclosedend(5))
211 call assert_equal(10, foldclosedend(7))
212 call assert_equal(14, foldclosedend(11))
213
214 call delete('Xfile')
215 bwipe!
216 set foldmethod& foldexpr&
217endfunc
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100218
Bram Moolenaar94be6192017-04-22 22:40:11 +0200219func Check_foldlevels(expected)
220 call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
221endfunc
222
223func Test_move_folds_around_manual()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100224 new
225 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
226 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
227 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
228 " all folds closed
229 set foldenable foldlevel=0 fdm=indent
230 " needs a forced redraw
231 redraw!
232 set fdm=manual
233 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
234 call assert_equal(input, getline(1, '$'))
235 7,12m0
236 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
237 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
238 10,12m0
239 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
240 call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
241 " moving should not close the folds
242 %d
243 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
244 set fdm=indent
245 redraw!
246 set fdm=manual
247 call cursor(2, 1)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100248 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100249 7,12m0
250 let folds=repeat([-1], 18)
251 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
252 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
253 norm! zM
254 " folds are not corrupted and all have been closed
255 call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
256 %d
257 call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
258 set fdm=indent
259 redraw!
260 set fdm=manual
261 %foldopen
262 3m4
263 %foldclose
264 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
265 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
266 %d
267 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
268 set fdm=indent foldlevel=0
269 set fdm=manual
270 %foldopen
271 3m1
272 %foldclose
273 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
274 call assert_equal(0, foldlevel(2))
275 call assert_equal(5, foldclosedend(3))
276 call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
277 2,6m$
278 %foldclose
279 call assert_equal(5, foldclosedend(2))
280 call assert_equal(0, foldlevel(6))
281 call assert_equal(9, foldclosedend(7))
282 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
Bram Moolenaar495b7dd2017-09-16 17:19:22 +0200283
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100284 %d
285 " Ensure moving around the edges still works.
286 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
287 set fdm=indent foldlevel=0
288 set fdm=manual
289 %foldopen
290 6m$
291 " The first fold has been truncated to the 5'th line.
292 " Second fold has been moved up because the moved line is now below it.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200293 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
294
295 %delete
296 set fdm=indent foldlevel=0
297 call setline(1, [
298 \ "a",
299 \ "\ta",
300 \ "\t\ta",
301 \ "\t\ta",
302 \ "\t\ta",
303 \ "a",
304 \ "a"])
305 set fdm=manual
306 %foldopen!
307 4,5m6
308 call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
309
310 %delete
311 set fdm=indent
312 call setline(1, [
313 \ "\ta",
314 \ "\t\ta",
315 \ "\t\ta",
316 \ "\t\ta",
317 \ "\ta",
318 \ "\t\ta",
319 \ "\t\ta",
320 \ "\t\ta",
321 \ "\ta",
322 \ "\t\ta",
323 \ "\t\ta",
324 \ "\t\ta",
325 \ "\t\ta",
326 \ "\ta",
327 \ "a"])
328 set fdm=manual
329 %foldopen!
330 13m7
331 call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
332
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100333 bw!
334endfunc
335
Bram Moolenaar94be6192017-04-22 22:40:11 +0200336func Test_move_folds_around_indent()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100337 new
338 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
339 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
340 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
341 " all folds closed
342 set fdm=indent
343 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
344 call assert_equal(input, getline(1, '$'))
345 7,12m0
346 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
347 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
348 10,12m0
349 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
350 call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
351 " moving should not close the folds
352 %d
353 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
354 set fdm=indent
355 call cursor(2, 1)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100356 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100357 7,12m0
358 let folds=repeat([-1], 18)
359 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
360 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
361 norm! zM
362 " folds are not corrupted and all have been closed
363 call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
364 %d
365 call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
366 set fdm=indent
367 %foldopen
368 3m4
369 %foldclose
370 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
371 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
372 %d
373 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
374 set fdm=indent foldlevel=0
375 %foldopen
376 3m1
377 %foldclose
378 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
379 call assert_equal(1, foldlevel(2))
380 call assert_equal(5, foldclosedend(3))
381 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
382 2,6m$
383 %foldclose
384 call assert_equal(9, foldclosedend(2))
385 call assert_equal(1, foldlevel(6))
386 call assert_equal(9, foldclosedend(7))
387 call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100388 " Ensure moving around the edges still works.
389 %d
390 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
391 set fdm=indent foldlevel=0
392 %foldopen
393 6m$
394 " The first fold has been truncated to the 5'th line.
395 " Second fold has been moved up because the moved line is now below it.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200396 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100397 bw!
398endfunc
Bram Moolenaar518c9b12017-03-21 11:48:39 +0100399
400func Test_folddoopen_folddoclosed()
401 new
402 call setline(1, range(1, 9))
403 set foldmethod=manual
404 1,3 fold
405 6,8 fold
406
407 " Test without range.
408 folddoopen s/$/o/
409 folddoclosed s/$/c/
410 call assert_equal(['1c', '2c', '3c',
411 \ '4o', '5o',
412 \ '6c', '7c', '8c',
413 \ '9o'], getline(1, '$'))
414
415 " Test with range.
416 call setline(1, range(1, 9))
417 1,8 folddoopen s/$/o/
418 4,$ folddoclosed s/$/c/
419 call assert_equal(['1', '2', '3',
420 \ '4o', '5o',
421 \ '6c', '7c', '8c',
422 \ '9'], getline(1, '$'))
423
424 set foldmethod&
425 bw!
426endfunc
427
428func Test_fold_error()
429 new
430 call setline(1, [1, 2])
431
432 for fm in ['indent', 'expr', 'syntax', 'diff']
433 exe 'set foldmethod=' . fm
434 call assert_fails('norm zf', 'E350:')
435 call assert_fails('norm zd', 'E351:')
436 call assert_fails('norm zE', 'E352:')
437 endfor
438
439 set foldmethod=manual
440 call assert_fails('norm zd', 'E490:')
441 call assert_fails('norm zo', 'E490:')
442 call assert_fails('3fold', 'E16:')
443
444 set foldmethod=marker
445 set nomodifiable
446 call assert_fails('1,2fold', 'E21:')
447
448 set modifiable&
449 set foldmethod&
450 bw!
451endfunc
Bram Moolenaar495b7dd2017-09-16 17:19:22 +0200452
453func Test_foldtext_recursive()
454 new
455 call setline(1, ['{{{', 'some text', '}}}'])
456 setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart)
457 " This was crashing because of endless recursion.
458 2foldclose
459 redraw
460 call assert_equal(1, foldlevel(2))
461 call assert_equal(1, foldclosed(2))
462 call assert_equal(3, foldclosedend(2))
463 bwipe!
464endfunc
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100465
466" Various fold related tests
467
468" Basic test if a fold can be created, opened, moving to the end and closed
469func Test_fold_manual()
470 enew!
471 set fdm=manual
472
473 let content = ['1 aa', '2 bb', '3 cc']
474 call append(0, content)
475 call cursor(1, 1)
476 normal zf2j
477 call assert_equal('1 aa', getline(foldclosed('.')))
478 normal zo
479 call assert_equal(-1, foldclosed('.'))
480 normal ]z
481 call assert_equal('3 cc', getline('.'))
482 normal zc
483 call assert_equal('1 aa', getline(foldclosed('.')))
484
485 set fdm&
486 enew!
487endfunc
488
489" test folding with markers.
490func Test_fold_marker()
491 enew!
492 set fdm=marker fdl=1 fdc=3
493
494 let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
495 call append(0, content)
496 call cursor(2, 1)
497 call assert_equal(2, foldlevel('.'))
498 normal [z
499 call assert_equal(1, foldlevel('.'))
500 exe "normal jo{{ \<Esc>r{jj"
501 call assert_equal(1, foldlevel('.'))
502 normal kYpj
503 call assert_equal(0, foldlevel('.'))
504
505 set fdm& fdl& fdc&
506 enew!
507endfunc
508
Bram Moolenaar4af72592018-12-09 15:00:52 +0100509" test create fold markers with C filetype
510func Test_fold_create_marker_in_C()
511 enew!
512 set fdm=marker fdl=9
513 set filetype=c
514
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200515 let content =<< trim [CODE]
516 /*
517 * comment
518 *
519 *
520 */
521 int f(int* p) {
522 *p = 3;
523 return 0;
524 }
525 [CODE]
526
Bram Moolenaar4af72592018-12-09 15:00:52 +0100527 for c in range(len(content) - 1)
528 bw!
529 call append(0, content)
530 call cursor(c + 1, 1)
531 norm! zfG
532 call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1))
533 endfor
534
535 set fdm& fdl&
536 enew!
537endfunc
538
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100539" test folding with indent
540func Test_fold_indent()
541 enew!
542 set fdm=indent sw=2
543
544 let content = ['1 aa', '2 bb', '3 cc']
545 call append(0, content)
546 call cursor(2, 1)
547 exe "normal i \<Esc>jI "
548 call assert_equal(2, foldlevel('.'))
549 normal k
550 call assert_equal(1, foldlevel('.'))
551
552 set fdm& sw&
553 enew!
554endfunc
555
556" test syntax folding
557func Test_fold_syntax()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200558 CheckFeature syntax
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100559
560 enew!
561 set fdm=syntax fdl=0
562
563 syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
564 syn region Fd1 start="ee" end="ff" fold contained
565 syn region Fd2 start="gg" end="hh" fold contained
566 syn region Fd3 start="commentstart" end="commentend" fold contained
567 let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
568 \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
569 call append(0, content)
570 normal Gzk
571 call assert_equal('9 ii', getline('.'))
572 normal k
573 call assert_equal('3 cc', getline('.'))
574 exe "normal jAcommentstart \<Esc>Acommentend"
575 set fdl=1
576 normal 3j
577 call assert_equal('7 gg', getline('.'))
578 set fdl=0
579 exe "normal zO\<C-L>j"
580 call assert_equal('8 hh', getline('.'))
581 syn clear Fd1 Fd2 Fd3 Hup
582
583 set fdm& fdl&
584 enew!
585endfunc
586
587func Flvl()
588 let l = getline(v:lnum)
589 if l =~ "bb$"
590 return 2
591 elseif l =~ "gg$"
592 return "s1"
593 elseif l =~ "ii$"
594 return ">2"
595 elseif l =~ "kk$"
596 return "0"
597 endif
598 return "="
599endfun
600
601" test expression folding
602func Test_fold_expr()
603 enew!
604 set fdm=expr fde=Flvl()
605
606 let content = ['1 aa',
607 \ '2 bb',
608 \ '3 cc',
609 \ '4 dd {{{commentstart commentend',
610 \ '5 ee {{{ }}}',
611 \ '{{{',
612 \ '6 ff }}}',
613 \ '6 ff }}}',
614 \ ' 7 gg',
615 \ ' 8 hh',
616 \ '9 ii',
617 \ 'a jj',
618 \ 'b kk']
619 call append(0, content)
620 call cursor(1, 1)
621 exe "normal /bb$\<CR>"
622 call assert_equal(2, foldlevel('.'))
623 exe "normal /hh$\<CR>"
624 call assert_equal(1, foldlevel('.'))
625 exe "normal /ii$\<CR>"
626 call assert_equal(2, foldlevel('.'))
627 exe "normal /kk$\<CR>"
628 call assert_equal(0, foldlevel('.'))
629
630 set fdm& fde&
631 enew!
632endfunc
633
634" Bug with fdm=indent and moving folds
635" Moving a fold a few times, messes up the folds below the moved fold.
636" Fixed by 7.4.700
637func Test_fold_move()
638 enew!
639 set fdm=indent sw=2 fdl=0
640
641 let content = ['', '', 'Line1', ' Line2', ' Line3',
642 \ 'Line4', ' Line5', ' Line6',
643 \ 'Line7', ' Line8', ' Line9']
644 call append(0, content)
645 normal zM
646 call cursor(4, 1)
647 move 2
648 move 1
649 call assert_equal(7, foldclosed(7))
650 call assert_equal(8, foldclosedend(7))
651 call assert_equal(0, foldlevel(9))
652 call assert_equal(10, foldclosed(10))
653 call assert_equal(11, foldclosedend(10))
654 call assert_equal('+-- 2 lines: Line2', foldtextresult(2))
Bram Moolenaara4208962019-08-24 20:50:19 +0200655 call assert_equal('+-- 2 lines: Line8', 10->foldtextresult())
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100656
657 set fdm& sw& fdl&
658 enew!
659endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100660
661" test for patch 7.3.637
662" Cannot catch the error caused by a foldopen when there is no fold.
663func Test_foldopen_exception()
664 enew!
665 let a = 'No error caught'
666 try
667 foldopen
668 catch
669 let a = matchstr(v:exception,'^[^ ]*')
670 endtry
671 call assert_equal('Vim(foldopen):E490:', a)
672
673 let a = 'No error caught'
674 try
675 foobar
676 catch
677 let a = matchstr(v:exception,'^[^ ]*')
678 endtry
679 call assert_match('E492:', a)
680endfunc
Bram Moolenaar907dad72018-07-10 15:07:15 +0200681
682func Test_fold_last_line_with_pagedown()
683 enew!
684 set fdm=manual
685
686 let expect = '+-- 11 lines: 9---'
687 let content = range(1,19)
688 call append(0, content)
689 normal dd9G
690 normal zfG
691 normal zt
692 call assert_equal('9', getline(foldclosed('.')))
693 call assert_equal('19', getline(foldclosedend('.')))
694 call assert_equal(expect, ScreenLines(1, len(expect))[0])
695 call feedkeys("\<C-F>", 'xt')
696 call assert_equal(expect, ScreenLines(1, len(expect))[0])
697 call feedkeys("\<C-F>", 'xt')
698 call assert_equal(expect, ScreenLines(1, len(expect))[0])
699 call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt')
700 call assert_equal(expect, ScreenLines(1, len(expect))[0])
701
702 set fdm&
703 enew!
704endfunc
Bram Moolenaar7701f302018-10-02 21:20:32 +0200705
706func Test_folds_with_rnu()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200707 CheckScreendump
Bram Moolenaar7701f302018-10-02 21:20:32 +0200708
709 call writefile([
710 \ 'set fdm=marker rnu foldcolumn=2',
711 \ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])',
712 \ ], 'Xtest_folds_with_rnu')
713 let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {})
714
715 call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {})
716 call term_sendkeys(buf, "j")
717 call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {})
718
719 " clean up
720 call StopVimInTerminal(buf)
721 call delete('Xtest_folds_with_rnu')
722endfunc
Bram Moolenaar53932812018-12-07 21:08:49 +0100723
724func Test_folds_marker_in_comment2()
725 new
726 call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit'])
727 setl fen fdm=marker
728 setl commentstring=<!--%s-->
729 setl comments=s:<!--,m:\ \ \ \ ,e:-->
730 norm! zf2j
731 setl nofen
732 :1y
733 call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1))
734 :+2y
735 call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1))
736
737 set foldmethod&
738 bwipe!
739endfunc
Bram Moolenaar9a4a8c42019-08-19 22:48:30 +0200740
741func Test_fold_delete_with_marker()
742 new
743 call setline(1, ['func Func() {{{1', 'endfunc'])
744 1,2yank
745 new
746 set fdm=marker
747 call setline(1, 'x')
748 normal! Vp
749 normal! zd
750 call assert_equal(['func Func() ', 'endfunc'], getline(1, '$'))
751
752 set fdm&
753 bwipe!
754 bwipe!
755endfunc
Bram Moolenaar7a9bd7c2019-09-17 22:42:55 +0200756
757func Test_fold_delete_with_marker_and_whichwrap()
758 new
759 let content1 = ['']
760 let content2 = ['folded line 1 "{{{1', ' test', ' test2', ' test3', '', 'folded line 2 "{{{1', ' test', ' test2', ' test3']
761 call setline(1, content1 + content2)
762 set fdm=marker ww+=l
763 normal! x
764 call assert_equal(content2, getline(1, '$'))
765 set fdm& ww&
766 bwipe!
767endfunc
Bram Moolenaar3b681232019-12-13 19:35:55 +0100768
769func Test_fold_delete_first_line()
770 new
771 call setline(1, [
772 \ '" x {{{1',
773 \ '" a',
774 \ '" aa',
775 \ '" x {{{1',
776 \ '" b',
777 \ '" bb',
778 \ '" x {{{1',
779 \ '" c',
780 \ '" cc',
781 \ ])
782 set foldmethod=marker
783 1
784 normal dj
785 call assert_equal([
786 \ '" x {{{1',
787 \ '" c',
788 \ '" cc',
789 \ ], getline(1,'$'))
790 bwipe!
791 set foldmethod&
792endfunc
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +0200793
794" Test for errors in 'foldexpr'
795func Test_fold_expr_error()
796 new
797 call setline(1, ['one', 'two', 'three'])
798
799 " Return a list from the expression
800 set foldexpr=[]
801 set foldmethod=expr
802 for i in range(3)
803 call assert_equal(0, foldlevel(i))
804 endfor
805
806 " expression error
807 set foldexpr=[{]
808 set foldmethod=expr
809 for i in range(3)
810 call assert_equal(0, foldlevel(i))
811 endfor
812
813 set foldmethod& foldexpr&
814 close!
815endfunc
816
Bram Moolenaarda697642020-09-17 19:36:04 +0200817func Test_undo_fold_deletion()
818 new
819 set fdm=marker
820 let lines =<< trim END
821 " {{{
822 " }}}1
823 " {{{
824 END
825 call setline(1, lines)
826 3d
827 g/"/d
828 undo
829 redo
830 eval getline(1, '$')->assert_equal([''])
831
832 set fdm&vim
833 bwipe!
834endfunc
835
Bram Moolenaarc136a352020-11-03 20:05:40 +0100836" this was crashing
837func Test_move_no_folds()
838 new
839 fold
840 setlocal fdm=expr
841 normal zj
842 bwipe!
843endfunc
844
Bram Moolenaar5e1f22f2020-11-10 18:23:52 +0100845" this was crashing
846func Test_fold_create_delete_create()
847 new
848 fold
849 fold
850 normal zd
851 fold
852 bwipe!
853endfunc
854
Bram Moolenaar6a78f322020-12-21 14:01:41 +0100855" this was crashing
856func Test_fold_create_delete()
857 new
858 norm zFzFzdzj
859 bwipe!
860endfunc
861
Bram Moolenaare71996b2021-01-21 17:03:07 +0100862func Test_fold_relative_move()
863 enew!
864 set fdm=indent sw=2 wrap tw=80
865
866 let content = [ ' foo', ' bar', ' baz',
Bram Moolenaar7cf0c112021-01-24 12:00:01 +0100867 \ repeat('x', &columns + 1),
Bram Moolenaare71996b2021-01-21 17:03:07 +0100868 \ ' foo', ' bar', ' baz'
869 \ ]
870 call append(0, content)
871
872 normal zM
873
874 call cursor(3, 1)
875 call assert_true(foldclosed(line('.')))
876 normal gj
877 call assert_equal(2, winline())
878
879 call cursor(2, 1)
880 call assert_true(foldclosed(line('.')))
881 normal 2gj
882 call assert_equal(3, winline())
883
884 call cursor(5, 1)
885 call assert_true(foldclosed(line('.')))
886 normal gk
887 call assert_equal(3, winline())
888
889 call cursor(6, 1)
890 call assert_true(foldclosed(line('.')))
891 normal 2gk
892 call assert_equal(2, winline())
893
894 set fdm& sw& wrap& tw&
895endfunc
896
Bram Moolenaar4fa11752021-03-03 13:26:02 +0100897" Test for using multibyte characters as 'foldopen', 'foldclose' and
898" 'foldsetp' items in 'fillchars'
899func s:mbyte_fillchar_tests(fo, fc, fs)
900 setlocal foldcolumn=3
901
902 normal zE
903 1,2fold
904 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
905 \ ScreenLines([1, 2], 10))
906 1,2foldopen
907 call assert_equal([a:fo .. ' one ', a:fs .. ' two '],
908 \ ScreenLines([1, 2], 7))
909 1,2foldclose
910 redraw!
911 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
912 \ ScreenLines([1, 2], 10))
913
914 " Two level fold
915 normal zE
916 2,3fold
917 1,4fold
918 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
919 \ ScreenLines([1, 2], 10))
920 1,4foldopen
921 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
922 \ ScreenLines([1, 2], 10))
923 1,4foldopen
924 call assert_equal([a:fo .. ' one ', a:fs .. a:fo .. ' two ',
925 \ a:fs .. a:fs .. ' three '], ScreenLines([1, 3], 10))
926 2,3foldclose
927 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
928 \ ScreenLines([1, 2], 10))
929 1,4foldclose
930 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
931 \ ScreenLines([1, 2], 10))
932
933 " Three level fold
934 normal zE
935 3,4fold
936 2,5fold
937 1,6fold
938 call assert_equal([a:fc .. ' +-- 6 '], ScreenLines(1, 10))
939 " open all the folds
940 normal zR
941 call assert_equal([
942 \ a:fo .. ' one ',
943 \ a:fs .. a:fo .. ' two ',
944 \ '2' .. a:fo .. ' three ',
945 \ '23 four ',
946 \ a:fs .. a:fs .. ' five ',
947 \ a:fs .. ' six ',
948 \ ], ScreenLines([1, 6], 10))
949 " close the innermost fold
950 3,4foldclose
951 call assert_equal([
952 \ a:fo .. ' one ',
953 \ a:fs .. a:fo .. ' two ',
954 \ a:fs .. a:fs .. a:fc .. '+---- ',
955 \ a:fs .. a:fs .. ' five ',
956 \ a:fs .. ' six ',
957 \ ], ScreenLines([1, 5], 10))
958 " close the next fold
959 2,5foldclose
960 call assert_equal([
961 \ a:fo .. ' one ',
962 \ a:fs .. a:fc .. ' +--- 4',
963 \ a:fs .. ' six ',
964 \ ], ScreenLines([1, 3], 10))
965
966 " set the fold column size to 2
967 setlocal fdc=2
968 normal zR
969 call assert_equal([
970 \ a:fo .. ' one ',
971 \ a:fo .. ' two ',
972 \ a:fo .. ' three',
973 \ '3 four ',
974 \ '2 five ',
975 \ a:fs .. ' six ',
976 \ ], ScreenLines([1, 6], 7))
977
978 " set the fold column size to 1
979 setlocal fdc=1
980 normal zR
981 call assert_equal([
982 \ a:fo .. 'one ',
983 \ a:fo .. 'two ',
984 \ a:fo .. 'three ',
985 \ '3four ',
986 \ '2five ',
987 \ a:fs .. 'six ',
988 \ ], ScreenLines([1, 6], 7))
989
990 setlocal foldcolumn&
991endfunc
992
993func Test_foldcolumn_multibyte_char()
994 new
995 call setline(1, ['one', 'two', 'three', 'four', 'five', 'six'])
996 setlocal foldenable foldmethod=manual
997
998 " First test with the default setting
999 call s:mbyte_fillchar_tests('-', '+', '|')
1000
1001 " Use multi-byte characters
1002 set fillchars+=foldopen:▾,foldsep:│,foldclose:▸
1003 call s:mbyte_fillchar_tests('', '', '')
1004
1005 bw!
1006 set foldenable& fdc& fdm& fillchars&
1007endfunc
1008
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +02001009" vim: shiftwidth=2 sts=2 expandtab