/* vim:set ts=8 sts=4 sw=4:
 *
 * 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.
 */

/*
 * diff.c: code for diff'ing two or three buffers.
 */

#include "vim.h"

#if defined(FEAT_DIFF) || defined(PROTO)

#define DB_COUNT 4	/* up to four buffers can be diff'ed */

/*
 * Each diffblock defines where a block of lines starts in each of the buffers
 * and how many lines it occupies in that buffer.  When the lines are missing
 * in the buffer the df_count[] is zero.  This is all counted in
 * buffer lines.
 * There is always at least one unchanged line in between the diffs.
 * Otherwise it would have been included in the diff above or below it.
 * df_lnum[] + df_count[] is the lnum below the change.  When in one buffer
 * lines have been inserted, in the other buffer df_lnum[] is the line below
 * the insertion and df_count[] is zero.  When appending lines at the end of
 * the buffer, df_lnum[] is one beyond the end!
 * This is using a linked list, because the number of differences is expected
 * to be reasonable small.  The list is sorted on lnum.
 */
typedef struct diffblock diff_T;
struct diffblock
{
    diff_T	*df_next;
    linenr_T	df_lnum[DB_COUNT];	/* line number in buffer */
    linenr_T	df_count[DB_COUNT];	/* nr of inserted/changed lines */
};

static diff_T	*first_diff = NULL;

static buf_T	*(diffbuf[DB_COUNT]);

static int	diff_invalid = TRUE;	/* list of diffs is outdated */

static int	diff_busy = FALSE;	/* ex_diffgetput() is busy */

/* flags obtained from the 'diffopt' option */
#define DIFF_FILLER	1	/* display filler lines */
#define DIFF_ICASE	2	/* ignore case */
#define DIFF_IWHITE	4	/* ignore change in white space */
static int	diff_flags = DIFF_FILLER;

#define LBUFLEN 50		/* length of line in diff file */

static int diff_a_works = MAYBE; /* TRUE when "diff -a" works, FALSE when it
				    doesn't work, MAYBE when not checked yet */
#if defined(MSWIN) || defined(MSDOS)
static int diff_bin_works = MAYBE; /* TRUE when "diff --binary" works, FALSE
				      when it doesn't work, MAYBE when not
				      checked yet */
#endif

static int diff_buf_idx __ARGS((buf_T *buf));
static void diff_check_unchanged __ARGS((diff_T *dp));
static int diff_check_sanity __ARGS((diff_T *dp));
static void diff_redraw __ARGS((int dofold));
static int diff_write __ARGS((buf_T *buf, char_u *fname));
static void diff_file __ARGS((char_u *tmp_orig, char_u *tmp_new, char_u *tmp_diff));
static int diff_equal_entry __ARGS((diff_T *dp, int idx1, int idx2));
static int diff_cmp __ARGS((char_u *s1, char_u *s2));
#ifdef FEAT_FOLDING
static void diff_fold_update __ARGS((diff_T *dp, int skip_idx));
#endif
static void diff_read __ARGS((int idx_orig, int idx_new, char_u *fname));
static void diff_copy_entry __ARGS((diff_T *dprev, diff_T *dp, int idx_orig, int idx_new));
static diff_T *diff_alloc_new __ARGS((diff_T *dprev, diff_T *dp));

#ifndef USE_CR
# define tag_fgets vim_fgets
#endif

/*
 * Call this when a new buffer is being edited in the current window.  curbuf
 * must already have been set.
 * Marks the current buffer as being part of the diff and requireing updating.
 * This must be done before any autocmd, because a command the uses info
 * about the screen contents.
 */
    void
diff_new_buffer()
{
    if (curwin->w_p_diff)
	diff_buf_add(curbuf);
}

/*
 * Called when deleting or unloading a buffer: No longer make a diff with it.
 * Also called when 'diff' is reset in the last window showing a diff for a
 * buffer.
 */
    void
diff_buf_delete(buf)
    buf_T	*buf;
{
    int		i;

    i = diff_buf_idx(buf);
    if (i != DB_COUNT)
    {
	diffbuf[i] = NULL;
	diff_invalid = TRUE;
    }
}

/*
 * Check if the current buffer should be added to or removed from the list of
 * diff buffers.
 */
    void
diff_buf_adjust(win)
    win_T	*win;
{
    win_T	*wp;

    if (!win->w_p_diff)
    {
	/* When there is no window showing a diff for this buffer, remove
	 * it from the diffs. */
	for (wp = firstwin; wp != NULL; wp = wp->w_next)
	    if (wp->w_buffer == win->w_buffer && wp->w_p_diff)
		break;
	if (wp == NULL)
	    diff_buf_delete(win->w_buffer);
    }
    else
	diff_buf_add(win->w_buffer);
}

/*
 * Add a buffer to make diffs for.
 */
    void
diff_buf_add(buf)
    buf_T	*buf;
{
    int		i;

    if (diff_buf_idx(buf) != DB_COUNT)
	return;		/* It's already there. */

    for (i = 0; i < DB_COUNT; ++i)
	if (diffbuf[i] == NULL)
	{
	    diffbuf[i] = buf;
	    diff_invalid = TRUE;
	    return;
	}

    EMSGN(_("E96: Can not diff more than %ld buffers"), DB_COUNT);
}

/*
 * Find buffer "buf" in the list of diff buffers.
 * Return its index or DB_COUNT if not found.
 */
    static int
diff_buf_idx(buf)
    buf_T	*buf;
{
    int		idx;

    for (idx = 0; idx < DB_COUNT; ++idx)
	if (diffbuf[idx] == buf)
	    break;
    return idx;
}

/*
 * Mark the diff info as invalid, it will be updated when info is requested.
 */
    void
diff_invalidate()
{
    if (curwin->w_p_diff)
    {
	diff_invalid = TRUE;
	diff_redraw(TRUE);
    }
}

/*
 * Called by mark_adjust(): update line numbers.
 * This attempts to update the changes as much as possible:
 * When inserting/deleting lines outside of existing change blocks, create a
 * new change block and update the line numbers in following blocks.
 * When inserting/deleting lines in existing change blocks, update them.
 */
    void
diff_mark_adjust(line1, line2, amount, amount_after)
    linenr_T	line1;
    linenr_T	line2;
    long	amount;
    long	amount_after;
{
    diff_T	*dp;
    diff_T	*dprev;
    diff_T	*dnext;
    int		idx;
    int		i;
    int		inserted, deleted;
    int		n, off;
    linenr_T	last;
    linenr_T	lnum_deleted = line1;	/* lnum of remaining deletion */
    int		check_unchanged;

    /* Find the index for the current buffer. */
    idx = diff_buf_idx(curbuf);
    if (idx == DB_COUNT)
	return;		/* This buffer doesn't have diffs. */

    if (line2 == MAXLNUM)
    {
	/* mark_adjust(99, MAXLNUM, 9, 0): insert lines */
	inserted = amount;
	deleted = 0;
    }
    else if (amount_after > 0)
    {
	/* mark_adjust(99, 98, MAXLNUM, 9): a change that inserts lines*/
	inserted = amount_after;
	deleted = 0;
    }
    else
    {
	/* mark_adjust(98, 99, MAXLNUM, -2): delete lines */
	inserted = 0;
	deleted = -amount_after;
    }

    dprev = NULL;
    dp = first_diff;
    for (;;)
    {
	/* If the change is after the previous diff block and before the next
	 * diff block, thus not touching an existing change, create a new diff
	 * block.  Don't do this when ex_diffgetput() is busy. */
	if ((dp == NULL || dp->df_lnum[idx] - 1 > line2
		    || (line2 == MAXLNUM && dp->df_lnum[idx] > line1))
		&& (dprev == NULL
		    || dprev->df_lnum[idx] + dprev->df_count[idx] < line1)
		&& !diff_busy)
	{
	    dnext = diff_alloc_new(dprev, dp);
	    if (dnext == NULL)
		return;

	    dnext->df_lnum[idx] = line1;
	    dnext->df_count[idx] = inserted;
	    for (i = 0; i < DB_COUNT; ++i)
		if (diffbuf[i] != NULL && i != idx)
		{
		    if (dprev == NULL)
			dnext->df_lnum[i] = line1;
		    else
			dnext->df_lnum[i] = line1
			    + (dprev->df_lnum[i] + dprev->df_count[i])
			    - (dprev->df_lnum[idx] + dprev->df_count[idx]);
		    dnext->df_count[i] = deleted;
		}
	}

	/* if at end of the list, quit */
	if (dp == NULL)
	    break;

	/*
	 * 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
	 */
	/* compute last line of this change */
	last = dp->df_lnum[idx] + dp->df_count[idx] - 1;

	/* 1. change completely above line1: nothing to do */
	if (last >= line1 - 1)
	{
	    /* 6. change below line2: only adjust for amount_after; also when
	     * "deleted" became zero when deleted all lines between two diffs */
	    if (dp->df_lnum[idx] - (deleted + inserted != 0) > line2)
	    {
		if (amount_after == 0)
		    break;	/* nothing left to change */
		dp->df_lnum[idx] += amount_after;
	    }
	    else
	    {
		check_unchanged = FALSE;

		/* 2. 3. 4. 5.: inserted/deleted lines touching this diff. */
		if (deleted > 0)
		{
		    if (dp->df_lnum[idx] >= line1)
		    {
			off = dp->df_lnum[idx] - lnum_deleted;
			if (last <= line2)
			{
			    /* 4. delete all lines of diff */
			    if (dp->df_next != NULL
				    && dp->df_next->df_lnum[idx] - 1 <= line2)
			    {
				/* delete continues in next diff, only do
				 * lines until that one */
				n = dp->df_next->df_lnum[idx] - lnum_deleted;
				deleted -= n;
				n -= dp->df_count[idx];
				lnum_deleted = dp->df_next->df_lnum[idx];
			    }
			    else
				n = deleted - dp->df_count[idx];
			    dp->df_count[idx] = 0;
			}
			else
			{
			    /* 5. delete lines at or just before top of diff */
			    n = off;
			    dp->df_count[idx] -= line2 - dp->df_lnum[idx] + 1;
			    check_unchanged = TRUE;
			}
			dp->df_lnum[idx] = line1;
		    }
		    else
		    {
			off = 0;
			if (last < line2)
			{
			    /* 2. delete at end of of diff */
			    dp->df_count[idx] -= last - lnum_deleted + 1;
			    if (dp->df_next != NULL
				    && dp->df_next->df_lnum[idx] - 1 <= line2)
			    {
				/* delete continues in next diff, only do
				 * lines until that one */
				n = dp->df_next->df_lnum[idx] - 1 - last;
				deleted -= dp->df_next->df_lnum[idx]
							       - lnum_deleted;
				lnum_deleted = dp->df_next->df_lnum[idx];
			    }
			    else
				n = line2 - last;
			    check_unchanged = TRUE;
			}
			else
			{
			    /* 3. delete lines inside the diff */
			    n = 0;
			    dp->df_count[idx] -= deleted;
			}
		    }

		    for (i = 0; i < DB_COUNT; ++i)
			if (diffbuf[i] != NULL && i != idx)
			{
			    dp->df_lnum[i] -= off;
			    dp->df_count[i] += n;
			}
		}
		else
		{
		    if (dp->df_lnum[idx] <= line1)
		    {
			/* inserted lines somewhere in this diff */
			dp->df_count[idx] += inserted;
			check_unchanged = TRUE;
		    }
		    else
			/* inserted lines somewhere above this diff */
			dp->df_lnum[idx] += inserted;
		}

		if (check_unchanged)
		    /* Check if inserted lines are equal, may reduce the
		     * size of the diff.  TODO: also check for equal lines
		     * in the middle and perhaps split the block. */
		    diff_check_unchanged(dp);
	    }
	}

	/* check if this block touches the previous one, may merge them. */
	if (dprev != NULL && dprev->df_lnum[idx] + dprev->df_count[idx]
							  == dp->df_lnum[idx])
	{
	    for (i = 0; i < DB_COUNT; ++i)
		if (diffbuf[i] != NULL)
		    dprev->df_count[i] += dp->df_count[i];
	    dprev->df_next = dp->df_next;
	    vim_free(dp);
	    dp = dprev->df_next;
	}
	else
	{
	    /* Advance to next entry. */
	    dprev = dp;
	    dp = dp->df_next;
	}
    }

    dprev = NULL;
    dp = first_diff;
    while (dp != NULL)
    {
	/* All counts are zero, remove this entry. */
	for (i = 0; i < DB_COUNT; ++i)
	    if (diffbuf[i] != NULL && dp->df_count[i] != 0)
		break;
	if (i == DB_COUNT)
	{
	    dnext = dp->df_next;
	    vim_free(dp);
	    dp = dnext;
	    if (dprev == NULL)
		first_diff = dnext;
	    else
		dprev->df_next = dnext;
	}
	else
	{
	    /* Advance to next entry. */
	    dprev = dp;
	    dp = dp->df_next;
	}

    }
    diff_redraw(TRUE);

    /* Recompute the scroll binding, may remove or add filler lines (e.g.,
     * when adding lines above w_topline). */
    check_scrollbind((linenr_T)0, 0L);
}

/*
 * Allocate a new diff block and link it between "dprev" and "dp".
 */
    static diff_T *
diff_alloc_new(dprev, dp)
    diff_T	*dprev;
    diff_T	*dp;
{
    diff_T	*dnew;

    dnew = (diff_T *)alloc((unsigned)sizeof(diff_T));
    if (dnew != NULL)
    {
	dnew->df_next = dp;
	if (dprev == NULL)
	    first_diff = dnew;
	else
	    dprev->df_next = dnew;
    }
    return dnew;
}

/*
 * Check if the diff block "dp" can be made smaller for lines at the start and
 * end that are equal.  Called after inserting lines.
 * This may result in a change where all buffers have zero lines, the caller
 * must take care of removing it.
 */
    static void
diff_check_unchanged(dp)
    diff_T	*dp;
{
    int		i_org;
    int		i_new;
    int		off_org, off_new;
    char_u	*line_org;
    int		dir = FORWARD;

    /* Find the first buffers, use it as the original, compare the other
     * buffer lines against this one. */
    for (i_org = 0; i_org < DB_COUNT; ++i_org)
	if (diffbuf[i_org] != NULL)
	    break;
    if (i_org == DB_COUNT)	/* safety check */
	return;

    if (diff_check_sanity(dp) == FAIL)
	return;

    /* First check lines at the top, then at the bottom. */
    off_org = 0;
    off_new = 0;
    for (;;)
    {
	/* Repeat until a line is found which is different or the number of
	 * lines has become zero. */
	while (dp->df_count[i_org] > 0)
	{
	    /* Copy the line, the next ml_get() will invalidate it.  */
	    if (dir == BACKWARD)
		off_org = dp->df_count[i_org] - 1;
	    line_org = vim_strsave(ml_get_buf(diffbuf[i_org],
					dp->df_lnum[i_org] + off_org, FALSE));
	    if (line_org == NULL)
		return;
	    for (i_new = i_org + 1; i_new < DB_COUNT; ++i_new)
	    {
		if (diffbuf[i_new] == NULL)
		    continue;
		if (dir == BACKWARD)
		    off_new = dp->df_count[i_new] - 1;
		/* if other buffer doesn't have this line, it was inserted */
		if (off_new < 0 || off_new >= dp->df_count[i_new])
		    break;
		if (diff_cmp(line_org, ml_get_buf(diffbuf[i_new],
				   dp->df_lnum[i_new] + off_new, FALSE)) != 0)
		    break;
	    }
	    vim_free(line_org);

	    /* Stop when a line isn't equal in all diff buffers. */
	    if (i_new != DB_COUNT)
		break;

	    /* Line matched in all buffers, remove it from the diff. */
	    for (i_new = i_org; i_new < DB_COUNT; ++i_new)
		if (diffbuf[i_new] != NULL)
		{
		    if (dir == FORWARD)
			++dp->df_lnum[i_new];
		    --dp->df_count[i_new];
		}
	}
	if (dir == BACKWARD)
	    break;
	dir = BACKWARD;
    }
}

/*
 * Check if a diff block doesn't contain invalid line numbers.
 * This can happen when the diff program returns invalid results.
 */
    static int
diff_check_sanity(dp)
    diff_T	*dp;
{
    int		i;

    for (i = 0; i < DB_COUNT; ++i)
	if (diffbuf[i] != NULL)
	    if (dp->df_lnum[i] + dp->df_count[i] - 1
					     > diffbuf[i]->b_ml.ml_line_count)
		return FAIL;
    return OK;
}

/*
 * Mark all diff buffers for redraw.
 */
    static void
diff_redraw(dofold)
    int		dofold;	    /* also recompute the folds */
{
    win_T	*wp;
    int		n;

    for (wp = firstwin; wp != NULL; wp = wp->w_next)
	if (wp->w_p_diff)
	{
	    redraw_win_later(wp, NOT_VALID);
#ifdef FEAT_FOLDING
	    if (dofold && foldmethodIsDiff(wp))
		foldUpdateAll(wp);
#endif
	    /* A change may have made filler lines invalid, need to take care
	     * of that for other windows. */
	    if (wp != curwin && wp->w_topfill > 0)
	    {
		n = diff_check(wp, wp->w_topline);
		if (wp->w_topfill > n)
		    wp->w_topfill = (n < 0 ? 0 : n);
	    }
	}
}

/*
 * Write buffer "buf" to file "name".
 * Always use 'fileformat' set to "unix".
 * Return FAIL for failure
 */
    static int
diff_write(buf, fname)
    buf_T	*buf;
    char_u	*fname;
{
    int		r;
    char_u	*save_ff;

    save_ff = buf->b_p_ff;
    buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
    r = buf_write(buf, fname, NULL, (linenr_T)1, buf->b_ml.ml_line_count,
					     NULL, FALSE, FALSE, FALSE, TRUE);
    free_string_option(buf->b_p_ff);
    buf->b_p_ff = save_ff;
    return r;
}

/*
 * Completely update the diffs for the buffers involved.
 * This uses the ordinary "diff" command.
 * The buffers are written to a file, also for unmodified buffers (the file
 * could have been produced by autocommands, e.g. the netrw plugin).
 */
/*ARGSUSED*/
    void
ex_diffupdate(eap)
    exarg_T	*eap;
{
    buf_T	*buf;
    int		idx_orig;
    int		idx_new;
    char_u	*tmp_orig;
    char_u	*tmp_new;
    char_u	*tmp_diff;
    FILE	*fd;
    int		ok;

    /* Delete all diffblocks. */
    diff_clear();
    diff_invalid = FALSE;

    /* Use the first buffer as the original text. */
    for (idx_orig = 0; idx_orig < DB_COUNT; ++idx_orig)
	if (diffbuf[idx_orig] != NULL)
	    break;
    if (idx_orig == DB_COUNT)
	return;

    /* Only need to do something when there is another buffer. */
    for (idx_new = idx_orig + 1; idx_new < DB_COUNT; ++idx_new)
	if (diffbuf[idx_new] != NULL)
	    break;
    if (idx_new == DB_COUNT)
	return;

    /* We need three temp file names. */
    tmp_orig = vim_tempname('o');
    tmp_new = vim_tempname('n');
    tmp_diff = vim_tempname('d');
    if (tmp_orig == NULL || tmp_new == NULL || tmp_diff == NULL)
	goto theend;

    /*
     * Do a quick test if "diff" really works.  Otherwise it looks like there
     * are no differences.  Can't use the return value, it's non-zero when
     * there are differences.
     * May try twice, first with "-a" and then without.
     */
    for (;;)
    {
	ok = FALSE;
	fd = mch_fopen((char *)tmp_orig, "w");
	if (fd != NULL)
	{
	    fwrite("line1\n", (size_t)6, (size_t)1, fd);
	    fclose(fd);
	    fd = mch_fopen((char *)tmp_new, "w");
	    if (fd != NULL)
	    {
		fwrite("line2\n", (size_t)6, (size_t)1, fd);
		fclose(fd);
		diff_file(tmp_orig, tmp_new, tmp_diff);
		fd = mch_fopen((char *)tmp_diff, "r");
		if (fd != NULL)
		{
		    char_u	linebuf[LBUFLEN];

		    for (;;)
		    {
			/* There must be a line that contains "1c1". */
			if (tag_fgets(linebuf, LBUFLEN, fd))
			    break;
			if (STRNCMP(linebuf, "1c1", 3) == 0)
			    ok = TRUE;
		    }
		    fclose(fd);
		}
		mch_remove(tmp_diff);
		mch_remove(tmp_new);
	    }
	    mch_remove(tmp_orig);
	}

#ifdef FEAT_EVAL
	/* When using 'diffexpr' break here. */
	if (*p_dex != NUL)
	    break;
#endif

#if defined(MSWIN) || defined(MSDOS)
	/* If the "-a" argument works, also check if "--binary" works. */
	if (ok && diff_a_works == MAYBE && diff_bin_works == MAYBE)
	{
	    diff_a_works = TRUE;
	    diff_bin_works = TRUE;
	    continue;
	}
	if (!ok && diff_a_works == TRUE && diff_bin_works == TRUE)
	{
	    /* Tried --binary, but it failed. "-a" works though. */
	    diff_bin_works = FALSE;
	    ok = TRUE;
	}
#endif

	/* If we checked if "-a" works already, break here. */
	if (diff_a_works != MAYBE)
	    break;
	diff_a_works = ok;

	/* If "-a" works break here, otherwise retry without "-a". */
	if (ok)
	    break;
    }
    if (!ok)
    {
	EMSG(_("E97: Cannot create diffs"));
	diff_a_works = MAYBE;
#if defined(MSWIN) || defined(MSDOS)
	diff_bin_works = MAYBE;
#endif
	goto theend;
    }

    /* Write the first buffer to a tempfile. */
    buf = diffbuf[idx_orig];
    if (diff_write(buf, tmp_orig) == FAIL)
	goto theend;

    /* Make a difference between the first buffer and every other. */
    for (idx_new = idx_orig + 1; idx_new < DB_COUNT; ++idx_new)
    {
	buf = diffbuf[idx_new];
	if (buf == NULL)
	    continue;
	if (diff_write(buf, tmp_new) == FAIL)
	    continue;
	diff_file(tmp_orig, tmp_new, tmp_diff);

	/* Read the diff output and add each entry to the diff list. */
	diff_read(idx_orig, idx_new, tmp_diff);
	mch_remove(tmp_diff);
	mch_remove(tmp_new);
    }
    mch_remove(tmp_orig);

    diff_redraw(TRUE);

theend:
    vim_free(tmp_orig);
    vim_free(tmp_new);
    vim_free(tmp_diff);
}

/*
 * Make a diff between files "tmp_orig" and "tmp_new", results in "tmp_diff".
 */
    static void
diff_file(tmp_orig, tmp_new, tmp_diff)
    char_u	*tmp_orig;
    char_u	*tmp_new;
    char_u	*tmp_diff;
{
    char_u	*cmd;

#ifdef FEAT_EVAL
    if (*p_dex != NUL)
	/* Use 'diffexpr' to generate the diff file. */
	eval_diff(tmp_orig, tmp_new, tmp_diff);
    else
#endif
    {
	cmd = alloc((unsigned)(STRLEN(tmp_orig) + STRLEN(tmp_new)
				+ STRLEN(tmp_diff) + STRLEN(p_srr) + 27));
	if (cmd != NULL)
	{
	    /* We don't want $DIFF_OPTIONS to get in the way. */
	    if (getenv("DIFF_OPTIONS"))
		vim_setenv((char_u *)"DIFF_OPTIONS", (char_u *)"");

	    /* Build the diff command and execute it.  Always use -a, binary
	     * differences are of no use.  Ignore errors, diff returns
	     * non-zero when differences have been found. */
	    sprintf((char *)cmd, "diff %s%s%s%s%s %s",
		    diff_a_works == FALSE ? "" : "-a ",
#if defined(MSWIN) || defined(MSDOS)
		    diff_bin_works == TRUE ? "--binary " : "",
#else
		    "",
#endif
		    (diff_flags & DIFF_IWHITE) ? "-b " : "",
		    (diff_flags & DIFF_ICASE) ? "-i " : "",
		    tmp_orig, tmp_new);
	    append_redir(cmd, p_srr, tmp_diff);
	    (void)call_shell(cmd, SHELL_FILTER|SHELL_SILENT|SHELL_DOOUT);
	    vim_free(cmd);
	}
    }
}

/*
 * Create a new version of a file from the current buffer and a diff file.
 * The buffer is written to a file, also for unmodified buffers (the file
 * could have been produced by autocommands, e.g. the netrw plugin).
 */
    void
ex_diffpatch(eap)
    exarg_T	*eap;
{
    char_u	*tmp_orig;	/* name of original temp file */
    char_u	*tmp_new;	/* name of patched temp file */
    char_u	*buf = NULL;
    win_T	*old_curwin = curwin;
    char_u	*newname = NULL;	/* name of patched file buffer */
#ifdef UNIX
    char_u	dirbuf[MAXPATHL];
    char_u	*fullname = NULL;
#endif
#ifdef FEAT_BROWSE
    char_u	*browseFile = NULL;
    int		browse_flag = cmdmod.browse;
#endif

#ifdef FEAT_BROWSE
    if (cmdmod.browse)
    {
	browseFile = do_browse(0, (char_u *)_("Patch file"),
			 eap->arg, NULL, NULL, BROWSE_FILTER_ALL_FILES, NULL);
	if (browseFile == NULL)
	    return;		/* operation cancelled */
	eap->arg = browseFile;
	cmdmod.browse = FALSE;	/* don't let do_ecmd() browse again */
    }
#endif

    /* We need two temp file names. */
    tmp_orig = vim_tempname('o');
    tmp_new = vim_tempname('n');
    if (tmp_orig == NULL || tmp_new == NULL)
	goto theend;

    /* Write the current buffer to "tmp_orig". */
    if (buf_write(curbuf, tmp_orig, NULL,
		(linenr_T)1, curbuf->b_ml.ml_line_count,
				     NULL, FALSE, FALSE, FALSE, TRUE) == FAIL)
	goto theend;

#ifdef UNIX
    /* Get the absolute path of the patchfile, changing directory below. */
    fullname = FullName_save(eap->arg, FALSE);
#endif
    buf = alloc((unsigned)(STRLEN(tmp_orig) + (
# ifdef UNIX
		    fullname != NULL ? STRLEN(fullname) :
# endif
		    STRLEN(eap->arg)) + STRLEN(tmp_new) + 16));
    if (buf == NULL)
	goto theend;

#ifdef UNIX
    /* Temporaraly chdir to /tmp, to avoid patching files in the current
     * directory when the patch file contains more than one patch.  When we
     * have our own temp dir use that instead, it will be cleaned up when we
     * exit (any .rej files created).  Don't change directory if we can't
     * return to the current. */
    if (mch_dirname(dirbuf, MAXPATHL) != OK || mch_chdir((char *)dirbuf) != 0)
	dirbuf[0] = NUL;
    else
    {
# ifdef TEMPDIRNAMES
	if (vim_tempdir != NULL)
	    mch_chdir((char *)vim_tempdir);
	else
# endif
	    mch_chdir("/tmp");
	shorten_fnames(TRUE);
    }
#endif

#ifdef FEAT_EVAL
    if (*p_pex != NUL)
	/* Use 'patchexpr' to generate the new file. */
	eval_patch(tmp_orig,
# ifdef UNIX
		fullname != NULL ? fullname :
# endif
		eap->arg, tmp_new);
    else
#endif
    {
	/* Build the patch command and execute it.  Ignore errors.  Switch to
	 * cooked mode to allow the user to respond to prompts. */
	sprintf((char *)buf, "patch -o %s %s < \"%s\"", tmp_new, tmp_orig,
# ifdef UNIX
		fullname != NULL ? fullname :
# endif
		eap->arg);
	(void)call_shell(buf, SHELL_FILTER | SHELL_COOKED);
    }

#ifdef UNIX
    if (dirbuf[0] != NUL)
    {
	if (mch_chdir((char *)dirbuf) != 0)
	    EMSG(_(e_prev_dir));
	shorten_fnames(TRUE);
    }
#endif

    /* patch probably has written over the screen */
    redraw_later(CLEAR);

    /* Delete any .orig or .rej file created. */
    STRCPY(buf, tmp_new);
    STRCAT(buf, ".orig");
    mch_remove(buf);
    STRCPY(buf, tmp_new);
    STRCAT(buf, ".rej");
    mch_remove(buf);

    if (curbuf->b_fname != NULL)
    {
	newname = vim_strnsave(curbuf->b_fname,
					  (int)(STRLEN(curbuf->b_fname) + 4));
	if (newname != NULL)
	    STRCAT(newname, ".new");
    }

#ifdef FEAT_GUI
    need_mouse_correct = TRUE;
#endif
    if (win_split(0, 0) != FAIL)
    {
	/* Pretend it was a ":split fname" command */
	eap->cmdidx = CMD_split;
	eap->arg = tmp_new;
	do_exedit(eap, old_curwin);

	if (curwin != old_curwin)		/* split must have worked */
	{
	    /* Set 'diff', 'scrollbind' on and 'wrap' off. */
	    diff_win_options(curwin, TRUE);
	    diff_win_options(old_curwin, TRUE);

	    if (newname != NULL)
	    {
		/* do a ":file filename.new" on the patched buffer */
		eap->arg = newname;
		ex_file(eap);

#ifdef FEAT_AUTOCMD
		/* Do filetype detection with the new name. */
		do_cmdline_cmd((char_u *)":doau filetypedetect BufRead");
#endif
	    }
	}
    }

theend:
    if (tmp_orig != NULL)
	mch_remove(tmp_orig);
    vim_free(tmp_orig);
    if (tmp_new != NULL)
	mch_remove(tmp_new);
    vim_free(tmp_new);
    vim_free(newname);
    vim_free(buf);
#ifdef UNIX
    vim_free(fullname);
#endif
#ifdef FEAT_BROWSE
    vim_free(browseFile);
    cmdmod.browse = browse_flag;
#endif
}

/*
 * Split the window and edit another file, setting options to show the diffs.
 */
    void
ex_diffsplit(eap)
    exarg_T	*eap;
{
    win_T	*old_curwin = curwin;

#ifdef FEAT_GUI
    need_mouse_correct = TRUE;
#endif
    if (win_split(0, 0) != FAIL)
    {
	/* Pretend it was a ":split fname" command */
	eap->cmdidx = CMD_split;
	curwin->w_p_diff = TRUE;
	do_exedit(eap, old_curwin);

	if (curwin != old_curwin)		/* split must have worked */
	{
	    /* Set 'diff', 'scrollbind' on and 'wrap' off. */
	    diff_win_options(curwin, TRUE);
	    diff_win_options(old_curwin, TRUE);
	}
    }
}

/*
 * Set options to show difs for the current window.
 */
/*ARGSUSED*/
    void
ex_diffthis(eap)
    exarg_T	*eap;
{
    /* Set 'diff', 'scrollbind' on and 'wrap' off. */
    diff_win_options(curwin, TRUE);
}

/*
 * Set options in window "wp" for diff mode.
 */
    void
diff_win_options(wp, addbuf)
    win_T	*wp;
    int		addbuf;		/* Add buffer to diff. */
{
    wp->w_p_diff = TRUE;
    wp->w_p_scb = TRUE;
    wp->w_p_wrap = FALSE;
# ifdef FEAT_FOLDING
    {
	win_T	    *old_curwin = curwin;

	curwin = wp;
	curbuf = curwin->w_buffer;
	set_string_option_direct((char_u *)"fdm", -1, (char_u *)"diff",
							  OPT_LOCAL|OPT_FREE);
	curwin = old_curwin;
	curbuf = curwin->w_buffer;
	wp->w_p_fdc = 2;
	wp->w_p_fen = TRUE;
	wp->w_p_fdl = 0;
	foldUpdateAll(wp);
	/* make sure topline is not halfway a fold */
	changed_window_setting_win(wp);
    }
# endif
#ifdef FEAT_SCROLLBIND
    if (vim_strchr(p_sbo, 'h') == NULL)
	do_cmdline_cmd((char_u *)"set sbo+=hor");
#endif

    if (addbuf)
	diff_buf_add(wp->w_buffer);
    redraw_win_later(wp, NOT_VALID);
}

/*
 * Set options not to show diffs.  For the current window or all windows.
 */
    void
ex_diffoff(eap)
    exarg_T	*eap;
{
    win_T	*wp;
    win_T	*old_curwin = curwin;
#ifdef FEAT_SCROLLBIND
    int		diffwin = FALSE;
#endif

    for (wp = firstwin; wp != NULL; wp = wp->w_next)
    {
	if (wp == curwin || eap->forceit)
	{
	    /* Set 'diff', 'scrollbind' off and 'wrap' on. */
	    wp->w_p_diff = FALSE;
	    wp->w_p_scb = FALSE;
	    wp->w_p_wrap = TRUE;
#ifdef FEAT_FOLDING
	    curwin = wp;
	    curbuf = curwin->w_buffer;
	    set_string_option_direct((char_u *)"fdm", -1,
				      (char_u *)"manual", OPT_LOCAL|OPT_FREE);
	    curwin = old_curwin;
	    curbuf = curwin->w_buffer;
	    wp->w_p_fdc = 0;
	    wp->w_p_fen = FALSE;
	    wp->w_p_fdl = 0;
	    foldUpdateAll(wp);
	    /* make sure topline is not halfway a fold */
	    changed_window_setting_win(wp);
#endif
	    diff_buf_adjust(wp);
	}
#ifdef FEAT_SCROLLBIND
	diffwin |= wp->w_p_diff;
#endif
    }

#ifdef FEAT_SCROLLBIND
    /* Remove "hor" from from 'scrollopt' if there are no diff windows left. */
    if (!diffwin && vim_strchr(p_sbo, 'h') != NULL)
	do_cmdline_cmd((char_u *)"set sbo-=hor");
#endif
}

/*
 * Read the diff output and add each entry to the diff list.
 */
    static void
diff_read(idx_orig, idx_new, fname)
    int		idx_orig;	/* idx of original file */
    int		idx_new;	/* idx of new file */
    char_u	*fname;		/* name of diff output file */
{
    FILE	*fd;
    diff_T	*dprev = NULL;
    diff_T	*dp = first_diff;
    diff_T	*dn, *dpl;
    long	f1, l1, f2, l2;
    char_u	linebuf[LBUFLEN];   /* only need to hold the diff line */
    int		difftype;
    char_u	*p;
    long	off;
    int		i;
    linenr_T	lnum_orig, lnum_new;
    long	count_orig, count_new;
    int		notset = TRUE;	    /* block "*dp" not set yet */

    fd = mch_fopen((char *)fname, "r");
    if (fd == NULL)
    {
	EMSG(_("E98: Cannot read diff output"));
	return;
    }

    for (;;)
    {
	if (tag_fgets(linebuf, LBUFLEN, fd))
	    break;		/* end of file */
	if (!isdigit(*linebuf))
	    continue;		/* not the start of a diff block */

	/* This line must be one of three formats:
	 * {first}[,{last}]c{first}[,{last}]
	 * {first}a{first}[,{last}]
	 * {first}[,{last}]d{first}
	 */
	p = linebuf;
	f1 = getdigits(&p);
	if (*p == ',')
	{
	    ++p;
	    l1 = getdigits(&p);
	}
	else
	    l1 = f1;
	if (*p != 'a' && *p != 'c' && *p != 'd')
	    continue;		/* invalid diff format */
	difftype = *p++;
	f2 = getdigits(&p);
	if (*p == ',')
	{
	    ++p;
	    l2 = getdigits(&p);
	}
	else
	    l2 = f2;
	if (l1 < f1 || l2 < f2)
	    continue;		/* invalid line range */

	if (difftype == 'a')
	{
	    lnum_orig = f1 + 1;
	    count_orig = 0;
	}
	else
	{
	    lnum_orig = f1;
	    count_orig = l1 - f1 + 1;
	}
	if (difftype == 'd')
	{
	    lnum_new = f2 + 1;
	    count_new = 0;
	}
	else
	{
	    lnum_new = f2;
	    count_new = l2 - f2 + 1;
	}

	/* Go over blocks before the change, for which orig and new are equal.
	 * Copy blocks from orig to new. */
	while (dp != NULL
		&& lnum_orig > dp->df_lnum[idx_orig] + dp->df_count[idx_orig])
	{
	    if (notset)
		diff_copy_entry(dprev, dp, idx_orig, idx_new);
	    dprev = dp;
	    dp = dp->df_next;
	    notset = TRUE;
	}

	if (dp != NULL
		&& lnum_orig <= dp->df_lnum[idx_orig] + dp->df_count[idx_orig]
		&& lnum_orig + count_orig >= dp->df_lnum[idx_orig])
	{
	    /* New block overlaps with existing block(s).
	     * First find last block that overlaps. */
	    for (dpl = dp; dpl->df_next != NULL; dpl = dpl->df_next)
		if (lnum_orig + count_orig < dpl->df_next->df_lnum[idx_orig])
		    break;

	    /* If the newly found block starts before the old one, set the
	     * start back a number of lines. */
	    off = dp->df_lnum[idx_orig] - lnum_orig;
	    if (off > 0)
	    {
		for (i = idx_orig; i < idx_new; ++i)
		    if (diffbuf[i] != NULL)
			dp->df_lnum[i] -= off;
		dp->df_lnum[idx_new] = lnum_new;
		dp->df_count[idx_new] = count_new;
	    }
	    else if (notset)
	    {
		/* new block inside existing one, adjust new block */
		dp->df_lnum[idx_new] = lnum_new + off;
		dp->df_count[idx_new] = count_new - off;
	    }
	    else
		/* second overlap of new block with existing block */
		dp->df_count[idx_new] += count_new - count_orig;

	    /* Adjust the size of the block to include all the lines to the
	     * end of the existing block or the new diff, whatever ends last. */
	    off = (lnum_orig + count_orig)
			 - (dpl->df_lnum[idx_orig] + dpl->df_count[idx_orig]);
	    if (off < 0)
	    {
		/* new change ends in existing block, adjust the end if not
		 * done already */
		if (notset)
		    dp->df_count[idx_new] += -off;
		off = 0;
	    }
	    for (i = idx_orig; i < idx_new + !notset; ++i)
		if (diffbuf[i] != NULL)
		    dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
						       - dp->df_lnum[i] + off;

	    /* Delete the diff blocks that have been merged into one. */
	    dn = dp->df_next;
	    dp->df_next = dpl->df_next;
	    while (dn != dp->df_next)
	    {
		dpl = dn->df_next;
		vim_free(dn);
		dn = dpl;
	    }
	}
	else
	{
	    /* Allocate a new diffblock. */
	    dp = diff_alloc_new(dprev, dp);
	    if (dp == NULL)
		return;

	    dp->df_lnum[idx_orig] = lnum_orig;
	    dp->df_count[idx_orig] = count_orig;
	    dp->df_lnum[idx_new] = lnum_new;
	    dp->df_count[idx_new] = count_new;

	    /* Set values for other buffers, these must be equal to the
	     * original buffer, otherwise there would have been a change
	     * already. */
	    for (i = idx_orig + 1; i < idx_new; ++i)
		if (diffbuf[i] != NULL)
		    diff_copy_entry(dprev, dp, idx_orig, i);
	}
	notset = FALSE;		/* "*dp" has been set */
    }

    /* for remaining diff blocks orig and new are equal */
    while (dp != NULL)
    {
	if (notset)
	    diff_copy_entry(dprev, dp, idx_orig, idx_new);
	dprev = dp;
	dp = dp->df_next;
	notset = TRUE;
    }

    fclose(fd);
}

/*
 * Copy an entry at "dp" from "idx_orig" to "idx_new".
 */
    static void
diff_copy_entry(dprev, dp, idx_orig, idx_new)
    diff_T	*dprev;
    diff_T	*dp;
    int		idx_orig;
    int		idx_new;
{
    long	off;

    if (dprev == NULL)
	off = 0;
    else
	off = (dprev->df_lnum[idx_orig] + dprev->df_count[idx_orig])
	    - (dprev->df_lnum[idx_new] + dprev->df_count[idx_new]);
    dp->df_lnum[idx_new] = dp->df_lnum[idx_orig] - off;
    dp->df_count[idx_new] = dp->df_count[idx_orig];
}

/*
 * Clear the list of diffblocks.
 */
    void
diff_clear()
{
    diff_T	*p, *next_p;

    for (p = first_diff; p != NULL; p = next_p)
    {
	next_p = p->df_next;
	vim_free(p);
    }
    first_diff = NULL;
}

/*
 * Check diff status for line "lnum" in buffer "buf":
 * Returns 0 for nothing special
 * Returns -1 for a line that should be highlighted as changed.
 * Returns -2 for a line that should be highlighted as added/deleted.
 * Returns > 0 for inserting that many filler lines above it (never happens
 * when 'diffopt' doesn't contain "filler").
 * This should only be used for windows where 'diff' is set.
 */
    int
diff_check(wp, lnum)
    win_T	*wp;
    linenr_T	lnum;
{
    int		idx;		/* index in diffbuf[] for this buffer */
    diff_T	*dp;
    int		maxcount;
    int		i;
    buf_T	*buf = wp->w_buffer;
    int		cmp;

    if (diff_invalid)
	ex_diffupdate(NULL);		/* update after a big change */

    if (first_diff == NULL || !wp->w_p_diff)	/* no diffs at all */
	return 0;

    /* safety check: "lnum" must be a buffer line */
    if (lnum < 1 || lnum > buf->b_ml.ml_line_count + 1)
	return 0;

    idx = diff_buf_idx(buf);
    if (idx == DB_COUNT)
	return 0;		/* no diffs for buffer "buf" */

#ifdef FEAT_FOLDING
    /* A closed fold never has filler lines. */
    if (hasFoldingWin(wp, lnum, NULL, NULL, TRUE, NULL))
	return 0;
#endif

    /* search for a change that includes "lnum" in the list of diffblocks. */
    for (dp = first_diff; dp != NULL; dp = dp->df_next)
	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
	    break;
    if (dp == NULL || lnum < dp->df_lnum[idx])
	return 0;

    if (lnum < dp->df_lnum[idx] + dp->df_count[idx])
    {
	int	zero = FALSE;

	/* Changed or inserted line.  If the other buffers have a count of
	 * zero, the lines were inserted.  If the other buffers have the same
	 * count, check if the lines are identical. */
	cmp = FALSE;
	for (i = 0; i < DB_COUNT; ++i)
	    if (i != idx && diffbuf[i] != NULL)
	    {
		if (dp->df_count[i] == 0)
		    zero = TRUE;
		else
		{
		    if (dp->df_count[i] != dp->df_count[idx])
			return -1;	    /* nr of lines changed. */
		    cmp = TRUE;
		}
	    }
	if (cmp)
	{
	    /* Compare all lines.  If they are equal the lines were inserted
	     * in some buffers, deleted in others, but not changed. */
	    for (i = 0; i < DB_COUNT; ++i)
		if (i != idx && diffbuf[i] != NULL && dp->df_count[i] != 0)
		    if (!diff_equal_entry(dp, idx, i))
			return -1;
	}
	/* If there is no buffer with zero lines then there is no difference
	 * any longer.  Happens when making a change (or undo) that removes
	 * the difference.  Can't remove the entry here, we might be halfway
	 * updating the window.  Just report the text as unchanged.  Other
	 * windows might still show the change though. */
	if (zero == FALSE)
	    return 0;
	return -2;
    }

    /* If 'diffopt' doesn't contain "filler", return 0. */
    if (!(diff_flags & DIFF_FILLER))
	return 0;

    /* Insert filler lines above the line just below the change.  Will return
     * 0 when this buf had the max count. */
    maxcount = 0;
    for (i = 0; i < DB_COUNT; ++i)
	if (diffbuf[i] != NULL && dp->df_count[i] > maxcount)
	    maxcount = dp->df_count[i];
    return maxcount - dp->df_count[idx];
}

/*
 * Compare two entries in diff "*dp" and return TRUE if they are equal.
 */
    static int
diff_equal_entry(dp, idx1, idx2)
    diff_T	*dp;
    int		idx1;
    int		idx2;
{
    int		i;
    char_u	*line;
    int		cmp;

    if (dp->df_count[idx1] != dp->df_count[idx2])
	return FALSE;
    if (diff_check_sanity(dp) == FAIL)
	return FALSE;
    for (i = 0; i < dp->df_count[idx1]; ++i)
    {
	line = vim_strsave(ml_get_buf(diffbuf[idx1],
					       dp->df_lnum[idx1] + i, FALSE));
	if (line == NULL)
	    return FALSE;
	cmp = diff_cmp(line, ml_get_buf(diffbuf[idx2],
					       dp->df_lnum[idx2] + i, FALSE));
	vim_free(line);
	if (cmp != 0)
	    return FALSE;
    }
    return TRUE;
}

/*
 * Compare strings "s1" and "s2" according to 'diffopt'.
 * Return non-zero when they are different.
 */
    static int
diff_cmp(s1, s2)
    char_u	*s1;
    char_u	*s2;
{
    char_u	*p1, *p2;
#ifdef FEAT_MBYTE
    int		l;
#endif

    if ((diff_flags & (DIFF_ICASE | DIFF_IWHITE)) == 0)
	return STRCMP(s1, s2);
    if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE))
	return MB_STRICMP(s1, s2);

    /* Ignore white space changes and possibly ignore case. */
    p1 = s1;
    p2 = s2;
    while (*p1 != NUL && *p2 != NUL)
    {
	if (vim_iswhite(*p1) && vim_iswhite(*p2))
	{
	    p1 = skipwhite(p1);
	    p2 = skipwhite(p2);
	}
	else
	{
#ifdef FEAT_MBYTE
	    l  = (*mb_ptr2len)(p1);
	    if (l != (*mb_ptr2len)(p2))
		break;
	    if (l > 1)
	    {
		if (STRNCMP(p1, p2, l) != 0
			&& (!enc_utf8
			    || !(diff_flags & DIFF_ICASE)
			    || utf_fold(utf_ptr2char(p1))
					       != utf_fold(utf_ptr2char(p2))))
		    break;
		p1 += l;
		p2 += l;
	    }
	    else
#endif
	    {
		if (*p1 != *p2 && (!(diff_flags & DIFF_ICASE)
				     || TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2)))
		    break;
		++p1;
		++p2;
	    }
	}
    }

    /* Ignore trailing white space. */
    p1 = skipwhite(p1);
    p2 = skipwhite(p2);
    if (*p1 != NUL || *p2 != NUL)
	return 1;
    return 0;
}

/*
 * Return the number of filler lines above "lnum".
 */
    int
diff_check_fill(wp, lnum)
    win_T	*wp;
    linenr_T	lnum;
{
    int		n;

    /* be quick when there are no filler lines */
    if (!(diff_flags & DIFF_FILLER))
	return 0;
    n = diff_check(wp, lnum);
    if (n <= 0)
	return 0;
    return n;
}

/*
 * Set the topline of "towin" to match the position in "fromwin", so that they
 * show the same diff'ed lines.
 */
    void
diff_set_topline(fromwin, towin)
    win_T	*fromwin;
    win_T	*towin;
{
    buf_T	*buf = fromwin->w_buffer;
    linenr_T	lnum = fromwin->w_topline;
    int		idx;
    diff_T	*dp;
    int		i;

    idx = diff_buf_idx(buf);
    if (idx == DB_COUNT)
	return;		/* safety check */

    if (diff_invalid)
	ex_diffupdate(NULL);		/* update after a big change */

    towin->w_topfill = 0;

    /* search for a change that includes "lnum" in the list of diffblocks. */
    for (dp = first_diff; dp != NULL; dp = dp->df_next)
	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
	    break;
    if (dp == NULL)
    {
	/* After last change, compute topline relative to end of file; no
	 * filler lines. */
	towin->w_topline = towin->w_buffer->b_ml.ml_line_count
					   - (buf->b_ml.ml_line_count - lnum);
    }
    else
    {
	/* Find index for "towin". */
	i = diff_buf_idx(towin->w_buffer);
	if (i == DB_COUNT)
	    return;		/* safety check */

	towin->w_topline = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]);
	if (lnum >= dp->df_lnum[idx])
	{
	    /* Inside a change: compute filler lines. */
	    if (dp->df_count[i] == dp->df_count[idx])
		towin->w_topfill = fromwin->w_topfill;
	    else if (dp->df_count[i] > dp->df_count[idx])
	    {
		if (lnum == dp->df_lnum[idx] + dp->df_count[idx])
		    towin->w_topline = dp->df_lnum[i] + dp->df_count[i]
							 - fromwin->w_topfill;
	    }
	    else
	    {
		if (towin->w_topline >= dp->df_lnum[i] + dp->df_count[i])
		{
		    if (diff_flags & DIFF_FILLER)
			towin->w_topfill = dp->df_lnum[idx]
						   + dp->df_count[idx] - lnum;
		    towin->w_topline = dp->df_lnum[i] + dp->df_count[i];
		}
	    }
	}
    }

    /* safety check (if diff info gets outdated strange things may happen) */
    towin->w_botfill = FALSE;
    if (towin->w_topline > towin->w_buffer->b_ml.ml_line_count)
    {
	towin->w_topline = towin->w_buffer->b_ml.ml_line_count;
	towin->w_botfill = TRUE;
    }
    if (towin->w_topline < 1)
    {
	towin->w_topline = 1;
	towin->w_topfill = 0;
    }

    /* When w_topline changes need to recompute w_botline and cursor position */
    invalidate_botline_win(towin);
    changed_line_abv_curs_win(towin);

    check_topfill(towin, FALSE);
#ifdef FEAT_FOLDING
    (void)hasFoldingWin(towin, towin->w_topline, &towin->w_topline,
							    NULL, TRUE, NULL);
#endif
}

/*
 * This is called when 'diffopt' is changed.
 */
    int
diffopt_changed()
{
    char_u	*p;
    int		diff_context_new = 6;
    int		diff_flags_new = 0;

    p = p_dip;
    while (*p != NUL)
    {
	if (STRNCMP(p, "filler", 6) == 0)
	{
	    p += 6;
	    diff_flags_new |= DIFF_FILLER;
	}
	else if (STRNCMP(p, "context:", 8) == 0 && VIM_ISDIGIT(p[8]))
	{
	    p += 8;
	    diff_context_new = getdigits(&p);
	}
	else if (STRNCMP(p, "icase", 5) == 0)
	{
	    p += 5;
	    diff_flags_new |= DIFF_ICASE;
	}
	else if (STRNCMP(p, "iwhite", 6) == 0)
	{
	    p += 6;
	    diff_flags_new |= DIFF_IWHITE;
	}
	if (*p != ',' && *p != NUL)
	    return FAIL;
	if (*p == ',')
	    ++p;
    }

    /* If "icase" or "iwhite" was added or removed, need to update the diff. */
    if (diff_flags != diff_flags_new)
	diff_invalid = TRUE;

    diff_flags = diff_flags_new;
    diff_context = diff_context_new;

    diff_redraw(TRUE);

    /* recompute the scroll binding with the new option value, may
     * remove or add filler lines */
    check_scrollbind((linenr_T)0, 0L);

    return OK;
}

/*
 * Find the difference within a changed line.
 * Returns TRUE if the line was added, no other buffer has it.
 */
    int
diff_find_change(wp, lnum, startp, endp)
    win_T	*wp;
    linenr_T	lnum;
    int		*startp;	/* first char of the change */
    int		*endp;		/* last char of the change */
{
    char_u	*line_org;
    char_u	*line_new;
    int		i;
    int		si, ei_org, ei_new;
    diff_T	*dp;
    int		idx;
    int		off;
    int		added = TRUE;

    /* Make a copy of the line, the next ml_get() will invalidate it. */
    line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE));
    if (line_org == NULL)
	return FALSE;

    idx = diff_buf_idx(wp->w_buffer);
    if (idx == DB_COUNT)	/* cannot happen */
	return FALSE;

    /* search for a change that includes "lnum" in the list of diffblocks. */
    for (dp = first_diff; dp != NULL; dp = dp->df_next)
	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
	    break;
    if (dp == NULL || diff_check_sanity(dp) == FAIL)
	return FALSE;

    off = lnum - dp->df_lnum[idx];

    for (i = 0; i < DB_COUNT; ++i)
	if (diffbuf[i] != NULL && i != idx)
	{
	    /* Skip lines that are not in the other change (filler lines). */
	    if (off >= dp->df_count[i])
		continue;
	    added = FALSE;
	    line_new = ml_get_buf(diffbuf[i], dp->df_lnum[i] + off, FALSE);

	    /* Search for start of difference */
	    for (si = 0; line_org[si] != NUL && line_org[si] == line_new[si]; )
		++si;
#ifdef FEAT_MBYTE
	    if (has_mbyte)
	    {
		/* Move back to first byte of character in both lines (may
		 * have "nn^" in line_org and "n^ in line_new). */
		si -= (*mb_head_off)(line_org, line_org + si);
		si -= (*mb_head_off)(line_new, line_new + si);
	    }
#endif
	    if (*startp > si)
		*startp = si;

	    /* Search for end of difference, if any. */
	    if (line_org[si] != NUL || line_new[si] != NUL)
	    {
		ei_org = (int)STRLEN(line_org);
		ei_new = (int)STRLEN(line_new);
		while (ei_org >= *startp && ei_new >= *startp
			&& ei_org >= 0 && ei_new >= 0
			&& line_org[ei_org] == line_new[ei_new])
		{
		    --ei_org;
		    --ei_new;
		}
		if (*endp < ei_org)
		    *endp = ei_org;
	    }
	}

    vim_free(line_org);
    return added;
}

#if defined(FEAT_FOLDING) || defined(PROTO)
/*
 * Return TRUE if line "lnum" is not close to a diff block, this line should
 * be in a fold.
 * Return FALSE if there are no diff blocks at all in this window.
 */
    int
diff_infold(wp, lnum)
    win_T	*wp;
    linenr_T	lnum;
{
    int		i;
    int		idx = -1;
    int		other = FALSE;
    diff_T	*dp;

    /* Return if 'diff' isn't set. */
    if (!wp->w_p_diff)
	return FALSE;

    for (i = 0; i < DB_COUNT; ++i)
    {
	if (diffbuf[i] == wp->w_buffer)
	    idx = i;
	else if (diffbuf[i] != NULL)
	    other = TRUE;
    }

    /* return here if there are no diffs in the window */
    if (idx == -1 || !other)
	return FALSE;

    if (diff_invalid)
	ex_diffupdate(NULL);		/* update after a big change */

    /* Return if there are no diff blocks.  All lines will be folded. */
    if (first_diff == NULL)
	return TRUE;

    for (dp = first_diff; dp != NULL; dp = dp->df_next)
    {
	/* If this change is below the line there can't be any further match. */
	if (dp->df_lnum[idx] - diff_context > lnum)
	    break;
	/* If this change ends before the line we have a match. */
	if (dp->df_lnum[idx] + dp->df_count[idx] + diff_context > lnum)
	    return FALSE;
    }
    return TRUE;
}
#endif

/*
 * "dp" and "do" commands.
 */
    void
nv_diffgetput(put)
    int		put;
{
    exarg_T	ea;

    ea.arg = (char_u *)"";
    if (put)
	ea.cmdidx = CMD_diffput;
    else
	ea.cmdidx = CMD_diffget;
    ea.addr_count = 0;
    ea.line1 = curwin->w_cursor.lnum;
    ea.line2 = curwin->w_cursor.lnum;
    ex_diffgetput(&ea);
}

/*
 * ":diffget"
 * ":diffput"
 */
    void
ex_diffgetput(eap)
    exarg_T	*eap;
{
    linenr_T	lnum;
    int		count;
    linenr_T	off = 0;
    diff_T	*dp;
    diff_T	*dprev;
    diff_T	*dfree;
    int		idx_cur;
    int		idx_other;
    int		idx_from;
    int		idx_to;
    int		i;
    int		added;
    char_u	*p;
    aco_save_T	aco;
    buf_T	*buf;
    int		start_skip, end_skip;
    int		new_count;

    /* Find the current buffer in the list of diff buffers. */
    idx_cur = diff_buf_idx(curbuf);
    if (idx_cur == DB_COUNT)
    {
	EMSG(_("E99: Current buffer is not in diff mode"));
	return;
    }

    if (*eap->arg == NUL)
    {
	/* No argument: Find the other buffer in the list of diff buffers. */
	for (idx_other = 0; idx_other < DB_COUNT; ++idx_other)
	    if (diffbuf[idx_other] != curbuf
		    && diffbuf[idx_other] != NULL
		    && (eap->cmdidx != CMD_diffput
					       || diffbuf[idx_other]->b_p_ma))
		break;
	if (idx_other == DB_COUNT)
	{
	    EMSG(_("E100: No other buffer in diff mode"));
	    return;
	}

	/* Check that there isn't a third buffer in the list */
	for (i = idx_other + 1; i < DB_COUNT; ++i)
	    if (diffbuf[i] != curbuf
		    && diffbuf[i] != NULL
		    && (eap->cmdidx != CMD_diffput || diffbuf[i]->b_p_ma))
	    {
		EMSG(_("E101: More than two buffers in diff mode, don't know which one to use"));
		return;
	    }
    }
    else
    {
	/* Buffer number or pattern given.  Ignore trailing white space. */
	p = eap->arg + STRLEN(eap->arg);
	while (p > eap->arg && vim_iswhite(p[-1]))
	    --p;
	for (i = 0; vim_isdigit(eap->arg[i]) && eap->arg + i < p; ++i)
	    ;
	if (eap->arg + i == p)	    /* digits only */
	    i = atol((char *)eap->arg);
	else
	{
	    i = buflist_findpat(eap->arg, p, FALSE, TRUE);
	    if (i < 0)
		return;		/* error message already given */
	}
	buf = buflist_findnr(i);
	if (buf == NULL)
	{
	    EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg);
	    return;
	}
	idx_other = diff_buf_idx(buf);
	if (idx_other == DB_COUNT)
	{
	    EMSG2(_("E103: Buffer \"%s\" is not in diff mode"), eap->arg);
	    return;
	}
    }

    diff_busy = TRUE;

    /* When no range given include the line above or below the cursor. */
    if (eap->addr_count == 0)
    {
	/* Make it possible that ":diffget" on the last line gets line below
	 * the cursor line when there is no difference above the cursor. */
	if (eap->cmdidx == CMD_diffget
		&& eap->line1 == curbuf->b_ml.ml_line_count
		&& diff_check(curwin, eap->line1) == 0
		&& (eap->line1 == 1 || diff_check(curwin, eap->line1 - 1) == 0))
	    ++eap->line2;
	else if (eap->line1 > 0)
	    --eap->line1;
    }

    if (eap->cmdidx == CMD_diffget)
    {
	idx_from = idx_other;
	idx_to = idx_cur;
    }
    else
    {
	idx_from = idx_cur;
	idx_to = idx_other;
	/* Need to make the other buffer the current buffer to be able to make
	 * changes in it. */
	/* set curwin/curbuf to buf and save a few things */
	aucmd_prepbuf(&aco, diffbuf[idx_other]);
    }

    dprev = NULL;
    for (dp = first_diff; dp != NULL; )
    {
	if (dp->df_lnum[idx_cur] > eap->line2 + off)
	    break;	/* past the range that was specified */

	dfree = NULL;
	lnum = dp->df_lnum[idx_to];
	count = dp->df_count[idx_to];
	if (dp->df_lnum[idx_cur] + dp->df_count[idx_cur] > eap->line1 + off
		&& u_save(lnum - 1, lnum + count) != FAIL)
	{
	    /* Inside the specified range and saving for undo worked. */
	    start_skip = 0;
	    end_skip = 0;
	    if (eap->addr_count > 0)
	    {
		/* A range was specified: check if lines need to be skipped. */
		start_skip = eap->line1 + off - dp->df_lnum[idx_cur];
		if (start_skip > 0)
		{
		    /* range starts below start of current diff block */
		    if (start_skip > count)
		    {
			lnum += count;
			count = 0;
		    }
		    else
		    {
			count -= start_skip;
			lnum += start_skip;
		    }
		}
		else
		    start_skip = 0;

		end_skip = dp->df_lnum[idx_cur] + dp->df_count[idx_cur] - 1
							 - (eap->line2 + off);
		if (end_skip > 0)
		{
		    /* range ends above end of current/from diff block */
		    if (idx_cur == idx_from)	/* :diffput */
		    {
			i = dp->df_count[idx_cur] - start_skip - end_skip;
			if (count > i)
			    count = i;
		    }
		    else			/* :diffget */
		    {
			count -= end_skip;
			end_skip = dp->df_count[idx_from] - start_skip - count;
			if (end_skip < 0)
			    end_skip = 0;
		    }
		}
		else
		    end_skip = 0;
	    }

	    added = 0;
	    for (i = 0; i < count; ++i)
	    {
		ml_delete(lnum, FALSE);
		--added;
	    }
	    for (i = 0; i < dp->df_count[idx_from] - start_skip - end_skip; ++i)
	    {
		linenr_T nr;

		nr = dp->df_lnum[idx_from] + start_skip + i;
		if (nr > diffbuf[idx_from]->b_ml.ml_line_count)
		    break;
		p = vim_strsave(ml_get_buf(diffbuf[idx_from], nr, FALSE));
		if (p != NULL)
		{
		    ml_append(lnum + i - 1, p, 0, FALSE);
		    vim_free(p);
		    ++added;
		}
	    }
	    new_count = dp->df_count[idx_to] + added;
	    dp->df_count[idx_to] = new_count;

	    if (start_skip == 0 && end_skip == 0)
	    {
		/* Check if there are any other buffers and if the diff is
		 * equal in them. */
		for (i = 0; i < DB_COUNT; ++i)
		    if (diffbuf[i] != NULL && i != idx_from && i != idx_to
			    && !diff_equal_entry(dp, idx_from, i))
			break;
		if (i == DB_COUNT)
		{
		    /* delete the diff entry, the buffers are now equal here */
		    dfree = dp;
		    dp = dp->df_next;
		    if (dprev == NULL)
			first_diff = dp;
		    else
			dprev->df_next = dp;
		}
	    }

	    /* Adjust marks.  This will change the following entries! */
	    if (added != 0)
	    {
		mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added);
		if (curwin->w_cursor.lnum >= lnum)
		{
		    /* Adjust the cursor position if it's in/after the changed
		     * lines. */
		    if (curwin->w_cursor.lnum >= lnum + count)
			curwin->w_cursor.lnum += added;
		    else if (added < 0)
			curwin->w_cursor.lnum = lnum;
		}
	    }
	    changed_lines(lnum, 0, lnum + count, (long)added);

	    if (dfree != NULL)
	    {
		/* Diff is deleted, update folds in other windows. */
#ifdef FEAT_FOLDING
		diff_fold_update(dfree, idx_to);
#endif
		vim_free(dfree);
	    }
	    else
		/* mark_adjust() may have changed the count in a wrong way */
		dp->df_count[idx_to] = new_count;

	    /* When changing the current buffer, keep track of line numbers */
	    if (idx_cur == idx_to)
		off += added;
	}

	/* If before the range or not deleted, go to next diff. */
	if (dfree == NULL)
	{
	    dprev = dp;
	    dp = dp->df_next;
	}
    }

    /* restore curwin/curbuf and a few other things */
    if (idx_other == idx_to)
    {
	/* Syncing undo only works for the current buffer, but we change
	 * another buffer.  Sync undo if the command was typed.  This isn't
	 * 100% right when ":diffput" is used in a function or mapping. */
	if (KeyTyped)
	    u_sync();
	aucmd_restbuf(&aco);
    }

    diff_busy = FALSE;

    /* Check that the cursor is on a valid character and update it's position.
     * When there were filler lines the topline has become invalid. */
    check_cursor();
    changed_line_abv_curs();

    /* Also need to redraw the other buffers. */
    diff_redraw(FALSE);
}

#ifdef FEAT_FOLDING
/*
 * Update folds for all diff buffers for entry "dp".
 * Skip buffer with index "skip_idx".
 * When there are no diffs, all folds are removed.
 */
    static void
diff_fold_update(dp, skip_idx)
    diff_T	*dp;
    int		skip_idx;
{
    int		i;
    win_T	*wp;

    for (wp = firstwin; wp != NULL; wp = wp->w_next)
	for (i = 0; i < DB_COUNT; ++i)
	    if (diffbuf[i] == wp->w_buffer && i != skip_idx)
		foldUpdate(wp, dp->df_lnum[i],
					    dp->df_lnum[i] + dp->df_count[i]);
}
#endif

/*
 * Return TRUE if buffer "buf" is in diff-mode.
 */
    int
diff_mode_buf(buf)
    buf_T	*buf;
{
    return diff_buf_idx(buf) != DB_COUNT;
}

/*
 * Move "count" times in direction "dir" to the next diff block.
 * Return FAIL if there isn't such a diff block.
 */
    int
diff_move_to(dir, count)
    int		dir;
    long	count;
{
    int		idx;
    linenr_T	lnum = curwin->w_cursor.lnum;
    diff_T	*dp;

    idx = diff_buf_idx(curbuf);
    if (idx == DB_COUNT || first_diff == NULL)
	return FAIL;

    if (diff_invalid)
	ex_diffupdate(NULL);		/* update after a big change */

    if (first_diff == NULL)		/* no diffs today */
	return FAIL;

    while (--count >= 0)
    {
	/* Check if already before first diff. */
	if (dir == BACKWARD && lnum <= first_diff->df_lnum[idx])
	    break;

	for (dp = first_diff; ; dp = dp->df_next)
	{
	    if (dp == NULL)
		break;
	    if ((dir == FORWARD && lnum < dp->df_lnum[idx])
		    || (dir == BACKWARD
			&& (dp->df_next == NULL
			    || lnum <= dp->df_next->df_lnum[idx])))
	    {
		lnum = dp->df_lnum[idx];
		break;
	    }
	}
    }

    /* don't end up past the end of the file */
    if (lnum > curbuf->b_ml.ml_line_count)
	lnum = curbuf->b_ml.ml_line_count;

    /* When the cursor didn't move at all we fail. */
    if (lnum == curwin->w_cursor.lnum)
	return FAIL;

    setpcmark();
    curwin->w_cursor.lnum = lnum;
    curwin->w_cursor.col = 0;

    return OK;
}

#if defined(FEAT_FOLDING) || defined(PROTO)
/*
 * For line "lnum" in the current window find the equivalent lnum in window
 * "wp", compensating for inserted/deleted lines.
 */
    linenr_T
diff_lnum_win(lnum, wp)
    linenr_T	lnum;
    win_T	*wp;
{
    diff_T	*dp;
    int		idx;
    int		i;
    linenr_T	n;

    idx = diff_buf_idx(curbuf);
    if (idx == DB_COUNT)		/* safety check */
	return (linenr_T)0;

    if (diff_invalid)
	ex_diffupdate(NULL);		/* update after a big change */

    /* search for a change that includes "lnum" in the list of diffblocks. */
    for (dp = first_diff; dp != NULL; dp = dp->df_next)
	if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
	    break;

    /* When after the last change, compute relative to the last line number. */
    if (dp == NULL)
	return wp->w_buffer->b_ml.ml_line_count
					- (curbuf->b_ml.ml_line_count - lnum);

    /* Find index for "wp". */
    i = diff_buf_idx(wp->w_buffer);
    if (i == DB_COUNT)			/* safety check */
	return (linenr_T)0;

    n = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]);
    if (n > dp->df_lnum[i] + dp->df_count[i])
	n = dp->df_lnum[i] + dp->df_count[i];
    return n;
}
#endif

#endif	/* FEAT_DIFF */
