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;
buf_T *(tp_diffbuf[DB_COUNT]);
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
ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
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,
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 deleted;
if (line2 == MAXLNUM) {
@ -840,7 +849,7 @@ theend:
/// Note that if the internal diff failed for one of the buffers, the external
/// diff will be used anyway.
///
static int diff_internal(void)
int diff_internal(void)
{
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.
///
/// 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).
/// When using the external "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).
///
/// @param eap can be NULL
void ex_diffupdate(exarg_T *eap)

View File

@ -1953,10 +1953,10 @@ changed_lines(
{
changed_lines_buf(curbuf, lnum, lnume, xtra);
if (xtra == 0 && curwin->w_p_diff) {
/* When the number of lines doesn't change then mark_adjust() isn't
* called and other diff buffers still need to be marked for
* displaying. */
if (xtra == 0 && curwin->w_p_diff && !diff_internal()) {
// When the number of lines doesn't change then mark_adjust() isn't
// called and other diff buffers still need to be marked for
// displaying.
linenr_T wlnum;
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 */
changed();
if (curwin->w_p_diff && diff_internal()) {
curtab->tp_diff_update = true;
}
/* set the '. mark */
if (!cmdmod.keepjumps) {
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_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
// here. Avoids doing it for every change.
if (diff_need_scrollbind) {