blob: 20171f03407a59ddb0bb95b88842e7a3881de37b [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
893 let content = [ ' foo', ' bar', ' baz',
Bram Moolenaar7cf0c112021-01-24 12:00:01 +0100894 \ repeat('x', &columns + 1),
Bram Moolenaare71996b2021-01-21 17:03:07 +0100895 \ ' foo', ' bar', ' baz'
896 \ ]
897 call append(0, content)
898
899 normal zM
900
901 call cursor(3, 1)
902 call assert_true(foldclosed(line('.')))
903 normal gj
904 call assert_equal(2, winline())
905
906 call cursor(2, 1)
907 call assert_true(foldclosed(line('.')))
908 normal 2gj
909 call assert_equal(3, winline())
910
911 call cursor(5, 1)
912 call assert_true(foldclosed(line('.')))
913 normal gk
914 call assert_equal(3, winline())
915
916 call cursor(6, 1)
917 call assert_true(foldclosed(line('.')))
918 normal 2gk
919 call assert_equal(2, winline())
920
921 set fdm& sw& wrap& tw&
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200922 bw!
Bram Moolenaare71996b2021-01-21 17:03:07 +0100923endfunc
924
Bram Moolenaar4fa11752021-03-03 13:26:02 +0100925" Test for using multibyte characters as 'foldopen', 'foldclose' and
926" 'foldsetp' items in 'fillchars'
927func s:mbyte_fillchar_tests(fo, fc, fs)
928 setlocal foldcolumn=3
929
930 normal zE
931 1,2fold
932 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
933 \ ScreenLines([1, 2], 10))
934 1,2foldopen
935 call assert_equal([a:fo .. ' one ', a:fs .. ' two '],
936 \ ScreenLines([1, 2], 7))
937 1,2foldclose
938 redraw!
939 call assert_equal([a:fc .. ' +-- 2 ', ' three '],
940 \ ScreenLines([1, 2], 10))
941
942 " Two level fold
943 normal zE
944 2,3fold
945 1,4fold
946 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
947 \ ScreenLines([1, 2], 10))
948 1,4foldopen
949 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
950 \ ScreenLines([1, 2], 10))
951 1,4foldopen
952 call assert_equal([a:fo .. ' one ', a:fs .. a:fo .. ' two ',
953 \ a:fs .. a:fs .. ' three '], ScreenLines([1, 3], 10))
954 2,3foldclose
955 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'],
956 \ ScreenLines([1, 2], 10))
957 1,4foldclose
958 call assert_equal([a:fc .. ' +-- 4 ', ' five '],
959 \ ScreenLines([1, 2], 10))
960
961 " Three level fold
962 normal zE
963 3,4fold
964 2,5fold
965 1,6fold
966 call assert_equal([a:fc .. ' +-- 6 '], ScreenLines(1, 10))
967 " open all the folds
968 normal zR
969 call assert_equal([
970 \ a:fo .. ' one ',
971 \ a:fs .. a:fo .. ' two ',
972 \ '2' .. a:fo .. ' three ',
973 \ '23 four ',
974 \ a:fs .. a:fs .. ' five ',
975 \ a:fs .. ' six ',
976 \ ], ScreenLines([1, 6], 10))
977 " close the innermost fold
978 3,4foldclose
979 call assert_equal([
980 \ a:fo .. ' one ',
981 \ a:fs .. a:fo .. ' two ',
982 \ a:fs .. a:fs .. a:fc .. '+---- ',
983 \ a:fs .. a:fs .. ' five ',
984 \ a:fs .. ' six ',
985 \ ], ScreenLines([1, 5], 10))
986 " close the next fold
987 2,5foldclose
988 call assert_equal([
989 \ a:fo .. ' one ',
990 \ a:fs .. a:fc .. ' +--- 4',
991 \ a:fs .. ' six ',
992 \ ], ScreenLines([1, 3], 10))
993
994 " set the fold column size to 2
995 setlocal fdc=2
996 normal zR
997 call assert_equal([
998 \ a:fo .. ' one ',
999 \ a:fo .. ' two ',
1000 \ a:fo .. ' three',
1001 \ '3 four ',
1002 \ '2 five ',
1003 \ a:fs .. ' six ',
1004 \ ], ScreenLines([1, 6], 7))
1005
1006 " set the fold column size to 1
1007 setlocal fdc=1
1008 normal zR
1009 call assert_equal([
1010 \ a:fo .. 'one ',
1011 \ a:fo .. 'two ',
1012 \ a:fo .. 'three ',
1013 \ '3four ',
1014 \ '2five ',
1015 \ a:fs .. 'six ',
1016 \ ], ScreenLines([1, 6], 7))
1017
Bram Moolenaar008bff92021-03-04 21:55:58 +01001018 " Enable number and sign columns and place some signs
1019 setlocal fdc=3
1020 setlocal number
1021 setlocal signcolumn=auto
1022 sign define S1 text=->
1023 sign place 10 line=3 name=S1
1024 call assert_equal([
1025 \ a:fo .. ' 1 one ',
1026 \ a:fs .. a:fo .. ' 2 two ',
1027 \ '2' .. a:fo .. ' -> 3 three',
1028 \ '23 4 four ',
1029 \ a:fs .. a:fs .. ' 5 five ',
1030 \ a:fs .. ' 6 six '
1031 \ ], ScreenLines([1, 6], 14))
1032
1033 " Test with 'rightleft'
1034 if has('rightleft')
1035 setlocal rightleft
1036 let lines = ScreenLines([1, 6], winwidth(0))
1037 call assert_equal('o 1 ' .. a:fo,
1038 \ strcharpart(lines[0], strchars(lines[0]) - 10, 10))
1039 call assert_equal('t 2 ' .. a:fo .. a:fs,
1040 \ strcharpart(lines[1], strchars(lines[1]) - 10, 10))
1041 call assert_equal('t 3 >- ' .. a:fo .. '2',
1042 \ strcharpart(lines[2], strchars(lines[2]) - 10, 10))
1043 call assert_equal('f 4 32',
1044 \ strcharpart(lines[3], strchars(lines[3]) - 10, 10))
1045 call assert_equal('f 5 ' .. a:fs .. a:fs,
1046 \ strcharpart(lines[4], strchars(lines[4]) - 10, 10))
1047 call assert_equal('s 6 ' .. a:fs,
1048 \ strcharpart(lines[5], strchars(lines[5]) - 10, 10))
1049 setlocal norightleft
1050 endif
1051
1052 sign unplace *
1053 sign undefine S1
1054 setlocal number& signcolumn&
1055
1056 " Add a test with more than 9 folds (and then delete some folds)
1057 normal zE
1058 for i in range(1, 10)
1059 normal zfGzo
1060 endfor
1061 normal zR
1062 call assert_equal([
1063 \ a:fo .. a:fo .. ' one ',
1064 \ '9> two '
1065 \ ], ScreenLines([1, 2], 7))
1066 normal 1Gzd
1067 call assert_equal([
1068 \ a:fo .. a:fo .. ' one ',
1069 \ '89 two '
1070 \ ], ScreenLines([1, 2], 7))
1071 normal 1Gzdzdzdzdzdzdzd
1072 call assert_equal([
1073 \ a:fo .. a:fo .. ' one ',
1074 \ a:fs .. a:fs .. ' two '
1075 \ ], ScreenLines([1, 2], 7))
1076
1077 setlocal foldcolumn& number& signcolumn&
Bram Moolenaar4fa11752021-03-03 13:26:02 +01001078endfunc
1079
1080func Test_foldcolumn_multibyte_char()
1081 new
1082 call setline(1, ['one', 'two', 'three', 'four', 'five', 'six'])
1083 setlocal foldenable foldmethod=manual
1084
1085 " First test with the default setting
1086 call s:mbyte_fillchar_tests('-', '+', '|')
1087
1088 " Use multi-byte characters
1089 set fillchars+=foldopen:▾,foldsep:│,foldclose:▸
1090 call s:mbyte_fillchar_tests('', '', '')
1091
Bram Moolenaar196a1f72021-03-21 14:39:19 +01001092 " Use a mix of multi-byte and single-byte characters
1093 set fillchars+=foldopen:¬,foldsep:\|,foldclose:+
1094 call s:mbyte_fillchar_tests('¬', '+', '|')
1095 set fillchars+=foldopen:+,foldsep:\|,foldclose:¬
1096 call s:mbyte_fillchar_tests('+', '¬', '|')
1097
Bram Moolenaar4fa11752021-03-03 13:26:02 +01001098 bw!
1099 set foldenable& fdc& fdm& fillchars&
1100endfunc
1101
Bram Moolenaar5c504f62021-04-01 13:39:51 +02001102" Test for calling foldlevel() from a fold expression
1103let g:FoldLevels = []
1104func FoldExpr1(lnum)
1105 let f = [a:lnum]
1106 for i in range(1, line('$'))
1107 call add(f, foldlevel(i))
1108 endfor
1109 call add(g:FoldLevels, f)
1110 return getline(a:lnum)[0] == "\t"
1111endfunc
1112
1113func Test_foldexpr_foldlevel()
1114 new
1115 call setline(1, ['one', "\ttwo", "\tthree"])
1116 setlocal foldmethod=expr
1117 setlocal foldexpr=FoldExpr1(v:lnum)
1118 setlocal foldenable
1119 setlocal foldcolumn=3
1120 redraw!
1121 call assert_equal([[1, -1, -1, -1], [2, -1, -1, -1], [3, 0, 1, -1]],
1122 \ g:FoldLevels)
1123 set foldmethod& foldexpr& foldenable& foldcolumn&
1124 bw!
1125endfunc
1126
1127" Test for returning different values from a fold expression
1128func FoldExpr2(lnum)
1129 if a:lnum == 1 || a:lnum == 4
1130 return -2
1131 elseif a:lnum == 2
1132 return 'a1'
1133 elseif a:lnum == 3
1134 return 's4'
1135 endif
1136 return '='
1137endfunc
1138
1139func Test_foldexpr_2()
1140 new
1141 call setline(1, ['one', 'two', 'three', 'four'])
1142 setlocal foldexpr=FoldExpr2(v:lnum)
1143 setlocal foldmethod=expr
1144 call assert_equal([0, 1, 1, 0], [foldlevel(1), foldlevel(2), foldlevel(3),
1145 \ foldlevel(4)])
1146 bw!
1147endfunc
1148
1149" Test for the 'foldclose' option
1150func Test_foldclose_opt()
1151 CheckScreendump
1152
1153 let lines =<< trim END
1154 set foldmethod=manual foldclose=all foldopen=all
1155 call setline(1, ['one', 'two', 'three', 'four'])
1156 2,3fold
1157 func XsaveFoldLevels()
1158 redraw!
1159 call writefile([json_encode([foldclosed(1), foldclosed(2), foldclosed(3),
1160 \ foldclosed(4)])], 'Xoutput', 'a')
1161 endfunc
1162 END
1163 call writefile(lines, 'Xscript')
1164 let rows = 10
1165 let buf = RunVimInTerminal('-S Xscript', {'rows': rows})
1166 call term_wait(buf)
1167 call term_sendkeys(buf, ":set noruler\n")
1168 call term_wait(buf)
1169 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1170 call term_sendkeys(buf, "2G")
1171 call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))})
1172 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1173 call term_sendkeys(buf, "4G")
1174 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1175 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1176 call term_sendkeys(buf, "3G")
1177 call WaitForAssert({-> assert_equal('three', term_getline(buf, 3))})
1178 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1179 call term_sendkeys(buf, "1G")
1180 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))})
1181 call term_sendkeys(buf, ":call XsaveFoldLevels()\n")
1182
1183 " clean up
1184 call StopVimInTerminal(buf)
1185
1186 call assert_equal(['[-1,2,2,-1]', '[-1,-1,-1,-1]', '[-1,2,2,-1]',
1187 \ '[-1,-1,-1,-1]', '[-1,2,2,-1]'], readfile('Xoutput'))
1188 call delete('Xscript')
1189 call delete('Xoutput')
1190endfunc
1191
1192" Test for foldtextresult()
1193func Test_foldtextresult()
1194 new
1195 call assert_equal('', foldtextresult(-1))
1196 call assert_equal('', foldtextresult(0))
1197 call assert_equal('', foldtextresult(1))
1198 call setline(1, ['one', 'two', 'three', 'four'])
1199 2,3fold
1200 call assert_equal('', foldtextresult(1))
1201 call assert_equal('+-- 2 lines: two', foldtextresult(2))
1202 setlocal foldtext=
1203 call assert_equal('+-- 2 lines folded ', foldtextresult(2))
1204
1205 " Fold text for a C comment fold
1206 %d _
1207 setlocal foldtext&
1208 call setline(1, ['', '/*', ' * Comment', ' */', ''])
1209 2,4fold
1210 call assert_equal('+-- 3 lines: Comment', foldtextresult(2))
1211
1212 bw!
1213endfunc
1214
1215" Test for merging two recursive folds when an intermediate line with no fold
1216" is removed
1217func Test_fold_merge_recrusive()
1218 new
1219 call setline(1, [' one', ' two', 'xxxx', ' three',
1220 \ ' four', "\tfive"])
1221 setlocal foldmethod=indent shiftwidth=2
1222 3d_
1223 %foldclose
1224 call assert_equal([1, 5], [foldclosed(5), foldclosedend(1)])
1225 bw!
1226endfunc
1227
1228" Test for moving a line which is the start of a fold from a recursive fold to
1229" outside. The fold length should reduce.
1230func Test_fold_move_foldlevel()
1231 new
1232 call setline(1, ['a{{{', 'b{{{', 'c{{{', 'd}}}', 'e}}}', 'f}}}', 'g'])
1233 setlocal foldmethod=marker
1234 normal zR
1235 call assert_equal([3, 2, 1], [foldlevel(4), foldlevel(5), foldlevel(6)])
1236 3move 7
1237 call assert_equal([2, 1, 0], [foldlevel(3), foldlevel(4), foldlevel(5)])
1238 call assert_equal(1, foldlevel(7))
1239
1240 " Move a line from outside a fold to inside the fold.
1241 %d _
1242 call setline(1, ['a', 'b{{{', 'c}}}'])
1243 normal zR
1244 1move 2
1245 call assert_equal([1, 1, 1], [foldlevel(1), foldlevel(2), foldlevel(3)])
1246
1247 " Move the start of one fold to inside another fold
1248 %d _
1249 call setline(1, ['a', 'b{{{', 'c}}}', 'd{{{', 'e}}}'])
1250 normal zR
1251 call assert_equal([0, 1, 1, 1, 1], [foldlevel(1), foldlevel(2),
1252 \ foldlevel(3), foldlevel(4), foldlevel(5)])
1253 1,2move 4
1254 call assert_equal([0, 1, 1, 2, 2], [foldlevel(1), foldlevel(2),
1255 \ foldlevel(3), foldlevel(4), foldlevel(5)])
1256
1257 bw!
1258endfunc
1259
Bram Moolenaar9d8d0b52020-04-24 22:47:31 +02001260" vim: shiftwidth=2 sts=2 expandtab