From 4f93d05d3985d90701fa9dace22daee82b4e48f9 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 10 Aug 2018 16:39:21 -0400 Subject: vim-patch:8.0.1037: "icase" of 'diffopt' is not used for highlighting Problem: "icase" of 'diffopt' is not used for highlighting differences. Solution: Also use "icase". (Rick Howe) https://github.com/vim/vim/commit/da22b8cc8b1b96fabd5a4c35c57b04a351340fb1 --- src/nvim/diff.c | 48 +++++++++++++++++++++++++++++++++----- src/nvim/testdir/test_diffmode.vim | 8 +++++-- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 8699c16351..7b06609fc3 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1870,6 +1870,35 @@ bool diffopt_horizontal(void) return (diff_flags & DIFF_HORIZONTAL) != 0; } +// Compare the characters at "p1" and "p2". If they are equal (possibly +// ignoring case) return true and set "len" to the number of bytes. +static bool diff_equal_char(const char_u *const p1, const char_u *const p2, + int *const len) +{ + const int l = utfc_ptr2len(p1); + + if (l != utfc_ptr2len(p2)) { + return false; + } + 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)))) { + return false; + } + *len = l; + } else { + if ((*p1 != *p2) + && (!(diff_flags & DIFF_ICASE) + || TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2))) { + return false; + } + *len = 1; + } + return true; +} + /// Find the difference within a changed line. /// /// @param wp window whose current buffer to check @@ -1887,6 +1916,7 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) int ei_org; int ei_new; bool added = true; + int l; // Make a copy of the line, the next ml_get() will invalidate it. char_u *line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE)); @@ -1933,11 +1963,11 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) si_org = (int)(skipwhite(line_org + si_org) - line_org); si_new = (int)(skipwhite(line_new + si_new) - line_new); } else { - if (line_org[si_org] != line_new[si_new]) { + if (!diff_equal_char(line_org + si_org, line_new + si_new, &l)) { break; } - ++si_org; - ++si_new; + si_org += l; + si_new += l; } } @@ -1972,11 +2002,17 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) ei_new--; } } else { - if (line_org[ei_org] != line_new[ei_new]) { + const char_u *p1 = line_org + ei_org; + const char_u *p2 = line_new + ei_new; + + p1 -= utf_head_off(line_org, p1); + p2 -= utf_head_off(line_new, p2); + + if (!diff_equal_char(p1, p2, &l)) { break; } - ei_org--; - ei_new--; + ei_org -= l; + ei_new -= l; } } diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index d95b29759e..f53fe438fc 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -279,13 +279,13 @@ func Test_diffopt_icase() set diffopt=icase,foldcolumn:0 e one - call setline(1, ['One', 'Two', 'Three', 'Four']) + call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve']) redraw let normattr = screenattr(1, 1) diffthis botright vert new two - call setline(1, ['one', 'TWO', 'Three ', 'Four']) + call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE']) diffthis redraw @@ -294,6 +294,10 @@ func Test_diffopt_icase() call assert_notequal(normattr, screenattr(3, 1)) call assert_equal(normattr, screenattr(4, 1)) + let dtextattr = screenattr(5, 3) + call assert_notequal(dtextattr, screenattr(5, 1)) + call assert_notequal(dtextattr, screenattr(5, 5)) + diffoff! %bwipe! set diffopt& -- cgit From fd334ec2a8109aee71fa11697f4608de76144df8 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 10 Aug 2018 17:13:02 -0400 Subject: vim-patch:8.0.1046: code duplication in diff mode Problem: Code duplication in diff mode. Solution: Use diff_equal_char() also in diff_cmp(). (Rick Howe) https://github.com/vim/vim/commit/ae96b8d058cffd9d07b78cb7a9ccd382185b9dd6 --- src/nvim/diff.c | 84 +++++++++++++++++++++++---------------------------------- 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 7b06609fc3..8dc9d0ee10 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1597,6 +1597,35 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2) return true; } +// Compare the characters at "p1" and "p2". If they are equal (possibly +// ignoring case) return true and set "len" to the number of bytes. +static bool diff_equal_char(const char_u *const p1, const char_u *const p2, + int *const len) +{ + const int l = utfc_ptr2len(p1); + + if (l != utfc_ptr2len(p2)) { + return false; + } + 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)))) { + return false; + } + *len = l; + } else { + if ((*p1 != *p2) + && (!(diff_flags & DIFF_ICASE) + || TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2))) { + return false; + } + *len = 1; + } + return true; +} + /// Compare strings "s1" and "s2" according to 'diffopt'. /// Return non-zero when they are different. /// @@ -1623,30 +1652,12 @@ static int diff_cmp(char_u *s1, char_u *s2) p1 = skipwhite(p1); p2 = skipwhite(p2); } else { - int l = (*mb_ptr2len)(p1); - if (l != (*mb_ptr2len)(p2)) { + int l; + if (!diff_equal_char(p1, p2, &l)) { 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 { - if ((*p1 != *p2) - && (!(diff_flags & DIFF_ICASE) - || (TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2)))) { - break; - } - ++p1; - ++p2; - } + p1 += l; + p2 += l; } } @@ -1870,35 +1881,6 @@ bool diffopt_horizontal(void) return (diff_flags & DIFF_HORIZONTAL) != 0; } -// Compare the characters at "p1" and "p2". If they are equal (possibly -// ignoring case) return true and set "len" to the number of bytes. -static bool diff_equal_char(const char_u *const p1, const char_u *const p2, - int *const len) -{ - const int l = utfc_ptr2len(p1); - - if (l != utfc_ptr2len(p2)) { - return false; - } - 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)))) { - return false; - } - *len = l; - } else { - if ((*p1 != *p2) - && (!(diff_flags & DIFF_ICASE) - || TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2))) { - return false; - } - *len = 1; - } - return true; -} - /// Find the difference within a changed line. /// /// @param wp window whose current buffer to check -- cgit From 90128843f68bc6b96cc7ab7a97d172aaae742aa4 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Fri, 10 Aug 2018 17:53:33 -0400 Subject: diff: drop enc_utf8 check in diff_equal_char() enc_utf8 is always true for nvim. --- src/nvim/diff.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 8dc9d0ee10..e7a176d336 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1609,8 +1609,7 @@ static bool diff_equal_char(const char_u *const p1, const char_u *const p2, } if (l > 1) { if (STRNCMP(p1, p2, l) != 0 - && (!enc_utf8 - || !(diff_flags & DIFF_ICASE) + && (!(diff_flags & DIFF_ICASE) || utf_fold(utf_ptr2char(p1)) != utf_fold(utf_ptr2char(p2)))) { return false; } -- cgit From 594536a1e71c90fd558501a675c459b8c7c242ea Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 11 Aug 2018 14:55:02 -0400 Subject: vim-patch:8.0.1361: some users don't want to diff with hidden buffers Problem: Some users don't want to diff with hidden buffers. Solution: Add the "hiddenoff" item to 'diffopt'. (Alisue, closes vim/vim#2394) https://github.com/vim/vim/commit/97ce419201421f65f4764549ed80307a7ef9c7a6 --- runtime/doc/options.txt | 3 +++ src/nvim/buffer.c | 4 ++++ src/nvim/diff.c | 10 ++++++++++ src/nvim/testdir/test_diffmode.vim | 23 +++++++++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 81726ca46b..cdec599a74 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1960,6 +1960,9 @@ A jump table for the options with a short description can be found at |Q_op|. vertical Start diff mode with vertical splits (unless explicitly specified otherwise). + hiddenoff Do not use diff mode for a buffer when it + becomes hidden. + foldcolumn:{n} Set the 'foldcolumn' option to {n} when starting diff mode. Without this 2 is used. diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 71e04ec0fb..d4e21d26f6 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -509,6 +509,10 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) if (buf->b_nwindows > 0) --buf->b_nwindows; + if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0) { + diff_buf_delete(buf); // Clear 'diff' for hidden buffer. + } + /* Return when a window is displaying the buffer or when it's not * unloaded. */ if (buf->b_nwindows > 0 || !unload_buf) diff --git a/src/nvim/diff.c b/src/nvim/diff.c index e7a176d336..878971a35c 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -44,6 +44,7 @@ static int diff_busy = FALSE; // ex_diffgetput() is busy #define DIFF_IWHITE 4 // ignore change in white space #define DIFF_HORIZONTAL 8 // horizontal splits #define DIFF_VERTICAL 16 // vertical splits +#define DIFF_HIDDEN_OFF 32 // diffoff when hidden static int diff_flags = DIFF_FILLER; #define LBUFLEN 50 // length of line in diff file @@ -1838,6 +1839,9 @@ int diffopt_changed(void) } else if ((STRNCMP(p, "foldcolumn:", 11) == 0) && ascii_isdigit(p[11])) { p += 11; diff_foldcolumn_new = getdigits_int(&p); + } else if (STRNCMP(p, "hiddenoff", 9) == 0) { + p += 9; + diff_flags_new |= DIFF_HIDDEN_OFF; } if ((*p != ',') && (*p != NUL)) { @@ -1880,6 +1884,12 @@ bool diffopt_horizontal(void) return (diff_flags & DIFF_HORIZONTAL) != 0; } +// Return true if 'diffopt' contains "hiddenoff". +bool diffopt_hiddenoff(void) +{ + return (diff_flags & DIFF_HIDDEN_OFF) != 0; +} + /// Find the difference within a changed line. /// /// @param wp window whose current buffer to check diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index f53fe438fc..90fd34d93e 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -375,6 +375,29 @@ func Test_diffopt_vertical() %bwipe endfunc +func Test_diffopt_hiddenoff() + set diffopt=filler,foldcolumn:0,hiddenoff + e! one + call setline(1, ['Two', 'Three']) + redraw + let normattr = screenattr(1, 1) + diffthis + botright vert new two + call setline(1, ['One', 'Four']) + diffthis + redraw + call assert_notequal(normattr, screenattr(1, 1)) + set hidden + close + redraw + " should not diffing with hidden buffer two while 'hiddenoff' is enabled + call assert_equal(normattr, screenattr(1, 1)) + + bwipe! + bwipe! + set hidden& diffopt& +endfunc + func Test_diffoff_hidden() set diffopt=filler,foldcolumn:0 e! one -- cgit From 3d77ca39c70446ed63a54ee286688c394826511c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 11 Aug 2018 18:24:00 -0400 Subject: lint --- src/nvim/buffer.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index d4e21d26f6..3fadcc75bf 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -505,9 +505,10 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) int nwindows = buf->b_nwindows; - /* decrease the link count from windows (unless not in any window) */ - if (buf->b_nwindows > 0) - --buf->b_nwindows; + // decrease the link count from windows (unless not in any window) + if (buf->b_nwindows > 0) { + buf->b_nwindows--; + } if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0) { diff_buf_delete(buf); // Clear 'diff' for hidden buffer. @@ -515,8 +516,9 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) /* Return when a window is displaying the buffer or when it's not * unloaded. */ - if (buf->b_nwindows > 0 || !unload_buf) + if (buf->b_nwindows > 0 || !unload_buf) { return; + } if (buf->terminal) { terminal_close(buf->terminal, NULL); -- cgit