forked from aniani/vim
updated for version 7.0200
This commit is contained in:
355
src/diff.c
355
src/diff.c
@@ -15,36 +15,6 @@
|
||||
|
||||
#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 */
|
||||
@@ -64,8 +34,10 @@ static int diff_bin_works = MAYBE; /* TRUE when "diff --binary" works, FALSE
|
||||
#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 int diff_buf_idx_tp __ARGS((buf_T *buf, tabpage_T *tp));
|
||||
static void diff_mark_adjust_tp __ARGS((tabpage_T *tp, int idx, linenr_T line1, linenr_T line2, long amount, long amount_after));
|
||||
static void diff_check_unchanged __ARGS((tabpage_T *tp, diff_T *dp));
|
||||
static int diff_check_sanity __ARGS((tabpage_T *tp, 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));
|
||||
@@ -76,42 +48,30 @@ 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));
|
||||
static diff_T *diff_alloc_new __ARGS((tabpage_T *tp, 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;
|
||||
tabpage_T *tp;
|
||||
|
||||
i = diff_buf_idx(buf);
|
||||
if (i != DB_COUNT)
|
||||
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
|
||||
{
|
||||
diffbuf[i] = NULL;
|
||||
diff_invalid = TRUE;
|
||||
i = diff_buf_idx_tp(buf, tp);
|
||||
if (i != DB_COUNT)
|
||||
{
|
||||
tp->tp_diffbuf[i] = NULL;
|
||||
tp->tp_diff_invalid = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +84,7 @@ diff_buf_adjust(win)
|
||||
win_T *win;
|
||||
{
|
||||
win_T *wp;
|
||||
int i;
|
||||
|
||||
if (!win->w_p_diff)
|
||||
{
|
||||
@@ -133,7 +94,14 @@ diff_buf_adjust(win)
|
||||
if (wp->w_buffer == win->w_buffer && wp->w_p_diff)
|
||||
break;
|
||||
if (wp == NULL)
|
||||
diff_buf_delete(win->w_buffer);
|
||||
{
|
||||
i = diff_buf_idx(win->w_buffer);
|
||||
if (i != DB_COUNT)
|
||||
{
|
||||
curtab->tp_diffbuf[i] = NULL;
|
||||
curtab->tp_diff_invalid = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
diff_buf_add(win->w_buffer);
|
||||
@@ -141,6 +109,11 @@ diff_buf_adjust(win)
|
||||
|
||||
/*
|
||||
* Add a buffer to make diffs for.
|
||||
* Call this when a new buffer is being edited in the current window where
|
||||
* 'diff' is set.
|
||||
* Marks the current buffer as being part of the diff and requireing updating.
|
||||
* This must be done before any autocmd, because a command may use info
|
||||
* about the screen contents.
|
||||
*/
|
||||
void
|
||||
diff_buf_add(buf)
|
||||
@@ -152,10 +125,10 @@ diff_buf_add(buf)
|
||||
return; /* It's already there. */
|
||||
|
||||
for (i = 0; i < DB_COUNT; ++i)
|
||||
if (diffbuf[i] == NULL)
|
||||
if (curtab->tp_diffbuf[i] == NULL)
|
||||
{
|
||||
diffbuf[i] = buf;
|
||||
diff_invalid = TRUE;
|
||||
curtab->tp_diffbuf[i] = buf;
|
||||
curtab->tp_diff_invalid = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -163,7 +136,7 @@ diff_buf_add(buf)
|
||||
}
|
||||
|
||||
/*
|
||||
* Find buffer "buf" in the list of diff buffers.
|
||||
* Find buffer "buf" in the list of diff buffers for the current tab page.
|
||||
* Return its index or DB_COUNT if not found.
|
||||
*/
|
||||
static int
|
||||
@@ -173,30 +146,53 @@ diff_buf_idx(buf)
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < DB_COUNT; ++idx)
|
||||
if (diffbuf[idx] == buf)
|
||||
if (curtab->tp_diffbuf[idx] == buf)
|
||||
break;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the diff info as invalid, it will be updated when info is requested.
|
||||
* Find buffer "buf" in the list of diff buffers for tab page "tp".
|
||||
* Return its index or DB_COUNT if not found.
|
||||
*/
|
||||
static int
|
||||
diff_buf_idx_tp(buf, tp)
|
||||
buf_T *buf;
|
||||
tabpage_T *tp;
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < DB_COUNT; ++idx)
|
||||
if (tp->tp_diffbuf[idx] == buf)
|
||||
break;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the diff info involving buffer "buf" as invalid, it will be updated
|
||||
* when info is requested.
|
||||
*/
|
||||
void
|
||||
diff_invalidate()
|
||||
diff_invalidate(buf)
|
||||
buf_T *buf;
|
||||
{
|
||||
if (curwin->w_p_diff)
|
||||
tabpage_T *tp;
|
||||
int i;
|
||||
|
||||
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
|
||||
{
|
||||
diff_invalid = TRUE;
|
||||
diff_redraw(TRUE);
|
||||
i = diff_buf_idx_tp(buf, tp);
|
||||
if (i != DB_COUNT)
|
||||
{
|
||||
tp->tp_diff_invalid = TRUE;
|
||||
if (tp == curtab)
|
||||
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.
|
||||
* Called by mark_adjust(): update line numbers in "curbuf".
|
||||
*/
|
||||
void
|
||||
diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
@@ -204,11 +200,38 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
linenr_T line2;
|
||||
long amount;
|
||||
long amount_after;
|
||||
{
|
||||
int idx;
|
||||
tabpage_T *tp;
|
||||
|
||||
/* Handle all tab pages that use the current buffer in a diff. */
|
||||
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
|
||||
{
|
||||
idx = diff_buf_idx_tp(curbuf, tp);
|
||||
if (idx != DB_COUNT)
|
||||
diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update line numbers in tab page "tp" for "curbuf" with index "idx".
|
||||
* 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.
|
||||
*/
|
||||
static void
|
||||
diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after)
|
||||
tabpage_T *tp;
|
||||
int idx;
|
||||
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;
|
||||
@@ -216,11 +239,6 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
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 */
|
||||
@@ -241,7 +259,7 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
}
|
||||
|
||||
dprev = NULL;
|
||||
dp = first_diff;
|
||||
dp = tp->tp_first_diff;
|
||||
for (;;)
|
||||
{
|
||||
/* If the change is after the previous diff block and before the next
|
||||
@@ -253,14 +271,14 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
|| dprev->df_lnum[idx] + dprev->df_count[idx] < line1)
|
||||
&& !diff_busy)
|
||||
{
|
||||
dnext = diff_alloc_new(dprev, dp);
|
||||
dnext = diff_alloc_new(tp, 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 (tp->tp_diffbuf[i] != NULL && i != idx)
|
||||
{
|
||||
if (dprev == NULL)
|
||||
dnext->df_lnum[i] = line1;
|
||||
@@ -367,7 +385,7 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
}
|
||||
|
||||
for (i = 0; i < DB_COUNT; ++i)
|
||||
if (diffbuf[i] != NULL && i != idx)
|
||||
if (tp->tp_diffbuf[i] != NULL && i != idx)
|
||||
{
|
||||
dp->df_lnum[i] -= off;
|
||||
dp->df_count[i] += n;
|
||||
@@ -390,7 +408,7 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
/* 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);
|
||||
diff_check_unchanged(tp, dp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,7 +417,7 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
== dp->df_lnum[idx])
|
||||
{
|
||||
for (i = 0; i < DB_COUNT; ++i)
|
||||
if (diffbuf[i] != NULL)
|
||||
if (tp->tp_diffbuf[i] != NULL)
|
||||
dprev->df_count[i] += dp->df_count[i];
|
||||
dprev->df_next = dp->df_next;
|
||||
vim_free(dp);
|
||||
@@ -414,12 +432,12 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
}
|
||||
|
||||
dprev = NULL;
|
||||
dp = first_diff;
|
||||
dp = tp->tp_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)
|
||||
if (tp->tp_diffbuf[i] != NULL && dp->df_count[i] != 0)
|
||||
break;
|
||||
if (i == DB_COUNT)
|
||||
{
|
||||
@@ -427,7 +445,7 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
vim_free(dp);
|
||||
dp = dnext;
|
||||
if (dprev == NULL)
|
||||
first_diff = dnext;
|
||||
tp->tp_first_diff = dnext;
|
||||
else
|
||||
dprev->df_next = dnext;
|
||||
}
|
||||
@@ -439,19 +457,24 @@ diff_mark_adjust(line1, line2, amount, amount_after)
|
||||
}
|
||||
|
||||
}
|
||||
diff_redraw(TRUE);
|
||||
|
||||
/* Need to recompute the scroll binding, may remove or add filler lines
|
||||
* (e.g., when adding lines above w_topline). But it's slow when making
|
||||
* many changes, postpone until redrawing. */
|
||||
diff_need_scrollbind = TRUE;
|
||||
if (tp == curtab)
|
||||
{
|
||||
diff_redraw(TRUE);
|
||||
|
||||
/* Need to recompute the scroll binding, may remove or add filler
|
||||
* lines (e.g., when adding lines above w_topline). But it's slow when
|
||||
* making many changes, postpone until redrawing. */
|
||||
diff_need_scrollbind = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new diff block and link it between "dprev" and "dp".
|
||||
*/
|
||||
static diff_T *
|
||||
diff_alloc_new(dprev, dp)
|
||||
diff_alloc_new(tp, dprev, dp)
|
||||
tabpage_T *tp;
|
||||
diff_T *dprev;
|
||||
diff_T *dp;
|
||||
{
|
||||
@@ -462,7 +485,7 @@ diff_alloc_new(dprev, dp)
|
||||
{
|
||||
dnew->df_next = dp;
|
||||
if (dprev == NULL)
|
||||
first_diff = dnew;
|
||||
tp->tp_first_diff = dnew;
|
||||
else
|
||||
dprev->df_next = dnew;
|
||||
}
|
||||
@@ -476,7 +499,8 @@ diff_alloc_new(dprev, dp)
|
||||
* must take care of removing it.
|
||||
*/
|
||||
static void
|
||||
diff_check_unchanged(dp)
|
||||
diff_check_unchanged(tp, dp)
|
||||
tabpage_T *tp;
|
||||
diff_T *dp;
|
||||
{
|
||||
int i_org;
|
||||
@@ -488,12 +512,12 @@ diff_check_unchanged(dp)
|
||||
/* 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)
|
||||
if (tp->tp_diffbuf[i_org] != NULL)
|
||||
break;
|
||||
if (i_org == DB_COUNT) /* safety check */
|
||||
return;
|
||||
|
||||
if (diff_check_sanity(dp) == FAIL)
|
||||
if (diff_check_sanity(tp, dp) == FAIL)
|
||||
return;
|
||||
|
||||
/* First check lines at the top, then at the bottom. */
|
||||
@@ -508,20 +532,20 @@ diff_check_unchanged(dp)
|
||||
/* 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],
|
||||
line_org = vim_strsave(ml_get_buf(tp->tp_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)
|
||||
if (tp->tp_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],
|
||||
if (diff_cmp(line_org, ml_get_buf(tp->tp_diffbuf[i_new],
|
||||
dp->df_lnum[i_new] + off_new, FALSE)) != 0)
|
||||
break;
|
||||
}
|
||||
@@ -533,7 +557,7 @@ diff_check_unchanged(dp)
|
||||
|
||||
/* 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 (tp->tp_diffbuf[i_new] != NULL)
|
||||
{
|
||||
if (dir == FORWARD)
|
||||
++dp->df_lnum[i_new];
|
||||
@@ -551,21 +575,22 @@ diff_check_unchanged(dp)
|
||||
* This can happen when the diff program returns invalid results.
|
||||
*/
|
||||
static int
|
||||
diff_check_sanity(dp)
|
||||
diff_check_sanity(tp, dp)
|
||||
tabpage_T *tp;
|
||||
diff_T *dp;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DB_COUNT; ++i)
|
||||
if (diffbuf[i] != NULL)
|
||||
if (tp->tp_diffbuf[i] != NULL)
|
||||
if (dp->df_lnum[i] + dp->df_count[i] - 1
|
||||
> diffbuf[i]->b_ml.ml_line_count)
|
||||
> tp->tp_diffbuf[i]->b_ml.ml_line_count)
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark all diff buffers for redraw.
|
||||
* Mark all diff buffers in the current tab page for redraw.
|
||||
*/
|
||||
static void
|
||||
diff_redraw(dofold)
|
||||
@@ -624,7 +649,7 @@ diff_write(buf, fname)
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ex_diffupdate(eap)
|
||||
exarg_T *eap;
|
||||
exarg_T *eap; /* can be NULL, it's not used */
|
||||
{
|
||||
buf_T *buf;
|
||||
int idx_orig;
|
||||
@@ -636,19 +661,19 @@ ex_diffupdate(eap)
|
||||
int ok;
|
||||
|
||||
/* Delete all diffblocks. */
|
||||
diff_clear();
|
||||
diff_invalid = FALSE;
|
||||
diff_clear(curtab);
|
||||
curtab->tp_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)
|
||||
if (curtab->tp_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)
|
||||
if (curtab->tp_diffbuf[idx_new] != NULL)
|
||||
break;
|
||||
if (idx_new == DB_COUNT)
|
||||
return;
|
||||
@@ -743,14 +768,14 @@ ex_diffupdate(eap)
|
||||
}
|
||||
|
||||
/* Write the first buffer to a tempfile. */
|
||||
buf = diffbuf[idx_orig];
|
||||
buf = curtab->tp_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];
|
||||
buf = curtab->tp_diffbuf[idx_new];
|
||||
if (buf == NULL)
|
||||
continue;
|
||||
if (diff_write(buf, tmp_new) == FAIL)
|
||||
@@ -1134,7 +1159,7 @@ diff_read(idx_orig, idx_new, fname)
|
||||
{
|
||||
FILE *fd;
|
||||
diff_T *dprev = NULL;
|
||||
diff_T *dp = first_diff;
|
||||
diff_T *dp = curtab->tp_first_diff;
|
||||
diff_T *dn, *dpl;
|
||||
long f1, l1, f2, l2;
|
||||
char_u linebuf[LBUFLEN]; /* only need to hold the diff line */
|
||||
@@ -1237,7 +1262,7 @@ diff_read(idx_orig, idx_new, fname)
|
||||
if (off > 0)
|
||||
{
|
||||
for (i = idx_orig; i < idx_new; ++i)
|
||||
if (diffbuf[i] != NULL)
|
||||
if (curtab->tp_diffbuf[i] != NULL)
|
||||
dp->df_lnum[i] -= off;
|
||||
dp->df_lnum[idx_new] = lnum_new;
|
||||
dp->df_count[idx_new] = count_new;
|
||||
@@ -1265,7 +1290,7 @@ diff_read(idx_orig, idx_new, fname)
|
||||
off = 0;
|
||||
}
|
||||
for (i = idx_orig; i < idx_new + !notset; ++i)
|
||||
if (diffbuf[i] != NULL)
|
||||
if (curtab->tp_diffbuf[i] != NULL)
|
||||
dp->df_count[i] = dpl->df_lnum[i] + dpl->df_count[i]
|
||||
- dp->df_lnum[i] + off;
|
||||
|
||||
@@ -1282,7 +1307,7 @@ diff_read(idx_orig, idx_new, fname)
|
||||
else
|
||||
{
|
||||
/* Allocate a new diffblock. */
|
||||
dp = diff_alloc_new(dprev, dp);
|
||||
dp = diff_alloc_new(curtab, dprev, dp);
|
||||
if (dp == NULL)
|
||||
return;
|
||||
|
||||
@@ -1295,7 +1320,7 @@ diff_read(idx_orig, idx_new, fname)
|
||||
* original buffer, otherwise there would have been a change
|
||||
* already. */
|
||||
for (i = idx_orig + 1; i < idx_new; ++i)
|
||||
if (diffbuf[i] != NULL)
|
||||
if (curtab->tp_diffbuf[i] != NULL)
|
||||
diff_copy_entry(dprev, dp, idx_orig, i);
|
||||
}
|
||||
notset = FALSE; /* "*dp" has been set */
|
||||
@@ -1336,19 +1361,20 @@ diff_copy_entry(dprev, dp, idx_orig, idx_new)
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the list of diffblocks.
|
||||
* Clear the list of diffblocks for tab page "tp".
|
||||
*/
|
||||
void
|
||||
diff_clear()
|
||||
diff_clear(tp)
|
||||
tabpage_T *tp;
|
||||
{
|
||||
diff_T *p, *next_p;
|
||||
|
||||
for (p = first_diff; p != NULL; p = next_p)
|
||||
for (p = tp->tp_first_diff; p != NULL; p = next_p)
|
||||
{
|
||||
next_p = p->df_next;
|
||||
vim_free(p);
|
||||
}
|
||||
first_diff = NULL;
|
||||
tp->tp_first_diff = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1365,17 +1391,17 @@ diff_check(wp, lnum)
|
||||
win_T *wp;
|
||||
linenr_T lnum;
|
||||
{
|
||||
int idx; /* index in diffbuf[] for this buffer */
|
||||
int idx; /* index in tp_diffbuf[] for this buffer */
|
||||
diff_T *dp;
|
||||
int maxcount;
|
||||
int i;
|
||||
buf_T *buf = wp->w_buffer;
|
||||
int cmp;
|
||||
|
||||
if (diff_invalid)
|
||||
if (curtab->tp_diff_invalid)
|
||||
ex_diffupdate(NULL); /* update after a big change */
|
||||
|
||||
if (first_diff == NULL || !wp->w_p_diff) /* no diffs at all */
|
||||
if (curtab->tp_first_diff == NULL || !wp->w_p_diff) /* no diffs at all */
|
||||
return 0;
|
||||
|
||||
/* safety check: "lnum" must be a buffer line */
|
||||
@@ -1393,7 +1419,7 @@ diff_check(wp, lnum)
|
||||
#endif
|
||||
|
||||
/* search for a change that includes "lnum" in the list of diffblocks. */
|
||||
for (dp = first_diff; dp != NULL; dp = dp->df_next)
|
||||
for (dp = curtab->tp_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])
|
||||
@@ -1408,7 +1434,7 @@ diff_check(wp, lnum)
|
||||
* count, check if the lines are identical. */
|
||||
cmp = FALSE;
|
||||
for (i = 0; i < DB_COUNT; ++i)
|
||||
if (i != idx && diffbuf[i] != NULL)
|
||||
if (i != idx && curtab->tp_diffbuf[i] != NULL)
|
||||
{
|
||||
if (dp->df_count[i] == 0)
|
||||
zero = TRUE;
|
||||
@@ -1424,7 +1450,7 @@ diff_check(wp, lnum)
|
||||
/* 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 (i != idx && curtab->tp_diffbuf[i] != NULL && dp->df_count[i] != 0)
|
||||
if (!diff_equal_entry(dp, idx, i))
|
||||
return -1;
|
||||
}
|
||||
@@ -1446,7 +1472,7 @@ diff_check(wp, lnum)
|
||||
* 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)
|
||||
if (curtab->tp_diffbuf[i] != NULL && dp->df_count[i] > maxcount)
|
||||
maxcount = dp->df_count[i];
|
||||
return maxcount - dp->df_count[idx];
|
||||
}
|
||||
@@ -1466,15 +1492,15 @@ diff_equal_entry(dp, idx1, idx2)
|
||||
|
||||
if (dp->df_count[idx1] != dp->df_count[idx2])
|
||||
return FALSE;
|
||||
if (diff_check_sanity(dp) == FAIL)
|
||||
if (diff_check_sanity(curtab, dp) == FAIL)
|
||||
return FALSE;
|
||||
for (i = 0; i < dp->df_count[idx1]; ++i)
|
||||
{
|
||||
line = vim_strsave(ml_get_buf(diffbuf[idx1],
|
||||
line = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx1],
|
||||
dp->df_lnum[idx1] + i, FALSE));
|
||||
if (line == NULL)
|
||||
return FALSE;
|
||||
cmp = diff_cmp(line, ml_get_buf(diffbuf[idx2],
|
||||
cmp = diff_cmp(line, ml_get_buf(curtab->tp_diffbuf[idx2],
|
||||
dp->df_lnum[idx2] + i, FALSE));
|
||||
vim_free(line);
|
||||
if (cmp != 0)
|
||||
@@ -1587,13 +1613,13 @@ diff_set_topline(fromwin, towin)
|
||||
if (idx == DB_COUNT)
|
||||
return; /* safety check */
|
||||
|
||||
if (diff_invalid)
|
||||
if (curtab->tp_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)
|
||||
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
|
||||
if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
|
||||
break;
|
||||
if (dp == NULL)
|
||||
@@ -1668,6 +1694,7 @@ diffopt_changed()
|
||||
char_u *p;
|
||||
int diff_context_new = 6;
|
||||
int diff_flags_new = 0;
|
||||
tabpage_T *tp;
|
||||
|
||||
p = p_dip;
|
||||
while (*p != NUL)
|
||||
@@ -1700,7 +1727,8 @@ diffopt_changed()
|
||||
|
||||
/* If "icase" or "iwhite" was added or removed, need to update the diff. */
|
||||
if (diff_flags != diff_flags_new)
|
||||
diff_invalid = TRUE;
|
||||
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
|
||||
tp->tp_diff_invalid = TRUE;
|
||||
|
||||
diff_flags = diff_flags_new;
|
||||
diff_context = diff_context_new;
|
||||
@@ -1744,22 +1772,22 @@ diff_find_change(wp, lnum, startp, endp)
|
||||
return FALSE;
|
||||
|
||||
/* search for a change that includes "lnum" in the list of diffblocks. */
|
||||
for (dp = first_diff; dp != NULL; dp = dp->df_next)
|
||||
for (dp = curtab->tp_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)
|
||||
if (dp == NULL || diff_check_sanity(curtab, dp) == FAIL)
|
||||
return FALSE;
|
||||
|
||||
off = lnum - dp->df_lnum[idx];
|
||||
|
||||
for (i = 0; i < DB_COUNT; ++i)
|
||||
if (diffbuf[i] != NULL && i != idx)
|
||||
if (curtab->tp_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);
|
||||
line_new = ml_get_buf(curtab->tp_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]; )
|
||||
@@ -1819,9 +1847,9 @@ diff_infold(wp, lnum)
|
||||
|
||||
for (i = 0; i < DB_COUNT; ++i)
|
||||
{
|
||||
if (diffbuf[i] == wp->w_buffer)
|
||||
if (curtab->tp_diffbuf[i] == wp->w_buffer)
|
||||
idx = i;
|
||||
else if (diffbuf[i] != NULL)
|
||||
else if (curtab->tp_diffbuf[i] != NULL)
|
||||
other = TRUE;
|
||||
}
|
||||
|
||||
@@ -1829,14 +1857,14 @@ diff_infold(wp, lnum)
|
||||
if (idx == -1 || !other)
|
||||
return FALSE;
|
||||
|
||||
if (diff_invalid)
|
||||
if (curtab->tp_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)
|
||||
if (curtab->tp_first_diff == NULL)
|
||||
return TRUE;
|
||||
|
||||
for (dp = first_diff; dp != NULL; dp = dp->df_next)
|
||||
for (dp = curtab->tp_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)
|
||||
@@ -1908,10 +1936,10 @@ ex_diffgetput(eap)
|
||||
{
|
||||
/* 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
|
||||
if (curtab->tp_diffbuf[idx_other] != curbuf
|
||||
&& curtab->tp_diffbuf[idx_other] != NULL
|
||||
&& (eap->cmdidx != CMD_diffput
|
||||
|| diffbuf[idx_other]->b_p_ma))
|
||||
|| curtab->tp_diffbuf[idx_other]->b_p_ma))
|
||||
break;
|
||||
if (idx_other == DB_COUNT)
|
||||
{
|
||||
@@ -1921,9 +1949,9 @@ ex_diffgetput(eap)
|
||||
|
||||
/* 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))
|
||||
if (curtab->tp_diffbuf[i] != curbuf
|
||||
&& curtab->tp_diffbuf[i] != NULL
|
||||
&& (eap->cmdidx != CMD_diffput || curtab->tp_diffbuf[i]->b_p_ma))
|
||||
{
|
||||
EMSG(_("E101: More than two buffers in diff mode, don't know which one to use"));
|
||||
return;
|
||||
@@ -1987,11 +2015,11 @@ ex_diffgetput(eap)
|
||||
/* 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]);
|
||||
aucmd_prepbuf(&aco, curtab->tp_diffbuf[idx_other]);
|
||||
}
|
||||
|
||||
dprev = NULL;
|
||||
for (dp = first_diff; dp != NULL; )
|
||||
for (dp = curtab->tp_first_diff; dp != NULL; )
|
||||
{
|
||||
if (dp->df_lnum[idx_cur] > eap->line2 + off)
|
||||
break; /* past the range that was specified */
|
||||
@@ -2063,9 +2091,9 @@ ex_diffgetput(eap)
|
||||
linenr_T nr;
|
||||
|
||||
nr = dp->df_lnum[idx_from] + start_skip + i;
|
||||
if (nr > diffbuf[idx_from]->b_ml.ml_line_count)
|
||||
if (nr > curtab->tp_diffbuf[idx_from]->b_ml.ml_line_count)
|
||||
break;
|
||||
p = vim_strsave(ml_get_buf(diffbuf[idx_from], nr, FALSE));
|
||||
p = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx_from], nr, FALSE));
|
||||
if (p != NULL)
|
||||
{
|
||||
ml_append(lnum + i - 1, p, 0, FALSE);
|
||||
@@ -2088,7 +2116,7 @@ ex_diffgetput(eap)
|
||||
/* 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
|
||||
if (curtab->tp_diffbuf[i] != NULL && i != idx_from && i != idx_to
|
||||
&& !diff_equal_entry(dp, idx_from, i))
|
||||
break;
|
||||
if (i == DB_COUNT)
|
||||
@@ -2097,7 +2125,7 @@ ex_diffgetput(eap)
|
||||
dfree = dp;
|
||||
dp = dp->df_next;
|
||||
if (dprev == NULL)
|
||||
first_diff = dp;
|
||||
curtab->tp_first_diff = dp;
|
||||
else
|
||||
dprev->df_next = dp;
|
||||
}
|
||||
@@ -2182,7 +2210,7 @@ diff_fold_update(dp, skip_idx)
|
||||
|
||||
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)
|
||||
if (curtab->tp_diffbuf[i] == wp->w_buffer && i != skip_idx)
|
||||
foldUpdate(wp, dp->df_lnum[i],
|
||||
dp->df_lnum[i] + dp->df_count[i]);
|
||||
}
|
||||
@@ -2195,7 +2223,12 @@ diff_fold_update(dp, skip_idx)
|
||||
diff_mode_buf(buf)
|
||||
buf_T *buf;
|
||||
{
|
||||
return diff_buf_idx(buf) != DB_COUNT;
|
||||
tabpage_T *tp;
|
||||
|
||||
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
|
||||
if (diff_buf_idx_tp(buf, tp) != DB_COUNT)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2212,22 +2245,22 @@ diff_move_to(dir, count)
|
||||
diff_T *dp;
|
||||
|
||||
idx = diff_buf_idx(curbuf);
|
||||
if (idx == DB_COUNT || first_diff == NULL)
|
||||
if (idx == DB_COUNT || curtab->tp_first_diff == NULL)
|
||||
return FAIL;
|
||||
|
||||
if (diff_invalid)
|
||||
if (curtab->tp_diff_invalid)
|
||||
ex_diffupdate(NULL); /* update after a big change */
|
||||
|
||||
if (first_diff == NULL) /* no diffs today */
|
||||
if (curtab->tp_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])
|
||||
if (dir == BACKWARD && lnum <= curtab->tp_first_diff->df_lnum[idx])
|
||||
break;
|
||||
|
||||
for (dp = first_diff; ; dp = dp->df_next)
|
||||
for (dp = curtab->tp_first_diff; ; dp = dp->df_next)
|
||||
{
|
||||
if (dp == NULL)
|
||||
break;
|
||||
@@ -2276,11 +2309,11 @@ diff_lnum_win(lnum, wp)
|
||||
if (idx == DB_COUNT) /* safety check */
|
||||
return (linenr_T)0;
|
||||
|
||||
if (diff_invalid)
|
||||
if (curtab->tp_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)
|
||||
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next)
|
||||
if (lnum <= dp->df_lnum[idx] + dp->df_count[idx])
|
||||
break;
|
||||
|
||||
|
Reference in New Issue
Block a user