/* vim:set ts=8 sts=4 sw=4: * vim600:fdm=marker fdl=1 fdc=3: * * VIM - Vi IMproved by Bram Moolenaar * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * fold.c: code for folding */ #include "vim.h" #if defined(FEAT_FOLDING) || defined(PROTO) /* local declarations. {{{1 *//* typedef fold_T {{{2 *//* * The toplevel folds for each window are stored in the w_folds growarray. * Each toplevel fold can contain an array of second level folds in the * fd_nested growarray. * The info stored in both growarrays is the same: An array of fold_T. */typedef struct{ linenr_T fd_top; /* first line of fold; for nested fold * relative to parent */ linenr_T fd_len; /* number of lines in the fold */ garray_T fd_nested; /* array of nested folds */ char fd_flags; /* see below */ char fd_small; /* TRUE, FALSE or MAYBE: fold smaller than 'foldminlines'; MAYBE applies to nested folds too */} fold_T; #define FD_OPEN 0 /* fold is open (nested ones can be closed) */#define FD_CLOSED 1 /* fold is closed */#define FD_LEVEL 2 /* depends on 'foldlevel' (nested folds too) */ #define MAX_LEVEL 20 /* maximum fold depth */ /* static functions {{{2 */static void newFoldLevelWin __ARGS((win_T *wp));static int checkCloseRec __ARGS((garray_T *gap, linenr_T lnum, int level));static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp));static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum));static void checkupdate __ARGS((win_T *wp));static void setFoldRepeat __ARGS((linenr_T lnum, long count, int open));static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse, int *donep));static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening, int recurse, int *donep));static void foldOpenNested __ARGS((fold_T *fpr));static void deleteFoldEntry __ARGS((garray_T *gap, int idx, int recursive));static void foldMarkAdjustRecurse __ARGS((garray_T *gap, linenr_T line1, linenr_T line2, long amount, long amount_after));static int getDeepestNestingRecurse __ARGS((garray_T *gap));static int check_closed __ARGS((win_T *win, fold_T *fp, int *use_levelp, int level, int *maybe_smallp, linenr_T lnum_off));static void checkSmall __ARGS((win_T *wp, fold_T *fp, linenr_T lnum_off));static void setSmallMaybe __ARGS((garray_T *gap));static void foldCreateMarkers __ARGS((linenr_T start, linenr_T end));static void foldAddMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen));static void deleteFoldMarkers __ARGS((fold_T *fp, int recursive, linenr_T lnum_off));static void foldDelMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen));static void foldUpdateIEMS __ARGS((win_T *wp, linenr_T top, linenr_T bot));static void parseMarker __ARGS((win_T *wp)); static char *e_nofold = N_("E490: No fold found"); /* * While updating the folds lines between invalid_top and invalid_bot have an * undefined fold level. Only used for the window currently being updated. */static linenr_T invalid_top = (linenr_T)0;static linenr_T invalid_bot = (linenr_T)0; /* * When using 'foldexpr' we sometimes get the level of the next line, which * calls foldlevel() to get the level of the current line, which hasn't been * stored yet. To get around this chicken-egg problem the level of the * previous line is stored here when available. prev_lnum is zero when the * level is not available. */static linenr_T prev_lnum = 0;static int prev_lnum_lvl = -1; /* Flags used for "done" argument of setManualFold. */#define DONE_NOTHING 0#define DONE_ACTION 1 /* did close or open a fold */#define DONE_FOLD 2 /* did find a fold */ static int foldstartmarkerlen;static char_u *foldendmarker;static int foldendmarkerlen; /* Exported folding functions. {{{1 *//* copyFoldingState() {{{2 */#if defined(FEAT_WINDOWS) || defined(PROTO)/* * Copy that folding state from window "wp_from" to window "wp_to". */ voidcopyFoldingState(wp_from, wp_to) win_T *wp_from; win_T *wp_to;{ wp_to->w_fold_manual = wp_from->w_fold_manual; wp_to->w_foldinvalid = wp_from->w_foldinvalid; cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds);}#endif /* hasAnyFolding() {{{2 *//* * Return TRUE if there may be folded lines in the current window. */ inthasAnyFolding(win) win_T *win;{ /* very simple now, but can become more complex later */ return (win->w_p_fen && (!foldmethodIsManual(win) || win->w_folds.ga_len > 0));} /* hasFolding() {{{2 *//* * Return TRUE if line "lnum" in the current window is part of a closed * fold. * When returning TRUE, *firstp and *lastp are set to the first and last * lnum of the sequence of folded lines (skipped when NULL). */ inthasFolding(lnum, firstp, lastp) linenr_T lnum; linenr_T *firstp; linenr_T *lastp;{ return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL);} /* hasFoldingWin() {{{2 */ inthasFoldingWin(win, lnum, firstp, lastp, cache, infop) win_T *win; linenr_T lnum; linenr_T *firstp; linenr_T *lastp; int cache; /* when TRUE: use cached values of window */ foldinfo_T *infop; /* where to store fold info */{ int had_folded = FALSE; linenr_T first = 0; linenr_T last = 0; linenr_T lnum_rel = lnum; int x; fold_T *fp; int level = 0; int use_level = FALSE; int maybe_small = FALSE; garray_T *gap; int low_level = 0;; checkupdate(win); /* * Return quickly when there is no folding at all in this window. */ if (!hasAnyFolding(win)) { if (infop != NULL) infop->fi_level = 0; return FALSE; } if (cache) { /* * First look in cached info for displayed lines. This is probably * the fastest, but it can only be used if the entry is still valid. */ x = find_wl_entry(win, lnum); if (x >= 0) { first = win->w_lines[x].wl_lnum; last = win->w_lines[x].wl_lastlnum; had_folded = win->w_lines[x].wl_folded; } } if (first == 0) { /* * Recursively search for a fold that contains "lnum". */ gap = &win->w_folds; for (;;) { if (!foldFind(gap, lnum_rel, &fp)) break; /* Remember lowest level of fold that starts in "lnum". */ if (lnum_rel == fp->fd_top && low_level == 0) low_level = level + 1; first += fp->fd_top; last += fp->fd_top; /* is this fold closed? */ had_folded = check_closed(win, fp, &use_level, level, &maybe_small, lnum - lnum_rel); if (had_folded) { /* Fold closed: Set last and quit loop. */ last += fp->fd_len - 1; break; } /* Fold found, but it's open: Check nested folds. Line number is * relative to containing fold. */ gap = &fp->fd_nested; lnum_rel -= fp->fd_top; ++level; } } if (!had_folded) { if (infop != NULL) { infop->fi_level = level; infop->fi_lnum = lnum - lnum_rel; infop->fi_low_level = low_level == 0 ? level : low_level; } return FALSE; } if (lastp != NULL) *lastp = last; if (firstp != NULL) *firstp = first; if (infop != NULL) { infop->fi_level = level + 1; infop->fi_lnum = first; infop->fi_low_level = low_level == 0 ? level + 1 : low_level; } return TRUE;} /* foldLevel() {{{2 *//* * Return fold level at line number "lnum" in the current window. */ intfoldLevel(lnum) linenr_T lnum;{ /* While updating the folds lines between invalid_top and invalid_bot have * an undefined fold level. Otherwise update the folds first. */ if (invalid_top == (linenr_T)0) checkupdate(curwin); else if (lnum == prev_lnum && prev_lnum_lvl >= 0) return prev_lnum_lvl; else if (lnum >= invalid_top && lnum <= invalid_bot) return -1; /* Return quickly when there is no folding at all in this window. */ if (!hasAnyFolding(curwin)) return 0; return foldLevelWin(curwin, lnum);} /* lineFolded() {{{2 *//* * Low level function to check if a line is folded. Doesn't use any caching. * Return TRUE if line is folded. * Return FALSE if line is not folded. * Return MAYBE if the line is folded when next to a folded line. */ intlineFolded(win, lnum) win_T *win; linenr_T lnum;{ return foldedCount(win, lnum, NULL) != 0;} /* foldedCount() {{{2 *//* * Count the number of lines that are folded at line number "lnum". * Normally "lnum" is the first line of a possible fold, and the returned * number is the number of lines in the fold. * Doesn't use caching from the displayed window. * Returns number of folded lines from "lnum", or 0 if line is not folded. * When "infop" is not NULL, fills *infop with the fold level info. */ longfoldedCount(win, lnum, infop) win_T *win; linenr_T lnum; foldinfo_T *infop;{ linenr_T last; if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop)) return (long)(last - lnum + 1); return 0;} /* foldmethodIsManual() {{{2 *//* * Return TRUE if 'foldmethod' is "manual" */ intfoldmethodIsManual(wp) win_T *wp;{ return (wp->w_p_fdm[3] == 'u');} /* foldmethodIsIndent() {{{2 *//* * Return TRUE if 'foldmethod' is "indent" */ intfoldmethodIsIndent(wp) win_T *wp;{ return (wp->w_p_fdm[0] == 'i');} /* foldmethodIsExpr() {{{2 *//* * Return TRUE if 'foldmethod' is "expr" */ intfoldmethodIsExpr(wp) win_T *wp;{ return (wp->w_p_fdm[1] == 'x');} /* foldmethodIsMarker() {{{2 *//* * Return TRUE if 'foldmethod' is "marker" */ intfoldmethodIsMarker(wp) win_T *wp;{ return (wp->w_p_fdm[2] == 'r');} /* foldmethodIsSyntax() {{{2 *//* * Return TRUE if 'foldmethod' is "syntax" */ intfoldmethodIsSyntax(wp) win_T *wp;{ return (wp->w_p_fdm[0] == 's');} /* foldmethodIsDiff() {{{2 *//* * Return TRUE if 'foldmethod' is "diff" */ intfoldmethodIsDiff(wp) win_T *wp;{ return (wp->w_p_fdm[0] == 'd');} /* closeFold() {{{2 *//* * Close fold for current window at line "lnum". * Repeat "count" times. */ voidcloseFold(lnum, count) linenr_T lnum; long count;{ setFoldRepeat(lnum, count, FALSE);} /* closeFoldRecurse() {{{2 *//* * Close fold for current window at line "lnum" recursively. */ voidcloseFoldRecurse(lnum) linenr_T lnum;{ (void)setManualFold(lnum, FALSE, TRUE, NULL);} /* opFoldRange() {{{2 *//* * Open or Close folds for current window in lines "first" to "last". * Used for "zo", "zO", "zc" and "zC" in Visual mode. */ voidopFoldRange(first, last, opening, recurse, had_visual) linenr_T first; linenr_T last; int opening; /* TRUE to open, FALSE to close */ int recurse; /* TRUE to do it recursively */ int had_visual; /* TRUE when Visual selection used */{ int done = DONE_NOTHING; /* avoid error messages */ linenr_T lnum; linenr_T lnum_next; for (lnum = first; lnum <= last; lnum = lnum_next + 1) { lnum_next = lnum; /* Opening one level only: next fold to open is after the one going to * be opened. */ if (opening && !recurse) (void)hasFolding(lnum, NULL, &lnum_next); (void)setManualFold(lnum, opening, recurse, &done); /* Closing one level only: next line to close a fold is after just * closed fold. */ if (!opening && !recurse) (void)hasFolding(lnum, NULL, &lnum_next); } if (done == DONE_NOTHING) EMSG(_(e_nofold));#ifdef FEAT_VISUAL /* Force a redraw to remove the Visual highlighting. */ if (had_visual) redraw_curbuf_later(INVERTED);#endif} /* openFold() {{{2 *//* * Open fold for current window at line "lnum". * Repeat "count" times. */ voidopenFold(lnum, count) linenr_T lnum; long count;{ setFoldRepeat(lnum, count, TRUE);} /* openFoldRecurse() {{{2 *//* * Open fold for current window at line "lnum" recursively. */ voidopenFoldRecurse(lnum) linenr_T lnum;{ (void)setManualFold(lnum, TRUE, TRUE, NULL);} /* foldOpenCursor() {{{2 *//* * Open folds until the cursor line is not in a closed fold. */ voidfoldOpenCursor(){ int done; checkupdate(curwin); if (hasAnyFolding(curwin)) for (;;) { done = DONE_NOTHING; (void)setManualFold(curwin->w_cursor.lnum, TRUE, FALSE, &done); if (!(done & DONE_ACTION)) break; }} /* newFoldLevel() {{{2 *//* * Set new foldlevel for current window. */ voidnewFoldLevel(){ newFoldLevelWin(curwin); #ifdef FEAT_DIFF if (foldmethodIsDiff(curwin) && curwin->w_p_scb) { win_T *wp; /* * Set the same foldlevel in other windows in diff mode. */Lines 1–500 of 3338. Load more
/* vim:set ts=8 sts=4 sw=4: * vim600:fdm=marker fdl=1 fdc=3: * * VIM - Vi IMproved by Bram Moolenaar * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. */ /* * fold.c: code for folding */ #include "vim.h" #if defined(FEAT_FOLDING) || defined(PROTO) /* local declarations. {{{1 */ /* typedef fold_T {{{2 */ /* * The toplevel folds for each window are stored in the w_folds growarray. * Each toplevel fold can contain an array of second level folds in the * fd_nested growarray. * The info stored in both growarrays is the same: An array of fold_T. */ typedef struct { linenr_T fd_top; /* first line of fold; for nested fold * relative to parent */ linenr_T fd_len; /* number of lines in the fold */ garray_T fd_nested; /* array of nested folds */ char fd_flags; /* see below */ char fd_small; /* TRUE, FALSE or MAYBE: fold smaller than 'foldminlines'; MAYBE applies to nested folds too */ } fold_T; #define FD_OPEN 0 /* fold is open (nested ones can be closed) */ #define FD_CLOSED 1 /* fold is closed */ #define FD_LEVEL 2 /* depends on 'foldlevel' (nested folds too) */ #define MAX_LEVEL 20 /* maximum fold depth */ /* static functions {{{2 */ static void newFoldLevelWin __ARGS((win_T *wp)); static int checkCloseRec __ARGS((garray_T *gap, linenr_T lnum, int level)); static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp)); static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum)); static void checkupdate __ARGS((win_T *wp)); static void setFoldRepeat __ARGS((linenr_T lnum, long count, int open)); static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse, int *donep)); static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening, int recurse, int *donep)); static void foldOpenNested __ARGS((fold_T *fpr)); static void deleteFoldEntry __ARGS((garray_T *gap, int idx, int recursive)); static void foldMarkAdjustRecurse __ARGS((garray_T *gap, linenr_T line1, linenr_T line2, long amount, long amount_after)); static int getDeepestNestingRecurse __ARGS((garray_T *gap)); static int check_closed __ARGS((win_T *win, fold_T *fp, int *use_levelp, int level, int *maybe_smallp, linenr_T lnum_off)); static void checkSmall __ARGS((win_T *wp, fold_T *fp, linenr_T lnum_off)); static void setSmallMaybe __ARGS((garray_T *gap)); static void foldCreateMarkers __ARGS((linenr_T start, linenr_T end)); static void foldAddMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen)); static void deleteFoldMarkers __ARGS((fold_T *fp, int recursive, linenr_T lnum_off)); static void foldDelMarker __ARGS((linenr_T lnum, char_u *marker, int markerlen)); static void foldUpdateIEMS __ARGS((win_T *wp, linenr_T top, linenr_T bot)); static void parseMarker __ARGS((win_T *wp)); static char *e_nofold = N_("E490: No fold found"); /* * While updating the folds lines between invalid_top and invalid_bot have an * undefined fold level. Only used for the window currently being updated. */ static linenr_T invalid_top = (linenr_T)0; static linenr_T invalid_bot = (linenr_T)0; /* * When using 'foldexpr' we sometimes get the level of the next line, which * calls foldlevel() to get the level of the current line, which hasn't been * stored yet. To get around this chicken-egg problem the level of the * previous line is stored here when available. prev_lnum is zero when the * level is not available. */ static linenr_T prev_lnum = 0; static int prev_lnum_lvl = -1; /* Flags used for "done" argument of setManualFold. */ #define DONE_NOTHING 0 #define DONE_ACTION 1 /* did close or open a fold */ #define DONE_FOLD 2 /* did find a fold */ static int foldstartmarkerlen; static char_u *foldendmarker; static int foldendmarkerlen; /* Exported folding functions. {{{1 */ /* copyFoldingState() {{{2 */ #if defined(FEAT_WINDOWS) || defined(PROTO) /* * Copy that folding state from window "wp_from" to window "wp_to". */ void copyFoldingState(wp_from, wp_to) win_T *wp_from; win_T *wp_to; { wp_to->w_fold_manual = wp_from->w_fold_manual; wp_to->w_foldinvalid = wp_from->w_foldinvalid; cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds); } #endif /* hasAnyFolding() {{{2 */ /* * Return TRUE if there may be folded lines in the current window. */ int hasAnyFolding(win) win_T *win; { /* very simple now, but can become more complex later */ return (win->w_p_fen && (!foldmethodIsManual(win) || win->w_folds.ga_len > 0)); } /* hasFolding() {{{2 */ /* * Return TRUE if line "lnum" in the current window is part of a closed * fold. * When returning TRUE, *firstp and *lastp are set to the first and last * lnum of the sequence of folded lines (skipped when NULL). */ int hasFolding(lnum, firstp, lastp) linenr_T lnum; linenr_T *firstp; linenr_T *lastp; { return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL); } /* hasFoldingWin() {{{2 */ int hasFoldingWin(win, lnum, firstp, lastp, cache, infop) win_T *win; linenr_T lnum; linenr_T *firstp; linenr_T *lastp; int cache; /* when TRUE: use cached values of window */ foldinfo_T *infop; /* where to store fold info */ { int had_folded = FALSE; linenr_T first = 0; linenr_T last = 0; linenr_T lnum_rel = lnum; int x; fold_T *fp; int level = 0; int use_level = FALSE; int maybe_small = FALSE; garray_T *gap; int low_level = 0;; checkupdate(win); /* * Return quickly when there is no folding at all in this window. */ if (!hasAnyFolding(win)) { if (infop != NULL) infop->fi_level = 0; return FALSE; } if (cache) { /* * First look in cached info for displayed lines. This is probably * the fastest, but it can only be used if the entry is still valid. */ x = find_wl_entry(win, lnum); if (x >= 0) { first = win->w_lines[x].wl_lnum; last = win->w_lines[x].wl_lastlnum; had_folded = win->w_lines[x].wl_folded; } } if (first == 0) { /* * Recursively search for a fold that contains "lnum". */ gap = &win->w_folds; for (;;) { if (!foldFind(gap, lnum_rel, &fp)) break; /* Remember lowest level of fold that starts in "lnum". */ if (lnum_rel == fp->fd_top && low_level == 0) low_level = level + 1; first += fp->fd_top; last += fp->fd_top; /* is this fold closed? */ had_folded = check_closed(win, fp, &use_level, level, &maybe_small, lnum - lnum_rel); if (had_folded) { /* Fold closed: Set last and quit loop. */ last += fp->fd_len - 1; break; } /* Fold found, but it's open: Check nested folds. Line number is * relative to containing fold. */ gap = &fp->fd_nested; lnum_rel -= fp->fd_top; ++level; } } if (!had_folded) { if (infop != NULL) { infop->fi_level = level; infop->fi_lnum = lnum - lnum_rel; infop->fi_low_level = low_level == 0 ? level : low_level; } return FALSE; } if (lastp != NULL) *lastp = last; if (firstp != NULL) *firstp = first; if (infop != NULL) { infop->fi_level = level + 1; infop->fi_lnum = first; infop->fi_low_level = low_level == 0 ? level + 1 : low_level; } return TRUE; } /* foldLevel() {{{2 */ /* * Return fold level at line number "lnum" in the current window. */ int foldLevel(lnum) linenr_T lnum; { /* While updating the folds lines between invalid_top and invalid_bot have * an undefined fold level. Otherwise update the folds first. */ if (invalid_top == (linenr_T)0) checkupdate(curwin); else if (lnum == prev_lnum && prev_lnum_lvl >= 0) return prev_lnum_lvl; else if (lnum >= invalid_top && lnum <= invalid_bot) return -1; /* Return quickly when there is no folding at all in this window. */ if (!hasAnyFolding(curwin)) return 0; return foldLevelWin(curwin, lnum); } /* lineFolded() {{{2 */ /* * Low level function to check if a line is folded. Doesn't use any caching. * Return TRUE if line is folded. * Return FALSE if line is not folded. * Return MAYBE if the line is folded when next to a folded line. */ int lineFolded(win, lnum) win_T *win; linenr_T lnum; { return foldedCount(win, lnum, NULL) != 0; } /* foldedCount() {{{2 */ /* * Count the number of lines that are folded at line number "lnum". * Normally "lnum" is the first line of a possible fold, and the returned * number is the number of lines in the fold. * Doesn't use caching from the displayed window. * Returns number of folded lines from "lnum", or 0 if line is not folded. * When "infop" is not NULL, fills *infop with the fold level info. */ long foldedCount(win, lnum, infop) win_T *win; linenr_T lnum; foldinfo_T *infop; { linenr_T last; if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop)) return (long)(last - lnum + 1); return 0; } /* foldmethodIsManual() {{{2 */ /* * Return TRUE if 'foldmethod' is "manual" */ int foldmethodIsManual(wp) win_T *wp; { return (wp->w_p_fdm[3] == 'u'); } /* foldmethodIsIndent() {{{2 */ /* * Return TRUE if 'foldmethod' is "indent" */ int foldmethodIsIndent(wp) win_T *wp; { return (wp->w_p_fdm[0] == 'i'); } /* foldmethodIsExpr() {{{2 */ /* * Return TRUE if 'foldmethod' is "expr" */ int foldmethodIsExpr(wp) win_T *wp; { return (wp->w_p_fdm[1] == 'x'); } /* foldmethodIsMarker() {{{2 */ /* * Return TRUE if 'foldmethod' is "marker" */ int foldmethodIsMarker(wp) win_T *wp; { return (wp->w_p_fdm[2] == 'r'); } /* foldmethodIsSyntax() {{{2 */ /* * Return TRUE if 'foldmethod' is "syntax" */ int foldmethodIsSyntax(wp) win_T *wp; { return (wp->w_p_fdm[0] == 's'); } /* foldmethodIsDiff() {{{2 */ /* * Return TRUE if 'foldmethod' is "diff" */ int foldmethodIsDiff(wp) win_T *wp; { return (wp->w_p_fdm[0] == 'd'); } /* closeFold() {{{2 */ /* * Close fold for current window at line "lnum". * Repeat "count" times. */ void closeFold(lnum, count) linenr_T lnum; long count; { setFoldRepeat(lnum, count, FALSE); } /* closeFoldRecurse() {{{2 */ /* * Close fold for current window at line "lnum" recursively. */ void closeFoldRecurse(lnum) linenr_T lnum; { (void)setManualFold(lnum, FALSE, TRUE, NULL); } /* opFoldRange() {{{2 */ /* * Open or Close folds for current window in lines "first" to "last". * Used for "zo", "zO", "zc" and "zC" in Visual mode. */ void opFoldRange(first, last, opening, recurse, had_visual) linenr_T first; linenr_T last; int opening; /* TRUE to open, FALSE to close */ int recurse; /* TRUE to do it recursively */ int had_visual; /* TRUE when Visual selection used */ { int done = DONE_NOTHING; /* avoid error messages */ linenr_T lnum; linenr_T lnum_next; for (lnum = first; lnum <= last; lnum = lnum_next + 1) { lnum_next = lnum; /* Opening one level only: next fold to open is after the one going to * be opened. */ if (opening && !recurse) (void)hasFolding(lnum, NULL, &lnum_next); (void)setManualFold(lnum, opening, recurse, &done); /* Closing one level only: next line to close a fold is after just * closed fold. */ if (!opening && !recurse) (void)hasFolding(lnum, NULL, &lnum_next); } if (done == DONE_NOTHING) EMSG(_(e_nofold)); #ifdef FEAT_VISUAL /* Force a redraw to remove the Visual highlighting. */ if (had_visual) redraw_curbuf_later(INVERTED); #endif } /* openFold() {{{2 */ /* * Open fold for current window at line "lnum". * Repeat "count" times. */ void openFold(lnum, count) linenr_T lnum; long count; { setFoldRepeat(lnum, count, TRUE); } /* openFoldRecurse() {{{2 */ /* * Open fold for current window at line "lnum" recursively. */ void openFoldRecurse(lnum) linenr_T lnum; { (void)setManualFold(lnum, TRUE, TRUE, NULL); } /* foldOpenCursor() {{{2 */ /* * Open folds until the cursor line is not in a closed fold. */ void foldOpenCursor() { int done; checkupdate(curwin); if (hasAnyFolding(curwin)) for (;;) { done = DONE_NOTHING; (void)setManualFold(curwin->w_cursor.lnum, TRUE, FALSE, &done); if (!(done & DONE_ACTION)) break; } } /* newFoldLevel() {{{2 */ /* * Set new foldlevel for current window. */ void newFoldLevel() { newFoldLevelWin(curwin); #ifdef FEAT_DIFF if (foldmethodIsDiff(curwin) && curwin->w_p_scb) { win_T *wp; /* * Set the same foldlevel in other windows in diff mode. */