/* 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.
	 */
	FOR_ALL_WINDOWS(wp)
	{
	    if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb)
	    {
		wp->w_p_fdl = curwin->w_p_fdl;
		newFoldLevelWin(wp);
	    }
	}
    }
#endif
}

    static void
newFoldLevelWin(wp)
    win_T	*wp;
{
    fold_T	*fp;
    int		i;

    checkupdate(wp);
    if (wp->w_fold_manual)
    {
	/* Set all flags for the first level of folds to FD_LEVEL.  Following
	 * manual open/close will then change the flags to FD_OPEN or
	 * FD_CLOSED for those folds that don't use 'foldlevel'. */
	fp = (fold_T *)wp->w_folds.ga_data;
	for (i = 0; i < wp->w_folds.ga_len; ++i)
	    fp[i].fd_flags = FD_LEVEL;
	wp->w_fold_manual = FALSE;
    }
    changed_window_setting_win(wp);
}

/* foldCheckClose() {{{2 */
/*
 * Apply 'foldlevel' to all folds that don't contain the cursor.
 */
    void
foldCheckClose()
{
    if (*p_fcl != NUL)	/* can only be "all" right now */
    {
	checkupdate(curwin);
	if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
							(int)curwin->w_p_fdl))
	    changed_window_setting();
    }
}

/* checkCloseRec() {{{2 */
    static int
checkCloseRec(gap, lnum, level)
    garray_T	*gap;
    linenr_T	lnum;
    int		level;
{
    fold_T	*fp;
    int		retval = FALSE;
    int		i;

    fp = (fold_T *)gap->ga_data;
    for (i = 0; i < gap->ga_len; ++i)
    {
	/* Only manually opened folds may need to be closed. */
	if (fp[i].fd_flags == FD_OPEN)
	{
	    if (level <= 0 && (lnum < fp[i].fd_top
				      || lnum >= fp[i].fd_top + fp[i].fd_len))
	    {
		fp[i].fd_flags = FD_LEVEL;
		retval = TRUE;
	    }
	    else
		retval |= checkCloseRec(&fp[i].fd_nested, lnum - fp[i].fd_top,
								   level - 1);
	}
    }
    return retval;
}

/* foldCreateAllowed() {{{2 */
/*
 * Return TRUE if it's allowed to manually create or delete a fold.
 * Give an error message and return FALSE if not.
 */
    int
foldManualAllowed(create)
    int		create;
{
    if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin))
	return TRUE;
    if (create)
	EMSG(_("E350: Cannot create fold with current 'foldmethod'"));
    else
	EMSG(_("E351: Cannot delete fold with current 'foldmethod'"));
    return FALSE;
}

/* foldCreate() {{{2 */
/*
 * Create a fold from line "start" to line "end" (inclusive) in the current
 * window.
 */
    void
foldCreate(start, end)
    linenr_T	start;
    linenr_T	end;
{
    fold_T	*fp;
    garray_T	*gap;
    garray_T	fold_ga;
    int		i, j;
    int		cont;
    int		use_level = FALSE;
    int		closed = FALSE;
    int		level = 0;
    linenr_T	start_rel = start;
    linenr_T	end_rel = end;

    if (start > end)
    {
	/* reverse the range */
	end = start_rel;
	start = end_rel;
	start_rel = start;
	end_rel = end;
    }

    /* When 'foldmethod' is "marker" add markers, which creates the folds. */
    if (foldmethodIsMarker(curwin))
    {
	foldCreateMarkers(start, end);
	return;
    }

    checkupdate(curwin);

    /* Find the place to insert the new fold. */
    gap = &curwin->w_folds;
    for (;;)
    {
	if (!foldFind(gap, start_rel, &fp))
	    break;
	if (fp->fd_top + fp->fd_len > end_rel)
	{
	    /* New fold is completely inside this fold: Go one level deeper. */
	    gap = &fp->fd_nested;
	    start_rel -= fp->fd_top;
	    end_rel -= fp->fd_top;
	    if (use_level || fp->fd_flags == FD_LEVEL)
	    {
		use_level = TRUE;
		if (level >= curwin->w_p_fdl)
		    closed = TRUE;
	    }
	    else if (fp->fd_flags == FD_CLOSED)
		closed = TRUE;
	    ++level;
	}
	else
	{
	    /* This fold and new fold overlap: Insert here and move some folds
	     * inside the new fold. */
	    break;
	}
    }

    i = (int)(fp - (fold_T *)gap->ga_data);
    if (ga_grow(gap, 1) == OK)
    {
	fp = (fold_T *)gap->ga_data + i;
	ga_init2(&fold_ga, (int)sizeof(fold_T), 10);

	/* Count number of folds that will be contained in the new fold. */
	for (cont = 0; i + cont < gap->ga_len; ++cont)
	    if (fp[cont].fd_top > end_rel)
		break;
	if (cont > 0 && ga_grow(&fold_ga, cont) == OK)
	{
	    /* If the first fold starts before the new fold, let the new fold
	     * start there.  Otherwise the existing fold would change. */
	    if (start_rel > fp->fd_top)
		start_rel = fp->fd_top;

	    /* When last contained fold isn't completely contained, adjust end
	     * of new fold. */
	    if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1)
		end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1;
	    /* Move contained folds to inside new fold. */
	    mch_memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont);
	    fold_ga.ga_len += cont;
	    i += cont;

	    /* Adjust line numbers in contained folds to be relative to the
	     * new fold. */
	    for (j = 0; j < cont; ++j)
		((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel;
	}
	/* Move remaining entries to after the new fold. */
	if (i < gap->ga_len)
	    mch_memmove(fp + 1, (fold_T *)gap->ga_data + i,
				     sizeof(fold_T) * (gap->ga_len - i));
	gap->ga_len = gap->ga_len + 1 - cont;

	/* insert new fold */
	fp->fd_nested = fold_ga;
	fp->fd_top = start_rel;
	fp->fd_len = end_rel - start_rel + 1;

	/* We want the new fold to be closed.  If it would remain open because
	 * of using 'foldlevel', need to adjust fd_flags of containing folds.
	 */
	if (use_level && !closed && level < curwin->w_p_fdl)
	    closeFold(start, 1L);
	if (!use_level)
	    curwin->w_fold_manual = TRUE;
	fp->fd_flags = FD_CLOSED;
	fp->fd_small = MAYBE;

	/* redraw */
	changed_window_setting();
    }
}

/* deleteFold() {{{2 */
/*
 * Delete a fold at line "start" in the current window.
 * When "end" is not 0, delete all folds from "start" to "end".
 * When "recursive" is TRUE delete recursively.
 */
    void
deleteFold(start, end, recursive, had_visual)
    linenr_T	start;
    linenr_T	end;
    int		recursive;
    int		had_visual;	/* TRUE when Visual selection used */
{
    garray_T	*gap;
    fold_T	*fp;
    garray_T	*found_ga;
    fold_T	*found_fp = NULL;
    linenr_T	found_off = 0;
    int		use_level = FALSE;
    int		maybe_small = FALSE;
    int		level = 0;
    linenr_T	lnum = start;
    linenr_T	lnum_off;
    int		did_one = FALSE;
    linenr_T	first_lnum = MAXLNUM;
    linenr_T	last_lnum = 0;

    checkupdate(curwin);

    while (lnum <= end)
    {
	/* Find the deepest fold for "start". */
	gap = &curwin->w_folds;
	found_ga = NULL;
	lnum_off = 0;
	for (;;)
	{
	    if (!foldFind(gap, lnum - lnum_off, &fp))
		break;
	    /* lnum is inside this fold, remember info */
	    found_ga = gap;
	    found_fp = fp;
	    found_off = lnum_off;

	    /* if "lnum" is folded, don't check nesting */
	    if (check_closed(curwin, fp, &use_level, level,
						      &maybe_small, lnum_off))
		break;

	    /* check nested folds */
	    gap = &fp->fd_nested;
	    lnum_off += fp->fd_top;
	    ++level;
	}
	if (found_ga == NULL)
	{
	    ++lnum;
	}
	else
	{
	    lnum = found_fp->fd_top + found_fp->fd_len + found_off;
	    did_one = TRUE;

	    if (foldmethodIsManual(curwin))
		deleteFoldEntry(found_ga,
		    (int)(found_fp - (fold_T *)found_ga->ga_data), recursive);
	    else
	    {
		if (found_fp->fd_top + found_off < first_lnum)
		    first_lnum = found_fp->fd_top;
		if (lnum > last_lnum)
		    last_lnum = lnum;
		parseMarker(curwin);
		deleteFoldMarkers(found_fp, recursive, found_off);
	    }

	    /* redraw window */
	    changed_window_setting();
	}
    }
    if (!did_one)
    {
	EMSG(_(e_nofold));
#ifdef FEAT_VISUAL
	/* Force a redraw to remove the Visual highlighting. */
	if (had_visual)
	    redraw_curbuf_later(INVERTED);
#endif
    }
    if (last_lnum > 0)
	changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
}

/* clearFolding() {{{2 */
/*
 * Remove all folding for window "win".
 */
    void
clearFolding(win)
    win_T	*win;
{
    deleteFoldRecurse(&win->w_folds);
    win->w_foldinvalid = FALSE;
}

/* foldUpdate() {{{2 */
/*
 * Update folds for changes in the buffer of a window.
 * Note that inserted/deleted lines must have already been taken care of by
 * calling foldMarkAdjust().
 * The changes in lines from top to bot (inclusive).
 */
    void
foldUpdate(wp, top, bot)
    win_T	*wp;
    linenr_T	top;
    linenr_T	bot;
{
    fold_T	*fp;

    /* Mark all folds from top to bot as maybe-small. */
    (void)foldFind(&curwin->w_folds, curwin->w_cursor.lnum, &fp);
    while (fp < (fold_T *)curwin->w_folds.ga_data + curwin->w_folds.ga_len
	    && fp->fd_top < bot)
    {
	fp->fd_small = MAYBE;
	++fp;
    }

    if (foldmethodIsIndent(wp)
	    || foldmethodIsExpr(wp)
	    || foldmethodIsMarker(wp)
#ifdef FEAT_DIFF
	    || foldmethodIsDiff(wp)
#endif
	    || foldmethodIsSyntax(wp))
    {
	int save_got_int = got_int;

	/* reset got_int here, otherwise it won't work */
	got_int = FALSE;
	foldUpdateIEMS(wp, top, bot);
	got_int |= save_got_int;
    }
}

/* foldUpdateAll() {{{2 */
/*
 * Update all lines in a window for folding.
 * Used when a fold setting changes or after reloading the buffer.
 * The actual updating is postponed until fold info is used, to avoid doing
 * every time a setting is changed or a syntax item is added.
 */
    void
foldUpdateAll(win)
    win_T	*win;
{
    win->w_foldinvalid = TRUE;
    redraw_win_later(win, NOT_VALID);
}

/* foldMoveTo() {{{2 */
/*
 * If "updown" is FALSE: Move to the start or end of the fold.
 * If "updown" is TRUE: move to fold at the same level.
 * If not moved return FAIL.
 */
    int
foldMoveTo(updown, dir, count)
    int		updown;
    int		dir;	    /* FORWARD or BACKWARD */
    long	count;
{
    long	n;
    int		retval = FAIL;
    linenr_T	lnum_off;
    linenr_T	lnum_found;
    linenr_T	lnum;
    int		use_level;
    int		maybe_small;
    garray_T	*gap;
    fold_T	*fp;
    int		level;
    int		last;

    checkupdate(curwin);

    /* Repeat "count" times. */
    for (n = 0; n < count; ++n)
    {
	/* Find nested folds.  Stop when a fold is closed.  The deepest fold
	 * that moves the cursor is used. */
	lnum_off = 0;
	gap = &curwin->w_folds;
	use_level = FALSE;
	maybe_small = FALSE;
	lnum_found = curwin->w_cursor.lnum;
	level = 0;
	last = FALSE;
	for (;;)
	{
	    if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp))
	    {
		if (!updown)
		    break;

		/* When moving up, consider a fold above the cursor; when
		 * moving down consider a fold below the cursor. */
		if (dir == FORWARD)
		{
		    if (fp - (fold_T *)gap->ga_data >= gap->ga_len)
			break;
		    --fp;
		}
		else
		{
		    if (fp == (fold_T *)gap->ga_data)
			break;
		}
		/* don't look for contained folds, they will always move
		 * the cursor too far. */
		last = TRUE;
	    }

	    if (!last)
	    {
		/* Check if this fold is closed. */
		if (check_closed(curwin, fp, &use_level, level,
						      &maybe_small, lnum_off))
		    last = TRUE;

		/* "[z" and "]z" stop at closed fold */
		if (last && !updown)
		    break;
	    }

	    if (updown)
	    {
		if (dir == FORWARD)
		{
		    /* to start of next fold if there is one */
		    if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len)
		    {
			lnum = fp[1].fd_top + lnum_off;
			if (lnum > curwin->w_cursor.lnum)
			    lnum_found = lnum;
		    }
		}
		else
		{
		    /* to end of previous fold if there is one */
		    if (fp > (fold_T *)gap->ga_data)
		    {
			lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1;
			if (lnum < curwin->w_cursor.lnum)
			    lnum_found = lnum;
		    }
		}
	    }
	    else
	    {
		/* Open fold found, set cursor to its start/end and then check
		 * nested folds. */
		if (dir == FORWARD)
		{
		    lnum = fp->fd_top + lnum_off + fp->fd_len - 1;
		    if (lnum > curwin->w_cursor.lnum)
			lnum_found = lnum;
		}
		else
		{
		    lnum = fp->fd_top + lnum_off;
		    if (lnum < curwin->w_cursor.lnum)
			lnum_found = lnum;
		}
	    }

	    if (last)
		break;

	    /* Check nested folds (if any). */
	    gap = &fp->fd_nested;
	    lnum_off += fp->fd_top;
	    ++level;
	}
	if (lnum_found != curwin->w_cursor.lnum)
	{
	    if (retval == FAIL)
		setpcmark();
	    curwin->w_cursor.lnum = lnum_found;
	    curwin->w_cursor.col = 0;
	    retval = OK;
	}
	else
	    break;
    }

    return retval;
}

/* foldInitWin() {{{2 */
/*
 * Init the fold info in a new window.
 */
    void
foldInitWin(newwin)
    win_T	*newwin;
{
    ga_init2(&newwin->w_folds, (int)sizeof(fold_T), 10);
}

/* find_wl_entry() {{{2 */
/*
 * Find an entry in the win->w_lines[] array for buffer line "lnum".
 * Only valid entries are considered (for entries where wl_valid is FALSE the
 * line number can be wrong).
 * Returns index of entry or -1 if not found.
 */
    int
find_wl_entry(win, lnum)
    win_T	*win;
    linenr_T	lnum;
{
    int		i;

    if (win->w_lines_valid > 0)
	for (i = 0; i < win->w_lines_valid; ++i)
	    if (win->w_lines[i].wl_valid)
	    {
		if (lnum < win->w_lines[i].wl_lnum)
		    return -1;
		if (lnum <= win->w_lines[i].wl_lastlnum)
		    return i;
	    }
    return -1;
}

/* foldAdjustVisual() {{{2 */
#ifdef FEAT_VISUAL
/*
 * Adjust the Visual area to include any fold at the start or end completely.
 */
    void
foldAdjustVisual()
{
    pos_T	*start, *end;
    char_u	*ptr;

    if (!VIsual_active || !hasAnyFolding(curwin))
	return;

    if (ltoreq(VIsual, curwin->w_cursor))
    {
	start = &VIsual;
	end = &curwin->w_cursor;
    }
    else
    {
	start = &curwin->w_cursor;
	end = &VIsual;
    }
    if (hasFolding(start->lnum, &start->lnum, NULL))
	start->col = 0;
    if (hasFolding(end->lnum, NULL, &end->lnum))
    {
	ptr = ml_get(end->lnum);
	end->col = (colnr_T)STRLEN(ptr);
	if (end->col > 0 && *p_sel == 'o')
	    --end->col;
#ifdef FEAT_MBYTE
	/* prevent cursor from moving on the trail byte */
	if (has_mbyte)
	    mb_adjust_cursor();
#endif
    }
}
#endif

/* cursor_foldstart() {{{2 */
/*
 * Move the cursor to the first line of a closed fold.
 */
    void
foldAdjustCursor()
{
    (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL);
}

/* Internal functions for "fold_T" {{{1 */
/* cloneFoldGrowArray() {{{2 */
/*
 * Will "clone" (i.e deep copy) a garray_T of folds.
 *
 * Return FAIL if the operation cannot be completed, otherwise OK.
 */
    void
cloneFoldGrowArray(from, to)
    garray_T	*from;
    garray_T	*to;
{
    int		i;
    fold_T	*from_p;
    fold_T	*to_p;

    ga_init2(to, from->ga_itemsize, from->ga_growsize);
    if (from->ga_len == 0 || ga_grow(to, from->ga_len) == FAIL)
	return;

    from_p = (fold_T *)from->ga_data;
    to_p = (fold_T *)to->ga_data;

    for (i = 0; i < from->ga_len; i++)
    {
	to_p->fd_top = from_p->fd_top;
	to_p->fd_len = from_p->fd_len;
	to_p->fd_flags = from_p->fd_flags;
	to_p->fd_small = from_p->fd_small;
	cloneFoldGrowArray(&from_p->fd_nested, &to_p->fd_nested);
	++to->ga_len;
	++from_p;
	++to_p;
    }
}

/* foldFind() {{{2 */
/*
 * Search for line "lnum" in folds of growarray "gap".
 * Set *fpp to the fold struct for the fold that contains "lnum" or
 * the first fold below it (careful: it can be beyond the end of the array!).
 * Returns FALSE when there is no fold that contains "lnum".
 */
    static int
foldFind(gap, lnum, fpp)
    garray_T	*gap;
    linenr_T	lnum;
    fold_T	**fpp;
{
    linenr_T	low, high;
    fold_T	*fp;
    int		i;

    /*
     * Perform a binary search.
     * "low" is lowest index of possible match.
     * "high" is highest index of possible match.
     */
    fp = (fold_T *)gap->ga_data;
    low = 0;
    high = gap->ga_len - 1;
    while (low <= high)
    {
	i = (low + high) / 2;
	if (fp[i].fd_top > lnum)
	    /* fold below lnum, adjust high */
	    high = i - 1;
	else if (fp[i].fd_top + fp[i].fd_len <= lnum)
	    /* fold above lnum, adjust low */
	    low = i + 1;
	else
	{
	    /* lnum is inside this fold */
	    *fpp = fp + i;
	    return TRUE;
	}
    }
    *fpp = fp + low;
    return FALSE;
}

/* foldLevelWin() {{{2 */
/*
 * Return fold level at line number "lnum" in window "wp".
 */
    static int
foldLevelWin(wp, lnum)
    win_T	*wp;
    linenr_T	lnum;
{
    fold_T	*fp;
    linenr_T	lnum_rel = lnum;
    int		level =  0;
    garray_T	*gap;

    /* Recursively search for a fold that contains "lnum". */
    gap = &wp->w_folds;
    for (;;)
    {
	if (!foldFind(gap, lnum_rel, &fp))
	    break;
	/* Check nested folds.  Line number is relative to containing fold. */
	gap = &fp->fd_nested;
	lnum_rel -= fp->fd_top;
	++level;
    }

    return level;
}

/* checkupdate() {{{2 */
/*
 * Check if the folds in window "wp" are invalid and update them if needed.
 */
    static void
checkupdate(wp)
    win_T	*wp;
{
    if (wp->w_foldinvalid)
    {
	foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); /* will update all */
	wp->w_foldinvalid = FALSE;
    }
}

/* setFoldRepeat() {{{2 */
/*
 * Open or close fold for current window at line "lnum".
 * Repeat "count" times.
 */
    static void
setFoldRepeat(lnum, count, open)
    linenr_T	lnum;
    long	count;
    int		open;
{
    int		done;
    long	n;

    for (n = 0; n < count; ++n)
    {
	done = DONE_NOTHING;
	(void)setManualFold(lnum, open, FALSE, &done);
	if (!(done & DONE_ACTION))
	{
	    /* Only give an error message when no fold could be opened. */
	    if (n == 0 && !(done & DONE_FOLD))
		EMSG(_(e_nofold));
	    break;
	}
    }
}

/* setManualFold() {{{2 */
/*
 * Open or close the fold in the current window which contains "lnum".
 * Also does this for other windows in diff mode when needed.
 */
    static linenr_T
setManualFold(lnum, opening, recurse, donep)
    linenr_T	lnum;
    int		opening;    /* TRUE when opening, FALSE when closing */
    int		recurse;    /* TRUE when closing/opening recursive */
    int		*donep;
{
#ifdef FEAT_DIFF
    if (foldmethodIsDiff(curwin) && curwin->w_p_scb)
    {
	win_T	    *wp;
	linenr_T    dlnum;

	/*
	 * Do the same operation in other windows in diff mode.  Calculate the
	 * line number from the diffs.
	 */
	FOR_ALL_WINDOWS(wp)
	{
	    if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb)
	    {
		dlnum = diff_lnum_win(curwin->w_cursor.lnum, wp);
		if (dlnum != 0)
		    (void)setManualFoldWin(wp, dlnum, opening, recurse, NULL);
	    }
	}
    }
#endif

    return setManualFoldWin(curwin, lnum, opening, recurse, donep);
}

/* setManualFoldWin() {{{2 */
/*
 * Open or close the fold in window "wp" which contains "lnum".
 * "donep", when not NULL, points to flag that is set to DONE_FOLD when some
 * fold was found and to DONE_ACTION when some fold was opened or closed.
 * When "donep" is NULL give an error message when no fold was found for
 * "lnum", but only if "wp" is "curwin".
 * Return the line number of the next line that could be closed.
 * It's only valid when "opening" is TRUE!
 */
    static linenr_T
setManualFoldWin(wp, lnum, opening, recurse, donep)
    win_T	*wp;
    linenr_T	lnum;
    int		opening;    /* TRUE when opening, FALSE when closing */
    int		recurse;    /* TRUE when closing/opening recursive */
    int		*donep;
{
    fold_T	*fp;
    fold_T	*fp2;
    fold_T	*found = NULL;
    int		j;
    int		level = 0;
    int		use_level = FALSE;
    int		found_fold = FALSE;
    garray_T	*gap;
    linenr_T	next = MAXLNUM;
    linenr_T	off = 0;
    int		done = 0;

    checkupdate(wp);

    /*
     * Find the fold, open or close it.
     */
    gap = &wp->w_folds;
    for (;;)
    {
	if (!foldFind(gap, lnum, &fp))
	{
	    /* If there is a following fold, continue there next time. */
	    if (fp < (fold_T *)gap->ga_data + gap->ga_len)
		next = fp->fd_top + off;
	    break;
	}

	/* lnum is inside this fold */
	found_fold = TRUE;

	/* If there is a following fold, continue there next time. */
	if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len)
	    next = fp[1].fd_top + off;

	/* Change from level-dependent folding to manual. */
	if (use_level || fp->fd_flags == FD_LEVEL)
	{
	    use_level = TRUE;
	    if (level >= wp->w_p_fdl)
		fp->fd_flags = FD_CLOSED;
	    else
		fp->fd_flags = FD_OPEN;
	    fp2 = (fold_T *)fp->fd_nested.ga_data;
	    for (j = 0; j < fp->fd_nested.ga_len; ++j)
		fp2[j].fd_flags = FD_LEVEL;
	}

	/* Simple case: Close recursively means closing the fold. */
	if (!opening && recurse)
	{
	    if (fp->fd_flags != FD_CLOSED)
	    {
		done |= DONE_ACTION;
		fp->fd_flags = FD_CLOSED;
	    }
	}
	else if (fp->fd_flags == FD_CLOSED)
	{
	    /* When opening, open topmost closed fold. */
	    if (opening)
	    {
		fp->fd_flags = FD_OPEN;
		done |= DONE_ACTION;
		if (recurse)
		    foldOpenNested(fp);
	    }
	    break;
	}

	/* fold is open, check nested folds */
	found = fp;
	gap = &fp->fd_nested;
	lnum -= fp->fd_top;
	off += fp->fd_top;
	++level;
    }
    if (found_fold)
    {
	/* When closing and not recurse, close deepest open fold. */
	if (!opening && found != NULL)
	{
	    found->fd_flags = FD_CLOSED;
	    done |= DONE_ACTION;
	}
	wp->w_fold_manual = TRUE;
	if (done & DONE_ACTION)
	    changed_window_setting_win(wp);
	done |= DONE_FOLD;
    }
    else if (donep == NULL && wp == curwin)
	EMSG(_(e_nofold));

    if (donep != NULL)
	*donep |= done;

    return next;
}

/* foldOpenNested() {{{2 */
/*
 * Open all nested folds in fold "fpr" recursively.
 */
    static void
foldOpenNested(fpr)
    fold_T	*fpr;
{
    int		i;
    fold_T	*fp;

    fp = (fold_T *)fpr->fd_nested.ga_data;
    for (i = 0; i < fpr->fd_nested.ga_len; ++i)
    {
	foldOpenNested(&fp[i]);
	fp[i].fd_flags = FD_OPEN;
    }
}

/* deleteFoldEntry() {{{2 */
/*
 * Delete fold "idx" from growarray "gap".
 * When "recursive" is TRUE also delete all the folds contained in it.
 * When "recursive" is FALSE contained folds are moved one level up.
 */
    static void
deleteFoldEntry(gap, idx, recursive)
    garray_T	*gap;
    int		idx;
    int		recursive;
{
    fold_T	*fp;
    int		i;
    long	moved;
    fold_T	*nfp;

    fp = (fold_T *)gap->ga_data + idx;
    if (recursive || fp->fd_nested.ga_len == 0)
    {
	/* recursively delete the contained folds */
	deleteFoldRecurse(&fp->fd_nested);
	--gap->ga_len;
	if (idx < gap->ga_len)
	    mch_memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx));
    }
    else
    {
	/* move nested folds one level up, to overwrite the fold that is
	 * deleted. */
	moved = fp->fd_nested.ga_len;
	if (ga_grow(gap, (int)(moved - 1)) == OK)
	{
	    /* adjust fd_top and fd_flags for the moved folds */
	    nfp = (fold_T *)fp->fd_nested.ga_data;
	    for (i = 0; i < moved; ++i)
	    {
		nfp[i].fd_top += fp->fd_top;
		if (fp->fd_flags == FD_LEVEL)
		    nfp[i].fd_flags = FD_LEVEL;
		if (fp->fd_small == MAYBE)
		    nfp[i].fd_small = MAYBE;
	    }

	    /* move the existing folds down to make room */
	    if (idx < gap->ga_len)
		mch_memmove(fp + moved, fp + 1,
					sizeof(fold_T) * (gap->ga_len - idx));
	    /* move the contained folds one level up */
	    mch_memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved));
	    vim_free(nfp);
	    gap->ga_len += moved - 1;
	}
    }
}

/* deleteFoldRecurse() {{{2 */
/*
 * Delete nested folds in a fold.
 */
    void
deleteFoldRecurse(gap)
    garray_T	*gap;
{
    int		i;

    for (i = 0; i < gap->ga_len; ++i)
	deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested));
    ga_clear(gap);
}

/* foldMarkAdjust() {{{2 */
/*
 * Update line numbers of folds for inserted/deleted lines.
 */
    void
foldMarkAdjust(wp, line1, line2, amount, amount_after)
    win_T	*wp;
    linenr_T	line1;
    linenr_T	line2;
    long	amount;
    long	amount_after;
{
    /* If deleting marks from line1 to line2, but not deleting all those
     * lines, set line2 so that only deleted lines have their folds removed. */
    if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after)
	line2 = line1 - amount_after - 1;
    /* If appending a line in Insert mode, it should be included in the fold
     * just above the line. */
    if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
	--line1;
    foldMarkAdjustRecurse(&wp->w_folds, line1, line2, amount, amount_after);
}

/* foldMarkAdjustRecurse() {{{2 */
    static void
foldMarkAdjustRecurse(gap, line1, line2, amount, amount_after)
    garray_T	*gap;
    linenr_T	line1;
    linenr_T	line2;
    long	amount;
    long	amount_after;
{
    fold_T	*fp;
    int		i;
    linenr_T	last;
    linenr_T	top;

    /* In Insert mode an inserted line at the top of a fold is considered part
     * of the fold, otherwise it isn't. */
    if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM)
	top = line1 + 1;
    else
	top = line1;

    /* Find the fold containing or just below "line1". */
    (void)foldFind(gap, line1, &fp);

    /*
     * Adjust all folds below "line1" that are affected.
     */
    for (i = (int)(fp - (fold_T *)gap->ga_data); i < gap->ga_len; ++i, ++fp)
    {
	/*
	 * Check for these situations:
	 *	  1  2	3
	 *	  1  2	3
	 * line1     2	3  4  5
	 *	     2	3  4  5
	 *	     2	3  4  5
	 * line2     2	3  4  5
	 *		3     5  6
	 *		3     5  6
	 */

	last = fp->fd_top + fp->fd_len - 1; /* last line of fold */

	/* 1. fold completely above line1: nothing to do */
	if (last < line1)
	    continue;

	/* 6. fold below line2: only adjust for amount_after */
	if (fp->fd_top > line2)
	{
	    if (amount_after == 0)
		break;
	    fp->fd_top += amount_after;
	}
	else
	{
	    if (fp->fd_top >= top && last <= line2)
	    {
		/* 4. fold completely contained in range */
		if (amount == MAXLNUM)
		{
		    /* Deleting lines: delete the fold completely */
		    deleteFoldEntry(gap, i, TRUE);
		    --i;    /* adjust index for deletion */
		    --fp;
		}
		else
		    fp->fd_top += amount;
	    }
	    else
	    {
		/* 2, 3, or 5: need to correct nested folds too */
		foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
				  line2 - fp->fd_top, amount, amount_after);
		if (fp->fd_top < top)
		{
		    if (last <= line2)
		    {
			/* 2. fold contains line1, line2 is below fold */
			if (amount == MAXLNUM)
			    fp->fd_len = line1 - fp->fd_top;
			else
			    fp->fd_len += amount;
		    }
		    else
		    {
			/* 3. fold contains line1 and line2 */
			fp->fd_len += amount_after;
		    }
		}
		else
		{
		    /* 5. fold is below line1 and contains line2 */
		    if (amount == MAXLNUM)
		    {
			fp->fd_len -= line2 - fp->fd_top + 1;
			fp->fd_top = line1;
		    }
		    else
		    {
			fp->fd_len += amount_after - amount;
			fp->fd_top += amount;
		    }
		}
	    }
	}
    }
}

/* getDeepestNesting() {{{2 */
/*
 * Get the lowest 'foldlevel' value that makes the deepest nested fold in the
 * current window open.
 */
    int
getDeepestNesting()
{
    checkupdate(curwin);
    return getDeepestNestingRecurse(&curwin->w_folds);
}

    static int
getDeepestNestingRecurse(gap)
    garray_T	*gap;
{
    int		i;
    int		level;
    int		maxlevel = 0;
    fold_T	*fp;

    fp = (fold_T *)gap->ga_data;
    for (i = 0; i < gap->ga_len; ++i)
    {
	level = getDeepestNestingRecurse(&fp[i].fd_nested) + 1;
	if (level > maxlevel)
	    maxlevel = level;
    }

    return maxlevel;
}

/* check_closed() {{{2 */
/*
 * Check if a fold is closed and update the info needed to check nested folds.
 */
    static int
check_closed(win, fp, use_levelp, level, maybe_smallp, lnum_off)
    win_T	*win;
    fold_T	*fp;
    int		*use_levelp;	    /* TRUE: outer fold had FD_LEVEL */
    int		level;		    /* folding depth */
    int		*maybe_smallp;	    /* TRUE: outer this had fd_small == MAYBE */
    linenr_T	lnum_off;	    /* line number offset for fp->fd_top */
{
    int		closed = FALSE;

    /* Check if this fold is closed.  If the flag is FD_LEVEL this
     * fold and all folds it contains depend on 'foldlevel'. */
    if (*use_levelp || fp->fd_flags == FD_LEVEL)
    {
	*use_levelp = TRUE;
	if (level >= win->w_p_fdl)
	    closed = TRUE;
    }
    else if (fp->fd_flags == FD_CLOSED)
	closed = TRUE;

    /* Small fold isn't closed anyway. */
    if (fp->fd_small == MAYBE)
	*maybe_smallp = TRUE;
    if (closed)
    {
	if (*maybe_smallp)
	    fp->fd_small = MAYBE;
	checkSmall(win, fp, lnum_off);
	if (fp->fd_small == TRUE)
	    closed = FALSE;
    }
    return closed;
}

/* checkSmall() {{{2 */
/*
 * Update fd_small field of fold "fp".
 */
    static void
checkSmall(wp, fp, lnum_off)
    win_T	*wp;
    fold_T	*fp;
    linenr_T	lnum_off;	/* offset for fp->fd_top */
{
    int		count;
    int		n;

    if (fp->fd_small == MAYBE)
    {
	/* Mark any nested folds to maybe-small */
	setSmallMaybe(&fp->fd_nested);

	if (fp->fd_len > curwin->w_p_fml)
	    fp->fd_small = FALSE;
	else
	{
	    count = 0;
	    for (n = 0; n < fp->fd_len; ++n)
	    {
		count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
		if (count > curwin->w_p_fml)
		{
		    fp->fd_small = FALSE;
		    return;
		}
	    }
	    fp->fd_small = TRUE;
	}
    }
}

/* setSmallMaybe() {{{2 */
/*
 * Set small flags in "gap" to MAYBE.
 */
    static void
setSmallMaybe(gap)
    garray_T	*gap;
{
    int		i;
    fold_T	*fp;

    fp = (fold_T *)gap->ga_data;
    for (i = 0; i < gap->ga_len; ++i)
	fp[i].fd_small = MAYBE;
}

/* foldCreateMarkers() {{{2 */
/*
 * Create a fold from line "start" to line "end" (inclusive) in the current
 * window by adding markers.
 */
    static void
foldCreateMarkers(start, end)
    linenr_T	start;
    linenr_T	end;
{
    if (!curbuf->b_p_ma)
    {
	EMSG(_(e_modifiable));
	return;
    }
    parseMarker(curwin);

    foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen);
    foldAddMarker(end, foldendmarker, foldendmarkerlen);

    /* Update both changes here, to avoid all folds after the start are
     * changed when the start marker is inserted and the end isn't. */
    changed_lines(start, (colnr_T)0, end, 0L);
}

/* foldAddMarker() {{{2 */
/*
 * Add "marker[markerlen]" in 'commentstring' to line "lnum".
 */
    static void
foldAddMarker(lnum, marker, markerlen)
    linenr_T	lnum;
    char_u	*marker;
    int		markerlen;
{
    char_u	*cms = curbuf->b_p_cms;
    char_u	*line;
    int		line_len;
    char_u	*newline;
    char_u	*p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");

    /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
    line = ml_get(lnum);
    line_len = (int)STRLEN(line);

    if (u_save(lnum - 1, lnum + 1) == OK)
    {
	newline = alloc((unsigned)(line_len + markerlen + STRLEN(cms) + 1));
	if (newline == NULL)
	    return;
	STRCPY(newline, line);
	if (p == NULL)
	    vim_strncpy(newline + line_len, marker, markerlen);
	else
	{
	    STRCPY(newline + line_len, cms);
	    STRNCPY(newline + line_len + (p - cms), marker, markerlen);
	    STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
	}

	ml_replace(lnum, newline, FALSE);
    }
}

/* deleteFoldMarkers() {{{2 */
/*
 * Delete the markers for a fold, causing it to be deleted.
 */
    static void
deleteFoldMarkers(fp, recursive, lnum_off)
    fold_T	*fp;
    int		recursive;
    linenr_T	lnum_off;	/* offset for fp->fd_top */
{
    int		i;

    if (recursive)
	for (i = 0; i < fp->fd_nested.ga_len; ++i)
	    deleteFoldMarkers((fold_T *)fp->fd_nested.ga_data + i, TRUE,
						       lnum_off + fp->fd_top);
    foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen);
    foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1,
					     foldendmarker, foldendmarkerlen);
}

/* foldDelMarker() {{{2 */
/*
 * Delete marker "marker[markerlen]" at the end of line "lnum".
 * Delete 'commentstring' if it matches.
 * If the marker is not found, there is no error message.  Could a missing
 * close-marker.
 */
    static void
foldDelMarker(lnum, marker, markerlen)
    linenr_T	lnum;
    char_u	*marker;
    int		markerlen;
{
    char_u	*line;
    char_u	*newline;
    char_u	*p;
    int		len;
    char_u	*cms = curbuf->b_p_cms;
    char_u	*cms2;

    line = ml_get(lnum);
    for (p = line; *p != NUL; ++p)
	if (STRNCMP(p, marker, markerlen) == 0)
	{
	    /* Found the marker, include a digit if it's there. */
	    len = markerlen;
	    if (VIM_ISDIGIT(p[len]))
		++len;
	    if (*cms != NUL)
	    {
		/* Also delete 'commentstring' if it matches. */
		cms2 = (char_u *)strstr((char *)cms, "%s");
		if (p - line >= cms2 - cms
			&& STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
			&& STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0)
		{
		    p -= cms2 - cms;
		    len += (int)STRLEN(cms) - 2;
		}
	    }
	    if (u_save(lnum - 1, lnum + 1) == OK)
	    {
		/* Make new line: text-before-marker + text-after-marker */
		newline = alloc((unsigned)(STRLEN(line) - len + 1));
		if (newline != NULL)
		{
		    STRNCPY(newline, line, p - line);
		    STRCPY(newline + (p - line), p + len);
		    ml_replace(lnum, newline, FALSE);
		}
	    }
	    break;
	}
}

/* get_foldtext() {{{2 */
/*
 * Return the text for a closed fold at line "lnum", with last line "lnume".
 * When 'foldtext' isn't set puts the result in "buf[51]".  Otherwise the
 * result is in allocated memory.
 */
    char_u *
get_foldtext(wp, lnum, lnume, foldinfo, buf)
    win_T	*wp;
    linenr_T	lnum, lnume;
    foldinfo_T	*foldinfo;
    char_u	*buf;
{
    char_u	*text = NULL;

#ifdef FEAT_EVAL
    if (*wp->w_p_fdt != NUL)
    {
	char_u	dashes[51];
	win_T	*save_curwin;
	int	level;
	char_u	*p;

	/* Set "v:foldstart" and "v:foldend". */
	set_vim_var_nr(VV_FOLDSTART, lnum);
	set_vim_var_nr(VV_FOLDEND, lnume);

	/* Set "v:folddashes" to a string of "level" dashes. */
	/* Set "v:foldlevel" to "level". */
	level = foldinfo->fi_level;
	if (level > 50)
	    level = 50;
	vim_memset(dashes, '-', (size_t)level);
	dashes[level] = NUL;
	set_vim_var_string(VV_FOLDDASHES, dashes, -1);
	set_vim_var_nr(VV_FOLDLEVEL, (long)level);
	save_curwin = curwin;
	curwin = wp;
	curbuf = wp->w_buffer;

	++emsg_off;
	text = eval_to_string_safe(wp->w_p_fdt, NULL,
			 was_set_insecurely((char_u *)"foldtext", OPT_LOCAL));
	--emsg_off;

	curwin = save_curwin;
	curbuf = curwin->w_buffer;
	set_vim_var_string(VV_FOLDDASHES, NULL, -1);

	if (text != NULL)
	{
	    /* Replace unprintable characters, if there are any.  But
	     * replace a TAB with a space. */
	    for (p = text; *p != NUL; ++p)
	    {
# ifdef FEAT_MBYTE
		int	len;

		if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1)
		{
		    if (!vim_isprintc((*mb_ptr2char)(p)))
			break;
		    p += len - 1;
		}
		else
# endif
		    if (*p == TAB)
			*p = ' ';
		    else if (ptr2cells(p) > 1)
			break;
	    }
	    if (*p != NUL)
	    {
		p = transstr(text);
		vim_free(text);
		text = p;
	    }
	}
    }
    if (text == NULL)
#endif
    {
	sprintf((char *)buf, _("+--%3ld lines folded "),
						    (long)(lnume - lnum + 1));
	text = buf;
    }
    return text;
}

/* foldtext_cleanup() {{{2 */
/*
 * Remove 'foldmarker' and 'commentstring' from "str" (in-place).
 */
    void
foldtext_cleanup(str)
    char_u	*str;
{
    char_u	*cms_start;	/* first part or the whole comment */
    int		cms_slen = 0;	/* length of cms_start */
    char_u	*cms_end;	/* last part of the comment or NULL */
    int		cms_elen = 0;	/* length of cms_end */
    char_u	*s;
    char_u	*p;
    int		len;
    int		did1 = FALSE;
    int		did2 = FALSE;

    /* Ignore leading and trailing white space in 'commentstring'. */
    cms_start = skipwhite(curbuf->b_p_cms);
    cms_slen = (int)STRLEN(cms_start);
    while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
	--cms_slen;

    /* locate "%s" in 'commentstring', use the part before and after it. */
    cms_end = (char_u *)strstr((char *)cms_start, "%s");
    if (cms_end != NULL)
    {
	cms_elen = cms_slen - (int)(cms_end - cms_start);
	cms_slen = (int)(cms_end - cms_start);

	/* exclude white space before "%s" */
	while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
	    --cms_slen;

	/* skip "%s" and white space after it */
	s = skipwhite(cms_end + 2);
	cms_elen -= (int)(s - cms_end);
	cms_end = s;
    }
    parseMarker(curwin);

    for (s = str; *s != NUL; )
    {
	len = 0;
	if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0)
	    len = foldstartmarkerlen;
	else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0)
	    len = foldendmarkerlen;
	if (len > 0)
	{
	    if (VIM_ISDIGIT(s[len]))
		++len;

	    /* May remove 'commentstring' start.  Useful when it's a double
	     * quote and we already removed a double quote. */
	    for (p = s; p > str && vim_iswhite(p[-1]); --p)
		;
	    if (p >= str + cms_slen
			   && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0)
	    {
		len += (int)(s - p) + cms_slen;
		s = p - cms_slen;
	    }
	}
	else if (cms_end != NULL)
	{
	    if (!did1 && cms_slen > 0 && STRNCMP(s, cms_start, cms_slen) == 0)
	    {
		len = cms_slen;
		did1 = TRUE;
	    }
	    else if (!did2 && cms_elen > 0
					&& STRNCMP(s, cms_end, cms_elen) == 0)
	    {
		len = cms_elen;
		did2 = TRUE;
	    }
	}
	if (len != 0)
	{
	    while (vim_iswhite(s[len]))
		++len;
	    STRMOVE(s, s + len);
	}
	else
	{
	    mb_ptr_adv(s);
	}
    }
}

/* Folding by indent, expr, marker and syntax. {{{1 */
/* Define "fline_T", passed to get fold level for a line. {{{2 */
typedef struct
{
    win_T	*wp;		/* window */
    linenr_T	lnum;		/* current line number */
    linenr_T	off;		/* offset between lnum and real line number */
    linenr_T	lnum_save;	/* line nr used by foldUpdateIEMSRecurse() */
    int		lvl;		/* current level (-1 for undefined) */
    int		lvl_next;	/* level used for next line */
    int		start;		/* number of folds that are forced to start at
				   this line. */
    int		end;		/* level of fold that is forced to end below
				   this line */
    int		had_end;	/* level of fold that is forced to end above
				   this line (copy of "end" of prev. line) */
} fline_T;

/* Flag is set when redrawing is needed. */
static int fold_changed;

/* Function declarations. {{{2 */
static linenr_T foldUpdateIEMSRecurse __ARGS((garray_T *gap, int level, linenr_T startlnum, fline_T *flp, void (*getlevel)__ARGS((fline_T *)), linenr_T bot, int topflags));
static int foldInsert __ARGS((garray_T *gap, int i));
static void foldSplit __ARGS((garray_T *gap, int i, linenr_T top, linenr_T bot));
static void foldRemove __ARGS((garray_T *gap, linenr_T top, linenr_T bot));
static void foldMerge __ARGS((fold_T *fp1, garray_T *gap, fold_T *fp2));
static void foldlevelIndent __ARGS((fline_T *flp));
#ifdef FEAT_DIFF
static void foldlevelDiff __ARGS((fline_T *flp));
#endif
static void foldlevelExpr __ARGS((fline_T *flp));
static void foldlevelMarker __ARGS((fline_T *flp));
static void foldlevelSyntax __ARGS((fline_T *flp));

/* foldUpdateIEMS() {{{2 */
/*
 * Update the folding for window "wp", at least from lines "top" to "bot".
 * Return TRUE if any folds did change.
 */
    static void
foldUpdateIEMS(wp, top, bot)
    win_T	*wp;
    linenr_T	top;
    linenr_T	bot;
{
    linenr_T	start;
    linenr_T	end;
    fline_T	fline;
    void	(*getlevel)__ARGS((fline_T *));
    int		level;
    fold_T	*fp;

    /* Avoid problems when being called recursively. */
    if (invalid_top != (linenr_T)0)
	return;

    if (wp->w_foldinvalid)
    {
	/* Need to update all folds. */
	top = 1;
	bot = wp->w_buffer->b_ml.ml_line_count;
	wp->w_foldinvalid = FALSE;

	/* Mark all folds a maybe-small. */
	setSmallMaybe(&wp->w_folds);
    }

#ifdef FEAT_DIFF
    /* add the context for "diff" folding */
    if (foldmethodIsDiff(wp))
    {
	if (top > diff_context)
	    top -= diff_context;
	else
	    top = 1;
	bot += diff_context;
    }
#endif

    /* When deleting lines at the end of the buffer "top" can be past the end
     * of the buffer. */
    if (top > wp->w_buffer->b_ml.ml_line_count)
	top = wp->w_buffer->b_ml.ml_line_count;

    fold_changed = FALSE;
    fline.wp = wp;
    fline.off = 0;
    fline.lvl = 0;
    fline.lvl_next = -1;
    fline.start = 0;
    fline.end = MAX_LEVEL + 1;
    fline.had_end = MAX_LEVEL + 1;

    invalid_top = top;
    invalid_bot = bot;

    if (foldmethodIsMarker(wp))
    {
	getlevel = foldlevelMarker;

	/* Init marker variables to speed up foldlevelMarker(). */
	parseMarker(wp);

	/* Need to get the level of the line above top, it is used if there is
	 * no marker at the top. */
	if (top > 1)
	{
	    /* Get the fold level at top - 1. */
	    level = foldLevelWin(wp, top - 1);

	    /* The fold may end just above the top, check for that. */
	    fline.lnum = top - 1;
	    fline.lvl = level;
	    getlevel(&fline);

	    /* If a fold started here, we already had the level, if it stops
	     * here, we need to use lvl_next.  Could also start and end a fold
	     * in the same line. */
	    if (fline.lvl > level)
		fline.lvl = level - (fline.lvl - fline.lvl_next);
	    else
		fline.lvl = fline.lvl_next;
	}
	fline.lnum = top;
	getlevel(&fline);
    }
    else
    {
	fline.lnum = top;
	if (foldmethodIsExpr(wp))
	{
	    getlevel = foldlevelExpr;
	    /* start one line back, because a "<1" may indicate the end of a
	     * fold in the topline */
	    if (top > 1)
		--fline.lnum;
	}
	else if (foldmethodIsSyntax(wp))
	    getlevel = foldlevelSyntax;
#ifdef FEAT_DIFF
	else if (foldmethodIsDiff(wp))
	    getlevel = foldlevelDiff;
#endif
	else
	    getlevel = foldlevelIndent;

	/* Backup to a line for which the fold level is defined.  Since it's
	 * always defined for line one, we will stop there. */
	fline.lvl = -1;
	for ( ; !got_int; --fline.lnum)
	{
	    /* Reset lvl_next each time, because it will be set to a value for
	     * the next line, but we search backwards here. */
	    fline.lvl_next = -1;
	    getlevel(&fline);
	    if (fline.lvl >= 0)
		break;
	}
    }

    start = fline.lnum;
    end = bot;
    /* Do at least one line. */
    if (start > end && end < wp->w_buffer->b_ml.ml_line_count)
	end = start;
    while (!got_int)
    {
	/* Always stop at the end of the file ("end" can be past the end of
	 * the file). */
	if (fline.lnum > wp->w_buffer->b_ml.ml_line_count)
	    break;
	if (fline.lnum > end)
	{
	    /* For "marker", "expr"  and "syntax"  methods: If a change caused
	     * a fold to be removed, we need to continue at least until where
	     * it ended. */
	    if (getlevel != foldlevelMarker
		    && getlevel != foldlevelSyntax
		    && getlevel != foldlevelExpr)
		break;
	    if ((start <= end
			&& foldFind(&wp->w_folds, end, &fp)
			&& fp->fd_top + fp->fd_len - 1 > end)
		    || (fline.lvl == 0
			&& foldFind(&wp->w_folds, fline.lnum, &fp)
			&& fp->fd_top < fline.lnum))
		end = fp->fd_top + fp->fd_len - 1;
	    else if (getlevel == foldlevelSyntax
		    && foldLevelWin(wp, fline.lnum) != fline.lvl)
		/* For "syntax" method: Compare the foldlevel that the syntax
		 * tells us to the foldlevel from the existing folds.  If they
		 * don't match continue updating folds. */
		end = fline.lnum;
	    else
		break;
	}

	/* A level 1 fold starts at a line with foldlevel > 0. */
	if (fline.lvl > 0)
	{
	    invalid_top = fline.lnum;
	    invalid_bot = end;
	    end = foldUpdateIEMSRecurse(&wp->w_folds,
				   1, start, &fline, getlevel, end, FD_LEVEL);
	    start = fline.lnum;
	}
	else
	{
	    if (fline.lnum == wp->w_buffer->b_ml.ml_line_count)
		break;
	    ++fline.lnum;
	    fline.lvl = fline.lvl_next;
	    getlevel(&fline);
	}
    }

    /* There can't be any folds from start until end now. */
    foldRemove(&wp->w_folds, start, end);

    /* If some fold changed, need to redraw and position cursor. */
    if (fold_changed && wp->w_p_fen)
	changed_window_setting_win(wp);

    /* If we updated folds past "bot", need to redraw more lines.  Don't do
     * this in other situations, the changed lines will be redrawn anyway and
     * this method can cause the whole window to be updated. */
    if (end != bot)
    {
	if (wp->w_redraw_top == 0 || wp->w_redraw_top > top)
	    wp->w_redraw_top = top;
	if (wp->w_redraw_bot < end)
	    wp->w_redraw_bot = end;
    }

    invalid_top = (linenr_T)0;
}

/* foldUpdateIEMSRecurse() {{{2 */
/*
 * Update a fold that starts at "flp->lnum".  At this line there is always a
 * valid foldlevel, and its level >= "level".
 * "flp" is valid for "flp->lnum" when called and it's valid when returning.
 * "flp->lnum" is set to the lnum just below the fold, if it ends before
 * "bot", it's "bot" plus one if the fold continues and it's bigger when using
 * the marker method and a text change made following folds to change.
 * When returning, "flp->lnum_save" is the line number that was used to get
 * the level when the level at "flp->lnum" is invalid.
 * Remove any folds from "startlnum" up to here at this level.
 * Recursively update nested folds.
 * Below line "bot" there are no changes in the text.
 * "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the
 * outer fold.
 * "flp->off" is the offset to the real line number in the buffer.
 *
 * All this would be a lot simpler if all folds in the range would be deleted
 * and then created again.  But we would lose all information about the
 * folds, even when making changes that don't affect the folding (e.g. "vj~").
 *
 * Returns bot, which may have been increased for lines that also need to be
 * updated as a result of a detected change in the fold.
 */
    static linenr_T
foldUpdateIEMSRecurse(gap, level, startlnum, flp, getlevel, bot, topflags)
    garray_T	*gap;
    int		level;
    linenr_T	startlnum;
    fline_T	*flp;
    void	(*getlevel)__ARGS((fline_T *));
    linenr_T	bot;
    int		topflags;	/* flags used by containing fold */
{
    linenr_T	ll;
    fold_T	*fp = NULL;
    fold_T	*fp2;
    int		lvl = level;
    linenr_T	startlnum2 = startlnum;
    linenr_T	firstlnum = flp->lnum;	/* first lnum we got */
    int		i;
    int		finish = FALSE;
    linenr_T	linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
    int		concat;

    /*
     * If using the marker method, the start line is not the start of a fold
     * at the level we're dealing with and the level is non-zero, we must use
     * the previous fold.  But ignore a fold that starts at or below
     * startlnum, it must be deleted.
     */
    if (getlevel == foldlevelMarker && flp->start <= flp->lvl - level
							      && flp->lvl > 0)
    {
	foldFind(gap, startlnum - 1, &fp);
	if (fp >= ((fold_T *)gap->ga_data) + gap->ga_len
						   || fp->fd_top >= startlnum)
	    fp = NULL;
    }

    /*
     * Loop over all lines in this fold, or until "bot" is hit.
     * Handle nested folds inside of this fold.
     * "flp->lnum" is the current line.  When finding the end of the fold, it
     * is just below the end of the fold.
     * "*flp" contains the level of the line "flp->lnum" or a following one if
     * there are lines with an invalid fold level.  "flp->lnum_save" is the
     * line number that was used to get the fold level (below "flp->lnum" when
     * it has an invalid fold level).  When called the fold level is always
     * valid, thus "flp->lnum_save" is equal to "flp->lnum".
     */
    flp->lnum_save = flp->lnum;
    while (!got_int)
    {
	/* Updating folds can be slow, check for CTRL-C. */
	line_breakcheck();

	/* Set "lvl" to the level of line "flp->lnum".  When flp->start is set
	 * and after the first line of the fold, set the level to zero to
	 * force the fold to end.  Do the same when had_end is set: Previous
	 * line was marked as end of a fold. */
	lvl = flp->lvl;
	if (lvl > MAX_LEVEL)
	    lvl = MAX_LEVEL;
	if (flp->lnum > firstlnum
		&& (level > lvl - flp->start || level >= flp->had_end))
	    lvl = 0;

	if (flp->lnum > bot && !finish && fp != NULL)
	{
	    /* For "marker" and "syntax" methods:
	     * - If a change caused a nested fold to be removed, we need to
	     *   delete it and continue at least until where it ended.
	     * - If a change caused a nested fold to be created, or this fold
	     *   to continue below its original end, need to finish this fold.
	     */
	    if (getlevel != foldlevelMarker
		    && getlevel != foldlevelExpr
		    && getlevel != foldlevelSyntax)
		break;
	    i = 0;
	    fp2 = fp;
	    if (lvl >= level)
	    {
		/* Compute how deep the folds currently are, if it's deeper
		 * than "lvl" then some must be deleted, need to update
		 * at least one nested fold. */
		ll = flp->lnum - fp->fd_top;
		while (foldFind(&fp2->fd_nested, ll, &fp2))
		{
		    ++i;
		    ll -= fp2->fd_top;
		}
	    }
	    if (lvl < level + i)
	    {
		foldFind(&fp->fd_nested, flp->lnum - fp->fd_top, &fp2);
		if (fp2 != NULL)
		    bot = fp2->fd_top + fp2->fd_len - 1 + fp->fd_top;
	    }
	    else if (fp->fd_top + fp->fd_len <= flp->lnum && lvl >= level)
		finish = TRUE;
	    else
		break;
	}

	/* At the start of the first nested fold and at the end of the current
	 * fold: check if existing folds at this level, before the current
	 * one, need to be deleted or truncated. */
	if (fp == NULL
		&& (lvl != level
		    || flp->lnum_save >= bot
		    || flp->start != 0
		    || flp->had_end <= MAX_LEVEL
		    || flp->lnum == linecount))
	{
	    /*
	     * Remove or update folds that have lines between startlnum and
	     * firstlnum.
	     */
	    while (!got_int)
	    {
		/* set concat to 1 if it's allowed to concatenated this fold
		 * with a previous one that touches it. */
		if (flp->start != 0 || flp->had_end <= MAX_LEVEL)
		    concat = 0;
		else
		    concat = 1;

		/* Find an existing fold to re-use.  Preferably one that
		 * includes startlnum, otherwise one that ends just before
		 * startlnum or starts after it. */
		if (foldFind(gap, startlnum, &fp)
			|| (fp < ((fold_T *)gap->ga_data) + gap->ga_len
			    && fp->fd_top <= firstlnum)
			|| foldFind(gap, firstlnum - concat, &fp)
			|| (fp < ((fold_T *)gap->ga_data) + gap->ga_len
			    && ((lvl < level && fp->fd_top < flp->lnum)
				|| (lvl >= level
					   && fp->fd_top <= flp->lnum_save))))
		{
		    if (fp->fd_top + fp->fd_len + concat > firstlnum)
		    {
			/* Use existing fold for the new fold.  If it starts
			 * before where we started looking, extend it.  If it
			 * starts at another line, update nested folds to keep
			 * their position, compensating for the new fd_top. */
			if (fp->fd_top >= startlnum && fp->fd_top != firstlnum)
			{
			    if (fp->fd_top > firstlnum)
				/* like lines are inserted */
				foldMarkAdjustRecurse(&fp->fd_nested,
					(linenr_T)0, (linenr_T)MAXLNUM,
					(long)(fp->fd_top - firstlnum), 0L);
			    else
				/* like lines are deleted */
				foldMarkAdjustRecurse(&fp->fd_nested,
					(linenr_T)0,
					(long)(firstlnum - fp->fd_top - 1),
					(linenr_T)MAXLNUM,
					(long)(fp->fd_top - firstlnum));
			    fp->fd_len += fp->fd_top - firstlnum;
			    fp->fd_top = firstlnum;
			    fold_changed = TRUE;
			}
			else if (flp->start != 0 && lvl == level
						   && fp->fd_top != firstlnum)
			{
			    /* Existing fold that includes startlnum must stop
			     * if we find the start of a new fold at the same
			     * level.  Split it.  Delete contained folds at
			     * this point to split them too. */
			    foldRemove(&fp->fd_nested, flp->lnum - fp->fd_top,
						      flp->lnum - fp->fd_top);
			    i = (int)(fp - (fold_T *)gap->ga_data);
			    foldSplit(gap, i, flp->lnum, flp->lnum - 1);
			    fp = (fold_T *)gap->ga_data + i + 1;
			    /* If using the "marker" or "syntax" method, we
			     * need to continue until the end of the fold is
			     * found. */
			    if (getlevel == foldlevelMarker
				    || getlevel == foldlevelExpr
				    || getlevel == foldlevelSyntax)
				finish = TRUE;
			}
			break;
		    }
		    if (fp->fd_top >= startlnum)
		    {
			/* A fold that starts at or after startlnum and stops
			 * before the new fold must be deleted.  Continue
			 * looking for the next one. */
			deleteFoldEntry(gap,
				     (int)(fp - (fold_T *)gap->ga_data), TRUE);
		    }
		    else
		    {
			/* A fold has some lines above startlnum, truncate it
			 * to stop just above startlnum.  */
			fp->fd_len = startlnum - fp->fd_top;
			foldMarkAdjustRecurse(&fp->fd_nested,
				(linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
						       (linenr_T)MAXLNUM, 0L);
			fold_changed = TRUE;
		    }
		}
		else
		{
		    /* Insert new fold.  Careful: ga_data may be NULL and it
		     * may change! */
		    i = (int)(fp - (fold_T *)gap->ga_data);
		    if (foldInsert(gap, i) != OK)
			return bot;
		    fp = (fold_T *)gap->ga_data + i;
		    /* The new fold continues until bot, unless we find the
		     * end earlier. */
		    fp->fd_top = firstlnum;
		    fp->fd_len = bot - firstlnum + 1;
		    /* When the containing fold is open, the new fold is open.
		     * The new fold is closed if the fold above it is closed.
		     * The first fold depends on the containing fold. */
		    if (topflags == FD_OPEN)
		    {
			flp->wp->w_fold_manual = TRUE;
			fp->fd_flags = FD_OPEN;
		    }
		    else if (i <= 0)
		    {
			fp->fd_flags = topflags;
			if (topflags != FD_LEVEL)
			    flp->wp->w_fold_manual = TRUE;
		    }
		    else
			fp->fd_flags = (fp - 1)->fd_flags;
		    fp->fd_small = MAYBE;
		    /* If using the "marker", "expr" or "syntax" method, we
		     * need to continue until the end of the fold is found. */
		    if (getlevel == foldlevelMarker
			    || getlevel == foldlevelExpr
			    || getlevel == foldlevelSyntax)
			finish = TRUE;
		    fold_changed = TRUE;
		    break;
		}
	    }
	}

	if (lvl < level || flp->lnum > linecount)
	{
	    /*
	     * Found a line with a lower foldlevel, this fold ends just above
	     * "flp->lnum".
	     */
	    break;
	}

	/*
	 * The fold includes the line "flp->lnum" and "flp->lnum_save".
	 * Check "fp" for safety.
	 */
	if (lvl > level && fp != NULL)
	{
	    /*
	     * There is a nested fold, handle it recursively.
	     */
	    /* At least do one line (can happen when finish is TRUE). */
	    if (bot < flp->lnum)
		bot = flp->lnum;

	    /* Line numbers in the nested fold are relative to the start of
	     * this fold. */
	    flp->lnum = flp->lnum_save - fp->fd_top;
	    flp->off += fp->fd_top;
	    i = (int)(fp - (fold_T *)gap->ga_data);
	    bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1,
				       startlnum2 - fp->fd_top, flp, getlevel,
					      bot - fp->fd_top, fp->fd_flags);
	    fp = (fold_T *)gap->ga_data + i;
	    flp->lnum += fp->fd_top;
	    flp->lnum_save += fp->fd_top;
	    flp->off -= fp->fd_top;
	    bot += fp->fd_top;
	    startlnum2 = flp->lnum;

	    /* This fold may end at the same line, don't incr. flp->lnum. */
	}
	else
	{
	    /*
	     * Get the level of the next line, then continue the loop to check
	     * if it ends there.
	     * Skip over undefined lines, to find the foldlevel after it.
	     * For the last line in the file the foldlevel is always valid.
	     */
	    flp->lnum = flp->lnum_save;
	    ll = flp->lnum + 1;
	    while (!got_int)
	    {
		/* Make the previous level available to foldlevel(). */
		prev_lnum = flp->lnum;
		prev_lnum_lvl = flp->lvl;

		if (++flp->lnum > linecount)
		    break;
		flp->lvl = flp->lvl_next;
		getlevel(flp);
		if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL)
		    break;
	    }
	    prev_lnum = 0;
	    if (flp->lnum > linecount)
		break;

	    /* leave flp->lnum_save to lnum of the line that was used to get
	     * the level, flp->lnum to the lnum of the next line. */
	    flp->lnum_save = flp->lnum;
	    flp->lnum = ll;
	}
    }

    if (fp == NULL)	/* only happens when got_int is set */
	return bot;

    /*
     * Get here when:
     * lvl < level: the folds ends just above "flp->lnum"
     * lvl >= level: fold continues below "bot"
     */

    /* Current fold at least extends until lnum. */
    if (fp->fd_len < flp->lnum - fp->fd_top)
    {
	fp->fd_len = flp->lnum - fp->fd_top;
	fp->fd_small = MAYBE;
	fold_changed = TRUE;
    }

    /* Delete contained folds from the end of the last one found until where
     * we stopped looking. */
    foldRemove(&fp->fd_nested, startlnum2 - fp->fd_top,
						  flp->lnum - 1 - fp->fd_top);

    if (lvl < level)
    {
	/* End of fold found, update the length when it got shorter. */
	if (fp->fd_len != flp->lnum - fp->fd_top)
	{
	    if (fp->fd_top + fp->fd_len > bot + 1)
	    {
		/* fold continued below bot */
		if (getlevel == foldlevelMarker
			|| getlevel == foldlevelExpr
			|| getlevel == foldlevelSyntax)
		{
		    /* marker method: truncate the fold and make sure the
		     * previously included lines are processed again */
		    bot = fp->fd_top + fp->fd_len - 1;
		    fp->fd_len = flp->lnum - fp->fd_top;
		}
		else
		{
		    /* indent or expr method: split fold to create a new one
		     * below bot */
		    i = (int)(fp - (fold_T *)gap->ga_data);
		    foldSplit(gap, i, flp->lnum, bot);
		    fp = (fold_T *)gap->ga_data + i;
		}
	    }
	    else
		fp->fd_len = flp->lnum - fp->fd_top;
	    fold_changed = TRUE;
	}
    }

    /* delete following folds that end before the current line */
    for (;;)
    {
	fp2 = fp + 1;
	if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len
						  || fp2->fd_top > flp->lnum)
	    break;
	if (fp2->fd_top + fp2->fd_len > flp->lnum)
	{
	    if (fp2->fd_top < flp->lnum)
	    {
		/* Make fold that includes lnum start at lnum. */
		foldMarkAdjustRecurse(&fp2->fd_nested,
			(linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1),
			(linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum));
		fp2->fd_len -= flp->lnum - fp2->fd_top;
		fp2->fd_top = flp->lnum;
		fold_changed = TRUE;
	    }

	    if (lvl >= level)
	    {
		/* merge new fold with existing fold that follows */
		foldMerge(fp, gap, fp2);
	    }
	    break;
	}
	fold_changed = TRUE;
	deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
    }

    /* Need to redraw the lines we inspected, which might be further down than
     * was asked for. */
    if (bot < flp->lnum - 1)
	bot = flp->lnum - 1;

    return bot;
}

/* foldInsert() {{{2 */
/*
 * Insert a new fold in "gap" at position "i".
 * Returns OK for success, FAIL for failure.
 */
    static int
foldInsert(gap, i)
    garray_T	*gap;
    int		i;
{
    fold_T	*fp;

    if (ga_grow(gap, 1) != OK)
	return FAIL;
    fp = (fold_T *)gap->ga_data + i;
    if (i < gap->ga_len)
	mch_memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i));
    ++gap->ga_len;
    ga_init2(&fp->fd_nested, (int)sizeof(fold_T), 10);
    return OK;
}

/* foldSplit() {{{2 */
/*
 * Split the "i"th fold in "gap", which starts before "top" and ends below
 * "bot" in two pieces, one ending above "top" and the other starting below
 * "bot".
 * The caller must first have taken care of any nested folds from "top" to
 * "bot"!
 */
    static void
foldSplit(gap, i, top, bot)
    garray_T	*gap;
    int		i;
    linenr_T	top;
    linenr_T	bot;
{
    fold_T	*fp;
    fold_T	*fp2;
    garray_T	*gap1;
    garray_T	*gap2;
    int		idx;
    int		len;

    /* The fold continues below bot, need to split it. */
    if (foldInsert(gap, i + 1) == FAIL)
	return;
    fp = (fold_T *)gap->ga_data + i;
    fp[1].fd_top = bot + 1;
    fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top);
    fp[1].fd_flags = fp->fd_flags;

    /* Move nested folds below bot to new fold.  There can't be
     * any between top and bot, they have been removed by the caller. */
    gap1 = &fp->fd_nested;
    gap2 = &fp[1].fd_nested;
    (void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2));
    len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
    if (len > 0 && ga_grow(gap2, len) == OK)
    {
	for (idx = 0; idx < len; ++idx)
	{
	    ((fold_T *)gap2->ga_data)[idx] = fp2[idx];
	    ((fold_T *)gap2->ga_data)[idx].fd_top
						 -= fp[1].fd_top - fp->fd_top;
	}
	gap2->ga_len = len;
	gap1->ga_len -= len;
    }
    fp->fd_len = top - fp->fd_top;
    fold_changed = TRUE;
}

/* foldRemove() {{{2 */
/*
 * Remove folds within the range "top" to and including "bot".
 * Check for these situations:
 *      1  2  3
 *      1  2  3
 * top     2  3  4  5
 *	   2  3  4  5
 * bot	   2  3  4  5
 *	      3     5  6
 *	      3     5  6
 *
 * 1: not changed
 * 2: truncate to stop above "top"
 * 3: split in two parts, one stops above "top", other starts below "bot".
 * 4: deleted
 * 5: made to start below "bot".
 * 6: not changed
 */
    static void
foldRemove(gap, top, bot)
    garray_T	*gap;
    linenr_T	top;
    linenr_T	bot;
{
    fold_T	*fp = NULL;

    if (bot < top)
	return;		/* nothing to do */

    for (;;)
    {
	/* Find fold that includes top or a following one. */
	if (foldFind(gap, top, &fp) && fp->fd_top < top)
	{
	    /* 2: or 3: need to delete nested folds */
	    foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
	    if (fp->fd_top + fp->fd_len > bot + 1)
	    {
		/* 3: need to split it. */
		foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
	    }
	    else
	    {
		/* 2: truncate fold at "top". */
		fp->fd_len = top - fp->fd_top;
	    }
	    fold_changed = TRUE;
	    continue;
	}
	if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len
		|| fp->fd_top > bot)
	{
	    /* 6: Found a fold below bot, can stop looking. */
	    break;
	}
	if (fp->fd_top >= top)
	{
	    /* Found an entry below top. */
	    fold_changed = TRUE;
	    if (fp->fd_top + fp->fd_len - 1 > bot)
	    {
		/* 5: Make fold that includes bot start below bot. */
		foldMarkAdjustRecurse(&fp->fd_nested,
			(linenr_T)0, (long)(bot - fp->fd_top),
			(linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
		fp->fd_len -= bot - fp->fd_top + 1;
		fp->fd_top = bot + 1;
		break;
	    }

	    /* 4: Delete completely contained fold. */
	    deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE);
	}
    }
}

/* foldMerge() {{{2 */
/*
 * Merge two adjacent folds (and the nested ones in them).
 * This only works correctly when the folds are really adjacent!  Thus "fp1"
 * must end just above "fp2".
 * The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1".
 * Fold entry "fp2" in "gap" is deleted.
 */
    static void
foldMerge(fp1, gap, fp2)
    fold_T	*fp1;
    garray_T	*gap;
    fold_T	*fp2;
{
    fold_T	*fp3;
    fold_T	*fp4;
    int		idx;
    garray_T	*gap1 = &fp1->fd_nested;
    garray_T	*gap2 = &fp2->fd_nested;

    /* If the last nested fold in fp1 touches the first nested fold in fp2,
     * merge them recursively. */
    if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4))
	foldMerge(fp3, gap2, fp4);

    /* Move nested folds in fp2 to the end of fp1. */
    if (gap2->ga_len > 0 && ga_grow(gap1, gap2->ga_len) == OK)
    {
	for (idx = 0; idx < gap2->ga_len; ++idx)
	{
	    ((fold_T *)gap1->ga_data)[gap1->ga_len]
					= ((fold_T *)gap2->ga_data)[idx];
	    ((fold_T *)gap1->ga_data)[gap1->ga_len].fd_top += fp1->fd_len;
	    ++gap1->ga_len;
	}
	gap2->ga_len = 0;
    }

    fp1->fd_len += fp2->fd_len;
    deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
    fold_changed = TRUE;
}

/* foldlevelIndent() {{{2 */
/*
 * Low level function to get the foldlevel for the "indent" method.
 * Doesn't use any caching.
 * Returns a level of -1 if the foldlevel depends on surrounding lines.
 */
    static void
foldlevelIndent(flp)
    fline_T	*flp;
{
    char_u	*s;
    buf_T	*buf;
    linenr_T	lnum = flp->lnum + flp->off;

    buf = flp->wp->w_buffer;
    s = skipwhite(ml_get_buf(buf, lnum, FALSE));

    /* empty line or lines starting with a character in 'foldignore': level
     * depends on surrounding lines */
    if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL)
    {
	/* first and last line can't be undefined, use level 0 */
	if (lnum == 1 || lnum == buf->b_ml.ml_line_count)
	    flp->lvl = 0;
	else
	    flp->lvl = -1;
    }
    else
	flp->lvl = get_indent_buf(buf, lnum) / buf->b_p_sw;
    if (flp->lvl > flp->wp->w_p_fdn)
    {
	flp->lvl = flp->wp->w_p_fdn;
	if (flp->lvl < 0)
	    flp->lvl = 0;
    }
}

/* foldlevelDiff() {{{2 */
#ifdef FEAT_DIFF
/*
 * Low level function to get the foldlevel for the "diff" method.
 * Doesn't use any caching.
 */
    static void
foldlevelDiff(flp)
    fline_T	*flp;
{
    if (diff_infold(flp->wp, flp->lnum + flp->off))
	flp->lvl = 1;
    else
	flp->lvl = 0;
}
#endif

/* foldlevelExpr() {{{2 */
/*
 * Low level function to get the foldlevel for the "expr" method.
 * Doesn't use any caching.
 * Returns a level of -1 if the foldlevel depends on surrounding lines.
 */
    static void
foldlevelExpr(flp)
    fline_T	*flp;
{
#ifndef FEAT_EVAL
    flp->start = FALSE;
    flp->lvl = 0;
#else
    win_T	*win;
    int		n;
    int		c;
    linenr_T	lnum = flp->lnum + flp->off;
    int		save_keytyped;

    win = curwin;
    curwin = flp->wp;
    curbuf = flp->wp->w_buffer;
    set_vim_var_nr(VV_LNUM, lnum);

    flp->start = 0;
    flp->had_end = flp->end;
    flp->end = MAX_LEVEL + 1;
    if (lnum <= 1)
	flp->lvl = 0;

    /* KeyTyped may be reset to 0 when calling a function which invokes
     * do_cmdline().  To make 'foldopen' work correctly restore KeyTyped. */
    save_keytyped = KeyTyped;
    n = eval_foldexpr(flp->wp->w_p_fde, &c);
    KeyTyped = save_keytyped;

    switch (c)
    {
	/* "a1", "a2", .. : add to the fold level */
	case 'a': if (flp->lvl >= 0)
		  {
		      flp->lvl += n;
		      flp->lvl_next = flp->lvl;
		  }
		  flp->start = n;
		  break;

	/* "s1", "s2", .. : subtract from the fold level */
	case 's': if (flp->lvl >= 0)
		  {
		      if (n > flp->lvl)
			  flp->lvl_next = 0;
		      else
			  flp->lvl_next = flp->lvl - n;
		      flp->end = flp->lvl_next + 1;
		  }
		  break;

	/* ">1", ">2", .. : start a fold with a certain level */
	case '>': flp->lvl = n;
		  flp->lvl_next = n;
		  flp->start = 1;
		  break;

	/* "<1", "<2", .. : end a fold with a certain level */
	case '<': flp->lvl_next = n - 1;
		  flp->end = n;
		  break;

	/* "=": No change in level */
	case '=': flp->lvl_next = flp->lvl;
		  break;

	/* "-1", "0", "1", ..: set fold level */
	default:  if (n < 0)
		      /* Use the current level for the next line, so that "a1"
		       * will work there. */
		      flp->lvl_next = flp->lvl;
		  else
		      flp->lvl_next = n;
		  flp->lvl = n;
		  break;
    }

    /* If the level is unknown for the first or the last line in the file, use
     * level 0. */
    if (flp->lvl < 0)
    {
	if (lnum <= 1)
	{
	    flp->lvl = 0;
	    flp->lvl_next = 0;
	}
	if (lnum == curbuf->b_ml.ml_line_count)
	    flp->lvl_next = 0;
    }

    curwin = win;
    curbuf = curwin->w_buffer;
#endif
}

/* parseMarker() {{{2 */
/*
 * Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and
 * "foldendmarkerlen".
 * Relies on the option value to have been checked for correctness already.
 */
    static void
parseMarker(wp)
    win_T	*wp;
{
    foldendmarker = vim_strchr(wp->w_p_fmr, ',');
    foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr);
    foldendmarkerlen = (int)STRLEN(foldendmarker);
}

/* foldlevelMarker() {{{2 */
/*
 * Low level function to get the foldlevel for the "marker" method.
 * "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been
 * set before calling this.
 * Requires that flp->lvl is set to the fold level of the previous line!
 * Careful: This means you can't call this function twice on the same line.
 * Doesn't use any caching.
 * Sets flp->start when a start marker was found.
 */
    static void
foldlevelMarker(flp)
    fline_T	*flp;
{
    char_u	*startmarker;
    int		cstart;
    int		cend;
    int		start_lvl = flp->lvl;
    char_u	*s;
    int		n;

    /* cache a few values for speed */
    startmarker = flp->wp->w_p_fmr;
    cstart = *startmarker;
    ++startmarker;
    cend = *foldendmarker;

    /* Default: no start found, next level is same as current level */
    flp->start = 0;
    flp->lvl_next = flp->lvl;

    s = ml_get_buf(flp->wp->w_buffer, flp->lnum + flp->off, FALSE);
    while (*s)
    {
	if (*s == cstart
		  && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0)
	{
	    /* found startmarker: set flp->lvl */
	    s += foldstartmarkerlen;
	    if (VIM_ISDIGIT(*s))
	    {
		n = atoi((char *)s);
		if (n > 0)
		{
		    flp->lvl = n;
		    flp->lvl_next = n;
		    if (n <= start_lvl)
			flp->start = 1;
		    else
			flp->start = n - start_lvl;
		}
	    }
	    else
	    {
		++flp->lvl;
		++flp->lvl_next;
		++flp->start;
	    }
	}
	else if (*s == cend
	      && STRNCMP(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0)
	{
	    /* found endmarker: set flp->lvl_next */
	    s += foldendmarkerlen;
	    if (VIM_ISDIGIT(*s))
	    {
		n = atoi((char *)s);
		if (n > 0)
		{
		    flp->lvl = n;
		    flp->lvl_next = n - 1;
		    /* never start a fold with an end marker */
		    if (flp->lvl_next > flp->lvl)
			flp->lvl_next = flp->lvl;
		}
	    }
	    else
		--flp->lvl_next;
	}
	else
	    mb_ptr_adv(s);
    }

    /* The level can't go negative, must be missing a start marker. */
    if (flp->lvl_next < 0)
	flp->lvl_next = 0;
}

/* foldlevelSyntax() {{{2 */
/*
 * Low level function to get the foldlevel for the "syntax" method.
 * Doesn't use any caching.
 */
    static void
foldlevelSyntax(flp)
    fline_T	*flp;
{
#ifndef FEAT_SYN_HL
    flp->start = 0;
    flp->lvl = 0;
#else
    linenr_T	lnum = flp->lnum + flp->off;
    int		n;

    /* Use the maximum fold level at the start of this line and the next. */
    flp->lvl = syn_get_foldlevel(flp->wp, lnum);
    flp->start = 0;
    if (lnum < flp->wp->w_buffer->b_ml.ml_line_count)
    {
	n = syn_get_foldlevel(flp->wp, lnum + 1);
	if (n > flp->lvl)
	{
	    flp->start = n - flp->lvl;	/* fold(s) start here */
	    flp->lvl = n;
	}
    }
#endif
}

/* functions for storing the fold state in a View {{{1 */
/* put_folds() {{{2 */
#if defined(FEAT_SESSION) || defined(PROTO)
static int put_folds_recurse __ARGS((FILE *fd, garray_T *gap, linenr_T off));
static int put_foldopen_recurse __ARGS((FILE *fd, garray_T *gap, linenr_T off));

/*
 * Write commands to "fd" to restore the manual folds in window "wp".
 * Return FAIL if writing fails.
 */
    int
put_folds(fd, wp)
    FILE	*fd;
    win_T	*wp;
{
    if (foldmethodIsManual(wp))
    {
	if (put_line(fd, "silent! normal! zE") == FAIL
		|| put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL)
	    return FAIL;
    }

    /* If some folds are manually opened/closed, need to restore that. */
    if (wp->w_fold_manual)
	return put_foldopen_recurse(fd, &wp->w_folds, (linenr_T)0);

    return OK;
}

/* put_folds_recurse() {{{2 */
/*
 * Write commands to "fd" to recreate manually created folds.
 * Returns FAIL when writing failed.
 */
    static int
put_folds_recurse(fd, gap, off)
    FILE	*fd;
    garray_T	*gap;
    linenr_T	off;
{
    int		i;
    fold_T	*fp;

    fp = (fold_T *)gap->ga_data;
    for (i = 0; i < gap->ga_len; i++)
    {
	/* Do nested folds first, they will be created closed. */
	if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL)
	    return FAIL;
	if (fprintf(fd, "%ld,%ldfold", fp->fd_top + off,
					fp->fd_top + off + fp->fd_len - 1) < 0
		|| put_eol(fd) == FAIL)
	    return FAIL;
	++fp;
    }
    return OK;
}

/* put_foldopen_recurse() {{{2 */
/*
 * Write commands to "fd" to open and close manually opened/closed folds.
 * Returns FAIL when writing failed.
 */
    static int
put_foldopen_recurse(fd, gap, off)
    FILE	*fd;
    garray_T	*gap;
    linenr_T	off;
{
    int		i;
    fold_T	*fp;

    fp = (fold_T *)gap->ga_data;
    for (i = 0; i < gap->ga_len; i++)
    {
	if (fp->fd_flags != FD_LEVEL)
	{
	    if (fp->fd_nested.ga_len > 0)
	    {
		/* open/close nested folds while this fold is open */
		if (fprintf(fd, "%ld", fp->fd_top + off) < 0
			|| put_eol(fd) == FAIL
			|| put_line(fd, "normal zo") == FAIL)
		    return FAIL;
		if (put_foldopen_recurse(fd, &fp->fd_nested, off + fp->fd_top)
			== FAIL)
		    return FAIL;
	    }
	    if (fprintf(fd, "%ld", fp->fd_top + off) < 0
		    || put_eol(fd) == FAIL
		    || fprintf(fd, "normal z%c",
				    fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0
		    || put_eol(fd) == FAIL)
		return FAIL;
	}
	++fp;
    }

    return OK;
}
#endif /* FEAT_SESSION */

/* }}}1 */
#endif /* defined(FEAT_FOLDING) || defined(PROTO) */
