comparison src/fold.c @ 18779:8f05b3cf8557 v8.1.2379

patch 8.1.2379: using old C style comments Commit: https://github.com/vim/vim/commit/217e1b8359447f5550dcb0d1ee43380a90c253c5 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Dec 1 21:41:28 2019 +0100 patch 8.1.2379: using old C style comments Problem: Using old C style comments. Solution: Use // comments where appropriate.
author Bram Moolenaar <Bram@vim.org>
date Sun, 01 Dec 2019 21:45:04 +0100
parents e0ec4cd7a865
children 3af71cbcfdbe
comparison
equal deleted inserted replaced
18778:2182f82b04e4 18779:8f05b3cf8557
14 14
15 #include "vim.h" 15 #include "vim.h"
16 16
17 #if defined(FEAT_FOLDING) || defined(PROTO) 17 #if defined(FEAT_FOLDING) || defined(PROTO)
18 18
19 /* local declarations. {{{1 */ 19 // local declarations. {{{1
20 /* typedef fold_T {{{2 */ 20 // typedef fold_T {{{2
21 /* 21 /*
22 * The toplevel folds for each window are stored in the w_folds growarray. 22 * The toplevel folds for each window are stored in the w_folds growarray.
23 * Each toplevel fold can contain an array of second level folds in the 23 * Each toplevel fold can contain an array of second level folds in the
24 * fd_nested growarray. 24 * fd_nested growarray.
25 * The info stored in both growarrays is the same: An array of fold_T. 25 * The info stored in both growarrays is the same: An array of fold_T.
26 */ 26 */
27 typedef struct 27 typedef struct
28 { 28 {
29 linenr_T fd_top; /* first line of fold; for nested fold 29 linenr_T fd_top; // first line of fold; for nested fold
30 * relative to parent */ 30 // relative to parent
31 linenr_T fd_len; /* number of lines in the fold */ 31 linenr_T fd_len; // number of lines in the fold
32 garray_T fd_nested; /* array of nested folds */ 32 garray_T fd_nested; // array of nested folds
33 char fd_flags; /* see below */ 33 char fd_flags; // see below
34 char fd_small; /* TRUE, FALSE or MAYBE: fold smaller than 34 char fd_small; // TRUE, FALSE or MAYBE: fold smaller than
35 'foldminlines'; MAYBE applies to nested 35 // 'foldminlines'; MAYBE applies to nested
36 folds too */ 36 // folds too
37 } fold_T; 37 } fold_T;
38 38
39 #define FD_OPEN 0 /* fold is open (nested ones can be closed) */ 39 #define FD_OPEN 0 // fold is open (nested ones can be closed)
40 #define FD_CLOSED 1 /* fold is closed */ 40 #define FD_CLOSED 1 // fold is closed
41 #define FD_LEVEL 2 /* depends on 'foldlevel' (nested folds too) */ 41 #define FD_LEVEL 2 // depends on 'foldlevel' (nested folds too)
42 42
43 #define MAX_LEVEL 20 /* maximum fold depth */ 43 #define MAX_LEVEL 20 // maximum fold depth
44 44
45 /* static functions {{{2 */ 45 // static functions {{{2
46 static void newFoldLevelWin(win_T *wp); 46 static void newFoldLevelWin(win_T *wp);
47 static int checkCloseRec(garray_T *gap, linenr_T lnum, int level); 47 static int checkCloseRec(garray_T *gap, linenr_T lnum, int level);
48 static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp); 48 static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp);
49 static int foldLevelWin(win_T *wp, linenr_T lnum); 49 static int foldLevelWin(win_T *wp, linenr_T lnum);
50 static void checkupdate(win_T *wp); 50 static void checkupdate(win_T *wp);
82 * level is not available. 82 * level is not available.
83 */ 83 */
84 static linenr_T prev_lnum = 0; 84 static linenr_T prev_lnum = 0;
85 static int prev_lnum_lvl = -1; 85 static int prev_lnum_lvl = -1;
86 86
87 /* Flags used for "done" argument of setManualFold. */ 87 // Flags used for "done" argument of setManualFold.
88 #define DONE_NOTHING 0 88 #define DONE_NOTHING 0
89 #define DONE_ACTION 1 /* did close or open a fold */ 89 #define DONE_ACTION 1 // did close or open a fold
90 #define DONE_FOLD 2 /* did find a fold */ 90 #define DONE_FOLD 2 // did find a fold
91 91
92 static int foldstartmarkerlen; 92 static int foldstartmarkerlen;
93 static char_u *foldendmarker; 93 static char_u *foldendmarker;
94 static int foldendmarkerlen; 94 static int foldendmarkerlen;
95 95
96 /* Exported folding functions. {{{1 */ 96 // Exported folding functions. {{{1
97 /* copyFoldingState() {{{2 */ 97 // copyFoldingState() {{{2
98 98
99 /* 99 /*
100 * Copy that folding state from window "wp_from" to window "wp_to". 100 * Copy that folding state from window "wp_from" to window "wp_to".
101 */ 101 */
102 void 102 void
105 wp_to->w_fold_manual = wp_from->w_fold_manual; 105 wp_to->w_fold_manual = wp_from->w_fold_manual;
106 wp_to->w_foldinvalid = wp_from->w_foldinvalid; 106 wp_to->w_foldinvalid = wp_from->w_foldinvalid;
107 cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds); 107 cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds);
108 } 108 }
109 109
110 /* hasAnyFolding() {{{2 */ 110 // hasAnyFolding() {{{2
111 /* 111 /*
112 * Return TRUE if there may be folded lines in the current window. 112 * Return TRUE if there may be folded lines in the current window.
113 */ 113 */
114 int 114 int
115 hasAnyFolding(win_T *win) 115 hasAnyFolding(win_T *win)
116 { 116 {
117 /* very simple now, but can become more complex later */ 117 // very simple now, but can become more complex later
118 return (win->w_p_fen 118 return (win->w_p_fen
119 && (!foldmethodIsManual(win) || win->w_folds.ga_len > 0)); 119 && (!foldmethodIsManual(win) || win->w_folds.ga_len > 0));
120 } 120 }
121 121
122 /* hasFolding() {{{2 */ 122 // hasFolding() {{{2
123 /* 123 /*
124 * Return TRUE if line "lnum" in the current window is part of a closed 124 * Return TRUE if line "lnum" in the current window is part of a closed
125 * fold. 125 * fold.
126 * When returning TRUE, *firstp and *lastp are set to the first and last 126 * When returning TRUE, *firstp and *lastp are set to the first and last
127 * lnum of the sequence of folded lines (skipped when NULL). 127 * lnum of the sequence of folded lines (skipped when NULL).
130 hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp) 130 hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp)
131 { 131 {
132 return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL); 132 return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL);
133 } 133 }
134 134
135 /* hasFoldingWin() {{{2 */ 135 // hasFoldingWin() {{{2
136 int 136 int
137 hasFoldingWin( 137 hasFoldingWin(
138 win_T *win, 138 win_T *win,
139 linenr_T lnum, 139 linenr_T lnum,
140 linenr_T *firstp, 140 linenr_T *firstp,
141 linenr_T *lastp, 141 linenr_T *lastp,
142 int cache, /* when TRUE: use cached values of window */ 142 int cache, // when TRUE: use cached values of window
143 foldinfo_T *infop) /* where to store fold info */ 143 foldinfo_T *infop) // where to store fold info
144 { 144 {
145 int had_folded = FALSE; 145 int had_folded = FALSE;
146 linenr_T first = 0; 146 linenr_T first = 0;
147 linenr_T last = 0; 147 linenr_T last = 0;
148 linenr_T lnum_rel = lnum; 148 linenr_T lnum_rel = lnum;
190 for (;;) 190 for (;;)
191 { 191 {
192 if (!foldFind(gap, lnum_rel, &fp)) 192 if (!foldFind(gap, lnum_rel, &fp))
193 break; 193 break;
194 194
195 /* Remember lowest level of fold that starts in "lnum". */ 195 // Remember lowest level of fold that starts in "lnum".
196 if (lnum_rel == fp->fd_top && low_level == 0) 196 if (lnum_rel == fp->fd_top && low_level == 0)
197 low_level = level + 1; 197 low_level = level + 1;
198 198
199 first += fp->fd_top; 199 first += fp->fd_top;
200 last += fp->fd_top; 200 last += fp->fd_top;
201 201
202 /* is this fold closed? */ 202 // is this fold closed?
203 had_folded = check_closed(win, fp, &use_level, level, 203 had_folded = check_closed(win, fp, &use_level, level,
204 &maybe_small, lnum - lnum_rel); 204 &maybe_small, lnum - lnum_rel);
205 if (had_folded) 205 if (had_folded)
206 { 206 {
207 /* Fold closed: Set last and quit loop. */ 207 // Fold closed: Set last and quit loop.
208 last += fp->fd_len - 1; 208 last += fp->fd_len - 1;
209 break; 209 break;
210 } 210 }
211 211
212 /* Fold found, but it's open: Check nested folds. Line number is 212 // Fold found, but it's open: Check nested folds. Line number is
213 * relative to containing fold. */ 213 // relative to containing fold.
214 gap = &fp->fd_nested; 214 gap = &fp->fd_nested;
215 lnum_rel -= fp->fd_top; 215 lnum_rel -= fp->fd_top;
216 ++level; 216 ++level;
217 } 217 }
218 } 218 }
241 infop->fi_low_level = low_level == 0 ? level + 1 : low_level; 241 infop->fi_low_level = low_level == 0 ? level + 1 : low_level;
242 } 242 }
243 return TRUE; 243 return TRUE;
244 } 244 }
245 245
246 /* foldLevel() {{{2 */ 246 // foldLevel() {{{2
247 #ifdef FEAT_EVAL 247 #ifdef FEAT_EVAL
248 /* 248 /*
249 * Return fold level at line number "lnum" in the current window. 249 * Return fold level at line number "lnum" in the current window.
250 */ 250 */
251 static int 251 static int
252 foldLevel(linenr_T lnum) 252 foldLevel(linenr_T lnum)
253 { 253 {
254 /* While updating the folds lines between invalid_top and invalid_bot have 254 // While updating the folds lines between invalid_top and invalid_bot have
255 * an undefined fold level. Otherwise update the folds first. */ 255 // an undefined fold level. Otherwise update the folds first.
256 if (invalid_top == (linenr_T)0) 256 if (invalid_top == (linenr_T)0)
257 checkupdate(curwin); 257 checkupdate(curwin);
258 else if (lnum == prev_lnum && prev_lnum_lvl >= 0) 258 else if (lnum == prev_lnum && prev_lnum_lvl >= 0)
259 return prev_lnum_lvl; 259 return prev_lnum_lvl;
260 else if (lnum >= invalid_top && lnum <= invalid_bot) 260 else if (lnum >= invalid_top && lnum <= invalid_bot)
261 return -1; 261 return -1;
262 262
263 /* Return quickly when there is no folding at all in this window. */ 263 // Return quickly when there is no folding at all in this window.
264 if (!hasAnyFolding(curwin)) 264 if (!hasAnyFolding(curwin))
265 return 0; 265 return 0;
266 266
267 return foldLevelWin(curwin, lnum); 267 return foldLevelWin(curwin, lnum);
268 } 268 }
269 #endif 269 #endif
270 270
271 /* lineFolded() {{{2 */ 271 // lineFolded() {{{2
272 /* 272 /*
273 * Low level function to check if a line is folded. Doesn't use any caching. 273 * Low level function to check if a line is folded. Doesn't use any caching.
274 * Return TRUE if line is folded. 274 * Return TRUE if line is folded.
275 * Return FALSE if line is not folded. 275 * Return FALSE if line is not folded.
276 * Return MAYBE if the line is folded when next to a folded line. 276 * Return MAYBE if the line is folded when next to a folded line.
279 lineFolded(win_T *win, linenr_T lnum) 279 lineFolded(win_T *win, linenr_T lnum)
280 { 280 {
281 return foldedCount(win, lnum, NULL) != 0; 281 return foldedCount(win, lnum, NULL) != 0;
282 } 282 }
283 283
284 /* foldedCount() {{{2 */ 284 // foldedCount() {{{2
285 /* 285 /*
286 * Count the number of lines that are folded at line number "lnum". 286 * Count the number of lines that are folded at line number "lnum".
287 * Normally "lnum" is the first line of a possible fold, and the returned 287 * Normally "lnum" is the first line of a possible fold, and the returned
288 * number is the number of lines in the fold. 288 * number is the number of lines in the fold.
289 * Doesn't use caching from the displayed window. 289 * Doesn't use caching from the displayed window.
298 if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop)) 298 if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop))
299 return (long)(last - lnum + 1); 299 return (long)(last - lnum + 1);
300 return 0; 300 return 0;
301 } 301 }
302 302
303 /* foldmethodIsManual() {{{2 */ 303 // foldmethodIsManual() {{{2
304 /* 304 /*
305 * Return TRUE if 'foldmethod' is "manual" 305 * Return TRUE if 'foldmethod' is "manual"
306 */ 306 */
307 int 307 int
308 foldmethodIsManual(win_T *wp) 308 foldmethodIsManual(win_T *wp)
309 { 309 {
310 return (wp->w_p_fdm[3] == 'u'); 310 return (wp->w_p_fdm[3] == 'u');
311 } 311 }
312 312
313 /* foldmethodIsIndent() {{{2 */ 313 // foldmethodIsIndent() {{{2
314 /* 314 /*
315 * Return TRUE if 'foldmethod' is "indent" 315 * Return TRUE if 'foldmethod' is "indent"
316 */ 316 */
317 int 317 int
318 foldmethodIsIndent(win_T *wp) 318 foldmethodIsIndent(win_T *wp)
319 { 319 {
320 return (wp->w_p_fdm[0] == 'i'); 320 return (wp->w_p_fdm[0] == 'i');
321 } 321 }
322 322
323 /* foldmethodIsExpr() {{{2 */ 323 // foldmethodIsExpr() {{{2
324 /* 324 /*
325 * Return TRUE if 'foldmethod' is "expr" 325 * Return TRUE if 'foldmethod' is "expr"
326 */ 326 */
327 int 327 int
328 foldmethodIsExpr(win_T *wp) 328 foldmethodIsExpr(win_T *wp)
329 { 329 {
330 return (wp->w_p_fdm[1] == 'x'); 330 return (wp->w_p_fdm[1] == 'x');
331 } 331 }
332 332
333 /* foldmethodIsMarker() {{{2 */ 333 // foldmethodIsMarker() {{{2
334 /* 334 /*
335 * Return TRUE if 'foldmethod' is "marker" 335 * Return TRUE if 'foldmethod' is "marker"
336 */ 336 */
337 int 337 int
338 foldmethodIsMarker(win_T *wp) 338 foldmethodIsMarker(win_T *wp)
339 { 339 {
340 return (wp->w_p_fdm[2] == 'r'); 340 return (wp->w_p_fdm[2] == 'r');
341 } 341 }
342 342
343 /* foldmethodIsSyntax() {{{2 */ 343 // foldmethodIsSyntax() {{{2
344 /* 344 /*
345 * Return TRUE if 'foldmethod' is "syntax" 345 * Return TRUE if 'foldmethod' is "syntax"
346 */ 346 */
347 int 347 int
348 foldmethodIsSyntax(win_T *wp) 348 foldmethodIsSyntax(win_T *wp)
349 { 349 {
350 return (wp->w_p_fdm[0] == 's'); 350 return (wp->w_p_fdm[0] == 's');
351 } 351 }
352 352
353 /* foldmethodIsDiff() {{{2 */ 353 // foldmethodIsDiff() {{{2
354 /* 354 /*
355 * Return TRUE if 'foldmethod' is "diff" 355 * Return TRUE if 'foldmethod' is "diff"
356 */ 356 */
357 int 357 int
358 foldmethodIsDiff(win_T *wp) 358 foldmethodIsDiff(win_T *wp)
359 { 359 {
360 return (wp->w_p_fdm[0] == 'd'); 360 return (wp->w_p_fdm[0] == 'd');
361 } 361 }
362 362
363 /* closeFold() {{{2 */ 363 // closeFold() {{{2
364 /* 364 /*
365 * Close fold for current window at line "lnum". 365 * Close fold for current window at line "lnum".
366 * Repeat "count" times. 366 * Repeat "count" times.
367 */ 367 */
368 void 368 void
369 closeFold(linenr_T lnum, long count) 369 closeFold(linenr_T lnum, long count)
370 { 370 {
371 setFoldRepeat(lnum, count, FALSE); 371 setFoldRepeat(lnum, count, FALSE);
372 } 372 }
373 373
374 /* closeFoldRecurse() {{{2 */ 374 // closeFoldRecurse() {{{2
375 /* 375 /*
376 * Close fold for current window at line "lnum" recursively. 376 * Close fold for current window at line "lnum" recursively.
377 */ 377 */
378 void 378 void
379 closeFoldRecurse(linenr_T lnum) 379 closeFoldRecurse(linenr_T lnum)
380 { 380 {
381 (void)setManualFold(lnum, FALSE, TRUE, NULL); 381 (void)setManualFold(lnum, FALSE, TRUE, NULL);
382 } 382 }
383 383
384 /* opFoldRange() {{{2 */ 384 // opFoldRange() {{{2
385 /* 385 /*
386 * Open or Close folds for current window in lines "first" to "last". 386 * Open or Close folds for current window in lines "first" to "last".
387 * Used for "zo", "zO", "zc" and "zC" in Visual mode. 387 * Used for "zo", "zO", "zc" and "zC" in Visual mode.
388 */ 388 */
389 void 389 void
390 opFoldRange( 390 opFoldRange(
391 linenr_T first, 391 linenr_T first,
392 linenr_T last, 392 linenr_T last,
393 int opening, /* TRUE to open, FALSE to close */ 393 int opening, // TRUE to open, FALSE to close
394 int recurse, /* TRUE to do it recursively */ 394 int recurse, // TRUE to do it recursively
395 int had_visual) /* TRUE when Visual selection used */ 395 int had_visual) // TRUE when Visual selection used
396 { 396 {
397 int done = DONE_NOTHING; /* avoid error messages */ 397 int done = DONE_NOTHING; // avoid error messages
398 linenr_T lnum; 398 linenr_T lnum;
399 linenr_T lnum_next; 399 linenr_T lnum_next;
400 400
401 for (lnum = first; lnum <= last; lnum = lnum_next + 1) 401 for (lnum = first; lnum <= last; lnum = lnum_next + 1)
402 { 402 {
403 lnum_next = lnum; 403 lnum_next = lnum;
404 /* Opening one level only: next fold to open is after the one going to 404 // Opening one level only: next fold to open is after the one going to
405 * be opened. */ 405 // be opened.
406 if (opening && !recurse) 406 if (opening && !recurse)
407 (void)hasFolding(lnum, NULL, &lnum_next); 407 (void)hasFolding(lnum, NULL, &lnum_next);
408 (void)setManualFold(lnum, opening, recurse, &done); 408 (void)setManualFold(lnum, opening, recurse, &done);
409 /* Closing one level only: next line to close a fold is after just 409 // Closing one level only: next line to close a fold is after just
410 * closed fold. */ 410 // closed fold.
411 if (!opening && !recurse) 411 if (!opening && !recurse)
412 (void)hasFolding(lnum, NULL, &lnum_next); 412 (void)hasFolding(lnum, NULL, &lnum_next);
413 } 413 }
414 if (done == DONE_NOTHING) 414 if (done == DONE_NOTHING)
415 emsg(_(e_nofold)); 415 emsg(_(e_nofold));
416 /* Force a redraw to remove the Visual highlighting. */ 416 // Force a redraw to remove the Visual highlighting.
417 if (had_visual) 417 if (had_visual)
418 redraw_curbuf_later(INVERTED); 418 redraw_curbuf_later(INVERTED);
419 } 419 }
420 420
421 /* openFold() {{{2 */ 421 // openFold() {{{2
422 /* 422 /*
423 * Open fold for current window at line "lnum". 423 * Open fold for current window at line "lnum".
424 * Repeat "count" times. 424 * Repeat "count" times.
425 */ 425 */
426 void 426 void
427 openFold(linenr_T lnum, long count) 427 openFold(linenr_T lnum, long count)
428 { 428 {
429 setFoldRepeat(lnum, count, TRUE); 429 setFoldRepeat(lnum, count, TRUE);
430 } 430 }
431 431
432 /* openFoldRecurse() {{{2 */ 432 // openFoldRecurse() {{{2
433 /* 433 /*
434 * Open fold for current window at line "lnum" recursively. 434 * Open fold for current window at line "lnum" recursively.
435 */ 435 */
436 void 436 void
437 openFoldRecurse(linenr_T lnum) 437 openFoldRecurse(linenr_T lnum)
438 { 438 {
439 (void)setManualFold(lnum, TRUE, TRUE, NULL); 439 (void)setManualFold(lnum, TRUE, TRUE, NULL);
440 } 440 }
441 441
442 /* foldOpenCursor() {{{2 */ 442 // foldOpenCursor() {{{2
443 /* 443 /*
444 * Open folds until the cursor line is not in a closed fold. 444 * Open folds until the cursor line is not in a closed fold.
445 */ 445 */
446 void 446 void
447 foldOpenCursor(void) 447 foldOpenCursor(void)
457 if (!(done & DONE_ACTION)) 457 if (!(done & DONE_ACTION))
458 break; 458 break;
459 } 459 }
460 } 460 }
461 461
462 /* newFoldLevel() {{{2 */ 462 // newFoldLevel() {{{2
463 /* 463 /*
464 * Set new foldlevel for current window. 464 * Set new foldlevel for current window.
465 */ 465 */
466 void 466 void
467 newFoldLevel(void) 467 newFoldLevel(void)
495 int i; 495 int i;
496 496
497 checkupdate(wp); 497 checkupdate(wp);
498 if (wp->w_fold_manual) 498 if (wp->w_fold_manual)
499 { 499 {
500 /* Set all flags for the first level of folds to FD_LEVEL. Following 500 // Set all flags for the first level of folds to FD_LEVEL. Following
501 * manual open/close will then change the flags to FD_OPEN or 501 // manual open/close will then change the flags to FD_OPEN or
502 * FD_CLOSED for those folds that don't use 'foldlevel'. */ 502 // FD_CLOSED for those folds that don't use 'foldlevel'.
503 fp = (fold_T *)wp->w_folds.ga_data; 503 fp = (fold_T *)wp->w_folds.ga_data;
504 for (i = 0; i < wp->w_folds.ga_len; ++i) 504 for (i = 0; i < wp->w_folds.ga_len; ++i)
505 fp[i].fd_flags = FD_LEVEL; 505 fp[i].fd_flags = FD_LEVEL;
506 wp->w_fold_manual = FALSE; 506 wp->w_fold_manual = FALSE;
507 } 507 }
508 changed_window_setting_win(wp); 508 changed_window_setting_win(wp);
509 } 509 }
510 510
511 /* foldCheckClose() {{{2 */ 511 // foldCheckClose() {{{2
512 /* 512 /*
513 * Apply 'foldlevel' to all folds that don't contain the cursor. 513 * Apply 'foldlevel' to all folds that don't contain the cursor.
514 */ 514 */
515 void 515 void
516 foldCheckClose(void) 516 foldCheckClose(void)
517 { 517 {
518 if (*p_fcl != NUL) /* can only be "all" right now */ 518 if (*p_fcl != NUL) // can only be "all" right now
519 { 519 {
520 checkupdate(curwin); 520 checkupdate(curwin);
521 if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum, 521 if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
522 (int)curwin->w_p_fdl)) 522 (int)curwin->w_p_fdl))
523 changed_window_setting(); 523 changed_window_setting();
524 } 524 }
525 } 525 }
526 526
527 /* checkCloseRec() {{{2 */ 527 // checkCloseRec() {{{2
528 static int 528 static int
529 checkCloseRec(garray_T *gap, linenr_T lnum, int level) 529 checkCloseRec(garray_T *gap, linenr_T lnum, int level)
530 { 530 {
531 fold_T *fp; 531 fold_T *fp;
532 int retval = FALSE; 532 int retval = FALSE;
533 int i; 533 int i;
534 534
535 fp = (fold_T *)gap->ga_data; 535 fp = (fold_T *)gap->ga_data;
536 for (i = 0; i < gap->ga_len; ++i) 536 for (i = 0; i < gap->ga_len; ++i)
537 { 537 {
538 /* Only manually opened folds may need to be closed. */ 538 // Only manually opened folds may need to be closed.
539 if (fp[i].fd_flags == FD_OPEN) 539 if (fp[i].fd_flags == FD_OPEN)
540 { 540 {
541 if (level <= 0 && (lnum < fp[i].fd_top 541 if (level <= 0 && (lnum < fp[i].fd_top
542 || lnum >= fp[i].fd_top + fp[i].fd_len)) 542 || lnum >= fp[i].fd_top + fp[i].fd_len))
543 { 543 {
550 } 550 }
551 } 551 }
552 return retval; 552 return retval;
553 } 553 }
554 554
555 /* foldCreateAllowed() {{{2 */ 555 // foldCreateAllowed() {{{2
556 /* 556 /*
557 * Return TRUE if it's allowed to manually create or delete a fold. 557 * Return TRUE if it's allowed to manually create or delete a fold.
558 * Give an error message and return FALSE if not. 558 * Give an error message and return FALSE if not.
559 */ 559 */
560 int 560 int
567 else 567 else
568 emsg(_("E351: Cannot delete fold with current 'foldmethod'")); 568 emsg(_("E351: Cannot delete fold with current 'foldmethod'"));
569 return FALSE; 569 return FALSE;
570 } 570 }
571 571
572 /* foldCreate() {{{2 */ 572 // foldCreate() {{{2
573 /* 573 /*
574 * Create a fold from line "start" to line "end" (inclusive) in the current 574 * Create a fold from line "start" to line "end" (inclusive) in the current
575 * window. 575 * window.
576 */ 576 */
577 void 577 void
588 linenr_T start_rel = start; 588 linenr_T start_rel = start;
589 linenr_T end_rel = end; 589 linenr_T end_rel = end;
590 590
591 if (start > end) 591 if (start > end)
592 { 592 {
593 /* reverse the range */ 593 // reverse the range
594 end = start_rel; 594 end = start_rel;
595 start = end_rel; 595 start = end_rel;
596 start_rel = start; 596 start_rel = start;
597 end_rel = end; 597 end_rel = end;
598 } 598 }
599 599
600 /* When 'foldmethod' is "marker" add markers, which creates the folds. */ 600 // When 'foldmethod' is "marker" add markers, which creates the folds.
601 if (foldmethodIsMarker(curwin)) 601 if (foldmethodIsMarker(curwin))
602 { 602 {
603 foldCreateMarkers(start, end); 603 foldCreateMarkers(start, end);
604 return; 604 return;
605 } 605 }
606 606
607 checkupdate(curwin); 607 checkupdate(curwin);
608 608
609 /* Find the place to insert the new fold. */ 609 // Find the place to insert the new fold.
610 gap = &curwin->w_folds; 610 gap = &curwin->w_folds;
611 for (;;) 611 for (;;)
612 { 612 {
613 if (!foldFind(gap, start_rel, &fp)) 613 if (!foldFind(gap, start_rel, &fp))
614 break; 614 break;
615 if (fp->fd_top + fp->fd_len > end_rel) 615 if (fp->fd_top + fp->fd_len > end_rel)
616 { 616 {
617 /* New fold is completely inside this fold: Go one level deeper. */ 617 // New fold is completely inside this fold: Go one level deeper.
618 gap = &fp->fd_nested; 618 gap = &fp->fd_nested;
619 start_rel -= fp->fd_top; 619 start_rel -= fp->fd_top;
620 end_rel -= fp->fd_top; 620 end_rel -= fp->fd_top;
621 if (use_level || fp->fd_flags == FD_LEVEL) 621 if (use_level || fp->fd_flags == FD_LEVEL)
622 { 622 {
628 closed = TRUE; 628 closed = TRUE;
629 ++level; 629 ++level;
630 } 630 }
631 else 631 else
632 { 632 {
633 /* This fold and new fold overlap: Insert here and move some folds 633 // This fold and new fold overlap: Insert here and move some folds
634 * inside the new fold. */ 634 // inside the new fold.
635 break; 635 break;
636 } 636 }
637 } 637 }
638 638
639 i = (int)(fp - (fold_T *)gap->ga_data); 639 i = (int)(fp - (fold_T *)gap->ga_data);
640 if (ga_grow(gap, 1) == OK) 640 if (ga_grow(gap, 1) == OK)
641 { 641 {
642 fp = (fold_T *)gap->ga_data + i; 642 fp = (fold_T *)gap->ga_data + i;
643 ga_init2(&fold_ga, (int)sizeof(fold_T), 10); 643 ga_init2(&fold_ga, (int)sizeof(fold_T), 10);
644 644
645 /* Count number of folds that will be contained in the new fold. */ 645 // Count number of folds that will be contained in the new fold.
646 for (cont = 0; i + cont < gap->ga_len; ++cont) 646 for (cont = 0; i + cont < gap->ga_len; ++cont)
647 if (fp[cont].fd_top > end_rel) 647 if (fp[cont].fd_top > end_rel)
648 break; 648 break;
649 if (cont > 0 && ga_grow(&fold_ga, cont) == OK) 649 if (cont > 0 && ga_grow(&fold_ga, cont) == OK)
650 { 650 {
651 /* If the first fold starts before the new fold, let the new fold 651 // If the first fold starts before the new fold, let the new fold
652 * start there. Otherwise the existing fold would change. */ 652 // start there. Otherwise the existing fold would change.
653 if (start_rel > fp->fd_top) 653 if (start_rel > fp->fd_top)
654 start_rel = fp->fd_top; 654 start_rel = fp->fd_top;
655 655
656 /* When last contained fold isn't completely contained, adjust end 656 // When last contained fold isn't completely contained, adjust end
657 * of new fold. */ 657 // of new fold.
658 if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1) 658 if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1)
659 end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1; 659 end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1;
660 /* Move contained folds to inside new fold. */ 660 // Move contained folds to inside new fold.
661 mch_memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont); 661 mch_memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont);
662 fold_ga.ga_len += cont; 662 fold_ga.ga_len += cont;
663 i += cont; 663 i += cont;
664 664
665 /* Adjust line numbers in contained folds to be relative to the 665 // Adjust line numbers in contained folds to be relative to the
666 * new fold. */ 666 // new fold.
667 for (j = 0; j < cont; ++j) 667 for (j = 0; j < cont; ++j)
668 ((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel; 668 ((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel;
669 } 669 }
670 /* Move remaining entries to after the new fold. */ 670 // Move remaining entries to after the new fold.
671 if (i < gap->ga_len) 671 if (i < gap->ga_len)
672 mch_memmove(fp + 1, (fold_T *)gap->ga_data + i, 672 mch_memmove(fp + 1, (fold_T *)gap->ga_data + i,
673 sizeof(fold_T) * (gap->ga_len - i)); 673 sizeof(fold_T) * (gap->ga_len - i));
674 gap->ga_len = gap->ga_len + 1 - cont; 674 gap->ga_len = gap->ga_len + 1 - cont;
675 675
676 /* insert new fold */ 676 // insert new fold
677 fp->fd_nested = fold_ga; 677 fp->fd_nested = fold_ga;
678 fp->fd_top = start_rel; 678 fp->fd_top = start_rel;
679 fp->fd_len = end_rel - start_rel + 1; 679 fp->fd_len = end_rel - start_rel + 1;
680 680
681 /* We want the new fold to be closed. If it would remain open because 681 // We want the new fold to be closed. If it would remain open because
682 * of using 'foldlevel', need to adjust fd_flags of containing folds. 682 // of using 'foldlevel', need to adjust fd_flags of containing folds.
683 */
684 if (use_level && !closed && level < curwin->w_p_fdl) 683 if (use_level && !closed && level < curwin->w_p_fdl)
685 closeFold(start, 1L); 684 closeFold(start, 1L);
686 if (!use_level) 685 if (!use_level)
687 curwin->w_fold_manual = TRUE; 686 curwin->w_fold_manual = TRUE;
688 fp->fd_flags = FD_CLOSED; 687 fp->fd_flags = FD_CLOSED;
689 fp->fd_small = MAYBE; 688 fp->fd_small = MAYBE;
690 689
691 /* redraw */ 690 // redraw
692 changed_window_setting(); 691 changed_window_setting();
693 } 692 }
694 } 693 }
695 694
696 /* deleteFold() {{{2 */ 695 // deleteFold() {{{2
697 /* 696 /*
698 * Delete a fold at line "start" in the current window. 697 * Delete a fold at line "start" in the current window.
699 * When "end" is not 0, delete all folds from "start" to "end". 698 * When "end" is not 0, delete all folds from "start" to "end".
700 * When "recursive" is TRUE delete recursively. 699 * When "recursive" is TRUE delete recursively.
701 */ 700 */
702 void 701 void
703 deleteFold( 702 deleteFold(
704 linenr_T start, 703 linenr_T start,
705 linenr_T end, 704 linenr_T end,
706 int recursive, 705 int recursive,
707 int had_visual) /* TRUE when Visual selection used */ 706 int had_visual) // TRUE when Visual selection used
708 { 707 {
709 garray_T *gap; 708 garray_T *gap;
710 fold_T *fp; 709 fold_T *fp;
711 garray_T *found_ga; 710 garray_T *found_ga;
712 fold_T *found_fp = NULL; 711 fold_T *found_fp = NULL;
722 721
723 checkupdate(curwin); 722 checkupdate(curwin);
724 723
725 while (lnum <= end) 724 while (lnum <= end)
726 { 725 {
727 /* Find the deepest fold for "start". */ 726 // Find the deepest fold for "start".
728 gap = &curwin->w_folds; 727 gap = &curwin->w_folds;
729 found_ga = NULL; 728 found_ga = NULL;
730 lnum_off = 0; 729 lnum_off = 0;
731 use_level = FALSE; 730 use_level = FALSE;
732 for (;;) 731 for (;;)
733 { 732 {
734 if (!foldFind(gap, lnum - lnum_off, &fp)) 733 if (!foldFind(gap, lnum - lnum_off, &fp))
735 break; 734 break;
736 /* lnum is inside this fold, remember info */ 735 // lnum is inside this fold, remember info
737 found_ga = gap; 736 found_ga = gap;
738 found_fp = fp; 737 found_fp = fp;
739 found_off = lnum_off; 738 found_off = lnum_off;
740 739
741 /* if "lnum" is folded, don't check nesting */ 740 // if "lnum" is folded, don't check nesting
742 if (check_closed(curwin, fp, &use_level, level, 741 if (check_closed(curwin, fp, &use_level, level,
743 &maybe_small, lnum_off)) 742 &maybe_small, lnum_off))
744 break; 743 break;
745 744
746 /* check nested folds */ 745 // check nested folds
747 gap = &fp->fd_nested; 746 gap = &fp->fd_nested;
748 lnum_off += fp->fd_top; 747 lnum_off += fp->fd_top;
749 ++level; 748 ++level;
750 } 749 }
751 if (found_ga == NULL) 750 if (found_ga == NULL)
769 parseMarker(curwin); 768 parseMarker(curwin);
770 deleteFoldMarkers(found_fp, recursive, found_off); 769 deleteFoldMarkers(found_fp, recursive, found_off);
771 } 770 }
772 did_one = TRUE; 771 did_one = TRUE;
773 772
774 /* redraw window */ 773 // redraw window
775 changed_window_setting(); 774 changed_window_setting();
776 } 775 }
777 } 776 }
778 if (!did_one) 777 if (!did_one)
779 { 778 {
780 emsg(_(e_nofold)); 779 emsg(_(e_nofold));
781 /* Force a redraw to remove the Visual highlighting. */ 780 // Force a redraw to remove the Visual highlighting.
782 if (had_visual) 781 if (had_visual)
783 redraw_curbuf_later(INVERTED); 782 redraw_curbuf_later(INVERTED);
784 } 783 }
785 else 784 else
786 /* Deleting markers may make cursor column invalid. */ 785 // Deleting markers may make cursor column invalid.
787 check_cursor_col(); 786 check_cursor_col();
788 787
789 if (last_lnum > 0) 788 if (last_lnum > 0)
790 changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L); 789 changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
791 } 790 }
792 791
793 /* clearFolding() {{{2 */ 792 // clearFolding() {{{2
794 /* 793 /*
795 * Remove all folding for window "win". 794 * Remove all folding for window "win".
796 */ 795 */
797 void 796 void
798 clearFolding(win_T *win) 797 clearFolding(win_T *win)
799 { 798 {
800 deleteFoldRecurse(&win->w_folds); 799 deleteFoldRecurse(&win->w_folds);
801 win->w_foldinvalid = FALSE; 800 win->w_foldinvalid = FALSE;
802 } 801 }
803 802
804 /* foldUpdate() {{{2 */ 803 // foldUpdate() {{{2
805 /* 804 /*
806 * Update folds for changes in the buffer of a window. 805 * Update folds for changes in the buffer of a window.
807 * Note that inserted/deleted lines must have already been taken care of by 806 * Note that inserted/deleted lines must have already been taken care of by
808 * calling foldMarkAdjust(). 807 * calling foldMarkAdjust().
809 * The changes in lines from top to bot (inclusive). 808 * The changes in lines from top to bot (inclusive).
819 if (need_diff_redraw) 818 if (need_diff_redraw)
820 // will update later 819 // will update later
821 return; 820 return;
822 #endif 821 #endif
823 822
824 /* Mark all folds from top to bot as maybe-small. */ 823 // Mark all folds from top to bot as maybe-small.
825 (void)foldFind(&wp->w_folds, top, &fp); 824 (void)foldFind(&wp->w_folds, top, &fp);
826 while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len 825 while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len
827 && fp->fd_top < bot) 826 && fp->fd_top < bot)
828 { 827 {
829 fp->fd_small = MAYBE; 828 fp->fd_small = MAYBE;
838 #endif 837 #endif
839 || foldmethodIsSyntax(wp)) 838 || foldmethodIsSyntax(wp))
840 { 839 {
841 int save_got_int = got_int; 840 int save_got_int = got_int;
842 841
843 /* reset got_int here, otherwise it won't work */ 842 // reset got_int here, otherwise it won't work
844 got_int = FALSE; 843 got_int = FALSE;
845 foldUpdateIEMS(wp, top, bot); 844 foldUpdateIEMS(wp, top, bot);
846 got_int |= save_got_int; 845 got_int |= save_got_int;
847 } 846 }
848 } 847 }
849 848
850 /* foldUpdateAll() {{{2 */ 849 // foldUpdateAll() {{{2
851 /* 850 /*
852 * Update all lines in a window for folding. 851 * Update all lines in a window for folding.
853 * Used when a fold setting changes or after reloading the buffer. 852 * Used when a fold setting changes or after reloading the buffer.
854 * The actual updating is postponed until fold info is used, to avoid doing 853 * The actual updating is postponed until fold info is used, to avoid doing
855 * every time a setting is changed or a syntax item is added. 854 * every time a setting is changed or a syntax item is added.
859 { 858 {
860 win->w_foldinvalid = TRUE; 859 win->w_foldinvalid = TRUE;
861 redraw_win_later(win, NOT_VALID); 860 redraw_win_later(win, NOT_VALID);
862 } 861 }
863 862
864 /* foldMoveTo() {{{2 */ 863 // foldMoveTo() {{{2
865 /* 864 /*
866 * If "updown" is FALSE: Move to the start or end of the fold. 865 * If "updown" is FALSE: Move to the start or end of the fold.
867 * If "updown" is TRUE: move to fold at the same level. 866 * If "updown" is TRUE: move to fold at the same level.
868 * If not moved return FAIL. 867 * If not moved return FAIL.
869 */ 868 */
870 int 869 int
871 foldMoveTo( 870 foldMoveTo(
872 int updown, 871 int updown,
873 int dir, /* FORWARD or BACKWARD */ 872 int dir, // FORWARD or BACKWARD
874 long count) 873 long count)
875 { 874 {
876 long n; 875 long n;
877 int retval = FAIL; 876 int retval = FAIL;
878 linenr_T lnum_off; 877 linenr_T lnum_off;
885 int level; 884 int level;
886 int last; 885 int last;
887 886
888 checkupdate(curwin); 887 checkupdate(curwin);
889 888
890 /* Repeat "count" times. */ 889 // Repeat "count" times.
891 for (n = 0; n < count; ++n) 890 for (n = 0; n < count; ++n)
892 { 891 {
893 /* Find nested folds. Stop when a fold is closed. The deepest fold 892 // Find nested folds. Stop when a fold is closed. The deepest fold
894 * that moves the cursor is used. */ 893 // that moves the cursor is used.
895 lnum_off = 0; 894 lnum_off = 0;
896 gap = &curwin->w_folds; 895 gap = &curwin->w_folds;
897 use_level = FALSE; 896 use_level = FALSE;
898 maybe_small = FALSE; 897 maybe_small = FALSE;
899 lnum_found = curwin->w_cursor.lnum; 898 lnum_found = curwin->w_cursor.lnum;
904 if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp)) 903 if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp))
905 { 904 {
906 if (!updown) 905 if (!updown)
907 break; 906 break;
908 907
909 /* When moving up, consider a fold above the cursor; when 908 // When moving up, consider a fold above the cursor; when
910 * moving down consider a fold below the cursor. */ 909 // moving down consider a fold below the cursor.
911 if (dir == FORWARD) 910 if (dir == FORWARD)
912 { 911 {
913 if (fp - (fold_T *)gap->ga_data >= gap->ga_len) 912 if (fp - (fold_T *)gap->ga_data >= gap->ga_len)
914 break; 913 break;
915 --fp; 914 --fp;
917 else 916 else
918 { 917 {
919 if (fp == (fold_T *)gap->ga_data) 918 if (fp == (fold_T *)gap->ga_data)
920 break; 919 break;
921 } 920 }
922 /* don't look for contained folds, they will always move 921 // don't look for contained folds, they will always move
923 * the cursor too far. */ 922 // the cursor too far.
924 last = TRUE; 923 last = TRUE;
925 } 924 }
926 925
927 if (!last) 926 if (!last)
928 { 927 {
929 /* Check if this fold is closed. */ 928 // Check if this fold is closed.
930 if (check_closed(curwin, fp, &use_level, level, 929 if (check_closed(curwin, fp, &use_level, level,
931 &maybe_small, lnum_off)) 930 &maybe_small, lnum_off))
932 last = TRUE; 931 last = TRUE;
933 932
934 /* "[z" and "]z" stop at closed fold */ 933 // "[z" and "]z" stop at closed fold
935 if (last && !updown) 934 if (last && !updown)
936 break; 935 break;
937 } 936 }
938 937
939 if (updown) 938 if (updown)
940 { 939 {
941 if (dir == FORWARD) 940 if (dir == FORWARD)
942 { 941 {
943 /* to start of next fold if there is one */ 942 // to start of next fold if there is one
944 if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len) 943 if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len)
945 { 944 {
946 lnum = fp[1].fd_top + lnum_off; 945 lnum = fp[1].fd_top + lnum_off;
947 if (lnum > curwin->w_cursor.lnum) 946 if (lnum > curwin->w_cursor.lnum)
948 lnum_found = lnum; 947 lnum_found = lnum;
949 } 948 }
950 } 949 }
951 else 950 else
952 { 951 {
953 /* to end of previous fold if there is one */ 952 // to end of previous fold if there is one
954 if (fp > (fold_T *)gap->ga_data) 953 if (fp > (fold_T *)gap->ga_data)
955 { 954 {
956 lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1; 955 lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1;
957 if (lnum < curwin->w_cursor.lnum) 956 if (lnum < curwin->w_cursor.lnum)
958 lnum_found = lnum; 957 lnum_found = lnum;
959 } 958 }
960 } 959 }
961 } 960 }
962 else 961 else
963 { 962 {
964 /* Open fold found, set cursor to its start/end and then check 963 // Open fold found, set cursor to its start/end and then check
965 * nested folds. */ 964 // nested folds.
966 if (dir == FORWARD) 965 if (dir == FORWARD)
967 { 966 {
968 lnum = fp->fd_top + lnum_off + fp->fd_len - 1; 967 lnum = fp->fd_top + lnum_off + fp->fd_len - 1;
969 if (lnum > curwin->w_cursor.lnum) 968 if (lnum > curwin->w_cursor.lnum)
970 lnum_found = lnum; 969 lnum_found = lnum;
978 } 977 }
979 978
980 if (last) 979 if (last)
981 break; 980 break;
982 981
983 /* Check nested folds (if any). */ 982 // Check nested folds (if any).
984 gap = &fp->fd_nested; 983 gap = &fp->fd_nested;
985 lnum_off += fp->fd_top; 984 lnum_off += fp->fd_top;
986 ++level; 985 ++level;
987 } 986 }
988 if (lnum_found != curwin->w_cursor.lnum) 987 if (lnum_found != curwin->w_cursor.lnum)
998 } 997 }
999 998
1000 return retval; 999 return retval;
1001 } 1000 }
1002 1001
1003 /* foldInitWin() {{{2 */ 1002 // foldInitWin() {{{2
1004 /* 1003 /*
1005 * Init the fold info in a new window. 1004 * Init the fold info in a new window.
1006 */ 1005 */
1007 void 1006 void
1008 foldInitWin(win_T *new_win) 1007 foldInitWin(win_T *new_win)
1009 { 1008 {
1010 ga_init2(&new_win->w_folds, (int)sizeof(fold_T), 10); 1009 ga_init2(&new_win->w_folds, (int)sizeof(fold_T), 10);
1011 } 1010 }
1012 1011
1013 /* find_wl_entry() {{{2 */ 1012 // find_wl_entry() {{{2
1014 /* 1013 /*
1015 * Find an entry in the win->w_lines[] array for buffer line "lnum". 1014 * Find an entry in the win->w_lines[] array for buffer line "lnum".
1016 * Only valid entries are considered (for entries where wl_valid is FALSE the 1015 * Only valid entries are considered (for entries where wl_valid is FALSE the
1017 * line number can be wrong). 1016 * line number can be wrong).
1018 * Returns index of entry or -1 if not found. 1017 * Returns index of entry or -1 if not found.
1031 return i; 1030 return i;
1032 } 1031 }
1033 return -1; 1032 return -1;
1034 } 1033 }
1035 1034
1036 /* foldAdjustVisual() {{{2 */ 1035 // foldAdjustVisual() {{{2
1037 /* 1036 /*
1038 * Adjust the Visual area to include any fold at the start or end completely. 1037 * Adjust the Visual area to include any fold at the start or end completely.
1039 */ 1038 */
1040 void 1039 void
1041 foldAdjustVisual(void) 1040 foldAdjustVisual(void)
1062 { 1061 {
1063 ptr = ml_get(end->lnum); 1062 ptr = ml_get(end->lnum);
1064 end->col = (colnr_T)STRLEN(ptr); 1063 end->col = (colnr_T)STRLEN(ptr);
1065 if (end->col > 0 && *p_sel == 'o') 1064 if (end->col > 0 && *p_sel == 'o')
1066 --end->col; 1065 --end->col;
1067 /* prevent cursor from moving on the trail byte */ 1066 // prevent cursor from moving on the trail byte
1068 if (has_mbyte) 1067 if (has_mbyte)
1069 mb_adjust_cursor(); 1068 mb_adjust_cursor();
1070 } 1069 }
1071 } 1070 }
1072 1071
1073 /* cursor_foldstart() {{{2 */ 1072 // cursor_foldstart() {{{2
1074 /* 1073 /*
1075 * Move the cursor to the first line of a closed fold. 1074 * Move the cursor to the first line of a closed fold.
1076 */ 1075 */
1077 void 1076 void
1078 foldAdjustCursor(void) 1077 foldAdjustCursor(void)
1079 { 1078 {
1080 (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL); 1079 (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL);
1081 } 1080 }
1082 1081
1083 /* Internal functions for "fold_T" {{{1 */ 1082 // Internal functions for "fold_T" {{{1
1084 /* cloneFoldGrowArray() {{{2 */ 1083 // cloneFoldGrowArray() {{{2
1085 /* 1084 /*
1086 * Will "clone" (i.e deep copy) a garray_T of folds. 1085 * Will "clone" (i.e deep copy) a garray_T of folds.
1087 * 1086 *
1088 * Return FAIL if the operation cannot be completed, otherwise OK. 1087 * Return FAIL if the operation cannot be completed, otherwise OK.
1089 */ 1088 */
1112 ++from_p; 1111 ++from_p;
1113 ++to_p; 1112 ++to_p;
1114 } 1113 }
1115 } 1114 }
1116 1115
1117 /* foldFind() {{{2 */ 1116 // foldFind() {{{2
1118 /* 1117 /*
1119 * Search for line "lnum" in folds of growarray "gap". 1118 * Search for line "lnum" in folds of growarray "gap".
1120 * Set *fpp to the fold struct for the fold that contains "lnum" or 1119 * Set *fpp to the fold struct for the fold that contains "lnum" or
1121 * the first fold below it (careful: it can be beyond the end of the array!). 1120 * the first fold below it (careful: it can be beyond the end of the array!).
1122 * Returns FALSE when there is no fold that contains "lnum". 1121 * Returns FALSE when there is no fold that contains "lnum".
1138 high = gap->ga_len - 1; 1137 high = gap->ga_len - 1;
1139 while (low <= high) 1138 while (low <= high)
1140 { 1139 {
1141 i = (low + high) / 2; 1140 i = (low + high) / 2;
1142 if (fp[i].fd_top > lnum) 1141 if (fp[i].fd_top > lnum)
1143 /* fold below lnum, adjust high */ 1142 // fold below lnum, adjust high
1144 high = i - 1; 1143 high = i - 1;
1145 else if (fp[i].fd_top + fp[i].fd_len <= lnum) 1144 else if (fp[i].fd_top + fp[i].fd_len <= lnum)
1146 /* fold above lnum, adjust low */ 1145 // fold above lnum, adjust low
1147 low = i + 1; 1146 low = i + 1;
1148 else 1147 else
1149 { 1148 {
1150 /* lnum is inside this fold */ 1149 // lnum is inside this fold
1151 *fpp = fp + i; 1150 *fpp = fp + i;
1152 return TRUE; 1151 return TRUE;
1153 } 1152 }
1154 } 1153 }
1155 *fpp = fp + low; 1154 *fpp = fp + low;
1156 return FALSE; 1155 return FALSE;
1157 } 1156 }
1158 1157
1159 /* foldLevelWin() {{{2 */ 1158 // foldLevelWin() {{{2
1160 /* 1159 /*
1161 * Return fold level at line number "lnum" in window "wp". 1160 * Return fold level at line number "lnum" in window "wp".
1162 */ 1161 */
1163 static int 1162 static int
1164 foldLevelWin(win_T *wp, linenr_T lnum) 1163 foldLevelWin(win_T *wp, linenr_T lnum)
1166 fold_T *fp; 1165 fold_T *fp;
1167 linenr_T lnum_rel = lnum; 1166 linenr_T lnum_rel = lnum;
1168 int level = 0; 1167 int level = 0;
1169 garray_T *gap; 1168 garray_T *gap;
1170 1169
1171 /* Recursively search for a fold that contains "lnum". */ 1170 // Recursively search for a fold that contains "lnum".
1172 gap = &wp->w_folds; 1171 gap = &wp->w_folds;
1173 for (;;) 1172 for (;;)
1174 { 1173 {
1175 if (!foldFind(gap, lnum_rel, &fp)) 1174 if (!foldFind(gap, lnum_rel, &fp))
1176 break; 1175 break;
1177 /* Check nested folds. Line number is relative to containing fold. */ 1176 // Check nested folds. Line number is relative to containing fold.
1178 gap = &fp->fd_nested; 1177 gap = &fp->fd_nested;
1179 lnum_rel -= fp->fd_top; 1178 lnum_rel -= fp->fd_top;
1180 ++level; 1179 ++level;
1181 } 1180 }
1182 1181
1183 return level; 1182 return level;
1184 } 1183 }
1185 1184
1186 /* checkupdate() {{{2 */ 1185 // checkupdate() {{{2
1187 /* 1186 /*
1188 * Check if the folds in window "wp" are invalid and update them if needed. 1187 * Check if the folds in window "wp" are invalid and update them if needed.
1189 */ 1188 */
1190 static void 1189 static void
1191 checkupdate(win_T *wp) 1190 checkupdate(win_T *wp)
1192 { 1191 {
1193 if (wp->w_foldinvalid) 1192 if (wp->w_foldinvalid)
1194 { 1193 {
1195 foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); /* will update all */ 1194 foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all
1196 wp->w_foldinvalid = FALSE; 1195 wp->w_foldinvalid = FALSE;
1197 } 1196 }
1198 } 1197 }
1199 1198
1200 /* setFoldRepeat() {{{2 */ 1199 // setFoldRepeat() {{{2
1201 /* 1200 /*
1202 * Open or close fold for current window at line "lnum". 1201 * Open or close fold for current window at line "lnum".
1203 * Repeat "count" times. 1202 * Repeat "count" times.
1204 */ 1203 */
1205 static void 1204 static void
1212 { 1211 {
1213 done = DONE_NOTHING; 1212 done = DONE_NOTHING;
1214 (void)setManualFold(lnum, do_open, FALSE, &done); 1213 (void)setManualFold(lnum, do_open, FALSE, &done);
1215 if (!(done & DONE_ACTION)) 1214 if (!(done & DONE_ACTION))
1216 { 1215 {
1217 /* Only give an error message when no fold could be opened. */ 1216 // Only give an error message when no fold could be opened.
1218 if (n == 0 && !(done & DONE_FOLD)) 1217 if (n == 0 && !(done & DONE_FOLD))
1219 emsg(_(e_nofold)); 1218 emsg(_(e_nofold));
1220 break; 1219 break;
1221 } 1220 }
1222 } 1221 }
1223 } 1222 }
1224 1223
1225 /* setManualFold() {{{2 */ 1224 // setManualFold() {{{2
1226 /* 1225 /*
1227 * Open or close the fold in the current window which contains "lnum". 1226 * Open or close the fold in the current window which contains "lnum".
1228 * Also does this for other windows in diff mode when needed. 1227 * Also does this for other windows in diff mode when needed.
1229 */ 1228 */
1230 static linenr_T 1229 static linenr_T
1231 setManualFold( 1230 setManualFold(
1232 linenr_T lnum, 1231 linenr_T lnum,
1233 int opening, /* TRUE when opening, FALSE when closing */ 1232 int opening, // TRUE when opening, FALSE when closing
1234 int recurse, /* TRUE when closing/opening recursive */ 1233 int recurse, // TRUE when closing/opening recursive
1235 int *donep) 1234 int *donep)
1236 { 1235 {
1237 #ifdef FEAT_DIFF 1236 #ifdef FEAT_DIFF
1238 if (foldmethodIsDiff(curwin) && curwin->w_p_scb) 1237 if (foldmethodIsDiff(curwin) && curwin->w_p_scb)
1239 { 1238 {
1257 #endif 1256 #endif
1258 1257
1259 return setManualFoldWin(curwin, lnum, opening, recurse, donep); 1258 return setManualFoldWin(curwin, lnum, opening, recurse, donep);
1260 } 1259 }
1261 1260
1262 /* setManualFoldWin() {{{2 */ 1261 // setManualFoldWin() {{{2
1263 /* 1262 /*
1264 * Open or close the fold in window "wp" which contains "lnum". 1263 * Open or close the fold in window "wp" which contains "lnum".
1265 * "donep", when not NULL, points to flag that is set to DONE_FOLD when some 1264 * "donep", when not NULL, points to flag that is set to DONE_FOLD when some
1266 * fold was found and to DONE_ACTION when some fold was opened or closed. 1265 * fold was found and to DONE_ACTION when some fold was opened or closed.
1267 * When "donep" is NULL give an error message when no fold was found for 1266 * When "donep" is NULL give an error message when no fold was found for
1271 */ 1270 */
1272 static linenr_T 1271 static linenr_T
1273 setManualFoldWin( 1272 setManualFoldWin(
1274 win_T *wp, 1273 win_T *wp,
1275 linenr_T lnum, 1274 linenr_T lnum,
1276 int opening, /* TRUE when opening, FALSE when closing */ 1275 int opening, // TRUE when opening, FALSE when closing
1277 int recurse, /* TRUE when closing/opening recursive */ 1276 int recurse, // TRUE when closing/opening recursive
1278 int *donep) 1277 int *donep)
1279 { 1278 {
1280 fold_T *fp; 1279 fold_T *fp;
1281 fold_T *fp2; 1280 fold_T *fp2;
1282 fold_T *found = NULL; 1281 fold_T *found = NULL;
1297 gap = &wp->w_folds; 1296 gap = &wp->w_folds;
1298 for (;;) 1297 for (;;)
1299 { 1298 {
1300 if (!foldFind(gap, lnum, &fp)) 1299 if (!foldFind(gap, lnum, &fp))
1301 { 1300 {
1302 /* If there is a following fold, continue there next time. */ 1301 // If there is a following fold, continue there next time.
1303 if (fp < (fold_T *)gap->ga_data + gap->ga_len) 1302 if (fp < (fold_T *)gap->ga_data + gap->ga_len)
1304 next = fp->fd_top + off; 1303 next = fp->fd_top + off;
1305 break; 1304 break;
1306 } 1305 }
1307 1306
1308 /* lnum is inside this fold */ 1307 // lnum is inside this fold
1309 found_fold = TRUE; 1308 found_fold = TRUE;
1310 1309
1311 /* If there is a following fold, continue there next time. */ 1310 // If there is a following fold, continue there next time.
1312 if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len) 1311 if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len)
1313 next = fp[1].fd_top + off; 1312 next = fp[1].fd_top + off;
1314 1313
1315 /* Change from level-dependent folding to manual. */ 1314 // Change from level-dependent folding to manual.
1316 if (use_level || fp->fd_flags == FD_LEVEL) 1315 if (use_level || fp->fd_flags == FD_LEVEL)
1317 { 1316 {
1318 use_level = TRUE; 1317 use_level = TRUE;
1319 if (level >= wp->w_p_fdl) 1318 if (level >= wp->w_p_fdl)
1320 fp->fd_flags = FD_CLOSED; 1319 fp->fd_flags = FD_CLOSED;
1323 fp2 = (fold_T *)fp->fd_nested.ga_data; 1322 fp2 = (fold_T *)fp->fd_nested.ga_data;
1324 for (j = 0; j < fp->fd_nested.ga_len; ++j) 1323 for (j = 0; j < fp->fd_nested.ga_len; ++j)
1325 fp2[j].fd_flags = FD_LEVEL; 1324 fp2[j].fd_flags = FD_LEVEL;
1326 } 1325 }
1327 1326
1328 /* Simple case: Close recursively means closing the fold. */ 1327 // Simple case: Close recursively means closing the fold.
1329 if (!opening && recurse) 1328 if (!opening && recurse)
1330 { 1329 {
1331 if (fp->fd_flags != FD_CLOSED) 1330 if (fp->fd_flags != FD_CLOSED)
1332 { 1331 {
1333 done |= DONE_ACTION; 1332 done |= DONE_ACTION;
1334 fp->fd_flags = FD_CLOSED; 1333 fp->fd_flags = FD_CLOSED;
1335 } 1334 }
1336 } 1335 }
1337 else if (fp->fd_flags == FD_CLOSED) 1336 else if (fp->fd_flags == FD_CLOSED)
1338 { 1337 {
1339 /* When opening, open topmost closed fold. */ 1338 // When opening, open topmost closed fold.
1340 if (opening) 1339 if (opening)
1341 { 1340 {
1342 fp->fd_flags = FD_OPEN; 1341 fp->fd_flags = FD_OPEN;
1343 done |= DONE_ACTION; 1342 done |= DONE_ACTION;
1344 if (recurse) 1343 if (recurse)
1345 foldOpenNested(fp); 1344 foldOpenNested(fp);
1346 } 1345 }
1347 break; 1346 break;
1348 } 1347 }
1349 1348
1350 /* fold is open, check nested folds */ 1349 // fold is open, check nested folds
1351 found = fp; 1350 found = fp;
1352 gap = &fp->fd_nested; 1351 gap = &fp->fd_nested;
1353 lnum -= fp->fd_top; 1352 lnum -= fp->fd_top;
1354 off += fp->fd_top; 1353 off += fp->fd_top;
1355 ++level; 1354 ++level;
1356 } 1355 }
1357 if (found_fold) 1356 if (found_fold)
1358 { 1357 {
1359 /* When closing and not recurse, close deepest open fold. */ 1358 // When closing and not recurse, close deepest open fold.
1360 if (!opening && found != NULL) 1359 if (!opening && found != NULL)
1361 { 1360 {
1362 found->fd_flags = FD_CLOSED; 1361 found->fd_flags = FD_CLOSED;
1363 done |= DONE_ACTION; 1362 done |= DONE_ACTION;
1364 } 1363 }
1374 *donep |= done; 1373 *donep |= done;
1375 1374
1376 return next; 1375 return next;
1377 } 1376 }
1378 1377
1379 /* foldOpenNested() {{{2 */ 1378 // foldOpenNested() {{{2
1380 /* 1379 /*
1381 * Open all nested folds in fold "fpr" recursively. 1380 * Open all nested folds in fold "fpr" recursively.
1382 */ 1381 */
1383 static void 1382 static void
1384 foldOpenNested(fold_T *fpr) 1383 foldOpenNested(fold_T *fpr)
1392 foldOpenNested(&fp[i]); 1391 foldOpenNested(&fp[i]);
1393 fp[i].fd_flags = FD_OPEN; 1392 fp[i].fd_flags = FD_OPEN;
1394 } 1393 }
1395 } 1394 }
1396 1395
1397 /* deleteFoldEntry() {{{2 */ 1396 // deleteFoldEntry() {{{2
1398 /* 1397 /*
1399 * Delete fold "idx" from growarray "gap". 1398 * Delete fold "idx" from growarray "gap".
1400 * When "recursive" is TRUE also delete all the folds contained in it. 1399 * When "recursive" is TRUE also delete all the folds contained in it.
1401 * When "recursive" is FALSE contained folds are moved one level up. 1400 * When "recursive" is FALSE contained folds are moved one level up.
1402 */ 1401 */
1409 fold_T *nfp; 1408 fold_T *nfp;
1410 1409
1411 fp = (fold_T *)gap->ga_data + idx; 1410 fp = (fold_T *)gap->ga_data + idx;
1412 if (recursive || fp->fd_nested.ga_len == 0) 1411 if (recursive || fp->fd_nested.ga_len == 0)
1413 { 1412 {
1414 /* recursively delete the contained folds */ 1413 // recursively delete the contained folds
1415 deleteFoldRecurse(&fp->fd_nested); 1414 deleteFoldRecurse(&fp->fd_nested);
1416 --gap->ga_len; 1415 --gap->ga_len;
1417 if (idx < gap->ga_len) 1416 if (idx < gap->ga_len)
1418 mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx)); 1417 mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx));
1419 } 1418 }
1420 else 1419 else
1421 { 1420 {
1422 /* Move nested folds one level up, to overwrite the fold that is 1421 // Move nested folds one level up, to overwrite the fold that is
1423 * deleted. */ 1422 // deleted.
1424 moved = fp->fd_nested.ga_len; 1423 moved = fp->fd_nested.ga_len;
1425 if (ga_grow(gap, (int)(moved - 1)) == OK) 1424 if (ga_grow(gap, (int)(moved - 1)) == OK)
1426 { 1425 {
1427 /* Get "fp" again, the array may have been reallocated. */ 1426 // Get "fp" again, the array may have been reallocated.
1428 fp = (fold_T *)gap->ga_data + idx; 1427 fp = (fold_T *)gap->ga_data + idx;
1429 1428
1430 /* adjust fd_top and fd_flags for the moved folds */ 1429 // adjust fd_top and fd_flags for the moved folds
1431 nfp = (fold_T *)fp->fd_nested.ga_data; 1430 nfp = (fold_T *)fp->fd_nested.ga_data;
1432 for (i = 0; i < moved; ++i) 1431 for (i = 0; i < moved; ++i)
1433 { 1432 {
1434 nfp[i].fd_top += fp->fd_top; 1433 nfp[i].fd_top += fp->fd_top;
1435 if (fp->fd_flags == FD_LEVEL) 1434 if (fp->fd_flags == FD_LEVEL)
1436 nfp[i].fd_flags = FD_LEVEL; 1435 nfp[i].fd_flags = FD_LEVEL;
1437 if (fp->fd_small == MAYBE) 1436 if (fp->fd_small == MAYBE)
1438 nfp[i].fd_small = MAYBE; 1437 nfp[i].fd_small = MAYBE;
1439 } 1438 }
1440 1439
1441 /* move the existing folds down to make room */ 1440 // move the existing folds down to make room
1442 if (idx + 1 < gap->ga_len) 1441 if (idx + 1 < gap->ga_len)
1443 mch_memmove(fp + moved, fp + 1, 1442 mch_memmove(fp + moved, fp + 1,
1444 sizeof(fold_T) * (gap->ga_len - (idx + 1))); 1443 sizeof(fold_T) * (gap->ga_len - (idx + 1)));
1445 /* move the contained folds one level up */ 1444 // move the contained folds one level up
1446 mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved)); 1445 mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved));
1447 vim_free(nfp); 1446 vim_free(nfp);
1448 gap->ga_len += moved - 1; 1447 gap->ga_len += moved - 1;
1449 } 1448 }
1450 } 1449 }
1451 } 1450 }
1452 1451
1453 /* deleteFoldRecurse() {{{2 */ 1452 // deleteFoldRecurse() {{{2
1454 /* 1453 /*
1455 * Delete nested folds in a fold. 1454 * Delete nested folds in a fold.
1456 */ 1455 */
1457 void 1456 void
1458 deleteFoldRecurse(garray_T *gap) 1457 deleteFoldRecurse(garray_T *gap)
1462 for (i = 0; i < gap->ga_len; ++i) 1461 for (i = 0; i < gap->ga_len; ++i)
1463 deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested)); 1462 deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested));
1464 ga_clear(gap); 1463 ga_clear(gap);
1465 } 1464 }
1466 1465
1467 /* foldMarkAdjust() {{{2 */ 1466 // foldMarkAdjust() {{{2
1468 /* 1467 /*
1469 * Update line numbers of folds for inserted/deleted lines. 1468 * Update line numbers of folds for inserted/deleted lines.
1470 */ 1469 */
1471 void 1470 void
1472 foldMarkAdjust( 1471 foldMarkAdjust(
1474 linenr_T line1, 1473 linenr_T line1,
1475 linenr_T line2, 1474 linenr_T line2,
1476 long amount, 1475 long amount,
1477 long amount_after) 1476 long amount_after)
1478 { 1477 {
1479 /* If deleting marks from line1 to line2, but not deleting all those 1478 // If deleting marks from line1 to line2, but not deleting all those
1480 * lines, set line2 so that only deleted lines have their folds removed. */ 1479 // lines, set line2 so that only deleted lines have their folds removed.
1481 if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) 1480 if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after)
1482 line2 = line1 - amount_after - 1; 1481 line2 = line1 - amount_after - 1;
1483 /* If appending a line in Insert mode, it should be included in the fold 1482 // If appending a line in Insert mode, it should be included in the fold
1484 * just above the line. */ 1483 // just above the line.
1485 if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) 1484 if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
1486 --line1; 1485 --line1;
1487 foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after); 1486 foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after);
1488 } 1487 }
1489 1488
1490 /* foldMarkAdjustRecurse() {{{2 */ 1489 // foldMarkAdjustRecurse() {{{2
1491 static void 1490 static void
1492 foldMarkAdjustRecurse( 1491 foldMarkAdjustRecurse(
1493 garray_T *gap, 1492 garray_T *gap,
1494 linenr_T line1, 1493 linenr_T line1,
1495 linenr_T line2, 1494 linenr_T line2,
1499 fold_T *fp; 1498 fold_T *fp;
1500 int i; 1499 int i;
1501 linenr_T last; 1500 linenr_T last;
1502 linenr_T top; 1501 linenr_T top;
1503 1502
1504 /* In Insert mode an inserted line at the top of a fold is considered part 1503 // In Insert mode an inserted line at the top of a fold is considered part
1505 * of the fold, otherwise it isn't. */ 1504 // of the fold, otherwise it isn't.
1506 if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) 1505 if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
1507 top = line1 + 1; 1506 top = line1 + 1;
1508 else 1507 else
1509 top = line1; 1508 top = line1;
1510 1509
1511 /* Find the fold containing or just below "line1". */ 1510 // Find the fold containing or just below "line1".
1512 (void)foldFind(gap, line1, &fp); 1511 (void)foldFind(gap, line1, &fp);
1513 1512
1514 /* 1513 /*
1515 * Adjust all folds below "line1" that are affected. 1514 * Adjust all folds below "line1" that are affected.
1516 */ 1515 */
1526 * line2 2 3 4 5 1525 * line2 2 3 4 5
1527 * 3 5 6 1526 * 3 5 6
1528 * 3 5 6 1527 * 3 5 6
1529 */ 1528 */
1530 1529
1531 last = fp->fd_top + fp->fd_len - 1; /* last line of fold */ 1530 last = fp->fd_top + fp->fd_len - 1; // last line of fold
1532 1531
1533 /* 1. fold completely above line1: nothing to do */ 1532 // 1. fold completely above line1: nothing to do
1534 if (last < line1) 1533 if (last < line1)
1535 continue; 1534 continue;
1536 1535
1537 /* 6. fold below line2: only adjust for amount_after */ 1536 // 6. fold below line2: only adjust for amount_after
1538 if (fp->fd_top > line2) 1537 if (fp->fd_top > line2)
1539 { 1538 {
1540 if (amount_after == 0) 1539 if (amount_after == 0)
1541 break; 1540 break;
1542 fp->fd_top += amount_after; 1541 fp->fd_top += amount_after;
1543 } 1542 }
1544 else 1543 else
1545 { 1544 {
1546 if (fp->fd_top >= top && last <= line2) 1545 if (fp->fd_top >= top && last <= line2)
1547 { 1546 {
1548 /* 4. fold completely contained in range */ 1547 // 4. fold completely contained in range
1549 if (amount == MAXLNUM) 1548 if (amount == MAXLNUM)
1550 { 1549 {
1551 /* Deleting lines: delete the fold completely */ 1550 // Deleting lines: delete the fold completely
1552 deleteFoldEntry(gap, i, TRUE); 1551 deleteFoldEntry(gap, i, TRUE);
1553 --i; /* adjust index for deletion */ 1552 --i; // adjust index for deletion
1554 --fp; 1553 --fp;
1555 } 1554 }
1556 else 1555 else
1557 fp->fd_top += amount; 1556 fp->fd_top += amount;
1558 } 1557 }
1559 else 1558 else
1560 { 1559 {
1561 if (fp->fd_top < top) 1560 if (fp->fd_top < top)
1562 { 1561 {
1563 /* 2 or 3: need to correct nested folds too */ 1562 // 2 or 3: need to correct nested folds too
1564 foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, 1563 foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
1565 line2 - fp->fd_top, amount, amount_after); 1564 line2 - fp->fd_top, amount, amount_after);
1566 if (last <= line2) 1565 if (last <= line2)
1567 { 1566 {
1568 /* 2. fold contains line1, line2 is below fold */ 1567 // 2. fold contains line1, line2 is below fold
1569 if (amount == MAXLNUM) 1568 if (amount == MAXLNUM)
1570 fp->fd_len = line1 - fp->fd_top; 1569 fp->fd_len = line1 - fp->fd_top;
1571 else 1570 else
1572 fp->fd_len += amount; 1571 fp->fd_len += amount;
1573 } 1572 }
1574 else 1573 else
1575 { 1574 {
1576 /* 3. fold contains line1 and line2 */ 1575 // 3. fold contains line1 and line2
1577 fp->fd_len += amount_after; 1576 fp->fd_len += amount_after;
1578 } 1577 }
1579 } 1578 }
1580 else 1579 else
1581 { 1580 {
1582 /* 5. fold is below line1 and contains line2; need to 1581 // 5. fold is below line1 and contains line2; need to
1583 * correct nested folds too */ 1582 // correct nested folds too
1584 if (amount == MAXLNUM) 1583 if (amount == MAXLNUM)
1585 { 1584 {
1586 foldMarkAdjustRecurse(&fp->fd_nested, 1585 foldMarkAdjustRecurse(&fp->fd_nested,
1587 line1 - fp->fd_top, 1586 line1 - fp->fd_top,
1588 line2 - fp->fd_top, 1587 line2 - fp->fd_top,
1605 } 1604 }
1606 } 1605 }
1607 } 1606 }
1608 } 1607 }
1609 1608
1610 /* getDeepestNesting() {{{2 */ 1609 // getDeepestNesting() {{{2
1611 /* 1610 /*
1612 * Get the lowest 'foldlevel' value that makes the deepest nested fold in the 1611 * Get the lowest 'foldlevel' value that makes the deepest nested fold in the
1613 * current window open. 1612 * current window open.
1614 */ 1613 */
1615 int 1614 int
1636 } 1635 }
1637 1636
1638 return maxlevel; 1637 return maxlevel;
1639 } 1638 }
1640 1639
1641 /* check_closed() {{{2 */ 1640 // check_closed() {{{2
1642 /* 1641 /*
1643 * Check if a fold is closed and update the info needed to check nested folds. 1642 * Check if a fold is closed and update the info needed to check nested folds.
1644 */ 1643 */
1645 static int 1644 static int
1646 check_closed( 1645 check_closed(
1647 win_T *win, 1646 win_T *win,
1648 fold_T *fp, 1647 fold_T *fp,
1649 int *use_levelp, /* TRUE: outer fold had FD_LEVEL */ 1648 int *use_levelp, // TRUE: outer fold had FD_LEVEL
1650 int level, /* folding depth */ 1649 int level, // folding depth
1651 int *maybe_smallp, /* TRUE: outer this had fd_small == MAYBE */ 1650 int *maybe_smallp, // TRUE: outer this had fd_small == MAYBE
1652 linenr_T lnum_off) /* line number offset for fp->fd_top */ 1651 linenr_T lnum_off) // line number offset for fp->fd_top
1653 { 1652 {
1654 int closed = FALSE; 1653 int closed = FALSE;
1655 1654
1656 /* Check if this fold is closed. If the flag is FD_LEVEL this 1655 // Check if this fold is closed. If the flag is FD_LEVEL this
1657 * fold and all folds it contains depend on 'foldlevel'. */ 1656 // fold and all folds it contains depend on 'foldlevel'.
1658 if (*use_levelp || fp->fd_flags == FD_LEVEL) 1657 if (*use_levelp || fp->fd_flags == FD_LEVEL)
1659 { 1658 {
1660 *use_levelp = TRUE; 1659 *use_levelp = TRUE;
1661 if (level >= win->w_p_fdl) 1660 if (level >= win->w_p_fdl)
1662 closed = TRUE; 1661 closed = TRUE;
1663 } 1662 }
1664 else if (fp->fd_flags == FD_CLOSED) 1663 else if (fp->fd_flags == FD_CLOSED)
1665 closed = TRUE; 1664 closed = TRUE;
1666 1665
1667 /* Small fold isn't closed anyway. */ 1666 // Small fold isn't closed anyway.
1668 if (fp->fd_small == MAYBE) 1667 if (fp->fd_small == MAYBE)
1669 *maybe_smallp = TRUE; 1668 *maybe_smallp = TRUE;
1670 if (closed) 1669 if (closed)
1671 { 1670 {
1672 if (*maybe_smallp) 1671 if (*maybe_smallp)
1676 closed = FALSE; 1675 closed = FALSE;
1677 } 1676 }
1678 return closed; 1677 return closed;
1679 } 1678 }
1680 1679
1681 /* checkSmall() {{{2 */ 1680 // checkSmall() {{{2
1682 /* 1681 /*
1683 * Update fd_small field of fold "fp". 1682 * Update fd_small field of fold "fp".
1684 */ 1683 */
1685 static void 1684 static void
1686 checkSmall( 1685 checkSmall(
1687 win_T *wp, 1686 win_T *wp,
1688 fold_T *fp, 1687 fold_T *fp,
1689 linenr_T lnum_off) /* offset for fp->fd_top */ 1688 linenr_T lnum_off) // offset for fp->fd_top
1690 { 1689 {
1691 int count; 1690 int count;
1692 int n; 1691 int n;
1693 1692
1694 if (fp->fd_small == MAYBE) 1693 if (fp->fd_small == MAYBE)
1695 { 1694 {
1696 /* Mark any nested folds to maybe-small */ 1695 // Mark any nested folds to maybe-small
1697 setSmallMaybe(&fp->fd_nested); 1696 setSmallMaybe(&fp->fd_nested);
1698 1697
1699 if (fp->fd_len > curwin->w_p_fml) 1698 if (fp->fd_len > curwin->w_p_fml)
1700 fp->fd_small = FALSE; 1699 fp->fd_small = FALSE;
1701 else 1700 else
1713 fp->fd_small = TRUE; 1712 fp->fd_small = TRUE;
1714 } 1713 }
1715 } 1714 }
1716 } 1715 }
1717 1716
1718 /* setSmallMaybe() {{{2 */ 1717 // setSmallMaybe() {{{2
1719 /* 1718 /*
1720 * Set small flags in "gap" to MAYBE. 1719 * Set small flags in "gap" to MAYBE.
1721 */ 1720 */
1722 static void 1721 static void
1723 setSmallMaybe(garray_T *gap) 1722 setSmallMaybe(garray_T *gap)
1728 fp = (fold_T *)gap->ga_data; 1727 fp = (fold_T *)gap->ga_data;
1729 for (i = 0; i < gap->ga_len; ++i) 1728 for (i = 0; i < gap->ga_len; ++i)
1730 fp[i].fd_small = MAYBE; 1729 fp[i].fd_small = MAYBE;
1731 } 1730 }
1732 1731
1733 /* foldCreateMarkers() {{{2 */ 1732 // foldCreateMarkers() {{{2
1734 /* 1733 /*
1735 * Create a fold from line "start" to line "end" (inclusive) in the current 1734 * Create a fold from line "start" to line "end" (inclusive) in the current
1736 * window by adding markers. 1735 * window by adding markers.
1737 */ 1736 */
1738 static void 1737 static void
1746 parseMarker(curwin); 1745 parseMarker(curwin);
1747 1746
1748 foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen); 1747 foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen);
1749 foldAddMarker(end, foldendmarker, foldendmarkerlen); 1748 foldAddMarker(end, foldendmarker, foldendmarkerlen);
1750 1749
1751 /* Update both changes here, to avoid all folds after the start are 1750 // Update both changes here, to avoid all folds after the start are
1752 * changed when the start marker is inserted and the end isn't. */ 1751 // changed when the start marker is inserted and the end isn't.
1753 changed_lines(start, (colnr_T)0, end, 0L); 1752 changed_lines(start, (colnr_T)0, end, 0L);
1754 } 1753 }
1755 1754
1756 /* foldAddMarker() {{{2 */ 1755 // foldAddMarker() {{{2
1757 /* 1756 /*
1758 * Add "marker[markerlen]" in 'commentstring' to line "lnum". 1757 * Add "marker[markerlen]" in 'commentstring' to line "lnum".
1759 */ 1758 */
1760 static void 1759 static void
1761 foldAddMarker(linenr_T lnum, char_u *marker, int markerlen) 1760 foldAddMarker(linenr_T lnum, char_u *marker, int markerlen)
1765 int line_len; 1764 int line_len;
1766 char_u *newline; 1765 char_u *newline;
1767 char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s"); 1766 char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
1768 int line_is_comment = FALSE; 1767 int line_is_comment = FALSE;
1769 1768
1770 /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */ 1769 // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
1771 line = ml_get(lnum); 1770 line = ml_get(lnum);
1772 line_len = (int)STRLEN(line); 1771 line_len = (int)STRLEN(line);
1773 1772
1774 if (u_save(lnum - 1, lnum + 1) == OK) 1773 if (u_save(lnum - 1, lnum + 1) == OK)
1775 { 1774 {
1776 /* Check if the line ends with an unclosed comment */ 1775 // Check if the line ends with an unclosed comment
1777 (void)skip_comment(line, FALSE, FALSE, &line_is_comment); 1776 (void)skip_comment(line, FALSE, FALSE, &line_is_comment);
1778 newline = alloc(line_len + markerlen + STRLEN(cms) + 1); 1777 newline = alloc(line_len + markerlen + STRLEN(cms) + 1);
1779 if (newline == NULL) 1778 if (newline == NULL)
1780 return; 1779 return;
1781 STRCPY(newline, line); 1780 STRCPY(newline, line);
1782 /* Append the marker to the end of the line */ 1781 // Append the marker to the end of the line
1783 if (p == NULL || line_is_comment) 1782 if (p == NULL || line_is_comment)
1784 vim_strncpy(newline + line_len, marker, markerlen); 1783 vim_strncpy(newline + line_len, marker, markerlen);
1785 else 1784 else
1786 { 1785 {
1787 STRCPY(newline + line_len, cms); 1786 STRCPY(newline + line_len, cms);
1791 1790
1792 ml_replace(lnum, newline, FALSE); 1791 ml_replace(lnum, newline, FALSE);
1793 } 1792 }
1794 } 1793 }
1795 1794
1796 /* deleteFoldMarkers() {{{2 */ 1795 // deleteFoldMarkers() {{{2
1797 /* 1796 /*
1798 * Delete the markers for a fold, causing it to be deleted. 1797 * Delete the markers for a fold, causing it to be deleted.
1799 */ 1798 */
1800 static void 1799 static void
1801 deleteFoldMarkers( 1800 deleteFoldMarkers(
1802 fold_T *fp, 1801 fold_T *fp,
1803 int recursive, 1802 int recursive,
1804 linenr_T lnum_off) /* offset for fp->fd_top */ 1803 linenr_T lnum_off) // offset for fp->fd_top
1805 { 1804 {
1806 int i; 1805 int i;
1807 1806
1808 if (recursive) 1807 if (recursive)
1809 for (i = 0; i < fp->fd_nested.ga_len; ++i) 1808 for (i = 0; i < fp->fd_nested.ga_len; ++i)
1812 foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen); 1811 foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen);
1813 foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1, 1812 foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1,
1814 foldendmarker, foldendmarkerlen); 1813 foldendmarker, foldendmarkerlen);
1815 } 1814 }
1816 1815
1817 /* foldDelMarker() {{{2 */ 1816 // foldDelMarker() {{{2
1818 /* 1817 /*
1819 * Delete marker "marker[markerlen]" at the end of line "lnum". 1818 * Delete marker "marker[markerlen]" at the end of line "lnum".
1820 * Delete 'commentstring' if it matches. 1819 * Delete 'commentstring' if it matches.
1821 * If the marker is not found, there is no error message. Could be a missing 1820 * If the marker is not found, there is no error message. Could be a missing
1822 * close-marker. 1821 * close-marker.
1836 return; 1835 return;
1837 line = ml_get(lnum); 1836 line = ml_get(lnum);
1838 for (p = line; *p != NUL; ++p) 1837 for (p = line; *p != NUL; ++p)
1839 if (STRNCMP(p, marker, markerlen) == 0) 1838 if (STRNCMP(p, marker, markerlen) == 0)
1840 { 1839 {
1841 /* Found the marker, include a digit if it's there. */ 1840 // Found the marker, include a digit if it's there.
1842 len = markerlen; 1841 len = markerlen;
1843 if (VIM_ISDIGIT(p[len])) 1842 if (VIM_ISDIGIT(p[len]))
1844 ++len; 1843 ++len;
1845 if (*cms != NUL) 1844 if (*cms != NUL)
1846 { 1845 {
1847 /* Also delete 'commentstring' if it matches. */ 1846 // Also delete 'commentstring' if it matches.
1848 cms2 = (char_u *)strstr((char *)cms, "%s"); 1847 cms2 = (char_u *)strstr((char *)cms, "%s");
1849 if (p - line >= cms2 - cms 1848 if (p - line >= cms2 - cms
1850 && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0 1849 && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
1851 && STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) 1850 && STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0)
1852 { 1851 {
1854 len += (int)STRLEN(cms) - 2; 1853 len += (int)STRLEN(cms) - 2;
1855 } 1854 }
1856 } 1855 }
1857 if (u_save(lnum - 1, lnum + 1) == OK) 1856 if (u_save(lnum - 1, lnum + 1) == OK)
1858 { 1857 {
1859 /* Make new line: text-before-marker + text-after-marker */ 1858 // Make new line: text-before-marker + text-after-marker
1860 newline = alloc(STRLEN(line) - len + 1); 1859 newline = alloc(STRLEN(line) - len + 1);
1861 if (newline != NULL) 1860 if (newline != NULL)
1862 { 1861 {
1863 STRNCPY(newline, line, p - line); 1862 STRNCPY(newline, line, p - line);
1864 STRCPY(newline + (p - line), p + len); 1863 STRCPY(newline + (p - line), p + len);
1867 } 1866 }
1868 break; 1867 break;
1869 } 1868 }
1870 } 1869 }
1871 1870
1872 /* get_foldtext() {{{2 */ 1871 // get_foldtext() {{{2
1873 /* 1872 /*
1874 * Return the text for a closed fold at line "lnum", with last line "lnume". 1873 * Return the text for a closed fold at line "lnum", with last line "lnume".
1875 * When 'foldtext' isn't set puts the result in "buf[FOLD_TEXT_LEN]". 1874 * When 'foldtext' isn't set puts the result in "buf[FOLD_TEXT_LEN]".
1876 * Otherwise the result is in allocated memory. 1875 * Otherwise the result is in allocated memory.
1877 */ 1876 */
1883 foldinfo_T *foldinfo, 1882 foldinfo_T *foldinfo,
1884 char_u *buf) 1883 char_u *buf)
1885 { 1884 {
1886 char_u *text = NULL; 1885 char_u *text = NULL;
1887 #ifdef FEAT_EVAL 1886 #ifdef FEAT_EVAL
1888 /* an error occurred when evaluating 'fdt' setting */ 1887 // an error occurred when evaluating 'fdt' setting
1889 static int got_fdt_error = FALSE; 1888 static int got_fdt_error = FALSE;
1890 int save_did_emsg = did_emsg; 1889 int save_did_emsg = did_emsg;
1891 static win_T *last_wp = NULL; 1890 static win_T *last_wp = NULL;
1892 static linenr_T last_lnum = 0; 1891 static linenr_T last_lnum = 0;
1893 1892
1894 if (last_wp != wp || last_wp == NULL 1893 if (last_wp != wp || last_wp == NULL
1895 || last_lnum > lnum || last_lnum == 0) 1894 || last_lnum > lnum || last_lnum == 0)
1896 /* window changed, try evaluating foldtext setting once again */ 1895 // window changed, try evaluating foldtext setting once again
1897 got_fdt_error = FALSE; 1896 got_fdt_error = FALSE;
1898 1897
1899 if (!got_fdt_error) 1898 if (!got_fdt_error)
1900 /* a previous error should not abort evaluating 'foldexpr' */ 1899 // a previous error should not abort evaluating 'foldexpr'
1901 did_emsg = FALSE; 1900 did_emsg = FALSE;
1902 1901
1903 if (*wp->w_p_fdt != NUL) 1902 if (*wp->w_p_fdt != NUL)
1904 { 1903 {
1905 char_u dashes[MAX_LEVEL + 2]; 1904 char_u dashes[MAX_LEVEL + 2];
1906 win_T *save_curwin; 1905 win_T *save_curwin;
1907 int level; 1906 int level;
1908 char_u *p; 1907 char_u *p;
1909 1908
1910 /* Set "v:foldstart" and "v:foldend". */ 1909 // Set "v:foldstart" and "v:foldend".
1911 set_vim_var_nr(VV_FOLDSTART, lnum); 1910 set_vim_var_nr(VV_FOLDSTART, lnum);
1912 set_vim_var_nr(VV_FOLDEND, lnume); 1911 set_vim_var_nr(VV_FOLDEND, lnume);
1913 1912
1914 /* Set "v:folddashes" to a string of "level" dashes. */ 1913 // Set "v:folddashes" to a string of "level" dashes.
1915 /* Set "v:foldlevel" to "level". */ 1914 // Set "v:foldlevel" to "level".
1916 level = foldinfo->fi_level; 1915 level = foldinfo->fi_level;
1917 if (level > (int)sizeof(dashes) - 1) 1916 if (level > (int)sizeof(dashes) - 1)
1918 level = (int)sizeof(dashes) - 1; 1917 level = (int)sizeof(dashes) - 1;
1919 vim_memset(dashes, '-', (size_t)level); 1918 vim_memset(dashes, '-', (size_t)level);
1920 dashes[level] = NUL; 1919 dashes[level] = NUL;
1921 set_vim_var_string(VV_FOLDDASHES, dashes, -1); 1920 set_vim_var_string(VV_FOLDDASHES, dashes, -1);
1922 set_vim_var_nr(VV_FOLDLEVEL, (long)level); 1921 set_vim_var_nr(VV_FOLDLEVEL, (long)level);
1923 1922
1924 /* skip evaluating foldtext on errors */ 1923 // skip evaluating foldtext on errors
1925 if (!got_fdt_error) 1924 if (!got_fdt_error)
1926 { 1925 {
1927 save_curwin = curwin; 1926 save_curwin = curwin;
1928 curwin = wp; 1927 curwin = wp;
1929 curbuf = wp->w_buffer; 1928 curbuf = wp->w_buffer;
1930 1929
1931 ++emsg_silent; /* handle exceptions, but don't display errors */ 1930 ++emsg_silent; // handle exceptions, but don't display errors
1932 text = eval_to_string_safe(wp->w_p_fdt, NULL, 1931 text = eval_to_string_safe(wp->w_p_fdt, NULL,
1933 was_set_insecurely((char_u *)"foldtext", OPT_LOCAL)); 1932 was_set_insecurely((char_u *)"foldtext", OPT_LOCAL));
1934 --emsg_silent; 1933 --emsg_silent;
1935 1934
1936 if (text == NULL || did_emsg) 1935 if (text == NULL || did_emsg)
1946 if (!did_emsg && save_did_emsg) 1945 if (!did_emsg && save_did_emsg)
1947 did_emsg = save_did_emsg; 1946 did_emsg = save_did_emsg;
1948 1947
1949 if (text != NULL) 1948 if (text != NULL)
1950 { 1949 {
1951 /* Replace unprintable characters, if there are any. But 1950 // Replace unprintable characters, if there are any. But
1952 * replace a TAB with a space. */ 1951 // replace a TAB with a space.
1953 for (p = text; *p != NUL; ++p) 1952 for (p = text; *p != NUL; ++p)
1954 { 1953 {
1955 int len; 1954 int len;
1956 1955
1957 if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1) 1956 if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1)
1986 text = buf; 1985 text = buf;
1987 } 1986 }
1988 return text; 1987 return text;
1989 } 1988 }
1990 1989
1991 /* foldtext_cleanup() {{{2 */ 1990 // foldtext_cleanup() {{{2
1992 #ifdef FEAT_EVAL 1991 #ifdef FEAT_EVAL
1993 /* 1992 /*
1994 * Remove 'foldmarker' and 'commentstring' from "str" (in-place). 1993 * Remove 'foldmarker' and 'commentstring' from "str" (in-place).
1995 */ 1994 */
1996 static void 1995 static void
1997 foldtext_cleanup(char_u *str) 1996 foldtext_cleanup(char_u *str)
1998 { 1997 {
1999 char_u *cms_start; /* first part or the whole comment */ 1998 char_u *cms_start; // first part or the whole comment
2000 int cms_slen = 0; /* length of cms_start */ 1999 int cms_slen = 0; // length of cms_start
2001 char_u *cms_end; /* last part of the comment or NULL */ 2000 char_u *cms_end; // last part of the comment or NULL
2002 int cms_elen = 0; /* length of cms_end */ 2001 int cms_elen = 0; // length of cms_end
2003 char_u *s; 2002 char_u *s;
2004 char_u *p; 2003 char_u *p;
2005 int len; 2004 int len;
2006 int did1 = FALSE; 2005 int did1 = FALSE;
2007 int did2 = FALSE; 2006 int did2 = FALSE;
2008 2007
2009 /* Ignore leading and trailing white space in 'commentstring'. */ 2008 // Ignore leading and trailing white space in 'commentstring'.
2010 cms_start = skipwhite(curbuf->b_p_cms); 2009 cms_start = skipwhite(curbuf->b_p_cms);
2011 cms_slen = (int)STRLEN(cms_start); 2010 cms_slen = (int)STRLEN(cms_start);
2012 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1])) 2011 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1]))
2013 --cms_slen; 2012 --cms_slen;
2014 2013
2015 /* locate "%s" in 'commentstring', use the part before and after it. */ 2014 // locate "%s" in 'commentstring', use the part before and after it.
2016 cms_end = (char_u *)strstr((char *)cms_start, "%s"); 2015 cms_end = (char_u *)strstr((char *)cms_start, "%s");
2017 if (cms_end != NULL) 2016 if (cms_end != NULL)
2018 { 2017 {
2019 cms_elen = cms_slen - (int)(cms_end - cms_start); 2018 cms_elen = cms_slen - (int)(cms_end - cms_start);
2020 cms_slen = (int)(cms_end - cms_start); 2019 cms_slen = (int)(cms_end - cms_start);
2021 2020
2022 /* exclude white space before "%s" */ 2021 // exclude white space before "%s"
2023 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1])) 2022 while (cms_slen > 0 && VIM_ISWHITE(cms_start[cms_slen - 1]))
2024 --cms_slen; 2023 --cms_slen;
2025 2024
2026 /* skip "%s" and white space after it */ 2025 // skip "%s" and white space after it
2027 s = skipwhite(cms_end + 2); 2026 s = skipwhite(cms_end + 2);
2028 cms_elen -= (int)(s - cms_end); 2027 cms_elen -= (int)(s - cms_end);
2029 cms_end = s; 2028 cms_end = s;
2030 } 2029 }
2031 parseMarker(curwin); 2030 parseMarker(curwin);
2040 if (len > 0) 2039 if (len > 0)
2041 { 2040 {
2042 if (VIM_ISDIGIT(s[len])) 2041 if (VIM_ISDIGIT(s[len]))
2043 ++len; 2042 ++len;
2044 2043
2045 /* May remove 'commentstring' start. Useful when it's a double 2044 // May remove 'commentstring' start. Useful when it's a double
2046 * quote and we already removed a double quote. */ 2045 // quote and we already removed a double quote.
2047 for (p = s; p > str && VIM_ISWHITE(p[-1]); --p) 2046 for (p = s; p > str && VIM_ISWHITE(p[-1]); --p)
2048 ; 2047 ;
2049 if (p >= str + cms_slen 2048 if (p >= str + cms_slen
2050 && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) 2049 && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0)
2051 { 2050 {
2079 } 2078 }
2080 } 2079 }
2081 } 2080 }
2082 #endif 2081 #endif
2083 2082
2084 /* Folding by indent, expr, marker and syntax. {{{1 */ 2083 // Folding by indent, expr, marker and syntax. {{{1
2085 /* Define "fline_T", passed to get fold level for a line. {{{2 */ 2084 // Define "fline_T", passed to get fold level for a line. {{{2
2086 typedef struct 2085 typedef struct
2087 { 2086 {
2088 win_T *wp; /* window */ 2087 win_T *wp; // window
2089 linenr_T lnum; /* current line number */ 2088 linenr_T lnum; // current line number
2090 linenr_T off; /* offset between lnum and real line number */ 2089 linenr_T off; // offset between lnum and real line number
2091 linenr_T lnum_save; /* line nr used by foldUpdateIEMSRecurse() */ 2090 linenr_T lnum_save; // line nr used by foldUpdateIEMSRecurse()
2092 int lvl; /* current level (-1 for undefined) */ 2091 int lvl; // current level (-1 for undefined)
2093 int lvl_next; /* level used for next line */ 2092 int lvl_next; // level used for next line
2094 int start; /* number of folds that are forced to start at 2093 int start; // number of folds that are forced to start at
2095 this line. */ 2094 // this line.
2096 int end; /* level of fold that is forced to end below 2095 int end; // level of fold that is forced to end below
2097 this line */ 2096 // this line
2098 int had_end; /* level of fold that is forced to end above 2097 int had_end; // level of fold that is forced to end above
2099 this line (copy of "end" of prev. line) */ 2098 // this line (copy of "end" of prev. line)
2100 } fline_T; 2099 } fline_T;
2101 2100
2102 /* Flag is set when redrawing is needed. */ 2101 // Flag is set when redrawing is needed.
2103 static int fold_changed; 2102 static int fold_changed;
2104 2103
2105 /* Function declarations. {{{2 */ 2104 // Function declarations. {{{2
2106 static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, linenr_T startlnum, fline_T *flp, void (*getlevel)(fline_T *), linenr_T bot, int topflags); 2105 static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, linenr_T startlnum, fline_T *flp, void (*getlevel)(fline_T *), linenr_T bot, int topflags);
2107 static int foldInsert(garray_T *gap, int i); 2106 static int foldInsert(garray_T *gap, int i);
2108 static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot); 2107 static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot);
2109 static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot); 2108 static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot);
2110 static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2); 2109 static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2);
2114 #endif 2113 #endif
2115 static void foldlevelExpr(fline_T *flp); 2114 static void foldlevelExpr(fline_T *flp);
2116 static void foldlevelMarker(fline_T *flp); 2115 static void foldlevelMarker(fline_T *flp);
2117 static void foldlevelSyntax(fline_T *flp); 2116 static void foldlevelSyntax(fline_T *flp);
2118 2117
2119 /* foldUpdateIEMS() {{{2 */ 2118 // foldUpdateIEMS() {{{2
2120 /* 2119 /*
2121 * Update the folding for window "wp", at least from lines "top" to "bot". 2120 * Update the folding for window "wp", at least from lines "top" to "bot".
2122 * Return TRUE if any folds did change. 2121 * Return TRUE if any folds did change.
2123 */ 2122 */
2124 static void 2123 static void
2129 fline_T fline; 2128 fline_T fline;
2130 void (*getlevel)(fline_T *); 2129 void (*getlevel)(fline_T *);
2131 int level; 2130 int level;
2132 fold_T *fp; 2131 fold_T *fp;
2133 2132
2134 /* Avoid problems when being called recursively. */ 2133 // Avoid problems when being called recursively.
2135 if (invalid_top != (linenr_T)0) 2134 if (invalid_top != (linenr_T)0)
2136 return; 2135 return;
2137 2136
2138 if (wp->w_foldinvalid) 2137 if (wp->w_foldinvalid)
2139 { 2138 {
2140 /* Need to update all folds. */ 2139 // Need to update all folds.
2141 top = 1; 2140 top = 1;
2142 bot = wp->w_buffer->b_ml.ml_line_count; 2141 bot = wp->w_buffer->b_ml.ml_line_count;
2143 wp->w_foldinvalid = FALSE; 2142 wp->w_foldinvalid = FALSE;
2144 2143
2145 /* Mark all folds a maybe-small. */ 2144 // Mark all folds a maybe-small.
2146 setSmallMaybe(&wp->w_folds); 2145 setSmallMaybe(&wp->w_folds);
2147 } 2146 }
2148 2147
2149 #ifdef FEAT_DIFF 2148 #ifdef FEAT_DIFF
2150 /* add the context for "diff" folding */ 2149 // add the context for "diff" folding
2151 if (foldmethodIsDiff(wp)) 2150 if (foldmethodIsDiff(wp))
2152 { 2151 {
2153 if (top > diff_context) 2152 if (top > diff_context)
2154 top -= diff_context; 2153 top -= diff_context;
2155 else 2154 else
2156 top = 1; 2155 top = 1;
2157 bot += diff_context; 2156 bot += diff_context;
2158 } 2157 }
2159 #endif 2158 #endif
2160 2159
2161 /* When deleting lines at the end of the buffer "top" can be past the end 2160 // When deleting lines at the end of the buffer "top" can be past the end
2162 * of the buffer. */ 2161 // of the buffer.
2163 if (top > wp->w_buffer->b_ml.ml_line_count) 2162 if (top > wp->w_buffer->b_ml.ml_line_count)
2164 top = wp->w_buffer->b_ml.ml_line_count; 2163 top = wp->w_buffer->b_ml.ml_line_count;
2165 2164
2166 fold_changed = FALSE; 2165 fold_changed = FALSE;
2167 fline.wp = wp; 2166 fline.wp = wp;
2177 2176
2178 if (foldmethodIsMarker(wp)) 2177 if (foldmethodIsMarker(wp))
2179 { 2178 {
2180 getlevel = foldlevelMarker; 2179 getlevel = foldlevelMarker;
2181 2180
2182 /* Init marker variables to speed up foldlevelMarker(). */ 2181 // Init marker variables to speed up foldlevelMarker().
2183 parseMarker(wp); 2182 parseMarker(wp);
2184 2183
2185 /* Need to get the level of the line above top, it is used if there is 2184 // Need to get the level of the line above top, it is used if there is
2186 * no marker at the top. */ 2185 // no marker at the top.
2187 if (top > 1) 2186 if (top > 1)
2188 { 2187 {
2189 /* Get the fold level at top - 1. */ 2188 // Get the fold level at top - 1.
2190 level = foldLevelWin(wp, top - 1); 2189 level = foldLevelWin(wp, top - 1);
2191 2190
2192 /* The fold may end just above the top, check for that. */ 2191 // The fold may end just above the top, check for that.
2193 fline.lnum = top - 1; 2192 fline.lnum = top - 1;
2194 fline.lvl = level; 2193 fline.lvl = level;
2195 getlevel(&fline); 2194 getlevel(&fline);
2196 2195
2197 /* If a fold started here, we already had the level, if it stops 2196 // If a fold started here, we already had the level, if it stops
2198 * here, we need to use lvl_next. Could also start and end a fold 2197 // here, we need to use lvl_next. Could also start and end a fold
2199 * in the same line. */ 2198 // in the same line.
2200 if (fline.lvl > level) 2199 if (fline.lvl > level)
2201 fline.lvl = level - (fline.lvl - fline.lvl_next); 2200 fline.lvl = level - (fline.lvl - fline.lvl_next);
2202 else 2201 else
2203 fline.lvl = fline.lvl_next; 2202 fline.lvl = fline.lvl_next;
2204 } 2203 }
2209 { 2208 {
2210 fline.lnum = top; 2209 fline.lnum = top;
2211 if (foldmethodIsExpr(wp)) 2210 if (foldmethodIsExpr(wp))
2212 { 2211 {
2213 getlevel = foldlevelExpr; 2212 getlevel = foldlevelExpr;
2214 /* start one line back, because a "<1" may indicate the end of a 2213 // start one line back, because a "<1" may indicate the end of a
2215 * fold in the topline */ 2214 // fold in the topline
2216 if (top > 1) 2215 if (top > 1)
2217 --fline.lnum; 2216 --fline.lnum;
2218 } 2217 }
2219 else if (foldmethodIsSyntax(wp)) 2218 else if (foldmethodIsSyntax(wp))
2220 getlevel = foldlevelSyntax; 2219 getlevel = foldlevelSyntax;
2223 getlevel = foldlevelDiff; 2222 getlevel = foldlevelDiff;
2224 #endif 2223 #endif
2225 else 2224 else
2226 getlevel = foldlevelIndent; 2225 getlevel = foldlevelIndent;
2227 2226
2228 /* Backup to a line for which the fold level is defined. Since it's 2227 // Backup to a line for which the fold level is defined. Since it's
2229 * always defined for line one, we will stop there. */ 2228 // always defined for line one, we will stop there.
2230 fline.lvl = -1; 2229 fline.lvl = -1;
2231 for ( ; !got_int; --fline.lnum) 2230 for ( ; !got_int; --fline.lnum)
2232 { 2231 {
2233 /* Reset lvl_next each time, because it will be set to a value for 2232 // Reset lvl_next each time, because it will be set to a value for
2234 * the next line, but we search backwards here. */ 2233 // the next line, but we search backwards here.
2235 fline.lvl_next = -1; 2234 fline.lvl_next = -1;
2236 getlevel(&fline); 2235 getlevel(&fline);
2237 if (fline.lvl >= 0) 2236 if (fline.lvl >= 0)
2238 break; 2237 break;
2239 } 2238 }
2273 } 2272 }
2274 } 2273 }
2275 2274
2276 start = fline.lnum; 2275 start = fline.lnum;
2277 end = bot; 2276 end = bot;
2278 /* Do at least one line. */ 2277 // Do at least one line.
2279 if (start > end && end < wp->w_buffer->b_ml.ml_line_count) 2278 if (start > end && end < wp->w_buffer->b_ml.ml_line_count)
2280 end = start; 2279 end = start;
2281 while (!got_int) 2280 while (!got_int)
2282 { 2281 {
2283 /* Always stop at the end of the file ("end" can be past the end of 2282 // Always stop at the end of the file ("end" can be past the end of
2284 * the file). */ 2283 // the file).
2285 if (fline.lnum > wp->w_buffer->b_ml.ml_line_count) 2284 if (fline.lnum > wp->w_buffer->b_ml.ml_line_count)
2286 break; 2285 break;
2287 if (fline.lnum > end) 2286 if (fline.lnum > end)
2288 { 2287 {
2289 /* For "marker", "expr" and "syntax" methods: If a change caused 2288 // For "marker", "expr" and "syntax" methods: If a change caused
2290 * a fold to be removed, we need to continue at least until where 2289 // a fold to be removed, we need to continue at least until where
2291 * it ended. */ 2290 // it ended.
2292 if (getlevel != foldlevelMarker 2291 if (getlevel != foldlevelMarker
2293 && getlevel != foldlevelSyntax 2292 && getlevel != foldlevelSyntax
2294 && getlevel != foldlevelExpr) 2293 && getlevel != foldlevelExpr)
2295 break; 2294 break;
2296 if ((start <= end 2295 if ((start <= end
2300 && foldFind(&wp->w_folds, fline.lnum, &fp) 2299 && foldFind(&wp->w_folds, fline.lnum, &fp)
2301 && fp->fd_top < fline.lnum)) 2300 && fp->fd_top < fline.lnum))
2302 end = fp->fd_top + fp->fd_len - 1; 2301 end = fp->fd_top + fp->fd_len - 1;
2303 else if (getlevel == foldlevelSyntax 2302 else if (getlevel == foldlevelSyntax
2304 && foldLevelWin(wp, fline.lnum) != fline.lvl) 2303 && foldLevelWin(wp, fline.lnum) != fline.lvl)
2305 /* For "syntax" method: Compare the foldlevel that the syntax 2304 // For "syntax" method: Compare the foldlevel that the syntax
2306 * tells us to the foldlevel from the existing folds. If they 2305 // tells us to the foldlevel from the existing folds. If they
2307 * don't match continue updating folds. */ 2306 // don't match continue updating folds.
2308 end = fline.lnum; 2307 end = fline.lnum;
2309 else 2308 else
2310 break; 2309 break;
2311 } 2310 }
2312 2311
2313 /* A level 1 fold starts at a line with foldlevel > 0. */ 2312 // A level 1 fold starts at a line with foldlevel > 0.
2314 if (fline.lvl > 0) 2313 if (fline.lvl > 0)
2315 { 2314 {
2316 invalid_top = fline.lnum; 2315 invalid_top = fline.lnum;
2317 invalid_bot = end; 2316 invalid_bot = end;
2318 end = foldUpdateIEMSRecurse(&wp->w_folds, 2317 end = foldUpdateIEMSRecurse(&wp->w_folds,
2327 fline.lvl = fline.lvl_next; 2326 fline.lvl = fline.lvl_next;
2328 getlevel(&fline); 2327 getlevel(&fline);
2329 } 2328 }
2330 } 2329 }
2331 2330
2332 /* There can't be any folds from start until end now. */ 2331 // There can't be any folds from start until end now.
2333 foldRemove(&wp->w_folds, start, end); 2332 foldRemove(&wp->w_folds, start, end);
2334 2333
2335 /* If some fold changed, need to redraw and position cursor. */ 2334 // If some fold changed, need to redraw and position cursor.
2336 if (fold_changed && wp->w_p_fen) 2335 if (fold_changed && wp->w_p_fen)
2337 changed_window_setting_win(wp); 2336 changed_window_setting_win(wp);
2338 2337
2339 /* If we updated folds past "bot", need to redraw more lines. Don't do 2338 // If we updated folds past "bot", need to redraw more lines. Don't do
2340 * this in other situations, the changed lines will be redrawn anyway and 2339 // this in other situations, the changed lines will be redrawn anyway and
2341 * this method can cause the whole window to be updated. */ 2340 // this method can cause the whole window to be updated.
2342 if (end != bot) 2341 if (end != bot)
2343 { 2342 {
2344 if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) 2343 if (wp->w_redraw_top == 0 || wp->w_redraw_top > top)
2345 wp->w_redraw_top = top; 2344 wp->w_redraw_top = top;
2346 if (wp->w_redraw_bot < end) 2345 if (wp->w_redraw_bot < end)
2348 } 2347 }
2349 2348
2350 invalid_top = (linenr_T)0; 2349 invalid_top = (linenr_T)0;
2351 } 2350 }
2352 2351
2353 /* foldUpdateIEMSRecurse() {{{2 */ 2352 // foldUpdateIEMSRecurse() {{{2
2354 /* 2353 /*
2355 * Update a fold that starts at "flp->lnum". At this line there is always a 2354 * Update a fold that starts at "flp->lnum". At this line there is always a
2356 * valid foldlevel, and its level >= "level". 2355 * valid foldlevel, and its level >= "level".
2357 * "flp" is valid for "flp->lnum" when called and it's valid when returning. 2356 * "flp" is valid for "flp->lnum" when called and it's valid when returning.
2358 * "flp->lnum" is set to the lnum just below the fold, if it ends before 2357 * "flp->lnum" is set to the lnum just below the fold, if it ends before
2380 int level, 2379 int level,
2381 linenr_T startlnum, 2380 linenr_T startlnum,
2382 fline_T *flp, 2381 fline_T *flp,
2383 void (*getlevel)(fline_T *), 2382 void (*getlevel)(fline_T *),
2384 linenr_T bot, 2383 linenr_T bot,
2385 int topflags) /* flags used by containing fold */ 2384 int topflags) // flags used by containing fold
2386 { 2385 {
2387 linenr_T ll; 2386 linenr_T ll;
2388 fold_T *fp = NULL; 2387 fold_T *fp = NULL;
2389 fold_T *fp2; 2388 fold_T *fp2;
2390 int lvl = level; 2389 int lvl = level;
2391 linenr_T startlnum2 = startlnum; 2390 linenr_T startlnum2 = startlnum;
2392 linenr_T firstlnum = flp->lnum; /* first lnum we got */ 2391 linenr_T firstlnum = flp->lnum; // first lnum we got
2393 int i; 2392 int i;
2394 int finish = FALSE; 2393 int finish = FALSE;
2395 linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off; 2394 linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
2396 int concat; 2395 int concat;
2397 2396
2422 * valid, thus "flp->lnum_save" is equal to "flp->lnum". 2421 * valid, thus "flp->lnum_save" is equal to "flp->lnum".
2423 */ 2422 */
2424 flp->lnum_save = flp->lnum; 2423 flp->lnum_save = flp->lnum;
2425 while (!got_int) 2424 while (!got_int)
2426 { 2425 {
2427 /* Updating folds can be slow, check for CTRL-C. */ 2426 // Updating folds can be slow, check for CTRL-C.
2428 line_breakcheck(); 2427 line_breakcheck();
2429 2428
2430 /* Set "lvl" to the level of line "flp->lnum". When flp->start is set 2429 // Set "lvl" to the level of line "flp->lnum". When flp->start is set
2431 * and after the first line of the fold, set the level to zero to 2430 // and after the first line of the fold, set the level to zero to
2432 * force the fold to end. Do the same when had_end is set: Previous 2431 // force the fold to end. Do the same when had_end is set: Previous
2433 * line was marked as end of a fold. */ 2432 // line was marked as end of a fold.
2434 lvl = flp->lvl; 2433 lvl = flp->lvl;
2435 if (lvl > MAX_LEVEL) 2434 if (lvl > MAX_LEVEL)
2436 lvl = MAX_LEVEL; 2435 lvl = MAX_LEVEL;
2437 if (flp->lnum > firstlnum 2436 if (flp->lnum > firstlnum
2438 && (level > lvl - flp->start || level >= flp->had_end)) 2437 && (level > lvl - flp->start || level >= flp->had_end))
2439 lvl = 0; 2438 lvl = 0;
2440 2439
2441 if (flp->lnum > bot && !finish && fp != NULL) 2440 if (flp->lnum > bot && !finish && fp != NULL)
2442 { 2441 {
2443 /* For "marker" and "syntax" methods: 2442 // For "marker" and "syntax" methods:
2444 * - If a change caused a nested fold to be removed, we need to 2443 // - If a change caused a nested fold to be removed, we need to
2445 * delete it and continue at least until where it ended. 2444 // delete it and continue at least until where it ended.
2446 * - If a change caused a nested fold to be created, or this fold 2445 // - If a change caused a nested fold to be created, or this fold
2447 * to continue below its original end, need to finish this fold. 2446 // to continue below its original end, need to finish this fold.
2448 */
2449 if (getlevel != foldlevelMarker 2447 if (getlevel != foldlevelMarker
2450 && getlevel != foldlevelExpr 2448 && getlevel != foldlevelExpr
2451 && getlevel != foldlevelSyntax) 2449 && getlevel != foldlevelSyntax)
2452 break; 2450 break;
2453 i = 0; 2451 i = 0;
2454 fp2 = fp; 2452 fp2 = fp;
2455 if (lvl >= level) 2453 if (lvl >= level)
2456 { 2454 {
2457 /* Compute how deep the folds currently are, if it's deeper 2455 // Compute how deep the folds currently are, if it's deeper
2458 * than "lvl" then some must be deleted, need to update 2456 // than "lvl" then some must be deleted, need to update
2459 * at least one nested fold. */ 2457 // at least one nested fold.
2460 ll = flp->lnum - fp->fd_top; 2458 ll = flp->lnum - fp->fd_top;
2461 while (foldFind(&fp2->fd_nested, ll, &fp2)) 2459 while (foldFind(&fp2->fd_nested, ll, &fp2))
2462 { 2460 {
2463 ++i; 2461 ++i;
2464 ll -= fp2->fd_top; 2462 ll -= fp2->fd_top;
2474 finish = TRUE; 2472 finish = TRUE;
2475 else 2473 else
2476 break; 2474 break;
2477 } 2475 }
2478 2476
2479 /* At the start of the first nested fold and at the end of the current 2477 // At the start of the first nested fold and at the end of the current
2480 * fold: check if existing folds at this level, before the current 2478 // fold: check if existing folds at this level, before the current
2481 * one, need to be deleted or truncated. */ 2479 // one, need to be deleted or truncated.
2482 if (fp == NULL 2480 if (fp == NULL
2483 && (lvl != level 2481 && (lvl != level
2484 || flp->lnum_save >= bot 2482 || flp->lnum_save >= bot
2485 || flp->start != 0 2483 || flp->start != 0
2486 || flp->had_end <= MAX_LEVEL 2484 || flp->had_end <= MAX_LEVEL
2490 * Remove or update folds that have lines between startlnum and 2488 * Remove or update folds that have lines between startlnum and
2491 * firstlnum. 2489 * firstlnum.
2492 */ 2490 */
2493 while (!got_int) 2491 while (!got_int)
2494 { 2492 {
2495 /* set concat to 1 if it's allowed to concatenated this fold 2493 // set concat to 1 if it's allowed to concatenated this fold
2496 * with a previous one that touches it. */ 2494 // with a previous one that touches it.
2497 if (flp->start != 0 || flp->had_end <= MAX_LEVEL) 2495 if (flp->start != 0 || flp->had_end <= MAX_LEVEL)
2498 concat = 0; 2496 concat = 0;
2499 else 2497 else
2500 concat = 1; 2498 concat = 1;
2501 2499
2502 /* Find an existing fold to re-use. Preferably one that 2500 // Find an existing fold to re-use. Preferably one that
2503 * includes startlnum, otherwise one that ends just before 2501 // includes startlnum, otherwise one that ends just before
2504 * startlnum or starts after it. */ 2502 // startlnum or starts after it.
2505 if (foldFind(gap, startlnum, &fp) 2503 if (foldFind(gap, startlnum, &fp)
2506 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len 2504 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len
2507 && fp->fd_top <= firstlnum) 2505 && fp->fd_top <= firstlnum)
2508 || foldFind(gap, firstlnum - concat, &fp) 2506 || foldFind(gap, firstlnum - concat, &fp)
2509 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len 2507 || (fp < ((fold_T *)gap->ga_data) + gap->ga_len
2511 || (lvl >= level 2509 || (lvl >= level
2512 && fp->fd_top <= flp->lnum_save)))) 2510 && fp->fd_top <= flp->lnum_save))))
2513 { 2511 {
2514 if (fp->fd_top + fp->fd_len + concat > firstlnum) 2512 if (fp->fd_top + fp->fd_len + concat > firstlnum)
2515 { 2513 {
2516 /* Use existing fold for the new fold. If it starts 2514 // Use existing fold for the new fold. If it starts
2517 * before where we started looking, extend it. If it 2515 // before where we started looking, extend it. If it
2518 * starts at another line, update nested folds to keep 2516 // starts at another line, update nested folds to keep
2519 * their position, compensating for the new fd_top. */ 2517 // their position, compensating for the new fd_top.
2520 if (fp->fd_top == firstlnum) 2518 if (fp->fd_top == firstlnum)
2521 { 2519 {
2522 /* have found a fold beginning where we want */ 2520 // have found a fold beginning where we want
2523 } 2521 }
2524 else if (fp->fd_top >= startlnum) 2522 else if (fp->fd_top >= startlnum)
2525 { 2523 {
2526 if (fp->fd_top > firstlnum) 2524 if (fp->fd_top > firstlnum)
2527 /* like lines are inserted */ 2525 // like lines are inserted
2528 foldMarkAdjustRecurse(&fp->fd_nested, 2526 foldMarkAdjustRecurse(&fp->fd_nested,
2529 (linenr_T)0, (linenr_T)MAXLNUM, 2527 (linenr_T)0, (linenr_T)MAXLNUM,
2530 (long)(fp->fd_top - firstlnum), 0L); 2528 (long)(fp->fd_top - firstlnum), 0L);
2531 else 2529 else
2532 /* like lines are deleted */ 2530 // like lines are deleted
2533 foldMarkAdjustRecurse(&fp->fd_nested, 2531 foldMarkAdjustRecurse(&fp->fd_nested,
2534 (linenr_T)0, 2532 (linenr_T)0,
2535 (long)(firstlnum - fp->fd_top - 1), 2533 (long)(firstlnum - fp->fd_top - 1),
2536 (linenr_T)MAXLNUM, 2534 (linenr_T)MAXLNUM,
2537 (long)(fp->fd_top - firstlnum)); 2535 (long)(fp->fd_top - firstlnum));
2575 breakend - fp->fd_top); 2573 breakend - fp->fd_top);
2576 i = (int)(fp - (fold_T *)gap->ga_data); 2574 i = (int)(fp - (fold_T *)gap->ga_data);
2577 foldSplit(gap, i, breakstart, breakend - 1); 2575 foldSplit(gap, i, breakstart, breakend - 1);
2578 fp = (fold_T *)gap->ga_data + i + 1; 2576 fp = (fold_T *)gap->ga_data + i + 1;
2579 2577
2580 /* If using the "marker" or "syntax" method, we 2578 // If using the "marker" or "syntax" method, we
2581 * need to continue until the end of the fold is 2579 // need to continue until the end of the fold is
2582 * found. */ 2580 // found.
2583 if (getlevel == foldlevelMarker 2581 if (getlevel == foldlevelMarker
2584 || getlevel == foldlevelExpr 2582 || getlevel == foldlevelExpr
2585 || getlevel == foldlevelSyntax) 2583 || getlevel == foldlevelSyntax)
2586 finish = TRUE; 2584 finish = TRUE;
2587 } 2585 }
2601 } 2599 }
2602 break; 2600 break;
2603 } 2601 }
2604 if (fp->fd_top >= startlnum) 2602 if (fp->fd_top >= startlnum)
2605 { 2603 {
2606 /* A fold that starts at or after startlnum and stops 2604 // A fold that starts at or after startlnum and stops
2607 * before the new fold must be deleted. Continue 2605 // before the new fold must be deleted. Continue
2608 * looking for the next one. */ 2606 // looking for the next one.
2609 deleteFoldEntry(gap, 2607 deleteFoldEntry(gap,
2610 (int)(fp - (fold_T *)gap->ga_data), TRUE); 2608 (int)(fp - (fold_T *)gap->ga_data), TRUE);
2611 } 2609 }
2612 else 2610 else
2613 { 2611 {
2614 /* A fold has some lines above startlnum, truncate it 2612 // A fold has some lines above startlnum, truncate it
2615 * to stop just above startlnum. */ 2613 // to stop just above startlnum.
2616 fp->fd_len = startlnum - fp->fd_top; 2614 fp->fd_len = startlnum - fp->fd_top;
2617 foldMarkAdjustRecurse(&fp->fd_nested, 2615 foldMarkAdjustRecurse(&fp->fd_nested,
2618 (linenr_T)fp->fd_len, (linenr_T)MAXLNUM, 2616 (linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
2619 (linenr_T)MAXLNUM, 0L); 2617 (linenr_T)MAXLNUM, 0L);
2620 fold_changed = TRUE; 2618 fold_changed = TRUE;
2621 } 2619 }
2622 } 2620 }
2623 else 2621 else
2624 { 2622 {
2625 /* Insert new fold. Careful: ga_data may be NULL and it 2623 // Insert new fold. Careful: ga_data may be NULL and it
2626 * may change! */ 2624 // may change!
2627 i = (int)(fp - (fold_T *)gap->ga_data); 2625 i = (int)(fp - (fold_T *)gap->ga_data);
2628 if (foldInsert(gap, i) != OK) 2626 if (foldInsert(gap, i) != OK)
2629 return bot; 2627 return bot;
2630 fp = (fold_T *)gap->ga_data + i; 2628 fp = (fold_T *)gap->ga_data + i;
2631 /* The new fold continues until bot, unless we find the 2629 // The new fold continues until bot, unless we find the
2632 * end earlier. */ 2630 // end earlier.
2633 fp->fd_top = firstlnum; 2631 fp->fd_top = firstlnum;
2634 fp->fd_len = bot - firstlnum + 1; 2632 fp->fd_len = bot - firstlnum + 1;
2635 /* When the containing fold is open, the new fold is open. 2633 // When the containing fold is open, the new fold is open.
2636 * The new fold is closed if the fold above it is closed. 2634 // The new fold is closed if the fold above it is closed.
2637 * The first fold depends on the containing fold. */ 2635 // The first fold depends on the containing fold.
2638 if (topflags == FD_OPEN) 2636 if (topflags == FD_OPEN)
2639 { 2637 {
2640 flp->wp->w_fold_manual = TRUE; 2638 flp->wp->w_fold_manual = TRUE;
2641 fp->fd_flags = FD_OPEN; 2639 fp->fd_flags = FD_OPEN;
2642 } 2640 }
2647 flp->wp->w_fold_manual = TRUE; 2645 flp->wp->w_fold_manual = TRUE;
2648 } 2646 }
2649 else 2647 else
2650 fp->fd_flags = (fp - 1)->fd_flags; 2648 fp->fd_flags = (fp - 1)->fd_flags;
2651 fp->fd_small = MAYBE; 2649 fp->fd_small = MAYBE;
2652 /* If using the "marker", "expr" or "syntax" method, we 2650 // If using the "marker", "expr" or "syntax" method, we
2653 * need to continue until the end of the fold is found. */ 2651 // need to continue until the end of the fold is found.
2654 if (getlevel == foldlevelMarker 2652 if (getlevel == foldlevelMarker
2655 || getlevel == foldlevelExpr 2653 || getlevel == foldlevelExpr
2656 || getlevel == foldlevelSyntax) 2654 || getlevel == foldlevelSyntax)
2657 finish = TRUE; 2655 finish = TRUE;
2658 fold_changed = TRUE; 2656 fold_changed = TRUE;
2677 if (lvl > level && fp != NULL) 2675 if (lvl > level && fp != NULL)
2678 { 2676 {
2679 /* 2677 /*
2680 * There is a nested fold, handle it recursively. 2678 * There is a nested fold, handle it recursively.
2681 */ 2679 */
2682 /* At least do one line (can happen when finish is TRUE). */ 2680 // At least do one line (can happen when finish is TRUE).
2683 if (bot < flp->lnum) 2681 if (bot < flp->lnum)
2684 bot = flp->lnum; 2682 bot = flp->lnum;
2685 2683
2686 /* Line numbers in the nested fold are relative to the start of 2684 // Line numbers in the nested fold are relative to the start of
2687 * this fold. */ 2685 // this fold.
2688 flp->lnum = flp->lnum_save - fp->fd_top; 2686 flp->lnum = flp->lnum_save - fp->fd_top;
2689 flp->off += fp->fd_top; 2687 flp->off += fp->fd_top;
2690 i = (int)(fp - (fold_T *)gap->ga_data); 2688 i = (int)(fp - (fold_T *)gap->ga_data);
2691 bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1, 2689 bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1,
2692 startlnum2 - fp->fd_top, flp, getlevel, 2690 startlnum2 - fp->fd_top, flp, getlevel,
2696 flp->lnum_save += fp->fd_top; 2694 flp->lnum_save += fp->fd_top;
2697 flp->off -= fp->fd_top; 2695 flp->off -= fp->fd_top;
2698 bot += fp->fd_top; 2696 bot += fp->fd_top;
2699 startlnum2 = flp->lnum; 2697 startlnum2 = flp->lnum;
2700 2698
2701 /* This fold may end at the same line, don't incr. flp->lnum. */ 2699 // This fold may end at the same line, don't incr. flp->lnum.
2702 } 2700 }
2703 else 2701 else
2704 { 2702 {
2705 /* 2703 /*
2706 * Get the level of the next line, then continue the loop to check 2704 * Get the level of the next line, then continue the loop to check
2710 */ 2708 */
2711 flp->lnum = flp->lnum_save; 2709 flp->lnum = flp->lnum_save;
2712 ll = flp->lnum + 1; 2710 ll = flp->lnum + 1;
2713 while (!got_int) 2711 while (!got_int)
2714 { 2712 {
2715 /* Make the previous level available to foldlevel(). */ 2713 // Make the previous level available to foldlevel().
2716 prev_lnum = flp->lnum; 2714 prev_lnum = flp->lnum;
2717 prev_lnum_lvl = flp->lvl; 2715 prev_lnum_lvl = flp->lvl;
2718 2716
2719 if (++flp->lnum > linecount) 2717 if (++flp->lnum > linecount)
2720 break; 2718 break;
2725 } 2723 }
2726 prev_lnum = 0; 2724 prev_lnum = 0;
2727 if (flp->lnum > linecount) 2725 if (flp->lnum > linecount)
2728 break; 2726 break;
2729 2727
2730 /* leave flp->lnum_save to lnum of the line that was used to get 2728 // leave flp->lnum_save to lnum of the line that was used to get
2731 * the level, flp->lnum to the lnum of the next line. */ 2729 // the level, flp->lnum to the lnum of the next line.
2732 flp->lnum_save = flp->lnum; 2730 flp->lnum_save = flp->lnum;
2733 flp->lnum = ll; 2731 flp->lnum = ll;
2734 } 2732 }
2735 } 2733 }
2736 2734
2737 if (fp == NULL) /* only happens when got_int is set */ 2735 if (fp == NULL) // only happens when got_int is set
2738 return bot; 2736 return bot;
2739 2737
2740 /* 2738 /*
2741 * Get here when: 2739 * Get here when:
2742 * lvl < level: the folds ends just above "flp->lnum" 2740 * lvl < level: the folds ends just above "flp->lnum"
2759 foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top, 2757 foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top,
2760 flp->lnum - 1 - fp->fd_top); 2758 flp->lnum - 1 - fp->fd_top);
2761 2759
2762 if (lvl < level) 2760 if (lvl < level)
2763 { 2761 {
2764 /* End of fold found, update the length when it got shorter. */ 2762 // End of fold found, update the length when it got shorter.
2765 if (fp->fd_len != flp->lnum - fp->fd_top) 2763 if (fp->fd_len != flp->lnum - fp->fd_top)
2766 { 2764 {
2767 if (fp->fd_top + fp->fd_len - 1 > bot) 2765 if (fp->fd_top + fp->fd_len - 1 > bot)
2768 { 2766 {
2769 /* fold continued below bot */ 2767 // fold continued below bot
2770 if (getlevel == foldlevelMarker 2768 if (getlevel == foldlevelMarker
2771 || getlevel == foldlevelExpr 2769 || getlevel == foldlevelExpr
2772 || getlevel == foldlevelSyntax) 2770 || getlevel == foldlevelSyntax)
2773 { 2771 {
2774 /* marker method: truncate the fold and make sure the 2772 // marker method: truncate the fold and make sure the
2775 * previously included lines are processed again */ 2773 // previously included lines are processed again
2776 bot = fp->fd_top + fp->fd_len - 1; 2774 bot = fp->fd_top + fp->fd_len - 1;
2777 fp->fd_len = flp->lnum - fp->fd_top; 2775 fp->fd_len = flp->lnum - fp->fd_top;
2778 } 2776 }
2779 else 2777 else
2780 { 2778 {
2781 /* indent or expr method: split fold to create a new one 2779 // indent or expr method: split fold to create a new one
2782 * below bot */ 2780 // below bot
2783 i = (int)(fp - (fold_T *)gap->ga_data); 2781 i = (int)(fp - (fold_T *)gap->ga_data);
2784 foldSplit(gap, i, flp->lnum, bot); 2782 foldSplit(gap, i, flp->lnum, bot);
2785 fp = (fold_T *)gap->ga_data + i; 2783 fp = (fold_T *)gap->ga_data + i;
2786 } 2784 }
2787 } 2785 }
2789 fp->fd_len = flp->lnum - fp->fd_top; 2787 fp->fd_len = flp->lnum - fp->fd_top;
2790 fold_changed = TRUE; 2788 fold_changed = TRUE;
2791 } 2789 }
2792 } 2790 }
2793 2791
2794 /* delete following folds that end before the current line */ 2792 // delete following folds that end before the current line
2795 for (;;) 2793 for (;;)
2796 { 2794 {
2797 fp2 = fp + 1; 2795 fp2 = fp + 1;
2798 if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len 2796 if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len
2799 || fp2->fd_top > flp->lnum) 2797 || fp2->fd_top > flp->lnum)
2800 break; 2798 break;
2801 if (fp2->fd_top + fp2->fd_len > flp->lnum) 2799 if (fp2->fd_top + fp2->fd_len > flp->lnum)
2802 { 2800 {
2803 if (fp2->fd_top < flp->lnum) 2801 if (fp2->fd_top < flp->lnum)
2804 { 2802 {
2805 /* Make fold that includes lnum start at lnum. */ 2803 // Make fold that includes lnum start at lnum.
2806 foldMarkAdjustRecurse(&fp2->fd_nested, 2804 foldMarkAdjustRecurse(&fp2->fd_nested,
2807 (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1), 2805 (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1),
2808 (linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum)); 2806 (linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum));
2809 fp2->fd_len -= flp->lnum - fp2->fd_top; 2807 fp2->fd_len -= flp->lnum - fp2->fd_top;
2810 fp2->fd_top = flp->lnum; 2808 fp2->fd_top = flp->lnum;
2811 fold_changed = TRUE; 2809 fold_changed = TRUE;
2812 } 2810 }
2813 2811
2814 if (lvl >= level) 2812 if (lvl >= level)
2815 { 2813 {
2816 /* merge new fold with existing fold that follows */ 2814 // merge new fold with existing fold that follows
2817 foldMerge(fp, gap, fp2); 2815 foldMerge(fp, gap, fp2);
2818 } 2816 }
2819 break; 2817 break;
2820 } 2818 }
2821 fold_changed = TRUE; 2819 fold_changed = TRUE;
2822 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); 2820 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
2823 } 2821 }
2824 2822
2825 /* Need to redraw the lines we inspected, which might be further down than 2823 // Need to redraw the lines we inspected, which might be further down than
2826 * was asked for. */ 2824 // was asked for.
2827 if (bot < flp->lnum - 1) 2825 if (bot < flp->lnum - 1)
2828 bot = flp->lnum - 1; 2826 bot = flp->lnum - 1;
2829 2827
2830 return bot; 2828 return bot;
2831 } 2829 }
2832 2830
2833 /* foldInsert() {{{2 */ 2831 // foldInsert() {{{2
2834 /* 2832 /*
2835 * Insert a new fold in "gap" at position "i". 2833 * Insert a new fold in "gap" at position "i".
2836 * Returns OK for success, FAIL for failure. 2834 * Returns OK for success, FAIL for failure.
2837 */ 2835 */
2838 static int 2836 static int
2848 ++gap->ga_len; 2846 ++gap->ga_len;
2849 ga_init2(&fp->fd_nested, (int)sizeof(fold_T), 10); 2847 ga_init2(&fp->fd_nested, (int)sizeof(fold_T), 10);
2850 return OK; 2848 return OK;
2851 } 2849 }
2852 2850
2853 /* foldSplit() {{{2 */ 2851 // foldSplit() {{{2
2854 /* 2852 /*
2855 * Split the "i"th fold in "gap", which starts before "top" and ends below 2853 * Split the "i"th fold in "gap", which starts before "top" and ends below
2856 * "bot" in two pieces, one ending above "top" and the other starting below 2854 * "bot" in two pieces, one ending above "top" and the other starting below
2857 * "bot". 2855 * "bot".
2858 * The caller must first have taken care of any nested folds from "top" to 2856 * The caller must first have taken care of any nested folds from "top" to
2870 garray_T *gap1; 2868 garray_T *gap1;
2871 garray_T *gap2; 2869 garray_T *gap2;
2872 int idx; 2870 int idx;
2873 int len; 2871 int len;
2874 2872
2875 /* The fold continues below bot, need to split it. */ 2873 // The fold continues below bot, need to split it.
2876 if (foldInsert(gap, i + 1) == FAIL) 2874 if (foldInsert(gap, i + 1) == FAIL)
2877 return; 2875 return;
2878 fp = (fold_T *)gap->ga_data + i; 2876 fp = (fold_T *)gap->ga_data + i;
2879 fp[1].fd_top = bot + 1; 2877 fp[1].fd_top = bot + 1;
2880 fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top); 2878 fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top);
2881 fp[1].fd_flags = fp->fd_flags; 2879 fp[1].fd_flags = fp->fd_flags;
2882 fp[1].fd_small = MAYBE; 2880 fp[1].fd_small = MAYBE;
2883 fp->fd_small = MAYBE; 2881 fp->fd_small = MAYBE;
2884 2882
2885 /* Move nested folds below bot to new fold. There can't be 2883 // Move nested folds below bot to new fold. There can't be
2886 * any between top and bot, they have been removed by the caller. */ 2884 // any between top and bot, they have been removed by the caller.
2887 gap1 = &fp->fd_nested; 2885 gap1 = &fp->fd_nested;
2888 gap2 = &fp[1].fd_nested; 2886 gap2 = &fp[1].fd_nested;
2889 (void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2)); 2887 (void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2));
2890 len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2); 2888 len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
2891 if (len > 0 && ga_grow(gap2, len) == OK) 2889 if (len > 0 && ga_grow(gap2, len) == OK)
2901 } 2899 }
2902 fp->fd_len = top - fp->fd_top; 2900 fp->fd_len = top - fp->fd_top;
2903 fold_changed = TRUE; 2901 fold_changed = TRUE;
2904 } 2902 }
2905 2903
2906 /* foldRemove() {{{2 */ 2904 // foldRemove() {{{2
2907 /* 2905 /*
2908 * Remove folds within the range "top" to and including "bot". 2906 * Remove folds within the range "top" to and including "bot".
2909 * Check for these situations: 2907 * Check for these situations:
2910 * 1 2 3 2908 * 1 2 3
2911 * 1 2 3 2909 * 1 2 3
2926 foldRemove(garray_T *gap, linenr_T top, linenr_T bot) 2924 foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
2927 { 2925 {
2928 fold_T *fp = NULL; 2926 fold_T *fp = NULL;
2929 2927
2930 if (bot < top) 2928 if (bot < top)
2931 return; /* nothing to do */ 2929 return; // nothing to do
2932 2930
2933 for (;;) 2931 for (;;)
2934 { 2932 {
2935 /* Find fold that includes top or a following one. */ 2933 // Find fold that includes top or a following one.
2936 if (foldFind(gap, top, &fp) && fp->fd_top < top) 2934 if (foldFind(gap, top, &fp) && fp->fd_top < top)
2937 { 2935 {
2938 /* 2: or 3: need to delete nested folds */ 2936 // 2: or 3: need to delete nested folds
2939 foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top); 2937 foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
2940 if (fp->fd_top + fp->fd_len - 1 > bot) 2938 if (fp->fd_top + fp->fd_len - 1 > bot)
2941 { 2939 {
2942 /* 3: need to split it. */ 2940 // 3: need to split it.
2943 foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot); 2941 foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
2944 } 2942 }
2945 else 2943 else
2946 { 2944 {
2947 /* 2: truncate fold at "top". */ 2945 // 2: truncate fold at "top".
2948 fp->fd_len = top - fp->fd_top; 2946 fp->fd_len = top - fp->fd_top;
2949 } 2947 }
2950 fold_changed = TRUE; 2948 fold_changed = TRUE;
2951 continue; 2949 continue;
2952 } 2950 }
2953 if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len 2951 if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len
2954 || fp->fd_top > bot) 2952 || fp->fd_top > bot)
2955 { 2953 {
2956 /* 6: Found a fold below bot, can stop looking. */ 2954 // 6: Found a fold below bot, can stop looking.
2957 break; 2955 break;
2958 } 2956 }
2959 if (fp->fd_top >= top) 2957 if (fp->fd_top >= top)
2960 { 2958 {
2961 /* Found an entry below top. */ 2959 // Found an entry below top.
2962 fold_changed = TRUE; 2960 fold_changed = TRUE;
2963 if (fp->fd_top + fp->fd_len - 1 > bot) 2961 if (fp->fd_top + fp->fd_len - 1 > bot)
2964 { 2962 {
2965 /* 5: Make fold that includes bot start below bot. */ 2963 // 5: Make fold that includes bot start below bot.
2966 foldMarkAdjustRecurse(&fp->fd_nested, 2964 foldMarkAdjustRecurse(&fp->fd_nested,
2967 (linenr_T)0, (long)(bot - fp->fd_top), 2965 (linenr_T)0, (long)(bot - fp->fd_top),
2968 (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1)); 2966 (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
2969 fp->fd_len -= bot - fp->fd_top + 1; 2967 fp->fd_len -= bot - fp->fd_top + 1;
2970 fp->fd_top = bot + 1; 2968 fp->fd_top = bot + 1;
2971 break; 2969 break;
2972 } 2970 }
2973 2971
2974 /* 4: Delete completely contained fold. */ 2972 // 4: Delete completely contained fold.
2975 deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE); 2973 deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE);
2976 } 2974 }
2977 } 2975 }
2978 } 2976 }
2979 2977
2980 /* foldReverseOrder() {{{2 */ 2978 // foldReverseOrder() {{{2
2981 static void 2979 static void
2982 foldReverseOrder(garray_T *gap, linenr_T start_arg, linenr_T end_arg) 2980 foldReverseOrder(garray_T *gap, linenr_T start_arg, linenr_T end_arg)
2983 { 2981 {
2984 fold_T *left, *right; 2982 fold_T *left, *right;
2985 fold_T tmp; 2983 fold_T tmp;
2994 *left = *right; 2992 *left = *right;
2995 *right = tmp; 2993 *right = tmp;
2996 } 2994 }
2997 } 2995 }
2998 2996
2999 /* foldMoveRange() {{{2 */ 2997 // foldMoveRange() {{{2
3000 /* 2998 /*
3001 * Move folds within the inclusive range "line1" to "line2" to after "dest" 2999 * Move folds within the inclusive range "line1" to "line2" to after "dest"
3002 * requires "line1" <= "line2" <= "dest" 3000 * requires "line1" <= "line2" <= "dest"
3003 * 3001 *
3004 * There are the following situations for the first fold at or below line1 - 1. 3002 * There are the following situations for the first fold at or below line1 - 1.
3052 3050
3053 if (at_start) 3051 if (at_start)
3054 { 3052 {
3055 if (fold_end(fp) > dest) 3053 if (fold_end(fp) > dest)
3056 { 3054 {
3057 /* Case 4 3055 // Case 4
3058 * don't have to change this fold, but have to move nested folds. 3056 // don't have to change this fold, but have to move nested folds.
3059 */
3060 foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 - 3057 foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 -
3061 fp->fd_top, dest - fp->fd_top); 3058 fp->fd_top, dest - fp->fd_top);
3062 return; 3059 return;
3063 } 3060 }
3064 else if (fold_end(fp) > line2) 3061 else if (fold_end(fp) > line2)
3065 { 3062 {
3066 /* Case 3 3063 // Case 3
3067 * Remove nested folds between line1 and line2 & reduce the 3064 // Remove nested folds between line1 and line2 & reduce the
3068 * length of fold by "range_len". 3065 // length of fold by "range_len".
3069 * Folds after this one must be dealt with. 3066 // Folds after this one must be dealt with.
3070 */
3071 foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, line2 - 3067 foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top, line2 -
3072 fp->fd_top, MAXLNUM, -range_len); 3068 fp->fd_top, MAXLNUM, -range_len);
3073 fp->fd_len -= range_len; 3069 fp->fd_len -= range_len;
3074 } 3070 }
3075 else 3071 else
3076 /* Case 2 truncate fold, folds after this one must be dealt with. */ 3072 // Case 2 truncate fold, folds after this one must be dealt with.
3077 truncate_fold(fp, line1 - 1); 3073 truncate_fold(fp, line1 - 1);
3078 3074
3079 /* Look at the next fold, and treat that one as if it were the first 3075 // Look at the next fold, and treat that one as if it were the first
3080 * after "line1" (because now it is). */ 3076 // after "line1" (because now it is).
3081 fp = fp + 1; 3077 fp = fp + 1;
3082 } 3078 }
3083 3079
3084 if (!valid_fold(fp, gap) || fp->fd_top > dest) 3080 if (!valid_fold(fp, gap) || fp->fd_top > dest)
3085 { 3081 {
3086 /* Case 10 3082 // Case 10
3087 * No folds after "line1" and before "dest" 3083 // No folds after "line1" and before "dest"
3088 */
3089 return; 3084 return;
3090 } 3085 }
3091 else if (fp->fd_top > line2) 3086 else if (fp->fd_top > line2)
3092 { 3087 {
3093 for (; valid_fold(fp, gap) && fold_end(fp) <= dest; fp++) 3088 for (; valid_fold(fp, gap) && fold_end(fp) <= dest; fp++)
3094 /* Case 9. (for all case 9's) -- shift up. */ 3089 // Case 9. (for all case 9's) -- shift up.
3095 fp->fd_top -= range_len; 3090 fp->fd_top -= range_len;
3096 3091
3097 if (valid_fold(fp, gap) && fp->fd_top <= dest) 3092 if (valid_fold(fp, gap) && fp->fd_top <= dest)
3098 { 3093 {
3099 /* Case 8. -- ensure truncated at dest, shift up */ 3094 // Case 8. -- ensure truncated at dest, shift up
3100 truncate_fold(fp, dest); 3095 truncate_fold(fp, dest);
3101 fp->fd_top -= range_len; 3096 fp->fd_top -= range_len;
3102 } 3097 }
3103 return; 3098 return;
3104 } 3099 }
3105 else if (fold_end(fp) > dest) 3100 else if (fold_end(fp) > dest)
3106 { 3101 {
3107 /* Case 7 -- remove nested folds and shrink */ 3102 // Case 7 -- remove nested folds and shrink
3108 foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top, dest - 3103 foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top, dest -
3109 fp->fd_top, MAXLNUM, -move_len); 3104 fp->fd_top, MAXLNUM, -move_len);
3110 fp->fd_len -= move_len; 3105 fp->fd_len -= move_len;
3111 fp->fd_top += move_len; 3106 fp->fd_top += move_len;
3112 return; 3107 return;
3113 } 3108 }
3114 3109
3115 /* Case 5 or 6 3110 // Case 5 or 6
3116 * changes rely on whether there are folds between the end of 3111 // changes rely on whether there are folds between the end of
3117 * this fold and "dest". 3112 // this fold and "dest".
3118 */
3119 move_start = fold_index(fp, gap); 3113 move_start = fold_index(fp, gap);
3120 3114
3121 for (; valid_fold(fp, gap) && fp->fd_top <= dest; fp++) 3115 for (; valid_fold(fp, gap) && fp->fd_top <= dest; fp++)
3122 { 3116 {
3123 if (fp->fd_top <= line2) 3117 if (fp->fd_top <= line2)
3124 { 3118 {
3125 /* 1. 2. or 3. */ 3119 // 1. 2. or 3.
3126 if (fold_end(fp) > line2) 3120 if (fold_end(fp) > line2)
3127 /* 2. or 3., truncate before moving */ 3121 // 2. or 3., truncate before moving
3128 truncate_fold(fp, line2); 3122 truncate_fold(fp, line2);
3129 3123
3130 fp->fd_top += move_len; 3124 fp->fd_top += move_len;
3131 continue; 3125 continue;
3132 } 3126 }
3133 3127
3134 /* Record index of the first fold after the moved range. */ 3128 // Record index of the first fold after the moved range.
3135 if (move_end == 0) 3129 if (move_end == 0)
3136 move_end = fold_index(fp, gap); 3130 move_end = fold_index(fp, gap);
3137 3131
3138 if (fold_end(fp) > dest) 3132 if (fold_end(fp) > dest)
3139 truncate_fold(fp, dest); 3133 truncate_fold(fp, dest);
3147 * All folds are now correct, but not necessarily in the correct order. We 3141 * All folds are now correct, but not necessarily in the correct order. We
3148 * must swap folds in the range [move_end, dest_index) with those in the 3142 * must swap folds in the range [move_end, dest_index) with those in the
3149 * range [move_start, move_end). 3143 * range [move_start, move_end).
3150 */ 3144 */
3151 if (move_end == 0) 3145 if (move_end == 0)
3152 /* There are no folds after those moved, hence no folds have been moved 3146 // There are no folds after those moved, hence no folds have been moved
3153 * out of order. */ 3147 // out of order.
3154 return; 3148 return;
3155 foldReverseOrder(gap, (linenr_T)move_start, (linenr_T)dest_index - 1); 3149 foldReverseOrder(gap, (linenr_T)move_start, (linenr_T)dest_index - 1);
3156 foldReverseOrder(gap, (linenr_T)move_start, 3150 foldReverseOrder(gap, (linenr_T)move_start,
3157 (linenr_T)(move_start + dest_index - move_end - 1)); 3151 (linenr_T)(move_start + dest_index - move_end - 1));
3158 foldReverseOrder(gap, (linenr_T)(move_start + dest_index - move_end), 3152 foldReverseOrder(gap, (linenr_T)(move_start + dest_index - move_end),
3160 } 3154 }
3161 #undef fold_end 3155 #undef fold_end
3162 #undef valid_fold 3156 #undef valid_fold
3163 #undef fold_index 3157 #undef fold_index
3164 3158
3165 /* foldMerge() {{{2 */ 3159 // foldMerge() {{{2
3166 /* 3160 /*
3167 * Merge two adjacent folds (and the nested ones in them). 3161 * Merge two adjacent folds (and the nested ones in them).
3168 * This only works correctly when the folds are really adjacent! Thus "fp1" 3162 * This only works correctly when the folds are really adjacent! Thus "fp1"
3169 * must end just above "fp2". 3163 * must end just above "fp2".
3170 * The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1". 3164 * The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1".
3177 fold_T *fp4; 3171 fold_T *fp4;
3178 int idx; 3172 int idx;
3179 garray_T *gap1 = &fp1->fd_nested; 3173 garray_T *gap1 = &fp1->fd_nested;
3180 garray_T *gap2 = &fp2->fd_nested; 3174 garray_T *gap2 = &fp2->fd_nested;
3181 3175
3182 /* If the last nested fold in fp1 touches the first nested fold in fp2, 3176 // If the last nested fold in fp1 touches the first nested fold in fp2,
3183 * merge them recursively. */ 3177 // merge them recursively.
3184 if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4)) 3178 if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4))
3185 foldMerge(fp3, gap2, fp4); 3179 foldMerge(fp3, gap2, fp4);
3186 3180
3187 /* Move nested folds in fp2 to the end of fp1. */ 3181 // Move nested folds in fp2 to the end of fp1.
3188 if (gap2->ga_len > 0 && ga_grow(gap1, gap2->ga_len) == OK) 3182 if (gap2->ga_len > 0 && ga_grow(gap1, gap2->ga_len) == OK)
3189 { 3183 {
3190 for (idx = 0; idx < gap2->ga_len; ++idx) 3184 for (idx = 0; idx < gap2->ga_len; ++idx)
3191 { 3185 {
3192 ((fold_T *)gap1->ga_data)[gap1->ga_len] 3186 ((fold_T *)gap1->ga_data)[gap1->ga_len]
3200 fp1->fd_len += fp2->fd_len; 3194 fp1->fd_len += fp2->fd_len;
3201 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); 3195 deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
3202 fold_changed = TRUE; 3196 fold_changed = TRUE;
3203 } 3197 }
3204 3198
3205 /* foldlevelIndent() {{{2 */ 3199 // foldlevelIndent() {{{2
3206 /* 3200 /*
3207 * Low level function to get the foldlevel for the "indent" method. 3201 * Low level function to get the foldlevel for the "indent" method.
3208 * Doesn't use any caching. 3202 * Doesn't use any caching.
3209 * Returns a level of -1 if the foldlevel depends on surrounding lines. 3203 * Returns a level of -1 if the foldlevel depends on surrounding lines.
3210 */ 3204 */
3216 linenr_T lnum = flp->lnum + flp->off; 3210 linenr_T lnum = flp->lnum + flp->off;
3217 3211
3218 buf = flp->wp->w_buffer; 3212 buf = flp->wp->w_buffer;
3219 s = skipwhite(ml_get_buf(buf, lnum, FALSE)); 3213 s = skipwhite(ml_get_buf(buf, lnum, FALSE));
3220 3214
3221 /* empty line or lines starting with a character in 'foldignore': level 3215 // empty line or lines starting with a character in 'foldignore': level
3222 * depends on surrounding lines */ 3216 // depends on surrounding lines
3223 if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) 3217 if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL)
3224 { 3218 {
3225 /* first and last line can't be undefined, use level 0 */ 3219 // first and last line can't be undefined, use level 0
3226 if (lnum == 1 || lnum == buf->b_ml.ml_line_count) 3220 if (lnum == 1 || lnum == buf->b_ml.ml_line_count)
3227 flp->lvl = 0; 3221 flp->lvl = 0;
3228 else 3222 else
3229 flp->lvl = -1; 3223 flp->lvl = -1;
3230 } 3224 }
3236 if (flp->lvl < 0) 3230 if (flp->lvl < 0)
3237 flp->lvl = 0; 3231 flp->lvl = 0;
3238 } 3232 }
3239 } 3233 }
3240 3234
3241 /* foldlevelDiff() {{{2 */ 3235 // foldlevelDiff() {{{2
3242 #ifdef FEAT_DIFF 3236 #ifdef FEAT_DIFF
3243 /* 3237 /*
3244 * Low level function to get the foldlevel for the "diff" method. 3238 * Low level function to get the foldlevel for the "diff" method.
3245 * Doesn't use any caching. 3239 * Doesn't use any caching.
3246 */ 3240 */
3252 else 3246 else
3253 flp->lvl = 0; 3247 flp->lvl = 0;
3254 } 3248 }
3255 #endif 3249 #endif
3256 3250
3257 /* foldlevelExpr() {{{2 */ 3251 // foldlevelExpr() {{{2
3258 /* 3252 /*
3259 * Low level function to get the foldlevel for the "expr" method. 3253 * Low level function to get the foldlevel for the "expr" method.
3260 * Doesn't use any caching. 3254 * Doesn't use any caching.
3261 * Returns a level of -1 if the foldlevel depends on surrounding lines. 3255 * Returns a level of -1 if the foldlevel depends on surrounding lines.
3262 */ 3256 */
3282 flp->had_end = flp->end; 3276 flp->had_end = flp->end;
3283 flp->end = MAX_LEVEL + 1; 3277 flp->end = MAX_LEVEL + 1;
3284 if (lnum <= 1) 3278 if (lnum <= 1)
3285 flp->lvl = 0; 3279 flp->lvl = 0;
3286 3280
3287 /* KeyTyped may be reset to 0 when calling a function which invokes 3281 // KeyTyped may be reset to 0 when calling a function which invokes
3288 * do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */ 3282 // do_cmdline(). To make 'foldopen' work correctly restore KeyTyped.
3289 save_keytyped = KeyTyped; 3283 save_keytyped = KeyTyped;
3290 n = (int)eval_foldexpr(flp->wp->w_p_fde, &c); 3284 n = (int)eval_foldexpr(flp->wp->w_p_fde, &c);
3291 KeyTyped = save_keytyped; 3285 KeyTyped = save_keytyped;
3292 3286
3293 switch (c) 3287 switch (c)
3294 { 3288 {
3295 /* "a1", "a2", .. : add to the fold level */ 3289 // "a1", "a2", .. : add to the fold level
3296 case 'a': if (flp->lvl >= 0) 3290 case 'a': if (flp->lvl >= 0)
3297 { 3291 {
3298 flp->lvl += n; 3292 flp->lvl += n;
3299 flp->lvl_next = flp->lvl; 3293 flp->lvl_next = flp->lvl;
3300 } 3294 }
3301 flp->start = n; 3295 flp->start = n;
3302 break; 3296 break;
3303 3297
3304 /* "s1", "s2", .. : subtract from the fold level */ 3298 // "s1", "s2", .. : subtract from the fold level
3305 case 's': if (flp->lvl >= 0) 3299 case 's': if (flp->lvl >= 0)
3306 { 3300 {
3307 if (n > flp->lvl) 3301 if (n > flp->lvl)
3308 flp->lvl_next = 0; 3302 flp->lvl_next = 0;
3309 else 3303 else
3310 flp->lvl_next = flp->lvl - n; 3304 flp->lvl_next = flp->lvl - n;
3311 flp->end = flp->lvl_next + 1; 3305 flp->end = flp->lvl_next + 1;
3312 } 3306 }
3313 break; 3307 break;
3314 3308
3315 /* ">1", ">2", .. : start a fold with a certain level */ 3309 // ">1", ">2", .. : start a fold with a certain level
3316 case '>': flp->lvl = n; 3310 case '>': flp->lvl = n;
3317 flp->lvl_next = n; 3311 flp->lvl_next = n;
3318 flp->start = 1; 3312 flp->start = 1;
3319 break; 3313 break;
3320 3314
3321 /* "<1", "<2", .. : end a fold with a certain level */ 3315 // "<1", "<2", .. : end a fold with a certain level
3322 case '<': flp->lvl_next = n - 1; 3316 case '<': flp->lvl_next = n - 1;
3323 flp->end = n; 3317 flp->end = n;
3324 break; 3318 break;
3325 3319
3326 /* "=": No change in level */ 3320 // "=": No change in level
3327 case '=': flp->lvl_next = flp->lvl; 3321 case '=': flp->lvl_next = flp->lvl;
3328 break; 3322 break;
3329 3323
3330 /* "-1", "0", "1", ..: set fold level */ 3324 // "-1", "0", "1", ..: set fold level
3331 default: if (n < 0) 3325 default: if (n < 0)
3332 /* Use the current level for the next line, so that "a1" 3326 // Use the current level for the next line, so that "a1"
3333 * will work there. */ 3327 // will work there.
3334 flp->lvl_next = flp->lvl; 3328 flp->lvl_next = flp->lvl;
3335 else 3329 else
3336 flp->lvl_next = n; 3330 flp->lvl_next = n;
3337 flp->lvl = n; 3331 flp->lvl = n;
3338 break; 3332 break;
3339 } 3333 }
3340 3334
3341 /* If the level is unknown for the first or the last line in the file, use 3335 // If the level is unknown for the first or the last line in the file, use
3342 * level 0. */ 3336 // level 0.
3343 if (flp->lvl < 0) 3337 if (flp->lvl < 0)
3344 { 3338 {
3345 if (lnum <= 1) 3339 if (lnum <= 1)
3346 { 3340 {
3347 flp->lvl = 0; 3341 flp->lvl = 0;
3354 curwin = win; 3348 curwin = win;
3355 curbuf = curwin->w_buffer; 3349 curbuf = curwin->w_buffer;
3356 #endif 3350 #endif
3357 } 3351 }
3358 3352
3359 /* parseMarker() {{{2 */ 3353 // parseMarker() {{{2
3360 /* 3354 /*
3361 * Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and 3355 * Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and
3362 * "foldendmarkerlen". 3356 * "foldendmarkerlen".
3363 * Relies on the option value to have been checked for correctness already. 3357 * Relies on the option value to have been checked for correctness already.
3364 */ 3358 */
3368 foldendmarker = vim_strchr(wp->w_p_fmr, ','); 3362 foldendmarker = vim_strchr(wp->w_p_fmr, ',');
3369 foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr); 3363 foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr);
3370 foldendmarkerlen = (int)STRLEN(foldendmarker); 3364 foldendmarkerlen = (int)STRLEN(foldendmarker);
3371 } 3365 }
3372 3366
3373 /* foldlevelMarker() {{{2 */ 3367 // foldlevelMarker() {{{2
3374 /* 3368 /*
3375 * Low level function to get the foldlevel for the "marker" method. 3369 * Low level function to get the foldlevel for the "marker" method.
3376 * "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been 3370 * "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been
3377 * set before calling this. 3371 * set before calling this.
3378 * Requires that flp->lvl is set to the fold level of the previous line! 3372 * Requires that flp->lvl is set to the fold level of the previous line!
3388 int cend; 3382 int cend;
3389 int start_lvl = flp->lvl; 3383 int start_lvl = flp->lvl;
3390 char_u *s; 3384 char_u *s;
3391 int n; 3385 int n;
3392 3386
3393 /* cache a few values for speed */ 3387 // cache a few values for speed
3394 startmarker = flp->wp->w_p_fmr; 3388 startmarker = flp->wp->w_p_fmr;
3395 cstart = *startmarker; 3389 cstart = *startmarker;
3396 ++startmarker; 3390 ++startmarker;
3397 cend = *foldendmarker; 3391 cend = *foldendmarker;
3398 3392
3399 /* Default: no start found, next level is same as current level */ 3393 // Default: no start found, next level is same as current level
3400 flp->start = 0; 3394 flp->start = 0;
3401 flp->lvl_next = flp->lvl; 3395 flp->lvl_next = flp->lvl;
3402 3396
3403 s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, FALSE); 3397 s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, FALSE);
3404 while (*s) 3398 while (*s)
3405 { 3399 {
3406 if (*s == cstart 3400 if (*s == cstart
3407 && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0) 3401 && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0)
3408 { 3402 {
3409 /* found startmarker: set flp->lvl */ 3403 // found startmarker: set flp->lvl
3410 s += foldstartmarkerlen; 3404 s += foldstartmarkerlen;
3411 if (VIM_ISDIGIT(*s)) 3405 if (VIM_ISDIGIT(*s))
3412 { 3406 {
3413 n = atoi((char *)s); 3407 n = atoi((char *)s);
3414 if (n > 0) 3408 if (n > 0)
3429 } 3423 }
3430 } 3424 }
3431 else if (*s == cend 3425 else if (*s == cend
3432 && STRNCMP(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0) 3426 && STRNCMP(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0)
3433 { 3427 {
3434 /* found endmarker: set flp->lvl_next */ 3428 // found endmarker: set flp->lvl_next
3435 s += foldendmarkerlen; 3429 s += foldendmarkerlen;
3436 if (VIM_ISDIGIT(*s)) 3430 if (VIM_ISDIGIT(*s))
3437 { 3431 {
3438 n = atoi((char *)s); 3432 n = atoi((char *)s);
3439 if (n > 0) 3433 if (n > 0)
3440 { 3434 {
3441 flp->lvl = n; 3435 flp->lvl = n;
3442 flp->lvl_next = n - 1; 3436 flp->lvl_next = n - 1;
3443 /* never start a fold with an end marker */ 3437 // never start a fold with an end marker
3444 if (flp->lvl_next > start_lvl) 3438 if (flp->lvl_next > start_lvl)
3445 flp->lvl_next = start_lvl; 3439 flp->lvl_next = start_lvl;
3446 } 3440 }
3447 } 3441 }
3448 else 3442 else
3450 } 3444 }
3451 else 3445 else
3452 MB_PTR_ADV(s); 3446 MB_PTR_ADV(s);
3453 } 3447 }
3454 3448
3455 /* The level can't go negative, must be missing a start marker. */ 3449 // The level can't go negative, must be missing a start marker.
3456 if (flp->lvl_next < 0) 3450 if (flp->lvl_next < 0)
3457 flp->lvl_next = 0; 3451 flp->lvl_next = 0;
3458 } 3452 }
3459 3453
3460 /* foldlevelSyntax() {{{2 */ 3454 // foldlevelSyntax() {{{2
3461 /* 3455 /*
3462 * Low level function to get the foldlevel for the "syntax" method. 3456 * Low level function to get the foldlevel for the "syntax" method.
3463 * Doesn't use any caching. 3457 * Doesn't use any caching.
3464 */ 3458 */
3465 static void 3459 static void
3470 flp->lvl = 0; 3464 flp->lvl = 0;
3471 #else 3465 #else
3472 linenr_T lnum = flp->lnum + flp->off; 3466 linenr_T lnum = flp->lnum + flp->off;
3473 int n; 3467 int n;
3474 3468
3475 /* Use the maximum fold level at the start of this line and the next. */ 3469 // Use the maximum fold level at the start of this line and the next.
3476 flp->lvl = syn_get_foldlevel(flp->wp, lnum); 3470 flp->lvl = syn_get_foldlevel(flp->wp, lnum);
3477 flp->start = 0; 3471 flp->start = 0;
3478 if (lnum < flp->wp->w_buffer->b_ml.ml_line_count) 3472 if (lnum < flp->wp->w_buffer->b_ml.ml_line_count)
3479 { 3473 {
3480 n = syn_get_foldlevel(flp->wp, lnum + 1); 3474 n = syn_get_foldlevel(flp->wp, lnum + 1);
3481 if (n > flp->lvl) 3475 if (n > flp->lvl)
3482 { 3476 {
3483 flp->start = n - flp->lvl; /* fold(s) start here */ 3477 flp->start = n - flp->lvl; // fold(s) start here
3484 flp->lvl = n; 3478 flp->lvl = n;
3485 } 3479 }
3486 } 3480 }
3487 #endif 3481 #endif
3488 } 3482 }
3489 3483
3490 /* functions for storing the fold state in a View {{{1 */ 3484 // functions for storing the fold state in a View {{{1
3491 /* put_folds() {{{2 */ 3485 // put_folds() {{{2
3492 #if defined(FEAT_SESSION) || defined(PROTO) 3486 #if defined(FEAT_SESSION) || defined(PROTO)
3493 static int put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off); 3487 static int put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off);
3494 static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off); 3488 static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off);
3495 static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off); 3489 static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off);
3496 3490
3506 if (put_line(fd, "silent! normal! zE") == FAIL 3500 if (put_line(fd, "silent! normal! zE") == FAIL
3507 || put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL) 3501 || put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL)
3508 return FAIL; 3502 return FAIL;
3509 } 3503 }
3510 3504
3511 /* If some folds are manually opened/closed, need to restore that. */ 3505 // If some folds are manually opened/closed, need to restore that.
3512 if (wp->w_fold_manual) 3506 if (wp->w_fold_manual)
3513 return put_foldopen_recurse(fd, wp, &wp->w_folds, (linenr_T)0); 3507 return put_foldopen_recurse(fd, wp, &wp->w_folds, (linenr_T)0);
3514 3508
3515 return OK; 3509 return OK;
3516 } 3510 }
3517 3511
3518 /* put_folds_recurse() {{{2 */ 3512 // put_folds_recurse() {{{2
3519 /* 3513 /*
3520 * Write commands to "fd" to recreate manually created folds. 3514 * Write commands to "fd" to recreate manually created folds.
3521 * Returns FAIL when writing failed. 3515 * Returns FAIL when writing failed.
3522 */ 3516 */
3523 static int 3517 static int
3527 fold_T *fp; 3521 fold_T *fp;
3528 3522
3529 fp = (fold_T *)gap->ga_data; 3523 fp = (fold_T *)gap->ga_data;
3530 for (i = 0; i < gap->ga_len; i++) 3524 for (i = 0; i < gap->ga_len; i++)
3531 { 3525 {
3532 /* Do nested folds first, they will be created closed. */ 3526 // Do nested folds first, they will be created closed.
3533 if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL) 3527 if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL)
3534 return FAIL; 3528 return FAIL;
3535 if (fprintf(fd, "%ld,%ldfold", fp->fd_top + off, 3529 if (fprintf(fd, "%ld,%ldfold", fp->fd_top + off,
3536 fp->fd_top + off + fp->fd_len - 1) < 0 3530 fp->fd_top + off + fp->fd_len - 1) < 0
3537 || put_eol(fd) == FAIL) 3531 || put_eol(fd) == FAIL)
3539 ++fp; 3533 ++fp;
3540 } 3534 }
3541 return OK; 3535 return OK;
3542 } 3536 }
3543 3537
3544 /* put_foldopen_recurse() {{{2 */ 3538 // put_foldopen_recurse() {{{2
3545 /* 3539 /*
3546 * Write commands to "fd" to open and close manually opened/closed folds. 3540 * Write commands to "fd" to open and close manually opened/closed folds.
3547 * Returns FAIL when writing failed. 3541 * Returns FAIL when writing failed.
3548 */ 3542 */
3549 static int 3543 static int
3562 { 3556 {
3563 if (fp->fd_flags != FD_LEVEL) 3557 if (fp->fd_flags != FD_LEVEL)
3564 { 3558 {
3565 if (fp->fd_nested.ga_len > 0) 3559 if (fp->fd_nested.ga_len > 0)
3566 { 3560 {
3567 /* open nested folds while this fold is open */ 3561 // open nested folds while this fold is open
3568 if (fprintf(fd, "%ld", fp->fd_top + off) < 0 3562 if (fprintf(fd, "%ld", fp->fd_top + off) < 0
3569 || put_eol(fd) == FAIL 3563 || put_eol(fd) == FAIL
3570 || put_line(fd, "normal! zo") == FAIL) 3564 || put_line(fd, "normal! zo") == FAIL)
3571 return FAIL; 3565 return FAIL;
3572 if (put_foldopen_recurse(fd, wp, &fp->fd_nested, 3566 if (put_foldopen_recurse(fd, wp, &fp->fd_nested,
3573 off + fp->fd_top) 3567 off + fp->fd_top)
3574 == FAIL) 3568 == FAIL)
3575 return FAIL; 3569 return FAIL;
3576 /* close the parent when needed */ 3570 // close the parent when needed
3577 if (fp->fd_flags == FD_CLOSED) 3571 if (fp->fd_flags == FD_CLOSED)
3578 { 3572 {
3579 if (put_fold_open_close(fd, fp, off) == FAIL) 3573 if (put_fold_open_close(fd, fp, off) == FAIL)
3580 return FAIL; 3574 return FAIL;
3581 } 3575 }
3582 } 3576 }
3583 else 3577 else
3584 { 3578 {
3585 /* Open or close the leaf according to the window foldlevel. 3579 // Open or close the leaf according to the window foldlevel.
3586 * Do not close a leaf that is already closed, as it will close 3580 // Do not close a leaf that is already closed, as it will close
3587 * the parent. */ 3581 // the parent.
3588 level = foldLevelWin(wp, off + fp->fd_top); 3582 level = foldLevelWin(wp, off + fp->fd_top);
3589 if ((fp->fd_flags == FD_CLOSED && wp->w_p_fdl >= level) 3583 if ((fp->fd_flags == FD_CLOSED && wp->w_p_fdl >= level)
3590 || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level)) 3584 || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level))
3591 if (put_fold_open_close(fd, fp, off) == FAIL) 3585 if (put_fold_open_close(fd, fp, off) == FAIL)
3592 return FAIL; 3586 return FAIL;
3596 } 3590 }
3597 3591
3598 return OK; 3592 return OK;
3599 } 3593 }
3600 3594
3601 /* put_fold_open_close() {{{2 */ 3595 // put_fold_open_close() {{{2
3602 /* 3596 /*
3603 * Write the open or close command to "fd". 3597 * Write the open or close command to "fd".
3604 * Returns FAIL when writing failed. 3598 * Returns FAIL when writing failed.
3605 */ 3599 */
3606 static int 3600 static int
3613 || put_eol(fd) == FAIL) 3607 || put_eol(fd) == FAIL)
3614 return FAIL; 3608 return FAIL;
3615 3609
3616 return OK; 3610 return OK;
3617 } 3611 }
3618 #endif /* FEAT_SESSION */ 3612 #endif // FEAT_SESSION
3619 3613
3620 /* }}}1 */ 3614 // }}}1
3621 #endif // defined(FEAT_FOLDING) || defined(PROTO) 3615 #endif // defined(FEAT_FOLDING) || defined(PROTO)
3622 3616
3623 #if defined(FEAT_EVAL) || defined(PROTO) 3617 #if defined(FEAT_EVAL) || defined(PROTO)
3624 3618
3625 /* 3619 /*