From bb6190bec5f18c1f9e2c1d29ef1f7cf7912ea625 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 1 Jun 2024 08:19:41 -0700 Subject: refactor: move shared messages to errors.h #26214 --- src/nvim/diff.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index ea846b46ec..54335fc93e 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -26,6 +26,7 @@ #include "nvim/cursor.h" #include "nvim/diff.h" #include "nvim/drawscreen.h" +#include "nvim/errors.h" #include "nvim/eval.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds_defs.h" -- cgit From bbd2f340a2895ed59785f952b2585e6590602cad Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 11 Jun 2024 10:25:32 +0200 Subject: refactor(memory): use builtin strcat() instead of STRCAT() The latter was mostly relevant with the past char_u madness. NOTE: STRCAT also functioned as a counterfeit "NOLINT" for clint apparently. But NOLINT-ing every usecase is just the same as disabling the check entirely. --- src/nvim/diff.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 54335fc93e..0fe1729029 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1273,10 +1273,10 @@ void ex_diffpatch(exarg_T *eap) // Delete any .orig or .rej file created. STRCPY(buf, tmp_new); - STRCAT(buf, ".orig"); + strcat(buf, ".orig"); os_remove(buf); STRCPY(buf, tmp_new); - STRCAT(buf, ".rej"); + strcat(buf, ".rej"); os_remove(buf); // Only continue if the output file was created. @@ -1288,7 +1288,7 @@ void ex_diffpatch(exarg_T *eap) } else { if (curbuf->b_fname != NULL) { newname = xstrnsave(curbuf->b_fname, strlen(curbuf->b_fname) + 4); - STRCAT(newname, ".new"); + strcat(newname, ".new"); } // don't use a new tab page, each tab page has its own diffs -- cgit From c37695a5d5f2e8914fff86f3581bed70b4c85d3c Mon Sep 17 00:00:00 2001 From: James <89495599+IAKOBVS@users.noreply.github.com> Date: Tue, 11 Jun 2024 22:40:24 +0700 Subject: refactor: use S_LEN(s) instead of s, n (#29219) --- src/nvim/diff.c | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 54335fc93e..e24c39e60c 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1020,7 +1020,7 @@ static int check_external_diff(diffio_T *diffio) if (fd == NULL) { io_error = true; } else { - if (fwrite("line1\n", 6, 1, fd) != 1) { + if (fwrite(S_LEN("line1\n"), 1, fd) != 1) { io_error = true; } fclose(fd); @@ -1029,7 +1029,7 @@ static int check_external_diff(diffio_T *diffio) if (fd == NULL) { io_error = true; } else { - if (fwrite("line2\n", 6, 1, fd) != 1) { + if (fwrite(S_LEN("line2\n"), 1, fd) != 1) { io_error = true; } fclose(fd); @@ -1050,8 +1050,8 @@ static int check_external_diff(diffio_T *diffio) break; } - if (strncmp(linebuf, "1c1", 3) == 0 - || strncmp(linebuf, "@@ -1 +1 @@", 11) == 0) { + if (strncmp(linebuf, S_LEN("1c1")) == 0 + || strncmp(linebuf, S_LEN("@@ -1 +1 @@")) == 0) { ok = kTrue; } } @@ -1583,13 +1583,13 @@ static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle) // @@ -1,3 +1,5 @@ if (isdigit((uint8_t)(*line))) { *diffstyle = DIFF_ED; - } else if ((strncmp(line, "@@ ", 3) == 0)) { + } else if ((strncmp(line, S_LEN("@@ ")) == 0)) { *diffstyle = DIFF_UNIFIED; - } else if ((strncmp(line, "--- ", 4) == 0) + } else if ((strncmp(line, S_LEN("--- ")) == 0) && (vim_fgets(line, LBUFLEN, fd) == 0) - && (strncmp(line, "+++ ", 4) == 0) + && (strncmp(line, S_LEN("+++ ")) == 0) && (vim_fgets(line, LBUFLEN, fd) == 0) - && (strncmp(line, "@@ ", 3) == 0)) { + && (strncmp(line, S_LEN("@@ ")) == 0)) { *diffstyle = DIFF_UNIFIED; } else { // Format not recognized yet, skip over this line. Cygwin diff @@ -1607,7 +1607,7 @@ static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle) } } else { assert(*diffstyle == DIFF_UNIFIED); - if (strncmp(line, "@@ ", 3) != 0) { + if (strncmp(line, S_LEN("@@ ")) != 0) { continue; // not the start of a diff block } if (parse_diff_unified(line, hunk) == FAIL) { @@ -2473,70 +2473,70 @@ int diffopt_changed(void) char *p = p_dip; while (*p != NUL) { // Note: Keep this in sync with p_dip_values - if (strncmp(p, "filler", 6) == 0) { + if (strncmp(p, S_LEN("filler")) == 0) { p += 6; diff_flags_new |= DIFF_FILLER; - } else if ((strncmp(p, "context:", 8) == 0) && ascii_isdigit(p[8])) { + } else if ((strncmp(p, S_LEN("context:")) == 0) && ascii_isdigit(p[8])) { p += 8; diff_context_new = getdigits_int(&p, false, diff_context_new); - } else if (strncmp(p, "iblank", 6) == 0) { + } else if (strncmp(p, S_LEN("iblank")) == 0) { p += 6; diff_flags_new |= DIFF_IBLANK; - } else if (strncmp(p, "icase", 5) == 0) { + } else if (strncmp(p, S_LEN("icase")) == 0) { p += 5; diff_flags_new |= DIFF_ICASE; - } else if (strncmp(p, "iwhiteall", 9) == 0) { + } else if (strncmp(p, S_LEN("iwhiteall")) == 0) { p += 9; diff_flags_new |= DIFF_IWHITEALL; - } else if (strncmp(p, "iwhiteeol", 9) == 0) { + } else if (strncmp(p, S_LEN("iwhiteeol")) == 0) { p += 9; diff_flags_new |= DIFF_IWHITEEOL; - } else if (strncmp(p, "iwhite", 6) == 0) { + } else if (strncmp(p, S_LEN("iwhite")) == 0) { p += 6; diff_flags_new |= DIFF_IWHITE; - } else if (strncmp(p, "horizontal", 10) == 0) { + } else if (strncmp(p, S_LEN("horizontal")) == 0) { p += 10; diff_flags_new |= DIFF_HORIZONTAL; - } else if (strncmp(p, "vertical", 8) == 0) { + } else if (strncmp(p, S_LEN("vertical")) == 0) { p += 8; diff_flags_new |= DIFF_VERTICAL; - } else if ((strncmp(p, "foldcolumn:", 11) == 0) && ascii_isdigit(p[11])) { + } else if ((strncmp(p, S_LEN("foldcolumn:")) == 0) && ascii_isdigit(p[11])) { p += 11; diff_foldcolumn_new = getdigits_int(&p, false, diff_foldcolumn_new); - } else if (strncmp(p, "hiddenoff", 9) == 0) { + } else if (strncmp(p, S_LEN("hiddenoff")) == 0) { p += 9; diff_flags_new |= DIFF_HIDDEN_OFF; - } else if (strncmp(p, "closeoff", 8) == 0) { + } else if (strncmp(p, S_LEN("closeoff")) == 0) { p += 8; diff_flags_new |= DIFF_CLOSE_OFF; - } else if (strncmp(p, "followwrap", 10) == 0) { + } else if (strncmp(p, S_LEN("followwrap")) == 0) { p += 10; diff_flags_new |= DIFF_FOLLOWWRAP; - } else if (strncmp(p, "indent-heuristic", 16) == 0) { + } else if (strncmp(p, S_LEN("indent-heuristic")) == 0) { p += 16; diff_indent_heuristic = XDF_INDENT_HEURISTIC; - } else if (strncmp(p, "internal", 8) == 0) { + } else if (strncmp(p, S_LEN("internal")) == 0) { p += 8; diff_flags_new |= DIFF_INTERNAL; - } else if (strncmp(p, "algorithm:", 10) == 0) { + } else if (strncmp(p, S_LEN("algorithm:")) == 0) { // Note: Keep this in sync with p_dip_algorithm_values. p += 10; - if (strncmp(p, "myers", 5) == 0) { + if (strncmp(p, S_LEN("myers")) == 0) { p += 5; diff_algorithm_new = 0; - } else if (strncmp(p, "minimal", 7) == 0) { + } else if (strncmp(p, S_LEN("minimal")) == 0) { p += 7; diff_algorithm_new = XDF_NEED_MINIMAL; - } else if (strncmp(p, "patience", 8) == 0) { + } else if (strncmp(p, S_LEN("patience")) == 0) { p += 8; diff_algorithm_new = XDF_PATIENCE_DIFF; - } else if (strncmp(p, "histogram", 9) == 0) { + } else if (strncmp(p, S_LEN("histogram")) == 0) { p += 9; diff_algorithm_new = XDF_HISTOGRAM_DIFF; } else { return FAIL; } - } else if ((strncmp(p, "linematch:", 10) == 0) && ascii_isdigit(p[10])) { + } else if ((strncmp(p, S_LEN("linematch:")) == 0) && ascii_isdigit(p[10])) { p += 10; linematch_lines_new = getdigits_int(&p, false, linematch_lines_new); diff_flags_new |= DIFF_LINEMATCH; -- cgit From 43d8435cf84468e776e0a6a98d05ae7bd62583b7 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 13 Jun 2024 22:20:06 +0100 Subject: revert: "refactor: use S_LEN macro" (#29319) revert: "refactor: use S_LEN(s) instead of s, n (#29219)" This reverts commit c37695a5d5f2e8914fff86f3581bed70b4c85d3c. --- src/nvim/diff.c | 60 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 750f0c3525..0fe1729029 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1020,7 +1020,7 @@ static int check_external_diff(diffio_T *diffio) if (fd == NULL) { io_error = true; } else { - if (fwrite(S_LEN("line1\n"), 1, fd) != 1) { + if (fwrite("line1\n", 6, 1, fd) != 1) { io_error = true; } fclose(fd); @@ -1029,7 +1029,7 @@ static int check_external_diff(diffio_T *diffio) if (fd == NULL) { io_error = true; } else { - if (fwrite(S_LEN("line2\n"), 1, fd) != 1) { + if (fwrite("line2\n", 6, 1, fd) != 1) { io_error = true; } fclose(fd); @@ -1050,8 +1050,8 @@ static int check_external_diff(diffio_T *diffio) break; } - if (strncmp(linebuf, S_LEN("1c1")) == 0 - || strncmp(linebuf, S_LEN("@@ -1 +1 @@")) == 0) { + if (strncmp(linebuf, "1c1", 3) == 0 + || strncmp(linebuf, "@@ -1 +1 @@", 11) == 0) { ok = kTrue; } } @@ -1583,13 +1583,13 @@ static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle) // @@ -1,3 +1,5 @@ if (isdigit((uint8_t)(*line))) { *diffstyle = DIFF_ED; - } else if ((strncmp(line, S_LEN("@@ ")) == 0)) { + } else if ((strncmp(line, "@@ ", 3) == 0)) { *diffstyle = DIFF_UNIFIED; - } else if ((strncmp(line, S_LEN("--- ")) == 0) + } else if ((strncmp(line, "--- ", 4) == 0) && (vim_fgets(line, LBUFLEN, fd) == 0) - && (strncmp(line, S_LEN("+++ ")) == 0) + && (strncmp(line, "+++ ", 4) == 0) && (vim_fgets(line, LBUFLEN, fd) == 0) - && (strncmp(line, S_LEN("@@ ")) == 0)) { + && (strncmp(line, "@@ ", 3) == 0)) { *diffstyle = DIFF_UNIFIED; } else { // Format not recognized yet, skip over this line. Cygwin diff @@ -1607,7 +1607,7 @@ static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle) } } else { assert(*diffstyle == DIFF_UNIFIED); - if (strncmp(line, S_LEN("@@ ")) != 0) { + if (strncmp(line, "@@ ", 3) != 0) { continue; // not the start of a diff block } if (parse_diff_unified(line, hunk) == FAIL) { @@ -2473,70 +2473,70 @@ int diffopt_changed(void) char *p = p_dip; while (*p != NUL) { // Note: Keep this in sync with p_dip_values - if (strncmp(p, S_LEN("filler")) == 0) { + if (strncmp(p, "filler", 6) == 0) { p += 6; diff_flags_new |= DIFF_FILLER; - } else if ((strncmp(p, S_LEN("context:")) == 0) && ascii_isdigit(p[8])) { + } else if ((strncmp(p, "context:", 8) == 0) && ascii_isdigit(p[8])) { p += 8; diff_context_new = getdigits_int(&p, false, diff_context_new); - } else if (strncmp(p, S_LEN("iblank")) == 0) { + } else if (strncmp(p, "iblank", 6) == 0) { p += 6; diff_flags_new |= DIFF_IBLANK; - } else if (strncmp(p, S_LEN("icase")) == 0) { + } else if (strncmp(p, "icase", 5) == 0) { p += 5; diff_flags_new |= DIFF_ICASE; - } else if (strncmp(p, S_LEN("iwhiteall")) == 0) { + } else if (strncmp(p, "iwhiteall", 9) == 0) { p += 9; diff_flags_new |= DIFF_IWHITEALL; - } else if (strncmp(p, S_LEN("iwhiteeol")) == 0) { + } else if (strncmp(p, "iwhiteeol", 9) == 0) { p += 9; diff_flags_new |= DIFF_IWHITEEOL; - } else if (strncmp(p, S_LEN("iwhite")) == 0) { + } else if (strncmp(p, "iwhite", 6) == 0) { p += 6; diff_flags_new |= DIFF_IWHITE; - } else if (strncmp(p, S_LEN("horizontal")) == 0) { + } else if (strncmp(p, "horizontal", 10) == 0) { p += 10; diff_flags_new |= DIFF_HORIZONTAL; - } else if (strncmp(p, S_LEN("vertical")) == 0) { + } else if (strncmp(p, "vertical", 8) == 0) { p += 8; diff_flags_new |= DIFF_VERTICAL; - } else if ((strncmp(p, S_LEN("foldcolumn:")) == 0) && ascii_isdigit(p[11])) { + } else if ((strncmp(p, "foldcolumn:", 11) == 0) && ascii_isdigit(p[11])) { p += 11; diff_foldcolumn_new = getdigits_int(&p, false, diff_foldcolumn_new); - } else if (strncmp(p, S_LEN("hiddenoff")) == 0) { + } else if (strncmp(p, "hiddenoff", 9) == 0) { p += 9; diff_flags_new |= DIFF_HIDDEN_OFF; - } else if (strncmp(p, S_LEN("closeoff")) == 0) { + } else if (strncmp(p, "closeoff", 8) == 0) { p += 8; diff_flags_new |= DIFF_CLOSE_OFF; - } else if (strncmp(p, S_LEN("followwrap")) == 0) { + } else if (strncmp(p, "followwrap", 10) == 0) { p += 10; diff_flags_new |= DIFF_FOLLOWWRAP; - } else if (strncmp(p, S_LEN("indent-heuristic")) == 0) { + } else if (strncmp(p, "indent-heuristic", 16) == 0) { p += 16; diff_indent_heuristic = XDF_INDENT_HEURISTIC; - } else if (strncmp(p, S_LEN("internal")) == 0) { + } else if (strncmp(p, "internal", 8) == 0) { p += 8; diff_flags_new |= DIFF_INTERNAL; - } else if (strncmp(p, S_LEN("algorithm:")) == 0) { + } else if (strncmp(p, "algorithm:", 10) == 0) { // Note: Keep this in sync with p_dip_algorithm_values. p += 10; - if (strncmp(p, S_LEN("myers")) == 0) { + if (strncmp(p, "myers", 5) == 0) { p += 5; diff_algorithm_new = 0; - } else if (strncmp(p, S_LEN("minimal")) == 0) { + } else if (strncmp(p, "minimal", 7) == 0) { p += 7; diff_algorithm_new = XDF_NEED_MINIMAL; - } else if (strncmp(p, S_LEN("patience")) == 0) { + } else if (strncmp(p, "patience", 8) == 0) { p += 8; diff_algorithm_new = XDF_PATIENCE_DIFF; - } else if (strncmp(p, S_LEN("histogram")) == 0) { + } else if (strncmp(p, "histogram", 9) == 0) { p += 9; diff_algorithm_new = XDF_HISTOGRAM_DIFF; } else { return FAIL; } - } else if ((strncmp(p, S_LEN("linematch:")) == 0) && ascii_isdigit(p[10])) { + } else if ((strncmp(p, "linematch:", 10) == 0) && ascii_isdigit(p[10])) { p += 10; linematch_lines_new = getdigits_int(&p, false, linematch_lines_new); diff_flags_new |= DIFF_LINEMATCH; -- cgit From 04c158fbec9aeeccd7bd1bb16fc8a688edadd353 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Mon, 15 Jul 2024 00:54:45 +0200 Subject: docs: misc (#29622) Co-authored-by: Christian Clason Co-authored-by: zeertzjq --- src/nvim/diff.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 0fe1729029..45bcb94a1f 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -213,9 +213,7 @@ void diff_buf_add(buf_T *buf) semsg(_("E96: Cannot diff more than %" PRId64 " buffers"), (int64_t)DB_COUNT); } -/// /// Remove all buffers to make diffs for. -/// static void diff_buf_clear(void) { for (int i = 0; i < DB_COUNT; i++) { @@ -367,7 +365,6 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T break; } - // // Check for these situations: // 1 2 3 // 1 2 3 @@ -835,7 +832,6 @@ static int diff_write(buf_T *buf, diffin_T *din) return r; } -/// /// Update the diffs for all buffers involved. /// /// @param dio @@ -909,20 +905,16 @@ theend: xfree(dio->dio_diff.dout_fname); } -/// /// Return true if the options are set to use the internal diff library. /// Note that if the internal diff failed for one of the buffers, the external /// diff will be used anyway. -/// int diff_internal(void) FUNC_ATTR_PURE { return (diff_flags & DIFF_INTERNAL) != 0 && *p_dex == NUL; } -/// /// Return true if the internal diff failed for one of the diff buffers. -/// static int diff_internal_failed(void) { // Only need to do something when there is another buffer. @@ -1003,11 +995,9 @@ theend: } } -/// /// Do a quick test if "diff" really works. Otherwise it looks like there /// are no differences. Can't use the return value, it's non-zero when /// there are differences. -/// static int check_external_diff(diffio_T *diffio) { // May try twice, first with "-a" and then without. @@ -1091,9 +1081,7 @@ static int check_external_diff(diffio_T *diffio) return OK; } -/// /// Invoke the xdiff function. -/// static int diff_file_internal(diffio_T *diffio) { xpparam_t param; @@ -1813,9 +1801,7 @@ void diff_clear(tabpage_T *tp) tp->tp_first_diff = NULL; } -/// -/// return true if the options are set to use diff linematch -/// +/// Return true if the options are set to use diff linematch. bool diff_linematch(diff_T *dp) { if (!(diff_flags & DIFF_LINEMATCH)) { -- cgit From d1bd3d643e5846eee7343ba1a12bdcbbc8cee7b0 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 19 Jul 2024 11:00:13 +0100 Subject: refactor: collapse statements in single assignments Problem: Variables are often assigned multiple places in common patterns. Solution: Replace these common patterns with different patterns that reduce the number of assignments. Use `MAX` and `MIN`: ```c if (x < y) { x = y; } // --> x = MAX(x, y); ``` ```c if (x > y) { x = y; } // --> x = MIN(x, y); ``` Use ternary: ```c int a; if (cond) { a = b; } els { a = c; } // --> int a = cond ? b : c; ``` --- src/nvim/diff.c | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 45bcb94a1f..0b9bdb6181 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -694,7 +694,7 @@ void diff_redraw(bool dofold) if (((wp != curwin) && (wp->w_topfill > 0)) || (n > 0)) { if (wp->w_topfill > n) { - wp->w_topfill = (n < 0 ? 0 : n); + wp->w_topfill = MAX(n, 0); } else if ((n > 0) && (n > wp->w_topfill)) { wp->w_topfill = n; if (wp == curwin) { @@ -2679,9 +2679,7 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) si_org -= utf_head_off(line_org, line_org + si_org); si_new -= utf_head_off(line_new, line_new + si_new); - if (*startp > si_org) { - *startp = si_org; - } + *startp = MIN(*startp, si_org); // Search for end of difference, if any. if ((line_org[si_org] != NUL) || (line_new[si_new] != NUL)) { @@ -2721,9 +2719,7 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) } } - if (*endp < ei_org) { - *endp = ei_org; - } + *endp = MAX(*endp, ei_org); } } } @@ -3051,19 +3047,11 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr // range ends above end of current/from diff block if (idx_cur == idx_from) { // :diffput - int i = dp->df_count[idx_cur] - start_skip - end_skip; - - if (count > i) { - count = i; - } + count = MIN(count, dp->df_count[idx_cur] - start_skip - end_skip); } else { // :diffget count -= end_skip; - end_skip = dp->df_count[idx_from] - start_skip - count; - - if (end_skip < 0) { - end_skip = 0; - } + end_skip = MAX(dp->df_count[idx_from] - start_skip - count, 0); } } else { end_skip = 0; @@ -3249,9 +3237,7 @@ int diff_move_to(int dir, int count) } // don't end up past the end of the file - if (lnum > curbuf->b_ml.ml_line_count) { - lnum = curbuf->b_ml.ml_line_count; - } + lnum = MIN(lnum, curbuf->b_ml.ml_line_count); // When the cursor didn't move at all we fail. if (lnum == curwin->w_cursor.lnum) { @@ -3297,10 +3283,7 @@ static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1) if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1) { // Inside the diffblock baseline = lnum1 - dp->df_lnum[idx1]; - - if (baseline > dp->df_count[idx2]) { - baseline = dp->df_count[idx2]; - } + baseline = MIN(baseline, dp->df_count[idx2]); return dp->df_lnum[idx2] + baseline; } @@ -3335,10 +3318,7 @@ 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 (lnum > curbuf->b_ml.ml_line_count) { - return curbuf->b_ml.ml_line_count; - } - return lnum; + return MIN(lnum, curbuf->b_ml.ml_line_count); } /// For line "lnum" in the current window find the equivalent lnum in window @@ -3381,10 +3361,7 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp) } linenr_T n = lnum + (dp->df_lnum[i] - dp->df_lnum[idx]); - if (n > dp->df_lnum[i] + dp->df_count[i]) { - n = dp->df_lnum[i] + dp->df_count[i]; - } - return n; + return MIN(n, dp->df_lnum[i] + dp->df_count[i]); } /// Handle an ED style diff line. -- cgit From 573a71469d37cc35f72bfc929f4ce1156833df9f Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 17 Jul 2024 12:23:15 +0100 Subject: fix(scrollbind): properly take filler/virtual lines into account Problem: `'scrollbind'` does not work properly if the window being scrolled automatically contains any filler/virtual lines (except for diff filler lines). This is because when the scrollbind check is done, the logic only considers changes to topline which are represented as line numbers. Solution: Write the logic for determine the scroll amount to take into account filler/virtual lines. Fixes #29751 --- src/nvim/diff.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 0b9bdb6181..6d5c301e81 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -2143,7 +2143,11 @@ int diff_check_with_linestatus(win_T *wp, linenr_T lnum, int *linestatus) return 0; } - if (!dp->is_linematched && diff_linematch(dp)) { + // Don't run linematch when lnum is offscreen. + // Useful for scrollbind calculations which need to count all the filler lines + // above the screen. + if (lnum >= wp->w_topline && lnum < wp->w_botline + && !dp->is_linematched && diff_linematch(dp)) { run_linematch_algorithm(dp); } -- cgit From fd65422b99c7cc69e5053a852244cfc9d46d7b65 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 31 Jul 2024 16:43:21 +0100 Subject: feat(diff): do not try external when out of memory - Also merge diff_buf_idx_tp into diff_buf_idx. --- src/nvim/diff.c | 115 ++++++++++++++++++-------------------------------------- 1 file changed, 36 insertions(+), 79 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 6d5c301e81..7096c5fa8a 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -140,7 +140,7 @@ typedef enum { void diff_buf_delete(buf_T *buf) { FOR_ALL_TABS(tp) { - int i = diff_buf_idx_tp(buf, tp); + int i = diff_buf_idx(buf, tp); if (i != DB_COUNT) { tp->tp_diffbuf[i] = NULL; @@ -173,7 +173,7 @@ void diff_buf_adjust(win_T *win) } if (!found_win) { - int i = diff_buf_idx(win->w_buffer); + int i = diff_buf_idx(win->w_buffer, curtab); if (i != DB_COUNT) { curtab->tp_diffbuf[i] = NULL; curtab->tp_diff_invalid = true; @@ -196,7 +196,7 @@ void diff_buf_adjust(win_T *win) /// @param buf The buffer to add. void diff_buf_add(buf_T *buf) { - if (diff_buf_idx(buf) != DB_COUNT) { + if (diff_buf_idx(buf, curtab) != DB_COUNT) { // It's already there. return; } @@ -225,23 +225,13 @@ static void diff_buf_clear(void) } } -/// Find buffer "buf" in the list of diff buffers for the current tab page. -/// -/// @param buf The buffer to find. -/// -/// @return Its index or DB_COUNT if not found. -static int diff_buf_idx(buf_T *buf) -{ - return diff_buf_idx_tp(buf, curtab); -} - /// Find buffer "buf" in the list of diff buffers for tab page "tp". /// /// @param buf /// @param tp /// /// @return its index or DB_COUNT if not found. -static int diff_buf_idx_tp(buf_T *buf, tabpage_T *tp) +static int diff_buf_idx(buf_T *buf, tabpage_T *tp) { int idx; for (idx = 0; idx < DB_COUNT; idx++) { @@ -259,7 +249,7 @@ static int diff_buf_idx_tp(buf_T *buf, tabpage_T *tp) void diff_invalidate(buf_T *buf) { FOR_ALL_TABS(tp) { - int i = diff_buf_idx_tp(buf, tp); + int i = diff_buf_idx(buf, tp); if (i != DB_COUNT) { tp->tp_diff_invalid = true; if (tp == curtab) { @@ -280,7 +270,7 @@ void diff_mark_adjust(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amoun { // Handle all tab pages that use "buf" in a diff. FOR_ALL_TABS(tp) { - int idx = diff_buf_idx_tp(buf, tp); + int idx = diff_buf_idx(buf, tp); if (idx != DB_COUNT) { diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after); } @@ -756,20 +746,7 @@ static int diff_write_buffer(buf_T *buf, mmfile_t *m, linenr_T start, linenr_T e for (linenr_T lnum = start; lnum <= end; lnum++) { len += (size_t)ml_get_buf_len(buf, lnum) + 1; } - char *ptr = try_malloc(len); - if (ptr == NULL) { - // Allocating memory failed. This can happen, because we try to read - // the whole buffer text into memory. Set the failed flag, the diff - // will be retried with external diff. The flag is never reset. - buf->b_diff_failed = true; - if (p_verbose > 0) { - verbose_enter(); - smsg(0, _("Not enough memory to use internal diff for buffer \"%s\""), - buf->b_fname); - verbose_leave(); - } - return FAIL; - } + char *ptr = xmalloc(len); m->ptr = ptr; m->size = (int)len; @@ -851,34 +828,33 @@ static void diff_try_update(diffio_T *dio, int idx_orig, exarg_T *eap) || dio->dio_diff.dout_fname == NULL) { goto theend; } + // Check external diff is actually working. + if (check_external_diff(dio) == FAIL) { + goto theend; + } } - // Check external diff is actually working. - if (!dio->dio_internal && check_external_diff(dio) == FAIL) { - goto theend; - } - - buf_T *buf; - // :diffupdate! if (eap != NULL && eap->forceit) { for (int idx_new = idx_orig; idx_new < DB_COUNT; idx_new++) { - buf = curtab->tp_diffbuf[idx_new]; + buf_T *buf = curtab->tp_diffbuf[idx_new]; if (buf_valid(buf)) { buf_check_timestamp(buf); } } } - // Write the first buffer to a tempfile or mmfile_t. - buf = curtab->tp_diffbuf[idx_orig]; - if (diff_write(buf, &dio->dio_orig) == FAIL) { - goto theend; + { + // Write the first buffer to a tempfile or mmfile_t. + buf_T *buf = curtab->tp_diffbuf[idx_orig]; + if (diff_write(buf, &dio->dio_orig) == FAIL) { + goto theend; + } } // Make a difference between the first buffer and every other. for (int idx_new = idx_orig + 1; idx_new < DB_COUNT; idx_new++) { - buf = curtab->tp_diffbuf[idx_new]; + buf_T *buf = curtab->tp_diffbuf[idx_new]; if (buf == NULL || buf->b_ml.ml_mfp == NULL) { continue; // skip buffer that isn't loaded } @@ -914,19 +890,6 @@ int diff_internal(void) return (diff_flags & DIFF_INTERNAL) != 0 && *p_dex == NUL; } -/// Return true if the internal diff failed for one of the diff buffers. -static int diff_internal_failed(void) -{ - // Only need to do something when there is another buffer. - for (int idx = 0; idx < DB_COUNT; idx++) { - if (curtab->tp_diffbuf[idx] != NULL - && curtab->tp_diffbuf[idx]->b_diff_failed) { - return true; - } - } - return false; -} - /// Completely update the diffs for the buffers involved. /// /// When using the external "diff" command the buffers are written to a file, @@ -974,14 +937,9 @@ void ex_diffupdate(exarg_T *eap) // Only use the internal method if it did not fail for one of the buffers. diffio_T diffio; CLEAR_FIELD(diffio); - diffio.dio_internal = diff_internal() && !diff_internal_failed(); + diffio.dio_internal = diff_internal(); diff_try_update(&diffio, idx_orig, eap); - if (diffio.dio_internal && diff_internal_failed()) { - // Internal diff failed, use external diff instead. - CLEAR_FIELD(diffio); - diff_try_update(&diffio, idx_orig, eap); - } // force updating cursor position on screen curwin->w_valid_cursor.lnum = 0; @@ -1023,10 +981,9 @@ static int check_external_diff(diffio_T *diffio) io_error = true; } fclose(fd); - fd = NULL; - if (diff_file(diffio) == OK) { - fd = os_fopen(diffio->dio_diff.dout_fname, "r"); - } + fd = diff_file(diffio) == OK + ? os_fopen(diffio->dio_diff.dout_fname, "r") + : NULL; if (fd == NULL) { io_error = true; @@ -2119,7 +2076,7 @@ int diff_check_with_linestatus(win_T *wp, linenr_T lnum, int *linestatus) return 0; } - int idx = diff_buf_idx(buf); // index in tp_diffbuf[] for this buffer + int idx = diff_buf_idx(buf, curtab); // index in tp_diffbuf[] for this buffer if (idx == DB_COUNT) { // no diffs for buffer "buf" @@ -2340,7 +2297,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin) buf_T *frombuf = fromwin->w_buffer; linenr_T lnum = fromwin->w_topline; - int fromidx = diff_buf_idx(frombuf); + int fromidx = diff_buf_idx(frombuf, curtab); if (fromidx == DB_COUNT) { // safety check return; @@ -2367,7 +2324,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin) - (frombuf->b_ml.ml_line_count - lnum); } else { // Find index for "towin". - int toidx = diff_buf_idx(towin->w_buffer); + int toidx = diff_buf_idx(towin->w_buffer, curtab); if (toidx == DB_COUNT) { // safety check @@ -2612,7 +2569,7 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) // Make a copy of the line, the next ml_get() will invalidate it. char *line_org = xstrdup(ml_get_buf(wp->w_buffer, lnum)); - int idx = diff_buf_idx(wp->w_buffer); + int idx = diff_buf_idx(wp->w_buffer, curtab); if (idx == DB_COUNT) { // cannot happen xfree(line_org); @@ -2834,7 +2791,7 @@ void ex_diffgetput(exarg_T *eap) int idx_other; // Find the current buffer in the list of diff buffers. - int idx_cur = diff_buf_idx(curbuf); + int idx_cur = diff_buf_idx(curbuf, curtab); if (idx_cur == DB_COUNT) { emsg(_("E99: Current buffer is not in diff mode")); return; @@ -2906,7 +2863,7 @@ void ex_diffgetput(exarg_T *eap) // nothing to do return; } - idx_other = diff_buf_idx(buf); + idx_other = diff_buf_idx(buf, curtab); if (idx_other == DB_COUNT) { semsg(_("E103: Buffer \"%s\" is not in diff mode"), eap->arg); @@ -2948,7 +2905,7 @@ void ex_diffgetput(exarg_T *eap) // everything up. if (!curbuf->b_changed) { change_warning(curbuf, 0); - if (diff_buf_idx(curbuf) != idx_to) { + if (diff_buf_idx(curbuf, curtab) != idx_to) { emsg(_("E787: Buffer changed unexpectedly")); goto theend; } @@ -3187,7 +3144,7 @@ bool diff_mode_buf(buf_T *buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) { FOR_ALL_TABS(tp) { - if (diff_buf_idx_tp(buf, tp) != DB_COUNT) { + if (diff_buf_idx(buf, tp) != DB_COUNT) { return true; } } @@ -3203,7 +3160,7 @@ bool diff_mode_buf(buf_T *buf) int diff_move_to(int dir, int count) { linenr_T lnum = curwin->w_cursor.lnum; - int idx = diff_buf_idx(curbuf); + int idx = diff_buf_idx(curbuf, curtab); if ((idx == DB_COUNT) || (curtab->tp_first_diff == NULL)) { return FAIL; } @@ -3261,8 +3218,8 @@ static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1) { linenr_T baseline = 0; - int idx1 = diff_buf_idx(buf1); - int idx2 = diff_buf_idx(curbuf); + int idx1 = diff_buf_idx(buf1, curtab); + int idx2 = diff_buf_idx(curbuf, curtab); if ((idx1 == DB_COUNT) || (idx2 == DB_COUNT) @@ -3331,7 +3288,7 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp) { diff_T *dp; - int idx = diff_buf_idx(curbuf); + int idx = diff_buf_idx(curbuf, curtab); if (idx == DB_COUNT) { // safety check @@ -3357,7 +3314,7 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp) } // Find index for "wp". - int i = diff_buf_idx(wp->w_buffer); + int i = diff_buf_idx(wp->w_buffer, curtab); if (i == DB_COUNT) { // safety check -- cgit From bfe0acaea167a5ce18d4c63f65ccd45966203413 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 23 Sep 2024 12:04:07 +0800 Subject: vim-patch:9.1.0740: incorrect internal diff with empty file (#30471) Problem: incorrect internal diff with an empty file Solution: Set pointer to NULL, instead of using an empty line file (Yukihiro Nakadaira) When using internal diff, empty file is read as one empty line file. So result differs from external diff. closes: vim/vim#15719 https://github.com/vim/vim/commit/f1694b439bb175d956b49da620f1253462ec507b Co-authored-by: Yukihiro Nakadaira --- src/nvim/diff.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 7096c5fa8a..0c59b8eb67 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -736,6 +736,12 @@ static void clear_diffout(diffout_T *dout) /// @return FAIL for failure. static int diff_write_buffer(buf_T *buf, mmfile_t *m, linenr_T start, linenr_T end) { + if (buf->b_ml.ml_flags & ML_EMPTY) { + m->ptr = NULL; + m->size = 0; + return OK; + } + size_t len = 0; if (end < 0) { -- cgit From 6f2fe8a791646d6d662e89d7eccf6c515ccc9c8c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 27 Sep 2024 15:14:39 +0800 Subject: vim-patch:9.1.0743: diff mode does not handle overlapping diffs correctly (#30532) Problem: diff mode does not handle overlapping diffs correctly Solution: correct the logic to handle overlapping blocks (Yukihiro Nakadaira) Vim merges overlapped diff blocks and it doesn't work expectedly in some situation. closes: vim/vim#15735 https://github.com/vim/vim/commit/06fe70c183a53ea97cd42ace490d4fb9fd14f042 Co-authored-by: Yukihiro Nakadaira --- src/nvim/diff.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 0c59b8eb67..05e5bed50c 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1609,6 +1609,7 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne for (int i = idx_orig; i < idx_new; i++) { if (curtab->tp_diffbuf[i] != NULL) { dp->df_lnum[i] -= off; + dp->df_count[i] += off; } } dp->df_lnum[idx_new] = hunk->lnum_new; @@ -1619,11 +1620,7 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne dp->df_count[idx_new] = (linenr_T)hunk->count_new - off; } else { // second overlap of new block with existing block - dp->df_count[idx_new] += (linenr_T)hunk->count_new - (linenr_T)hunk->count_orig - + dpl->df_lnum[idx_orig] + - dpl->df_count[idx_orig] - - (dp->df_lnum[idx_orig] + - dp->df_count[idx_orig]); + dp->df_count[idx_new] += (linenr_T)hunk->count_new; } // Adjust the size of the block to include all the lines to the @@ -1632,11 +1629,8 @@ static void process_hunk(diff_T **dpp, diff_T **dprevp, int idx_orig, int idx_ne - (dpl->df_lnum[idx_orig] + dpl->df_count[idx_orig]); if (off < 0) { - // new change ends in existing block, adjust the end if not - // done already - if (*notsetp) { - dp->df_count[idx_new] += -off; - } + // new change ends in existing block, adjust the end + dp->df_count[idx_new] += -off; off = 0; } -- cgit From c65646c2474d22948c604168a68f6626a645d1d2 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 26 Sep 2024 16:10:11 +0100 Subject: fix(diff): use mmfile_t in linematch Problem: Linematch used to use strchr to navigate a string, however strchr does not supoprt embedded NULs. Solution: Use `mmfile_t` instead of `char *` in linematch and introduce `strnchr()`. Also remove heap allocations from `matching_char_iwhite()` Fixes: #30505 --- src/nvim/diff.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/nvim/diff.c') diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 05e5bed50c..d22fb65827 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -2005,7 +2005,7 @@ static void run_linematch_algorithm(diff_T *dp) { // define buffers for diff algorithm mmfile_t diffbufs_mm[DB_COUNT]; - const char *diffbufs[DB_COUNT]; + const mmfile_t *diffbufs[DB_COUNT]; int diff_length[DB_COUNT]; size_t ndiffs = 0; for (int i = 0; i < DB_COUNT; i++) { @@ -2015,9 +2015,7 @@ static void run_linematch_algorithm(diff_T *dp) diff_write_buffer(curtab->tp_diffbuf[i], &diffbufs_mm[ndiffs], dp->df_lnum[i], dp->df_lnum[i] + dp->df_count[i] - 1); - // we want to get the char* to the diff buffer that was just written - // we add it to the array of char*, diffbufs - diffbufs[ndiffs] = diffbufs_mm[ndiffs].ptr; + diffbufs[ndiffs] = &diffbufs_mm[ndiffs]; // keep track of the length of this diff block to pass it to the linematch // algorithm -- cgit