diff options
Diffstat (limited to 'src/nvim/diff.c')
-rw-r--r-- | src/nvim/diff.c | 97 |
1 files changed, 57 insertions, 40 deletions
diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 11ade20c1c..cc0f3b2629 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + /// @file diff.c /// /// Code for diff'ing two, three or four buffers. @@ -132,6 +135,20 @@ void diff_buf_add(buf_T *buf) EMSGN(_("E96: Cannot diff more than %" PRId64 " buffers"), DB_COUNT); } +/// +/// Remove all buffers to make diffs for. +/// +static void diff_buf_clear(void) +{ + for (int i = 0; i < DB_COUNT; i++) { + if (curtab->tp_diffbuf[i] != NULL) { + curtab->tp_diffbuf[i] = NULL; + curtab->tp_diff_invalid = true; + diff_redraw(true); + } + } +} + /// Find buffer "buf" in the list of diff buffers for the current tab page. /// /// @param buf The buffer to find. @@ -1030,10 +1047,7 @@ void ex_diffsplit(exarg_T *eap) if (bufref_valid(&old_curbuf)) { // Move the cursor position to that of the old window. curwin->w_cursor.lnum = diff_get_corresponding_line( - old_curbuf.br_buf, - old_curwin->w_cursor.lnum, - curbuf, - curwin->w_cursor.lnum); + old_curbuf.br_buf, old_curwin->w_cursor.lnum); } } // Now that lines are folded scroll to show the cursor at the same @@ -1076,8 +1090,8 @@ void diff_win_options(win_T *wp, int addbuf) if (!wp->w_p_diff) { wp->w_p_wrap_save = wp->w_p_wrap; } - wp->w_p_wrap = FALSE; - curwin = wp; + wp->w_p_wrap = false; + curwin = wp; // -V519 curbuf = curwin->w_buffer; if (!wp->w_p_diff) { @@ -1175,6 +1189,11 @@ void ex_diffoff(exarg_T *eap) diffwin |= wp->w_p_diff; } + // Also remove hidden buffers from the list. + if (eap->forceit) { + diff_buf_clear(); + } + // Remove "hor" from from 'scrollopt' if there are no diff windows left. if (!diffwin && (vim_strchr(p_sbo, 'h') != NULL)) { do_cmdline_cmd("set sbo-=hor"); @@ -1586,7 +1605,7 @@ static int diff_cmp(char_u *s1, char_u *s2) } if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE)) { - return mb_stricmp(s1, s2); + return mb_stricmp((const char *)s1, (const char *)s2); } // Ignore white space changes and possibly ignore case. @@ -2308,7 +2327,7 @@ void ex_diffgetput(exarg_T *eap) // Adjust marks. This will change the following entries! if (added != 0) { - mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added); + mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added, false); if (curwin->w_cursor.lnum >= lnum) { // Adjust the cursor position if it's in/after the changed // lines. @@ -2460,25 +2479,17 @@ int diff_move_to(int dir, long count) return OK; } -/// Finds the corresponding line in a diff. -/// -/// @param buf1 -/// @param lnum1 -/// @param buf2 -/// @param lnum3 -/// -/// @return The corresponding line. -linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2, - linenr_T lnum3) +/// Return the line number in the current window that is closest to "lnum1" in +/// "buf1" in diff mode. +static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1) { int idx1; int idx2; diff_T *dp; int baseline = 0; - linenr_T lnum2; idx1 = diff_buf_idx(buf1); - idx2 = diff_buf_idx(buf2); + idx2 = diff_buf_idx(curbuf); if ((idx1 == DB_COUNT) || (idx2 == DB_COUNT) @@ -2498,15 +2509,9 @@ linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2, for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) { if (dp->df_lnum[idx1] > lnum1) { - lnum2 = lnum1 - baseline; - - // don't end up past the end of the file - if (lnum2 > buf2->b_ml.ml_line_count) { - lnum2 = buf2->b_ml.ml_line_count; - } - - return lnum2; - } else if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1) { + return lnum1 - baseline; + } + if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1) { // Inside the diffblock baseline = lnum1 - dp->df_lnum[idx1]; @@ -2515,30 +2520,42 @@ linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2, } return dp->df_lnum[idx2] + baseline; - } else if ((dp->df_lnum[idx1] == lnum1) - && (dp->df_count[idx1] == 0) - && (dp->df_lnum[idx2] <= lnum3) - && ((dp->df_lnum[idx2] + dp->df_count[idx2]) > lnum3)) { + } + if ((dp->df_lnum[idx1] == lnum1) + && (dp->df_count[idx1] == 0) + && (dp->df_lnum[idx2] <= curwin->w_cursor.lnum) + && ((dp->df_lnum[idx2] + dp->df_count[idx2]) + > curwin->w_cursor.lnum)) { // Special case: if the cursor is just after a zero-count // block (i.e. all filler) and the target cursor is already // inside the corresponding block, leave the target cursor // unmoved. This makes repeated CTRL-W W operations work // as expected. - return lnum3; + return curwin->w_cursor.lnum; } baseline = (dp->df_lnum[idx1] + dp->df_count[idx1]) - - (dp->df_lnum[idx2] + dp->df_count[idx2]); + - (dp->df_lnum[idx2] + dp->df_count[idx2]); } // If we get here then the cursor is after the last diff - lnum2 = lnum1 - baseline; + return lnum1 - baseline; +} + +/// Finds the corresponding line in a diff. +/// +/// @param buf1 +/// @param lnum1 +/// +/// @return The corresponding line. +linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1) +{ + linenr_T lnum = diff_get_corresponding_line_int(buf1, lnum1); // don't end up past the end of the file - if (lnum2 > buf2->b_ml.ml_line_count) { - lnum2 = buf2->b_ml.ml_line_count; + if (lnum > curbuf->b_ml.ml_line_count) { + return curbuf->b_ml.ml_line_count; } - - return lnum2; + return lnum; } /// For line "lnum" in the current window find the equivalent lnum in window |