vim-patch:8.1.0394: diffs are not always updated correctly

Problem:    Diffs are not always updated correctly.
Solution:   When using internal diff update for any changes properly.

e3521d9cbb
This commit is contained in:
Anatolii Sakhnik
2018-12-09 15:31:22 +02:00
parent 972ad11195
commit 7b6c92eac1
4 changed files with 30 additions and 8 deletions

View File

@@ -842,6 +842,7 @@ struct tabpage_S {
diff_T *tp_first_diff; diff_T *tp_first_diff;
buf_T *(tp_diffbuf[DB_COUNT]); buf_T *(tp_diffbuf[DB_COUNT]);
int tp_diff_invalid; ///< list of diffs is outdated int tp_diff_invalid; ///< list of diffs is outdated
int tp_diff_update; ///< update diffs before redrawing
frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots
ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary. ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
dict_T *tp_vars; ///< Internal variables, local to tab page. dict_T *tp_vars; ///< Internal variables, local to tab page.

View File

@@ -266,6 +266,15 @@ void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount,
static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
linenr_T line2, long amount, long amount_after) linenr_T line2, long amount, long amount_after)
{ {
if (diff_internal()) {
// Will udpate diffs before redrawing. Set _invalid to update the
// diffs themselves, set _update to also update folds properly just
// before redrawing.
tp->tp_diff_invalid = true;
tp->tp_diff_update = true;
return;
}
int inserted; int inserted;
int deleted; int deleted;
if (line2 == MAXLNUM) { if (line2 == MAXLNUM) {
@@ -840,7 +849,7 @@ theend:
/// Note that if the internal diff failed for one of the buffers, the external /// Note that if the internal diff failed for one of the buffers, the external
/// diff will be used anyway. /// diff will be used anyway.
/// ///
static int diff_internal(void) int diff_internal(void)
{ {
return (diff_flags & DIFF_INTERNAL) != 0 && *p_dex == NUL; return (diff_flags & DIFF_INTERNAL) != 0 && *p_dex == NUL;
} }
@@ -864,9 +873,9 @@ static int diff_internal_failed(void)
/// Completely update the diffs for the buffers involved. /// Completely update the diffs for the buffers involved.
/// ///
/// This uses the ordinary "diff" command. /// When using the external "diff" command the buffers are written to a file,
/// The buffers are written to a file, also for unmodified buffers (the file /// also for unmodified buffers (the file could have been produced by
/// could have been produced by autocommands, e.g. the netrw plugin). /// autocommands, e.g. the netrw plugin).
/// ///
/// @param eap can be NULL /// @param eap can be NULL
void ex_diffupdate(exarg_T *eap) void ex_diffupdate(exarg_T *eap)

View File

@@ -1953,10 +1953,10 @@ changed_lines(
{ {
changed_lines_buf(curbuf, lnum, lnume, xtra); changed_lines_buf(curbuf, lnum, lnume, xtra);
if (xtra == 0 && curwin->w_p_diff) { if (xtra == 0 && curwin->w_p_diff && !diff_internal()) {
/* When the number of lines doesn't change then mark_adjust() isn't // When the number of lines doesn't change then mark_adjust() isn't
* called and other diff buffers still need to be marked for // called and other diff buffers still need to be marked for
* displaying. */ // displaying.
linenr_T wlnum; linenr_T wlnum;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
@@ -2025,6 +2025,10 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra
/* mark the buffer as modified */ /* mark the buffer as modified */
changed(); changed();
if (curwin->w_p_diff && diff_internal()) {
curtab->tp_diff_update = true;
}
/* set the '. mark */ /* set the '. mark */
if (!cmdmod.keepjumps) { if (!cmdmod.keepjumps) {
RESET_FMARK(&curbuf->b_last_change, ((pos_T) {lnum, col, 0}), 0); RESET_FMARK(&curbuf->b_last_change, ((pos_T) {lnum, col, 0}), 0);

View File

@@ -1325,6 +1325,14 @@ static int normal_check(VimState *state)
normal_check_cursor_moved(s); normal_check_cursor_moved(s);
normal_check_text_changed(s); normal_check_text_changed(s);
// Updating diffs from changed() does not always work properly,
// esp. updating folds. Do an update just before redrawing if
// needed.
if (curtab->tp_diff_update || curtab->tp_diff_invalid) {
ex_diffupdate(NULL);
curtab->tp_diff_update = false;
}
// Scroll-binding for diff mode may have been postponed until // Scroll-binding for diff mode may have been postponed until
// here. Avoids doing it for every change. // here. Avoids doing it for every change.
if (diff_need_scrollbind) { if (diff_need_scrollbind) {