blob: e5dc1ececa88d68751081903aac815d5163dfb6e [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
Bram Moolenaar5c504f62021-04-01 13:39:51 +020097" 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
Bram Moolenaar1159b162017-02-28 21:53:56 +0100112func Test_manual_fold_with_filter()
Bram Moolenaaraeb313f2020-11-27 19:13:28 +0100113 CheckExecutable cat
Bram Moolenaar3f3897e2017-03-04 15:28:53 +0100114 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
Bram Moolenaar1159b162017-02-28 21:53:56 +0100130endfunc
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100131
Bram Moolenaar94be6192017-04-22 22:40:11 +0200132func Test_indent_fold_with_read()
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100133 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))
Bram Moolenaara4208962019-08-24 20:50:19 +0200149 call assert_equal(7, 5->foldclosedend())
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100150
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
Bram Moolenaar025a6b72017-03-12 20:37:21 +0100182func 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
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100198func 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))
Bram Moolenaara4208962019-08-24 20:50:19 +0200224 call assert_equal(0, 4->foldlevel())
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100225 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
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100233
Bram Moolenaar94be6192017-04-22 22:40:11 +0200234func Check_foldlevels(expected)
235 call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
236endfunc
237
238func Test_move_folds_around_manual()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100239 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)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100263 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100264 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)'))
Bram Moolenaar495b7dd2017-09-16 17:19:22 +0200298
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100299 %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.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200308 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
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100348 bw!
349endfunc
350
Bram Moolenaar94be6192017-04-22 22:40:11 +0200351func Test_move_folds_around_indent()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100352 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)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100371 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100372 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)'))
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100403 " 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.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200411 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100412 bw!
413endfunc
Bram Moolenaar518c9b12017-03-21 11:48:39 +0100414
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
Bram Moolenaar495b7dd2017-09-16 17:19:22 +0200467
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
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100480
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()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200485 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100486 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 set fdm&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200501 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100502endfunc
503
504" test folding with markers.
505func Test_fold_marker()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200506 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100507 set fdm=marker fdl=1 fdc=3
508
509 let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
510 call append(0, content)
511 call cursor(2, 1)
512 call assert_equal(2, foldlevel('.'))
513 normal [z
514 call assert_equal(1, foldlevel('.'))
515 exe "normal jo{{ \<Esc>r{jj"
516 call assert_equal(1, foldlevel('.'))
517 normal kYpj
518 call assert_equal(0, foldlevel('.'))
519
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200520 " Use only closing fold marker (without and with a count)
521 set fdl&
522 %d _
523 call setline(1, ['one }}}', 'two'])
524 call assert_equal([0, 0], [foldlevel(1), foldlevel(2)])
525 %d _
526 call setline(1, ['one }}}4', 'two'])
527 call assert_equal([4, 3], [foldlevel(1), foldlevel(2)])
528
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100529 set fdm& fdl& fdc&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200530 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100531endfunc
532
Bram Moolenaar4af72592018-12-09 15:00:52 +0100533" test create fold markers with C filetype
534func Test_fold_create_marker_in_C()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200535 bw!
Bram Moolenaar4af72592018-12-09 15:00:52 +0100536 set fdm=marker fdl=9
537 set filetype=c
538
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200539 let content =<< trim [CODE]
540 /*
541 * comment
542 *
543 *
544 */
545 int f(int* p) {
546 *p = 3;
547 return 0;
548 }
549 [CODE]
550
Bram Moolenaar4af72592018-12-09 15:00:52 +0100551 for c in range(len(content) - 1)
552 bw!
553 call append(0, content)
554 call cursor(c + 1, 1)
555 norm! zfG
556 call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1))
557 endfor
558
559 set fdm& fdl&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200560 bw!
Bram Moolenaar4af72592018-12-09 15:00:52 +0100561endfunc
562
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100563" test folding with indent
564func Test_fold_indent()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200565 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100566 set fdm=indent sw=2
567
568 let content = ['1 aa', '2 bb', '3 cc']
569 call append(0, content)
570 call cursor(2, 1)
571 exe "normal i \<Esc>jI "
572 call assert_equal(2, foldlevel('.'))
573 normal k
574 call assert_equal(1, foldlevel('.'))
575
576 set fdm& sw&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200577 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100578endfunc
579
580" test syntax folding
581func Test_fold_syntax()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200582 CheckFeature syntax
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100583
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200584 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100585 set fdm=syntax fdl=0
586
587 syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
588 syn region Fd1 start="ee" end="ff" fold contained
589 syn region Fd2 start="gg" end="hh" fold contained
590 syn region Fd3 start="commentstart" end="commentend" fold contained
591 let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
592 \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
593 call append(0, content)
594 normal Gzk
595 call assert_equal('9 ii', getline('.'))
596 normal k
597 call assert_equal('3 cc', getline('.'))
598 exe "normal jAcommentstart \<Esc>Acommentend"
599 set fdl=1
600 normal 3j
601 call assert_equal('7 gg', getline('.'))
602 set fdl=0
603 exe "normal zO\<C-L>j"
604 call assert_equal('8 hh', getline('.'))
605 syn clear Fd1 Fd2 Fd3 Hup
606
607 set fdm& fdl&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200608 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100609endfunc
610
611func Flvl()
612 let l = getline(v:lnum)
613 if l =~ "bb$"
614 return 2
615 elseif l =~ "gg$"
616 return "s1"
617 elseif l =~ "ii$"
618 return ">2"
619 elseif l =~ "kk$"
620 return "0"
621 endif
622 return "="
623endfun
624
625" test expression folding
626func Test_fold_expr()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200627 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100628 set fdm=expr fde=Flvl()
629
630 let content = ['1 aa',
631 \ '2 bb',
632 \ '3 cc',
633 \ '4 dd {{{commentstart commentend',
634 \ '5 ee {{{ }}}',
635 \ '{{{',
636 \ '6 ff }}}',
637 \ '6 ff }}}',
638 \ ' 7 gg',
639 \ ' 8 hh',
640 \ '9 ii',
641 \ 'a jj',
642 \ 'b kk']
643 call append(0, content)
644 call cursor(1, 1)
645 exe "normal /bb$\<CR>"
646 call assert_equal(2, foldlevel('.'))
647 exe "normal /hh$\<CR>"
648 call assert_equal(1, foldlevel('.'))
649 exe "normal /ii$\<CR>"
650 call assert_equal(2, foldlevel('.'))
651 exe "normal /kk$\<CR>"
652 call assert_equal(0, foldlevel('.'))
653
654 set fdm& fde&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200655 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100656endfunc
657
658" Bug with fdm=indent and moving folds
659" Moving a fold a few times, messes up the folds below the moved fold.
660" Fixed by 7.4.700
661func Test_fold_move()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200662 new
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100663 set fdm=indent sw=2 fdl=0
664
665 let content = ['', '', 'Line1', ' Line2', ' Line3',
666 \ 'Line4', ' Line5', ' Line6',
667 \ 'Line7', ' Line8', ' Line9']
668 call append(0, content)
669 normal zM
670 call cursor(4, 1)
671 move 2
672 move 1
673 call assert_equal(7, foldclosed(7))
674 call assert_equal(8, foldclosedend(7))
675 call assert_equal(0, foldlevel(9))
676 call assert_equal(10, foldclosed(10))
677 call assert_equal(11, foldclosedend(10))
678 call assert_equal('+-- 2 lines: Line2', foldtextresult(2))
Bram Moolenaara4208962019-08-24 20:50:19 +0200679 call assert_equal('+-- 2 lines: Line8', 10->foldtextresult())
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100680
681 set fdm& sw& fdl&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200682 bw!
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100683endfunc
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100684
685" test for patch 7.3.637
686" Cannot catch the error caused by a foldopen when there is no fold.
687func Test_foldopen_exception()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200688 new
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100689 let a = 'No error caught'
690 try
691 foldopen
692 catch
693 let a = matchstr(v:exception,'^[^ ]*')
694 endtry
695 call assert_equal('Vim(foldopen):E490:', a)
696
697 let a = 'No error caught'
698 try
699 foobar
700 catch
701 let a = matchstr(v:exception,'^[^ ]*')
702 endtry
703 call assert_match('E492:', a)
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200704 bw!
Bram Moolenaarfb094e12017-11-05 20:59:28 +0100705endfunc
Bram Moolenaar907dad72018-07-10 15:07:15 +0200706
707func Test_fold_last_line_with_pagedown()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200708 new
Bram Moolenaar907dad72018-07-10 15:07:15 +0200709 set fdm=manual
710
711 let expect = '+-- 11 lines: 9---'
712 let content = range(1,19)
713 call append(0, content)
714 normal dd9G
715 normal zfG
716 normal zt
717 call assert_equal('9', getline(foldclosed('.')))
718 call assert_equal('19', getline(foldclosedend('.')))
719 call assert_equal(expect, ScreenLines(1, len(expect))[0])
720 call feedkeys("\<C-F>", 'xt')
721 call assert_equal(expect, ScreenLines(1, len(expect))[0])
722 call feedkeys("\<C-F>", 'xt')
723 call assert_equal(expect, ScreenLines(1, len(expect))[0])
724 call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt')
725 call assert_equal(expect, ScreenLines(1, len(expect))[0])
726
727 set fdm&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200728 bw!
Bram Moolenaar907dad72018-07-10 15:07:15 +0200729endfunc
Bram Moolenaar7701f302018-10-02 21:20:32 +0200730
731func Test_folds_with_rnu()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200732 CheckScreendump
Bram Moolenaar7701f302018-10-02 21:20:32 +0200733
734 call writefile([
735 \ 'set fdm=marker rnu foldcolumn=2',
736 \ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])',
737 \ ], 'Xtest_folds_with_rnu')
738 let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {})
739
740 call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {})
741 call term_sendkeys(buf, "j")
742 call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {})
743
744 " clean up
745 call StopVimInTerminal(buf)
746 call delete('Xtest_folds_with_rnu')
747endfunc
Bram Moolenaar53932812018-12-07 21:08:49 +0100748
749func Test_folds_marker_in_comment2()
750 new
751 call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit'])
752 setl fen fdm=marker
753 setl commentstring=<!--%s-->
754 setl comments=s:<!--,m:\ \ \ \ ,e:-->
755 norm! zf2j
756 setl nofen
757 :1y
758 call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1))
759 :+2y
760 call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1))
761
762 set foldmethod&
763 bwipe!
764endfunc
Bram Moolenaar9a4a8c42019-08-19 22:48:30 +0200765
766func Test_fold_delete_with_marker()
767 new
768 call setline(1, ['func Func() {{{1', 'endfunc'])
769 1,2yank
770 new
771 set fdm=marker
772 call setline(1, 'x')
773 normal! Vp
774 normal! zd
775 call assert_equal(['func Func() ', 'endfunc'], getline(1, '$'))
776
777 set fdm&
778 bwipe!
779 bwipe!
780endfunc
Bram Moolenaar7a9bd7c2019-09-17 22:42:55 +0200781
782func Test_fold_delete_with_marker_and_whichwrap()
783 new
784 let content1 = ['']
785 let content2 = ['folded line 1 "{{{1', ' test', ' test2', ' test3', '', 'folded line 2 "{{{1', ' test', ' test2', ' test3']
786 call setline(1, content1 + content2)
787 set fdm=marker ww+=l
788 normal! x
789 call assert_equal(content2, getline(1, '$'))
790 set fdm& ww&
791 bwipe!
792endfunc
Bram Moolenaar3b681232019-12-13 19:35:55 +0100793
794func Test_fold_delete_first_line()
795 new
796 call setline(1, [
797 \ '" x {{{1',
798 \ '" a',
799 \ '" aa',
800 \ '" x {{{1',
801 \ '" b',
802 \ '" bb',
803 \ '" x {{{1',
804 \ '" c',
805 \ '" cc',
806 \ ])
807 set foldmethod=marker
808 1
809 normal dj
810 call assert_equal([
811 \ '" x {{{1',
812 \ '" c',
813 \ '" cc',
814 \ ], getline(1,'$'))
815 bwipe!
816 set foldmethod&
817endfunc
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +0200818
819" Test for errors in 'foldexpr'
820func Test_fold_expr_error()
821 new
822 call setline(1, ['one', 'two', 'three'])
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200823 " In a window with no folds, foldlevel() should return 0
824 call assert_equal(0, foldlevel(1))
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +0200825
826 " Return a list from the expression
827 set foldexpr=[]
828 set foldmethod=expr
829 for i in range(3)
830 call assert_equal(0, foldlevel(i))
831 endfor
832
833 " expression error
834 set foldexpr=[{]
835 set foldmethod=expr
836 for i in range(3)
837 call assert_equal(0, foldlevel(i))
838 endfor
839
840 set foldmethod& foldexpr&
841 close!
842endfunc
843
Bram Moolenaarda697642020-09-17 19:36:04 +0200844func Test_undo_fold_deletion()
845 new
846 set fdm=marker
847 let lines =<< trim END
848 " {{{
849 " }}}1
850 " {{{
851 END
852 call setline(1, lines)
853 3d
854 g/"/d
855 undo
856 redo
857 eval getline(1, '$')->assert_equal([''])
858
859 set fdm&vim
860 bwipe!
861endfunc
862
Bram Moolenaarc136a352020-11-03 20:05:40 +0100863" this was crashing
864func Test_move_no_folds()
865 new
866 fold
867 setlocal fdm=expr
868 normal zj
869 bwipe!
870endfunc
871
Bram Moolenaar5e1f22f2020-11-10 18:23:52 +0100872" this was crashing
873func Test_fold_create_delete_create()
874 new
875 fold
876 fold
877 normal zd
878 fold
879 bwipe!
880endfunc
881
Bram Moolenaar6a78f322020-12-21 14:01:41 +0100882" this was crashing
883func Test_fold_create_delete()
884 new
885 norm zFzFzdzj
886 bwipe!
887endfunc
888
Bram Moolenaare71996b2021-01-21 17:03:07 +0100889func Test_fold_relative_move()
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200890 new
Bram Moolenaare71996b2021-01-21 17:03:07 +0100891 set fdm=indent sw=2 wrap tw=80
892
Bram Moolenaar3c49e742021-04-04 21:26:04 +0200893 let longtext = repeat('x', &columns + 1)
894 let content = [ ' foo', ' ' .. longtext, ' baz',
895 \ longtext,
896 \ ' foo', ' ' .. longtext, ' baz'
Bram Moolenaare71996b2021-01-21 17:03:07 +0100897 \ ]
898 call append(0, content)
899
900 normal zM
901
Bram Moolenaar3c49e742021-04-04 21:26:04 +0200902 for lnum in range(1, 3)
903 call cursor(lnum, 1)
904 call assert_true(foldclosed(line('.')))
905 normal gj
906 call assert_equal(2, winline())
907 endfor
Bram Moolenaare71996b2021-01-21 17:03:07 +0100908
909 call cursor(2, 1)
910 call assert_true(foldclosed(line('.')))
911 normal 2gj
912 call assert_equal(3, winline())
913
Bram Moolenaar3c49e742021-04-04 21:26:04 +0200914 for lnum in range(5, 7)
915 call cursor(lnum, 1)
916 call assert_true(foldclosed(line('.')))
917 normal gk
918 call assert_equal(3, winline())
919 endfor
Bram Moolenaare71996b2021-01-21 17:03:07 +0100920
921 call cursor(6, 1)
922 call assert_true(foldclosed(line('.')))
923 normal 2gk
924 call assert_equal(2, winline())
925
926 set fdm& sw& wrap& tw&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200927 bw!
Bram Moolenaare71996b2021-01-21 17:03:07 +0100928endfunc
929
Bram Moolenaar4fa11752021-03-03 13:26:02 +0100930" Test for using multibyte characters as 'foldopen', 'foldclose' and
931" 'foldsetp' items in 'fillchars'
932func s:mbyte_fillchar_tests(fo, fc, fs)
933 setlocal foldcolumn=3
934
935 normal zE
936 1,2fold
937 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
938 \ ScreenLines([1, 2], 10))
939 1,2foldopen
940 call assert_equal([a:fo .. ' one ', a:fs .. ' two '],
941 \ ScreenLines([1, 2], 7))
942 1,2foldclose
943 redraw!
944 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
945 \ ScreenLines([1, 2], 10))
946
947 " Two level fold
948 normal zE
949 2,3fold
950 1,4fold
951 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
952 \ ScreenLines([1, 2], 10))
953 1,4foldopen
954 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
955 \ ScreenLines([1, 2], 10))
956 1,4foldopen
957 call assert_equal([a:fo .. ' one ', a:fs .. a:fo .. ' two ',
958 \ a:fs .. a:fs .. ' three '], ScreenLines([1, 3], 10))
959 2,3foldclose
960 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
961 \ ScreenLines([1, 2], 10))
962 1,4foldclose
963 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
964 \ ScreenLines([1, 2], 10))
965
966 " Three level fold
967 normal zE
968 3,4fold
969 2,5fold
970 1,6fold
971 call assert_equal([a:fc .. ' +-- 6 '], ScreenLines(1, 10))
972 " open all the folds
973 normal zR
974 call assert_equal([
975 \ a:fo .. ' one ',
976 \ a:fs .. a:fo .. ' two ',
977 \ '2' .. a:fo .. ' three ',
978 \ '23 four ',
979 \ a:fs .. a:fs .. ' five ',
980 \ a:fs .. ' six ',
981 \ ], ScreenLines([1, 6], 10))
982 " close the innermost fold
983 3,4foldclose
984 call assert_equal([
985 \ a:fo .. ' one ',
986 \ a:fs .. a:fo .. ' two ',
987 \ a:fs .. a:fs .. a:fc .. '+---- ',
988 \ a:fs .. a:fs .. ' five ',
989 \ a:fs .. ' six ',
990 \ ], ScreenLines([1, 5], 10))
991 " close the next fold
992 2,5foldclose
993 call assert_equal([
994 \ a:fo .. ' one ',
995 \ a:fs .. a:fc .. ' +--- 4',
996 \ a:fs .. ' six ',
997 \ ], ScreenLines([1, 3], 10))
998
999 " set the fold column size to 2
1000 setlocal fdc=2
1001 normal zR
1002 call assert_equal([
1003 \ a:fo .. ' one ',
1004 \ a:fo .. ' two ',
1005 \ a:fo .. ' three',
1006 \ '3 four ',
1007 \ '2 five ',
1008 \ a:fs .. ' six ',
1009 \ ], ScreenLines([1, 6], 7))
1010
1011 " set the fold column size to 1
1012 setlocal fdc=1
1013 normal zR
1014 call assert_equal([
1015 \ a:fo .. 'one ',
1016 \ a:fo .. 'two ',
1017 \ a:fo .. 'three ',
1018 \ '3four ',
1019 \ '2five ',
1020 \ a:fs .. 'six ',
1021 \ ], ScreenLines([1, 6], 7))
1022
Bram Moolenaar008bff92021-03-04 21:55:58 +01001023 " Enable number and sign columns and place some signs
1024 setlocal fdc=3
1025 setlocal number
1026 setlocal signcolumn=auto
1027 sign define S1 text=->
1028 sign place 10 line=3 name=S1
1029 call assert_equal([
1030 \ a:fo .. ' 1 one ',
1031 \ a:fs .. a:fo .. ' 2 two ',
1032 \ '2' .. a:fo .. ' -> 3 three',
1033 \ '23 4 four ',
1034 \ a:fs .. a:fs .. ' 5 five ',
1035 \ a:fs .. ' 6 six '
1036 \ ], ScreenLines([1, 6], 14))
1037
1038 " Test with 'rightleft'
1039 if has('rightleft')
1040 setlocal rightleft
1041 let lines = ScreenLines([1, 6], winwidth(0))
1042 call assert_equal('o 1 ' .. a:fo,
1043 \ strcharpart(lines[0], strchars(lines[0]) - 10, 10))
1044 call assert_equal('t 2 ' .. a:fo .. a:fs,
1045 \ strcharpart(lines[1], strchars(lines[1]) - 10, 10))
1046 call assert_equal('t 3 >- ' .. a:fo .. '2',
1047 \ strcharpart(lines[2], strchars(lines[2]) - 10, 10))
1048 call assert_equal('f 4 32',
1049 \ strcharpart(lines[3], strchars(lines[3]) - 10, 10))
1050 call assert_equal('f 5 ' .. a:fs .. a:fs,
1051 \ strcharpart(lines[4], strchars(lines[4]) - 10, 10))
1052 call assert_equal('s 6 ' .. a:fs,
1053 \ strcharpart(lines[5], strchars(lines[5]) - 10, 10))
1054 setlocal norightleft
1055 endif
1056
1057 sign unplace *
1058 sign undefine S1
1059 setlocal number& signcolumn&
1060
1061 " Add a test with more than 9 folds (and then delete some folds)
1062 normal zE
1063 for i in range(1, 10)
1064 normal zfGzo
1065 endfor
1066 normal zR
1067 call assert_equal([
1068 \ a:fo .. a:fo .. ' one ',
1069 \ '9> two '
1070 \ ], ScreenLines([1, 2], 7))
1071 normal 1Gzd
1072 call assert_equal([
1073 \ a:fo .. a:fo .. ' one ',
1074 \ '89 two '
1075 \ ], ScreenLines([1, 2], 7))
1076 normal 1Gzdzdzdzdzdzdzd
1077 call assert_equal([
1078 \ a:fo .. a:fo .. ' one ',
1079 \ a:fs .. a:fs .. ' two '
1080 \ ], ScreenLines([1, 2], 7))
1081
1082 setlocal foldcolumn& number& signcolumn&
Bram Moolenaar4fa11752021-03-03 13:26:02 +01001083endfunc
1084
1085func Test_foldcolumn_multibyte_char()
1086 new
1087 call setline(1, ['one', 'two', 'three', 'four', 'five', 'six'])
1088 setlocal foldenable foldmethod=manual
1089
1090 " First test with the default setting
1091 call s:mbyte_fillchar_tests('-', '+', '|')
1092
1093 " Use multi-byte characters
1094 set fillchars+=foldopen:▾,foldsep:│,foldclose:▸
1095 call s:mbyte_fillchar_tests('', '', '')
1096
Bram Moolenaar196a1f72021-03-21 14:39:19 +01001097 " Use a mix of multi-byte and single-byte characters
1098 set fillchars+=foldopen:¬,foldsep:\|,foldclose:+
1099 call s:mbyte_fillchar_tests('¬', '+', '|')
1100 set fillchars+=foldopen:+,foldsep:\|,foldclose:¬
1101 call s:mbyte_fillchar_tests('+', '¬', '|')
1102
Bram Moolenaar4fa11752021-03-03 13:26:02 +01001103 bw!
1104 set foldenable& fdc& fdm& fillchars&
1105endfunc
1106
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001107" Test for calling foldlevel() from a fold expression
1108let g:FoldLevels = []
1109func FoldExpr1(lnum)
1110 let f = [a:lnum]
1111 for i in range(1, line('$'))
1112 call add(f, foldlevel(i))
1113 endfor
1114 call add(g:FoldLevels, f)
1115 return getline(a:lnum)[0] == "\t"
1116endfunc
1117
1118func Test_foldexpr_foldlevel()
1119 new
1120 call setline(1, ['one', "\ttwo", "\tthree"])
1121 setlocal foldmethod=expr
1122 setlocal foldexpr=FoldExpr1(v:lnum)
1123 setlocal foldenable
1124 setlocal foldcolumn=3
1125 redraw!
1126 call assert_equal([[1, -1, -1, -1], [2, -1, -1, -1], [3, 0, 1, -1]],
1127 \ g:FoldLevels)
1128 set foldmethod& foldexpr& foldenable& foldcolumn&
1129 bw!
1130endfunc
1131
1132" Test for returning different values from a fold expression
1133func FoldExpr2(lnum)
1134 if a:lnum == 1 || a:lnum == 4
1135 return -2
1136 elseif a:lnum == 2
1137 return 'a1'
1138 elseif a:lnum == 3
1139 return 's4'
1140 endif
1141 return '='
1142endfunc
1143
1144func Test_foldexpr_2()
1145 new
1146 call setline(1, ['one', 'two', 'three', 'four'])
1147 setlocal foldexpr=FoldExpr2(v:lnum)
1148 setlocal foldmethod=expr
1149 call assert_equal([0, 1, 1, 0], [foldlevel(1), foldlevel(2), foldlevel(3),
1150 \ foldlevel(4)])
1151 bw!
1152endfunc
1153
1154" Test for the 'foldclose' option
1155func Test_foldclose_opt()
1156 CheckScreendump
1157
1158 let lines =<< trim END
1159 set foldmethod=manual foldclose=all foldopen=all
1160 call setline(1, ['one', 'two', 'three', 'four'])
1161 2,3fold
1162 func XsaveFoldLevels()
1163 redraw!
1164 call writefile([json_encode([foldclosed(1), foldclosed(2), foldclosed(3),
1165 \ foldclosed(4)])], 'Xoutput', 'a')
1166 endfunc
1167 END
1168 call writefile(lines, 'Xscript')
1169 let rows = 10
1170 let buf = RunVimInTerminal('-S Xscript', {'rows': rows})
1171 call term_wait(buf)
1172 call term_sendkeys(buf, ":set noruler\n")
1173 call term_wait(buf)
1174 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1175 call term_sendkeys(buf, "2G")
1176 call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
1177 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1178 call term_sendkeys(buf, "4G")
1179 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1180 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1181 call term_sendkeys(buf, "3G")
1182 call WaitForAssert({-> assert_equal('three', term_getline(buf, 3))})
1183 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1184 call term_sendkeys(buf, "1G")
1185 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1186 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1187
1188 " clean up
1189 call StopVimInTerminal(buf)
1190
1191 call assert_equal(['[-1,2,2,-1]', '[-1,-1,-1,-1]', '[-1,2,2,-1]',
1192 \ '[-1,-1,-1,-1]', '[-1,2,2,-1]'], readfile('Xoutput'))
1193 call delete('Xscript')
1194 call delete('Xoutput')
1195endfunc
1196
1197" Test for foldtextresult()
1198func Test_foldtextresult()
1199 new
1200 call assert_equal('', foldtextresult(-1))
1201 call assert_equal('', foldtextresult(0))
1202 call assert_equal('', foldtextresult(1))
1203 call setline(1, ['one', 'two', 'three', 'four'])
1204 2,3fold
1205 call assert_equal('', foldtextresult(1))
1206 call assert_equal('+-- 2 lines: two', foldtextresult(2))
1207 setlocal foldtext=
1208 call assert_equal('+-- 2 lines folded ', foldtextresult(2))
1209
1210 " Fold text for a C comment fold
1211 %d _
1212 setlocal foldtext&
1213 call setline(1, ['', '/*', ' * Comment', ' */', ''])
1214 2,4fold
1215 call assert_equal('+-- 3 lines: Comment', foldtextresult(2))
1216
1217 bw!
1218endfunc
1219
1220" Test for merging two recursive folds when an intermediate line with no fold
1221" is removed
1222func Test_fold_merge_recrusive()
1223 new
1224 call setline(1, [' one', ' two', 'xxxx', ' three',
1225 \ ' four', "\tfive"])
1226 setlocal foldmethod=indent shiftwidth=2
1227 3d_
1228 %foldclose
1229 call assert_equal([1, 5], [foldclosed(5), foldclosedend(1)])
1230 bw!
1231endfunc
1232
1233" Test for moving a line which is the start of a fold from a recursive fold to
1234" outside. The fold length should reduce.
1235func Test_fold_move_foldlevel()
1236 new
1237 call setline(1, ['a{{{', 'b{{{', 'c{{{', 'd}}}', 'e}}}', 'f}}}', 'g'])
1238 setlocal foldmethod=marker
1239 normal zR
1240 call assert_equal([3, 2, 1], [foldlevel(4), foldlevel(5), foldlevel(6)])
1241 3move 7
1242 call assert_equal([2, 1, 0], [foldlevel(3), foldlevel(4), foldlevel(5)])
1243 call assert_equal(1, foldlevel(7))
1244
1245 " Move a line from outside a fold to inside the fold.
1246 %d _
1247 call setline(1, ['a', 'b{{{', 'c}}}'])
1248 normal zR
1249 1move 2
1250 call assert_equal([1, 1, 1], [foldlevel(1), foldlevel(2), foldlevel(3)])
1251
1252 " Move the start of one fold to inside another fold
1253 %d _
1254 call setline(1, ['a', 'b{{{', 'c}}}', 'd{{{', 'e}}}'])
1255 normal zR
1256 call assert_equal([0, 1, 1, 1, 1], [foldlevel(1), foldlevel(2),
1257 \ foldlevel(3), foldlevel(4), foldlevel(5)])
1258 1,2move 4
1259 call assert_equal([0, 1, 1, 2, 2], [foldlevel(1), foldlevel(2),
1260 \ foldlevel(3), foldlevel(4), foldlevel(5)])
1261
1262 bw!
1263endfunc
1264
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +02001265" vim: shiftwidth=2 sts=2 expandtab