diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt index 1690042fc9..1362864f8c 100644 --- a/runtime/doc/cmdline.txt +++ b/runtime/doc/cmdline.txt @@ -142,13 +142,16 @@ CTRL-R {register} *c_CTRL-R* *c_* typing CTRL-R and the second character '"' will be displayed to indicate that you are expected to enter the name of a register. - The text is inserted as if you typed it, but mappings and - abbreviations are not used. Command-line completion through - 'wildchar' is not triggered though. And characters that end - the command line are inserted literally (, , , - ). A or CTRL-W could still end the command line - though, and remaining characters will then be interpreted in - another mode, which might not be what you intended. + When used with named or clipboard registers (A-Z,a-z,0-9,+) + text is inserted literally like pasting with "p". For other + registers, the text is inserted as if you typed it, but + mappings and abbreviations are not used. Command-line + completion through 'wildchar' is not triggered though. And + characters that end the command line are inserted literally + (, , , ). A or CTRL-W could still end + the command line though, and remaining characters will then be + interpreted in another mode, which might not be what you + intended. Special registers: '"' the unnamed register, containing the text of the last delete or yank @@ -176,7 +179,9 @@ CTRL-R {register} *c_CTRL-R* *c_* sure the expression evaluates to an empty string. E.g.: > =setcmdpos(2)[-1] -< See |registers| about registers. +< You can use this to insert a register as + typed with CTRL-R =@reg. + See |registers| about registers. Implementation detail: When using the |expression| register and invoking setcmdpos(), this sets the position before inserting the resulting string. Use CTRL-R CTRL-R to set the diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index 3366d1e149..a6eb054418 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -101,14 +101,17 @@ CTRL-N Find next keyword (see |i_CTRL-N|). CTRL-P Find previous keyword (see |i_CTRL-P|). CTRL-R {register} *i_CTRL-R* - Insert the contents of a register. Between typing CTRL-R and + Insert the contents of a register. Between typing CTRL-R and the second character, '"' will be displayed to indicate that - you are expected to enter the name of a register. - The text is inserted as if you typed it, but mappings and - abbreviations are not used. If you have options like - 'textwidth', 'formatoptions', or 'autoindent' set, this will - influence what will be inserted. This is different from what - happens with the "p" command and pasting with the mouse. + you are expected to enter the name of a register. When used + with When used with named or clipboard registers + (A-Z,a-z,0-9,+) text is inserted literally like pasting with + "p". For other registers, the text is inserted as if you typed + it, but mappings and abbreviations are not used. If you have + options like 'textwidth', 'formatoptions', or 'autoindent' + set, this will influence what will be inserted. This is + different from what happens with the "p" command and pasting + with the mouse. Special registers: '"' the unnamed register, containing the text of the last delete or yank @@ -131,6 +134,8 @@ CTRL-R {register} *i_CTRL-R* special keys. E.g., you can use this to move the cursor up: CTRL-R ="\" + you can use this to insert a register as + typed with CTRL-R =@reg. Use CTRL-R CTRL-R to insert text literally. When the result is a |List| the items are used as lines. They can have line breaks inside diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index f32be1abfe..b374b620c1 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -68,7 +68,8 @@ DIAGNOSTICS EDITOR -• todo +• |i_CTRL-R| inserts named registers (A-Z,a-z,0-9) literally like pasting instead of + as typed. To get the old behavior you can use `=@x`. EVENTS diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index b001361c41..bd52cf1606 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -316,6 +316,8 @@ Commands: Editor: - |prompt-buffer| supports multiline input/paste, undo/redo, and o/O normal commands. +- |i_CTRL-R| inserts named registers (A-Z,a-z,0-9) literally like pasting instead of + as typed. To get the old behavior you can use `=@x`. Events (autocommands): - Fixed inconsistent behavior in execution of nested autocommands #23368 diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 6a30fedc83..a15a66ab7c 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2854,6 +2854,8 @@ static void ins_reg(void) vim_beep(kOptBoFlagRegister); need_redraw = true; // remove the '"' } else { + yankreg_T *reg = get_yank_register(regname, YREG_PASTE); + if (literally == Ctrl_O || literally == Ctrl_P) { // Append the command to the redo buffer. AppendCharToRedobuff(Ctrl_R); @@ -2862,7 +2864,11 @@ static void ins_reg(void) do_put(regname, NULL, BACKWARD, 1, (literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND); - } else if (insert_reg(regname, NULL, literally) == FAIL) { + } else if (reg->y_size > 1 && is_literal_register(regname)) { + AppendCharToRedobuff(Ctrl_R); + AppendCharToRedobuff(regname); + do_put(regname, NULL, BACKWARD, 1, PUT_CURSEND); + } else if (insert_reg(regname, NULL, !!literally) == FAIL) { vim_beep(kOptBoFlagRegister); need_redraw = true; // remove the '"' } else if (stop_insert_mode) { diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 905944d863..3532d8f335 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -152,7 +152,7 @@ static inline int op_reg_index(const int regname) static inline bool is_literal_register(const int regname) FUNC_ATTR_CONST { - return regname == '*' || regname == '+'; + return regname == '*' || regname == '+' || ASCII_ISALNUM(regname); } EXTERN LuaRef repeat_luaref INIT( = LUA_NOREF); ///< LuaRef for "." diff --git a/test/functional/editor/mode_insert_spec.lua b/test/functional/editor/mode_insert_spec.lua index a9fa93590f..39227472b5 100644 --- a/test/functional/editor/mode_insert_spec.lua +++ b/test/functional/editor/mode_insert_spec.lua @@ -83,6 +83,36 @@ describe('insert-mode', function() {5:-- INSERT --} | ]]) end) + + it('inserts named registers literally', function() + local screen = Screen.new(50, 6) + -- regular text without special charecter command + command('let @a = "test"') + feed('ia') + screen:expect([[ + tes^t | + {1:~ }|*4 + | + ]]) + + -- text with backspace character gets written literally by default + command('let @a = "test\\"') + feed('cca') + screen:expect([[ + test{18:^^H} | + {1:~ }|*4 + | + ]]) + + -- =@reg can be used to get effect of keypress + command('let @a = "test\\"') + feed('cc=@a') + screen:expect([[ + te^s | + {1:~ }|*4 + | + ]]) + end) end) describe('Ctrl-O', function() diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim index 27274d0c41..a2f05ae80d 100644 --- a/test/old/testdir/test_autocmd.vim +++ b/test/old/testdir/test_autocmd.vim @@ -2090,7 +2090,7 @@ func Test_Cmdline() let g:log = [] let @r = 'abc' - call feedkeys(":0\r1\\r2\\r3\", 'xt') + call feedkeys(":0\=@r\1\\r2\\r3\", 'xt') call assert_equal([ \ '0', \ '0a', diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim index 1065f7f307..bb37d010da 100644 --- a/test/old/testdir/test_cmdline.vim +++ b/test/old/testdir/test_cmdline.vim @@ -905,7 +905,7 @@ func Test_cmdline_paste() " Test for pasting register containing CTRL-H using CTRL-R and CTRL-R CTRL-R let @a = "xy\z" - call feedkeys(":\"\a\", 'xt') + call feedkeys(":\"\=@a\\", 'xt') call assert_equal('"xz', @:) call feedkeys(":\"\\a\", 'xt') call assert_equal("\"xy\z", @:) diff --git a/test/old/testdir/test_ins_complete.vim b/test/old/testdir/test_ins_complete.vim index c606810492..9c92a49445 100644 --- a/test/old/testdir/test_ins_complete.vim +++ b/test/old/testdir/test_ins_complete.vim @@ -1523,7 +1523,7 @@ func Test_complete_reginsert() exe "normal Goa\\=\"\\\"\" call assert_equal('a123', getline(5)) let @r = "\\" - exe "normal GCa\\r" + exe "normal GCa\\=@r\" call assert_equal('a12', getline(5)) exe "normal GCa\\=\"x\"\" call assert_equal('a1234x', getline(5))