changeset 27263:93d4ee1e6113 v8.2.4160

patch 8.2.4160: cannot change the register used for Select mode delete Commit: https://github.com/vim/vim/commit/4ede01f18884961f2e008880b4964e5d61ea5c36 Author: Shougo Matsushita <Shougo.Matsu@gmail.com> Date: Thu Jan 20 15:26:03 2022 +0000 patch 8.2.4160: cannot change the register used for Select mode delete Problem: Cannot change the register used for Select mode delete. Solution: Make CTRL-R set the register to be used when deleting text for Select mode. (Shougo Matsushita, closes #9531)
author Bram Moolenaar <Bram@vim.org>
date Thu, 20 Jan 2022 16:30:04 +0100
parents f2056837b78a
children b2eff72f957e
files runtime/doc/visual.txt src/globals.h src/normal.c src/ops.c src/testdir/test_selectmode.vim src/version.c
diffstat 6 files changed, 96 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/visual.txt
+++ b/runtime/doc/visual.txt
@@ -488,6 +488,11 @@ Commands in Select mode:
 - ESC stops Select mode.
 - CTRL-O switches to Visual mode for the duration of one command. *v_CTRL-O*
 - CTRL-G switches to Visual mode.
+- CTRL-R {register} selects the register to be used for the text that is
+  deleted when typing text.					  *v_CTRL-R*
+  Unless you specify the "_" (black hole) register, the unnamed register is
+  also overwritten.
+
 
 Otherwise, typed characters are handled as in Visual mode.
 
--- a/src/globals.h
+++ b/src/globals.h
@@ -875,6 +875,8 @@ EXTERN int	VIsual_active INIT(= FALSE);
 				// whether Visual mode is active
 EXTERN int	VIsual_select INIT(= FALSE);
 				// whether Select mode is active
+EXTERN int	VIsual_select_reg INIT(= 0);
+				// register name for Select mode
 EXTERN int	restart_VIsual_select INIT(= 0);
 				// restart Select mode when next cmd finished
 EXTERN int	VIsual_reselect;
--- a/src/normal.c
+++ b/src/normal.c
@@ -89,7 +89,7 @@ static void	nv_window(cmdarg_T *cap);
 static void	nv_suspend(cmdarg_T *cap);
 static void	nv_g_cmd(cmdarg_T *cap);
 static void	nv_dot(cmdarg_T *cap);
-static void	nv_redo(cmdarg_T *cap);
+static void	nv_redo_or_register(cmdarg_T *cap);
 static void	nv_Undo(cmdarg_T *cap);
 static void	nv_tilde(cmdarg_T *cap);
 static void	nv_operator(cmdarg_T *cap);
@@ -188,7 +188,7 @@ static const struct nv_cmd
     {Ctrl_O,	nv_ctrlo,	0,			0},
     {Ctrl_P,	nv_up,		NV_STS,			FALSE},
     {Ctrl_Q,	nv_visual,	0,			FALSE},
-    {Ctrl_R,	nv_redo,	0,			0},
+    {Ctrl_R,	nv_redo_or_register, 0,			0},
     {Ctrl_S,	nv_ignore,	0,			0},
     {Ctrl_T,	nv_tagpop,	NV_NCW,			0},
     {Ctrl_U,	nv_halfpage,	0,			0},
@@ -1303,6 +1303,7 @@ normal_end:
 	    trigger_modechanged();
 	    showmode();
 	    restart_VIsual_select = 0;
+	    VIsual_select_reg = 0;
 	}
 	if (restart_edit != 0 && !VIsual_active && old_mapped_len == 0)
 	    (void)edit(restart_edit, FALSE, 1L);
@@ -5997,7 +5998,10 @@ nv_g_cmd(cmdarg_T *cap)
 	     * start Select mode.
 	     */
 	    if (cap->arg)
+	    {
 		VIsual_select = TRUE;
+		VIsual_select_reg = 0;
+	    }
 	    else
 		may_start_select('c');
 	    setmouse();
@@ -6550,11 +6554,30 @@ nv_dot(cmdarg_T *cap)
 }
 
 /*
- * CTRL-R: undo undo
+ * CTRL-R: undo undo or specify register in select mode
  */
     static void
-nv_redo(cmdarg_T *cap)
-{
+nv_redo_or_register(cmdarg_T *cap)
+{
+    if (VIsual_select && VIsual_active)
+    {
+	int reg;
+	// Get register name
+	++no_mapping;
+	++allow_keys;
+	reg = plain_vgetc();
+	LANGMAP_ADJUST(reg, TRUE);
+	--no_mapping;
+	--allow_keys;
+
+	if (reg == '"')
+	    // the unnamed register is 0
+	    reg = 0;
+
+        VIsual_select_reg = valid_yank_reg(reg, TRUE) ? reg : 0;
+	return;
+    }
+
     if (!checkclearopq(cap->oap))
     {
 	u_redo((int)cap->count1);
@@ -6926,7 +6949,10 @@ unadjust_for_sel(void)
 nv_select(cmdarg_T *cap)
 {
     if (VIsual_active)
+    {
 	VIsual_select = TRUE;
+	VIsual_select_reg = 0;
+    }
     else if (VIsual_reselect)
     {
 	cap->nchar = 'v';	    // fake "gv" command
--- a/src/ops.c
+++ b/src/ops.c
@@ -624,6 +624,10 @@ op_delete(oparg_T *oap)
 	return FAIL;
     }
 
+    if (VIsual_select && oap->is_VIsual)
+	// use register given with CTRL_R, defaults to zero
+        oap->regname = VIsual_select_reg;
+
 #ifdef FEAT_CLIPBOARD
     adjust_clip_reg(&oap->regname);
 #endif
--- a/src/testdir/test_selectmode.vim
+++ b/src/testdir/test_selectmode.vim
@@ -258,4 +258,56 @@ func Test_term_mouse_multiple_clicks_to_
   bwipe!
 endfunc
 
+" Test for selecting a register with CTRL-R
+func Test_selectmode_register()
+  new
+
+  " Default behavior: use unnamed register
+  call setline(1, 'foo')
+  call setreg('"', 'bar')
+  call setreg('a', 'baz')
+  exe ":norm! v\<c-g>a"
+  call assert_equal(getline('.'), 'aoo')
+  call assert_equal('f', getreg('"'))
+  call assert_equal('baz', getreg('a'))
+
+  " Use the black hole register
+  call setline(1, 'foo')
+  call setreg('"', 'bar')
+  call setreg('a', 'baz')
+  exe ":norm! v\<c-g>\<c-r>_a"
+  call assert_equal(getline('.'), 'aoo')
+  call assert_equal('bar', getreg('"'))
+  call assert_equal('baz', getreg('a'))
+
+  " Invalid register: use unnamed register
+  call setline(1, 'foo')
+  call setreg('"', 'bar')
+  call setreg('a', 'baz')
+  exe ":norm! v\<c-g>\<c-r>?a"
+  call assert_equal(getline('.'), 'aoo')
+  call assert_equal('f', getreg('"'))
+  call assert_equal('baz', getreg('a'))
+
+  " Use unnamed register
+  call setline(1, 'foo')
+  call setreg('"', 'bar')
+  call setreg('a', 'baz')
+  exe ":norm! v\<c-g>\<c-r>\"a"
+  call assert_equal(getline('.'), 'aoo')
+  call assert_equal('f', getreg('"'))
+  call assert_equal('baz', getreg('a'))
+
+  " use specicifed register, unnamed register is also written
+  call setline(1, 'foo')
+  call setreg('"', 'bar')
+  call setreg('a', 'baz')
+  exe ":norm! v\<c-g>\<c-r>aa"
+  call assert_equal(getline('.'), 'aoo')
+  call assert_equal('f', getreg('"'))
+  call assert_equal('f', getreg('a'))
+
+  bw!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4160,
+/**/
     4159,
 /**/
     4158,