blob: 213c0fa4583c97de5dcf613a1f5caed80f570533 [file] [log] [blame]
Bram Moolenaarded27822017-01-02 14:27:34 +01001" Test for folding
2
Bram Moolenaar94be6192017-04-22 22:40:11 +02003func PrepIndent(arg)
Bram Moolenaar88d298a2017-03-14 21:53:58 +01004 return [a:arg] + repeat(["\t".a:arg], 5)
5endfu
6
Bram Moolenaar94be6192017-04-22 22:40:11 +02007func Test_address_fold()
Bram Moolenaarded27822017-01-02 14:27:34 +01008 new
9 call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
10 \ 'after fold 1', 'after fold 2', 'after fold 3'])
11 setl fen fdm=marker
Bram Moolenaar518c9b12017-03-21 11:48:39 +010012 " The next commands should all copy the same part of the buffer,
13 " regardless of the addressing type, since the part to be copied
Bram Moolenaarded27822017-01-02 14:27:34 +010014 " is folded away
15 :1y
16 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
17 :.y
18 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
19 :.+y
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 :sil .1,.y
24 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
25 " use silent to make E493 go away
26 :sil .+,.y
27 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
28 :,y
29 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
30 :,+y
31 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/','after fold 1'], getreg(0,1,1))
32 " using .+3 as second address should copy the whole folded line + the next 3
33 " lines
34 :.,+3y
35 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/',
36 \ 'after fold 1', 'after fold 2', 'after fold 3'], getreg(0,1,1))
37 :sil .,-2y
38 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
39
40 " now test again with folding disabled
41 set nofoldenable
42 :1y
43 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
44 :.y
45 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
46 :.+y
47 call assert_equal(['1'], getreg(0,1,1))
48 :.,.y
49 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
50 " use silent to make E493 go away
51 :sil .1,.y
52 call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
53 " use silent to make E493 go away
54 :sil .+,.y
55 call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
56 :,y
57 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
58 :,+y
59 call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
60 " using .+3 as second address should copy the whole folded line + the next 3
61 " lines
62 :.,+3y
63 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3'], getreg(0,1,1))
64 :7
65 :sil .,-2y
66 call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1))
67
68 quit!
Bram Moolenaar1159b162017-02-28 21:53:56 +010069endfunc
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010070
Bram Moolenaar94be6192017-04-22 22:40:11 +020071func Test_indent_fold()
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010072 new
73 call setline(1, ['', 'a', ' b', ' c'])
74 setl fen fdm=indent
75 2
76 norm! >>
77 let a=map(range(1,4), 'foldclosed(v:val)')
78 call assert_equal([-1,-1,-1,-1], a)
79 bw!
Bram Moolenaar1159b162017-02-28 21:53:56 +010080endfunc
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010081
Bram Moolenaar94be6192017-04-22 22:40:11 +020082func Test_indent_fold2()
Bram Moolenaar54b2bfa2017-01-02 14:57:08 +010083 new
84 call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
85 setl fen fdm=marker
86 2
87 norm! >>
88 let a=map(range(1,5), 'foldclosed(v:val)')
89 call assert_equal([-1,-1,-1,4,4], a)
90 bw!
Bram Moolenaar1159b162017-02-28 21:53:56 +010091endfunc
92
93func Test_manual_fold_with_filter()
94 if !executable('cat')
95 return
96 endif
Bram Moolenaar3f3897e2017-03-04 15:28:53 +010097 for type in ['manual', 'marker']
98 exe 'set foldmethod=' . type
99 new
100 call setline(1, range(1, 20))
101 4,$fold
102 %foldopen
103 10,$fold
104 %foldopen
105 " This filter command should not have an effect
106 1,8! cat
107 call feedkeys('5ggzdzMGdd', 'xt')
108 call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
109
110 bwipe!
111 set foldmethod&
112 endfor
Bram Moolenaar1159b162017-02-28 21:53:56 +0100113endfunc
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100114
Bram Moolenaar94be6192017-04-22 22:40:11 +0200115func Test_indent_fold_with_read()
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100116 new
117 set foldmethod=indent
118 call setline(1, repeat(["\<Tab>a"], 4))
119 for n in range(1, 4)
120 call assert_equal(1, foldlevel(n))
121 endfor
122
123 call writefile(["a", "", "\<Tab>a"], 'Xfile')
124 foldopen
125 2read Xfile
126 %foldclose
127 call assert_equal(1, foldlevel(1))
128 call assert_equal(2, foldclosedend(1))
129 call assert_equal(0, foldlevel(3))
130 call assert_equal(0, foldlevel(4))
131 call assert_equal(1, foldlevel(5))
132 call assert_equal(7, foldclosedend(5))
133
134 bwipe!
135 set foldmethod&
136 call delete('Xfile')
137endfunc
138
139func Test_combining_folds_indent()
140 new
141 let one = "\<Tab>a"
142 let zero = 'a'
143 call setline(1, [one, one, zero, zero, zero, one, one, one])
144 set foldmethod=indent
145 3,5d
146 %foldclose
147 call assert_equal(5, foldclosedend(1))
148
149 set foldmethod&
150 bwipe!
151endfunc
152
153func Test_combining_folds_marker()
154 new
155 call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
156 set foldmethod=marker
157 3,5d
158 %foldclose
159 call assert_equal(2, foldclosedend(1))
160
161 set foldmethod&
162 bwipe!
163endfunc
164
Bram Moolenaar025a6b72017-03-12 20:37:21 +0100165func Test_folds_marker_in_comment()
166 new
167 call setline(1, ['" foo', 'bar', 'baz'])
168 setl fen fdm=marker
169 setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
170 norm! zf2j
171 setl nofen
172 :1y
173 call assert_equal(['" foo{{{'], getreg(0,1,1))
174 :+2y
175 call assert_equal(['baz"}}}'], getreg(0,1,1))
176
177 set foldmethod&
178 bwipe!
179endfunc
180
Bram Moolenaareadbc2b2017-03-04 18:42:39 +0100181func s:TestFoldExpr(lnum)
182 let thisline = getline(a:lnum)
183 if thisline == 'a'
184 return 1
185 elseif thisline == 'b'
186 return 0
187 elseif thisline == 'c'
188 return '<1'
189 elseif thisline == 'd'
190 return '>1'
191 endif
192 return 0
193endfunction
194
195func Test_update_folds_expr_read()
196 new
197 call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
198 set foldmethod=expr
199 set foldexpr=s:TestFoldExpr(v:lnum)
200 2
201 foldopen
202 call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
203 read Xfile
204 %foldclose
205 call assert_equal(2, foldclosedend(1))
206 call assert_equal(0, foldlevel(3))
207 call assert_equal(0, foldlevel(4))
208 call assert_equal(6, foldclosedend(5))
209 call assert_equal(10, foldclosedend(7))
210 call assert_equal(14, foldclosedend(11))
211
212 call delete('Xfile')
213 bwipe!
214 set foldmethod& foldexpr&
215endfunc
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100216
Bram Moolenaar94be6192017-04-22 22:40:11 +0200217func Check_foldlevels(expected)
218 call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
219endfunc
220
221func Test_move_folds_around_manual()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100222 new
223 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
224 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
225 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
226 " all folds closed
227 set foldenable foldlevel=0 fdm=indent
228 " needs a forced redraw
229 redraw!
230 set fdm=manual
231 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
232 call assert_equal(input, getline(1, '$'))
233 7,12m0
234 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
235 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
236 10,12m0
237 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
238 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)'))
239 " moving should not close the folds
240 %d
241 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
242 set fdm=indent
243 redraw!
244 set fdm=manual
245 call cursor(2, 1)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100246 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100247 7,12m0
248 let folds=repeat([-1], 18)
249 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
250 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
251 norm! zM
252 " folds are not corrupted and all have been closed
253 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)'))
254 %d
255 call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
256 set fdm=indent
257 redraw!
258 set fdm=manual
259 %foldopen
260 3m4
261 %foldclose
262 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
263 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
264 %d
265 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
266 set fdm=indent foldlevel=0
267 set fdm=manual
268 %foldopen
269 3m1
270 %foldclose
271 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
272 call assert_equal(0, foldlevel(2))
273 call assert_equal(5, foldclosedend(3))
274 call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
275 2,6m$
276 %foldclose
277 call assert_equal(5, foldclosedend(2))
278 call assert_equal(0, foldlevel(6))
279 call assert_equal(9, foldclosedend(7))
280 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100281 %d
282 " Ensure moving around the edges still works.
283 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
284 set fdm=indent foldlevel=0
285 set fdm=manual
286 %foldopen
287 6m$
288 " The first fold has been truncated to the 5'th line.
289 " Second fold has been moved up because the moved line is now below it.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200290 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
291
292 %delete
293 set fdm=indent foldlevel=0
294 call setline(1, [
295 \ "a",
296 \ "\ta",
297 \ "\t\ta",
298 \ "\t\ta",
299 \ "\t\ta",
300 \ "a",
301 \ "a"])
302 set fdm=manual
303 %foldopen!
304 4,5m6
305 call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
306
307 %delete
308 set fdm=indent
309 call setline(1, [
310 \ "\ta",
311 \ "\t\ta",
312 \ "\t\ta",
313 \ "\t\ta",
314 \ "\ta",
315 \ "\t\ta",
316 \ "\t\ta",
317 \ "\t\ta",
318 \ "\ta",
319 \ "\t\ta",
320 \ "\t\ta",
321 \ "\t\ta",
322 \ "\t\ta",
323 \ "\ta",
324 \ "a"])
325 set fdm=manual
326 %foldopen!
327 13m7
328 call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
329
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100330 bw!
331endfunc
332
Bram Moolenaar94be6192017-04-22 22:40:11 +0200333func Test_move_folds_around_indent()
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100334 new
335 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
336 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
337 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
338 " all folds closed
339 set fdm=indent
340 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
341 call assert_equal(input, getline(1, '$'))
342 7,12m0
343 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
344 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
345 10,12m0
346 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
347 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)'))
348 " moving should not close the folds
349 %d
350 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
351 set fdm=indent
352 call cursor(2, 1)
Bram Moolenaar40ebc0a2017-03-16 15:59:14 +0100353 %foldopen
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100354 7,12m0
355 let folds=repeat([-1], 18)
356 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
357 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
358 norm! zM
359 " folds are not corrupted and all have been closed
360 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)'))
361 %d
362 call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
363 set fdm=indent
364 %foldopen
365 3m4
366 %foldclose
367 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
368 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
369 %d
370 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
371 set fdm=indent foldlevel=0
372 %foldopen
373 3m1
374 %foldclose
375 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
376 call assert_equal(1, foldlevel(2))
377 call assert_equal(5, foldclosedend(3))
378 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
379 2,6m$
380 %foldclose
381 call assert_equal(9, foldclosedend(2))
382 call assert_equal(1, foldlevel(6))
383 call assert_equal(9, foldclosedend(7))
384 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 +0100385 " Ensure moving around the edges still works.
386 %d
387 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
388 set fdm=indent foldlevel=0
389 %foldopen
390 6m$
391 " The first fold has been truncated to the 5'th line.
392 " Second fold has been moved up because the moved line is now below it.
Bram Moolenaar94be6192017-04-22 22:40:11 +0200393 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
Bram Moolenaar88d298a2017-03-14 21:53:58 +0100394 bw!
395endfunc
Bram Moolenaar518c9b12017-03-21 11:48:39 +0100396
397func Test_folddoopen_folddoclosed()
398 new
399 call setline(1, range(1, 9))
400 set foldmethod=manual
401 1,3 fold
402 6,8 fold
403
404 " Test without range.
405 folddoopen s/$/o/
406 folddoclosed s/$/c/
407 call assert_equal(['1c', '2c', '3c',
408 \ '4o', '5o',
409 \ '6c', '7c', '8c',
410 \ '9o'], getline(1, '$'))
411
412 " Test with range.
413 call setline(1, range(1, 9))
414 1,8 folddoopen s/$/o/
415 4,$ folddoclosed s/$/c/
416 call assert_equal(['1', '2', '3',
417 \ '4o', '5o',
418 \ '6c', '7c', '8c',
419 \ '9'], getline(1, '$'))
420
421 set foldmethod&
422 bw!
423endfunc
424
425func Test_fold_error()
426 new
427 call setline(1, [1, 2])
428
429 for fm in ['indent', 'expr', 'syntax', 'diff']
430 exe 'set foldmethod=' . fm
431 call assert_fails('norm zf', 'E350:')
432 call assert_fails('norm zd', 'E351:')
433 call assert_fails('norm zE', 'E352:')
434 endfor
435
436 set foldmethod=manual
437 call assert_fails('norm zd', 'E490:')
438 call assert_fails('norm zo', 'E490:')
439 call assert_fails('3fold', 'E16:')
440
441 set foldmethod=marker
442 set nomodifiable
443 call assert_fails('1,2fold', 'E21:')
444
445 set modifiable&
446 set foldmethod&
447 bw!
448endfunc