From: Yee Cheng Chin Date: Thu, 7 Aug 2025 13:33:34 +0000 (+0200) Subject: patch 9.1.1600: using diff anchors with hidden buffers fails silently X-Git-Tag: v9.1.1600^0 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=cad3b2421de7b703e0ee619850a8a3bc55454281;p=thirdparty%2Fvim.git patch 9.1.1600: using diff anchors with hidden buffers fails silently Problem: diff: using diff anchors with hidden buffers fails silently Solution: Give specific error message for diff anchors when using hidden buffers (Yee Cheng Chin). Diff anchors currently will fail to parse if a buffer used for diff'ing is hidden. Previously it would just fail as the code assumes it would not happen normally, but this is actually possible to do if `closeoff` and `hideoff` are not set in diffopt. Git's default diff tool "vimdiff3" also takes advantage of this. This fix this properly would require the `{address}` parser to be smarter about whether a particular address relies on window position or not (e.g. the `'.` address requires an active window, but `'a` or `1234` do not). Since hidden diff buffers seem relatively niche, just provide a better error message / documentation for now. This could be improved later if there's a demand for it. related: #17615 closes: #17904 Signed-off-by: Yee Cheng Chin Signed-off-by: Christian Brabandt --- diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 7a12ee12b6..b22a1711dc 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 9.1. Last change: 2025 Aug 06 +*options.txt* For Vim version 9.1. Last change: 2025 Aug 07 VIM REFERENCE MANUAL by Bram Moolenaar @@ -3016,6 +3016,8 @@ A jump table for the options with a short description can be found at |Q_op|. If some of the {address} do not resolve to a line in each buffer (e.g. a pattern search that does not match anything), none of the anchors will be used. + *E1562* + Diff anchors can only be used when there are no hidden diff buffers. *'dex'* *'diffexpr'* 'diffexpr' 'dex' string (default "") diff --git a/runtime/doc/tags b/runtime/doc/tags index 116682504b..d94bc5ba94 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -4694,6 +4694,7 @@ E1559 vim9.txt /*E1559* E156 sign.txt /*E156* E1560 vim9.txt /*E1560* E1561 vim9.txt /*E1561* +E1562 options.txt /*E1562* E157 sign.txt /*E157* E158 sign.txt /*E158* E159 sign.txt /*E159* diff --git a/src/diff.c b/src/diff.c index d86dbf1530..b8d9de539d 100644 --- a/src/diff.c +++ b/src/diff.c @@ -2768,8 +2768,15 @@ parse_diffanchors(int check_only, buf_T *buf, linenr_T *anchors, int *num_anchor FOR_ALL_WINDOWS(bufwin) if (bufwin->w_buffer == buf && bufwin->w_p_diff) break; - if (bufwin == NULL) - return FAIL; // should not really happen + if (bufwin == NULL && *dia != NUL) + { + // The buffer is hidden. Currently this is not supported due to the + // edge cases of needing to decide if an address is window-specific + // or not. We could add more checks in the future so we can detect + // whether an address relies on curwin to make this more fleixble. + emsg(_(e_diff_anchors_with_hidden_windows)); + return FAIL; + } } for (i = 0; i < MAX_DIFF_ANCHORS && *dia != NUL; i++) diff --git a/src/errors.h b/src/errors.h index 8bb5214929..050fb42199 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3778,3 +3778,7 @@ EXTERN char e_not_a_generic_function_str[] EXTERN char e_duplicate_type_var_name_str[] INIT(= N_("E1561: Duplicate type variable name: %s")); #endif +#if defined(FEAT_DIFF) +EXTERN char e_diff_anchors_with_hidden_windows[] + INIT(= N_("E1562: Diff anchors cannot be used with hidden diff windows")); +#endif diff --git a/src/po/vim.pot b/src/po/vim.pot index cdb2e2ea2e..5b9ba3cd89 100644 --- a/src/po/vim.pot +++ b/src/po/vim.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-07-25 19:14+0200\n" +"POT-Creation-Date: 2025-08-07 15:32+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -8803,6 +8803,9 @@ msgstr "" msgid "E1561: Duplicate type variable name: %s" msgstr "" +msgid "E1562: Diff anchors cannot be used with hidden diff windows" +msgstr "" + #. type of cmdline window or 0 #. result of cmdline window or 0 #. buffer of cmdline window or NULL diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim index eee23729a1..5ea7a7c8a0 100644 --- a/src/testdir/test_diffmode.vim +++ b/src/testdir/test_diffmode.vim @@ -3483,6 +3483,10 @@ func Test_diffanchors_invalid() call assert_fails('diffupdate', 'E1550:') call assert_equal('orig_search_pat', @/) + " Hidden buffers are not supported right now + hide + call assert_fails('diffupdate', 'E1562:') + %bw! set diffopt& set diffanchors& diff --git a/src/version.c b/src/version.c index d1923b1dbe..3f3f1e1b63 100644 --- a/src/version.c +++ b/src/version.c @@ -719,6 +719,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1600, /**/ 1599, /**/