]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0705: :delete # silently fails to update "# and clobbers "0 v9.2.0705
authorDoug Kearns <dougkearns@gmail.com>
Mon, 22 Jun 2026 19:36:59 +0000 (19:36 +0000)
committerChristian Brabandt <cb@256bit.org>
Mon, 22 Jun 2026 19:37:56 +0000 (19:37 +0000)
Problem:  ':delete #' silently fails to update "# and clobbers "0.
Solution: Treat "# like "/, writable only with :let and setreg().

closes: #20592

Signed-off-by: Doug Kearns <dougkearns@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/change.txt
runtime/doc/tags
src/errors.h
src/po/vim.pot
src/register.c
src/testdir/test_excmd.vim
src/testdir/test_registers.vim
src/version.c
src/vim9compile.c

index afcdca16b097a10be6b11cac8cf60607505d0e0a..639484e33919995da9d36cfc2e627d7a4e46e0f0 100644 (file)
@@ -1,4 +1,4 @@
-*change.txt*   For Vim version 9.2.  Last change: 2026 Jun 18
+*change.txt*   For Vim version 9.2.  Last change: 2026 Jun 22
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1332,10 +1332,11 @@ and ":put" commands and with CTRL-R.
                the command was executed completely from a mapping.
                {not available when compiled without the |+cmdline_hist|
                feature}
-                                                       *quote_#* *quote#*
-6. Alternate file register "#
+
+6. Alternate file register "#                  *quote_#* *quote#* *@#*
 Contains the |alternate-file| name for current window
-This register is writeable and changes which buffer CTRL-^ enters.
+This register is writable with `:let` and |setreg()|.  This changes which buffer
+CTRL-^ enters.  You can't yank or delete into this register.
 A String is matched against existing buffer names, like |:buffer|: >
     let @# = 'buffer_name'
 Also supports using buffer number and |file-pattern|.
@@ -1398,11 +1399,12 @@ When writing to this register, nothing happens.  This can be used to delete
 text without affecting the normal registers.  When reading from this register,
 nothing is returned.
 
-10. Last search pattern register       "/              *quote_/* *quote/*
+10. Last search pattern register "/                    *quote_/* *quote/*
 Contains the most recent search-pattern.  This is used for "n" and 'hlsearch'.
-It is writable with `:let`, you can change it to have 'hlsearch' highlight
-other matches without actually searching.  You can't yank or delete into this
-register.  The search direction is available in |v:searchforward|.
+This register is writable with `:let` and |setreg()|.  You can change it to have
+'hlsearch' highlight other matches without actually searching.  You can't yank
+or delete into this register.  The search direction is available in
+|v:searchforward|.
 Note that the value is restored when returning from a function
 |function-search-undo|.
 
index 405e1254d4ac478d87c2865f4e91bc329b437e27..11ae058bbcfc75724cfe5bdfab9433a9ce9bf54c 100644 (file)
@@ -4015,6 +4015,7 @@ $quote    eval.txt        /*$quote*
 ?<CR>  pattern.txt     /*?<CR>*
 ??     eval.txt        /*??*
 @      repeat.txt      /*@*
+@#     change.txt      /*@#*
 @/     change.txt      /*@\/*
 @:     repeat.txt      /*@:*
 @=     change.txt      /*@=*
index 530e47c1d95396a95df9f4abad50a18d1ef786ce..e1e7ada84dd6b1ae6f60ffc448e3cedb976493d5 100644 (file)
@@ -2287,8 +2287,8 @@ EXTERN char e_line_count_changed_unexpectedly[]
 #ifdef FEAT_EVAL
 EXTERN char e_uniq_compare_function_failed[]
        INIT(= N_("E882: Uniq compare function failed"));
-EXTERN char e_search_pattern_and_expression_register_may_not_contain_two_or_more_lines[]
-       INIT(= N_("E883: Search pattern and expression register may not contain two or more lines"));
+EXTERN char e_register_char_cannot_contain_multiple_lines[]
+       INIT(= N_("E883: Register '%c' cannot contain multiple lines"));
 EXTERN char e_function_name_cannot_contain_colon_str[]
        INIT(= N_("E884: Function name cannot contain a colon: %s"));
 #endif
index b185a514445e1dc4ffaa8b7aff287ea64869dad8..bbbf9f0cc20a80cf56d551ee73172affd41956bf 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim\n"
 "Report-Msgid-Bugs-To: vim-dev@vim.org\n"
-"POT-Creation-Date: 2026-06-16 19:21+0000\n"
+"POT-Creation-Date: 2026-06-22 19:36+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -6678,9 +6678,8 @@ msgstr ""
 msgid "E882: Uniq compare function failed"
 msgstr ""
 
-msgid ""
-"E883: Search pattern and expression register may not contain two or more "
-"lines"
+#, c-format
+msgid "E883: Register '%c' cannot contain multiple lines"
 msgstr ""
 
 #, c-format
index 95a1145e43e0fde0f31aeaf7b3d0f13bf02fca9a..5d22dc34a8f04f1fceb355f4213b83a5125508bb 100644 (file)
@@ -181,12 +181,11 @@ valid_yank_reg(
     if (       (regname > 0 && ASCII_ISALNUM(regname))
            || (!writing && vim_strchr((char_u *)
 #ifdef FEAT_EVAL
-                                   "/.%:="
+                                   "/#.%:="
 #else
-                                   "/.%:"
+                                   "/#.%:"
 #endif
                                        , regname) != NULL)
-           || regname == '#'
            || regname == '"'
            || regname == '-'
            || regname == '_'
@@ -3093,7 +3092,7 @@ write_reg_contents_lst(
 {
     yankreg_T  *old_y_previous, *old_y_current;
 
-    if (name == '/' || name == '=')
+    if (name == '/' || name == '=' || name == '#')
     {
        char_u  *s;
 
@@ -3101,7 +3100,7 @@ write_reg_contents_lst(
            s = (char_u *)"";
        else if (strings[1] != NULL)
        {
-           emsg(_(e_search_pattern_and_expression_register_may_not_contain_two_or_more_lines));
+           semsg(_(e_register_char_cannot_contain_multiple_lines), name);
            return;
        }
        else
index 0de0771f78d8f32b8906f36a0c8a4e34950eb4ed..eea75d7e5d532d3922c5ebe8461fbdf33112fcc4 100644 (file)
@@ -4,11 +4,24 @@ source util/screendump.vim
 
 func Test_ex_delete()
   new
+
   call setline(1, ['a', 'b', 'c'])
   2
   " :dl is :delete with the "l" flag, not :dlist
   .dl
   call assert_equal(['a', 'c'], getline(1, 2))
+  %delete _
+
+  " :delete # used to clobber "0
+  call setreg('#', '')
+  call setreg('0', '')
+  call setline(1, ['a', 'b', 'c'])
+  call assert_fails("1delete #", 'E488:')
+  call assert_equal(['a', 'b', 'c'], getline(1, '$'))
+  call assert_equal('', getreg('#'))
+  call assert_equal('', getreg('0'))
+
+  bw!
 endfunc
 
 func Test_range_error()
index e1c493ac4b10589fea85b22346fb5ebbec52522e..d59da86b33d457e05da713e4ef8c84d09b12b536 100644 (file)
@@ -423,6 +423,7 @@ func Test_set_register()
   call assert_equal('', @=)
   call assert_fails("call setreg('/', ['a', 'b'])", 'E883:')
   call assert_fails("call setreg('=', ['a', 'b'])", 'E883:')
+  call assert_fails("call setreg('#', ['a', 'b'])", 'E883:')
   call assert_equal(0, setreg('_', ['a', 'b']))
 
   " Test for recording to a invalid register
index 6662a529e771347158f447fc203dd3619c40d9c3..14fb4ea48955fd40ce4ac76c47cdea781243bcb2 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    705,
 /**/
     704,
 /**/
index aa9384bbe99eb64ba74e348f3433e163a28a165a..181df2a6fb9758ea57ed474662bab645a406c356 100644 (file)
@@ -1481,7 +1481,7 @@ valid_dest_reg(int name)
 {
     if (name == '@')
        name = '"';
-    if (name == '/' || name == '=' || valid_yank_reg(name, TRUE))
+    if (name == '/' || name == '=' || name == '#' || valid_yank_reg(name, TRUE))
        return TRUE;
     emsg_invreg(name);
     return FAIL;