changeset 28333:04310f81143d v8.2.4692

patch 8.2.4692: no test for what 8.2.4691 fixes Commit: https://github.com/vim/vim/commit/0f68e6c07aaf62c034a242f183b93c1bb44e7f93 Author: zeertzjq <zeertzjq@outlook.com> Date: Tue Apr 5 13:17:01 2022 +0100 patch 8.2.4692: no test for what 8.2.4691 fixes Problem: No test for what 8.2.4691 fixes. Solution: Add a test. Use a more generic sotlution. (closes https://github.com/vim/vim/issues/10090)
author Bram Moolenaar <Bram@vim.org>
date Tue, 05 Apr 2022 14:30:03 +0200
parents 609c7fb65969
children a72c164495e0
files src/getchar.c src/mouse.c src/testdir/test_mapping.vim src/version.c
diffstat 4 files changed, 52 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1419,6 +1419,14 @@ static int old_char = -1;	// character p
 static int old_mod_mask;	// mod_mask for ungotten character
 static int old_mouse_row;	// mouse_row related to old_char
 static int old_mouse_col;	// mouse_col related to old_char
+static int old_KeyStuffed;	// whether old_char was stuffed
+
+static int can_get_old_char()
+{
+    // If the old character was not stuffed and characters have been added to
+    // the stuff buffer, need to first get the stuffed characters instead.
+    return old_char != -1 && (old_KeyStuffed || stuff_empty());
+}
 
 /*
  * Save all three kinds of typeahead, so that the user must type at a prompt.
@@ -1687,7 +1695,7 @@ vgetc(void)
      * If a character was put back with vungetc, it was already processed.
      * Return it directly.
      */
-    if (old_char != -1)
+    if (can_get_old_char())
     {
 	c = old_char;
 	old_char = -1;
@@ -1987,7 +1995,7 @@ plain_vgetc(void)
     int
 vpeekc(void)
 {
-    if (old_char != -1)
+    if (can_get_old_char())
 	return old_char;
     return vgetorpeek(FALSE);
 }
@@ -2942,6 +2950,8 @@ handle_mapping(
 
 /*
  * unget one character (can only be done once!)
+ * If the character was stuffed, vgetc() will get it next time it was called.
+ * Otherwise vgetc() will only get it when the stuff buffer is empty.
  */
     void
 vungetc(int c)
@@ -2950,6 +2960,7 @@ vungetc(int c)
     old_mod_mask = mod_mask;
     old_mouse_row = mouse_row;
     old_mouse_col = mouse_col;
+    old_KeyStuffed = KeyStuffed;
 }
 
 /*
@@ -3755,8 +3766,6 @@ getcmdkeycmd(
     int		c2;
     int		cmod = 0;
     int		aborted = FALSE;
-    int		first = TRUE;
-    int		got_ctrl_o = FALSE;
 
     ga_init2(&line_ga, 1, 32);
 
@@ -3784,15 +3793,6 @@ getcmdkeycmd(
 	// Get one character at a time.
 	c1 = vgetorpeek(TRUE);
 
-	// do not use Ctrl_O at the start, stuff it back later
-	if (first && c1 == Ctrl_O)
-	{
-	    got_ctrl_o = TRUE;
-	    first = FALSE;
-	    continue;
-	}
-	first = FALSE;
-
 	// Get two extra bytes for special keys
 	if (c1 == K_SPECIAL)
 	{
@@ -3844,8 +3844,6 @@ getcmdkeycmd(
     }
 
     no_mapping--;
-    if (got_ctrl_o)
-	stuffcharReadbuff(Ctrl_O);
 
     if (aborted)
 	ga_clear(&line_ga);
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -261,7 +261,10 @@ do_mouse(
 	{
 	    // If the next character is the same mouse event then use that
 	    // one. Speeds up dragging the status line.
-	    if (vpeekc() != NUL)
+	    // Note: Since characters added to the stuff buffer in the code
+	    // below need to come before the next character, do not do this
+	    // when the current character was stuffed.
+	    if (!KeyStuffed && vpeekc() != NUL)
 	    {
 		int nc;
 		int save_mouse_row = mouse_row;
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -1566,4 +1566,37 @@ func Test_plug_remap()
   %bw!
 endfunc
 
+" Test for mapping <LeftDrag> in Insert mode
+func Test_mouse_drag_insert_map()
+  set mouse=a
+  func ClickExpr()
+    call test_setmouse(1, 1)
+    return "\<LeftMouse>"
+  endfunc
+  func DragExpr()
+    call test_setmouse(1, 2)
+    return "\<LeftDrag>"
+  endfunc
+  inoremap <expr> <F2> ClickExpr()
+  imap <expr> <F3> DragExpr()
+
+  inoremap <LeftDrag> <LeftDrag><Cmd>let g:dragged = 1<CR>
+  exe "normal i\<F2>\<F3>"
+  call assert_equal(1, g:dragged)
+  call assert_equal('v', mode())
+  exe "normal! \<C-\>\<C-N>"
+  unlet g:dragged
+
+  inoremap <LeftDrag> <LeftDrag><C-\><C-N>
+  exe "normal i\<F2>\<F3>"
+  call assert_equal('n', mode())
+
+  iunmap <LeftDrag>
+  iunmap <F2>
+  iunmap <F3>
+  delfunc ClickExpr
+  delfunc DragExpr
+  set mouse&
+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 */
 /**/
+    4692,
+/**/
     4691,
 /**/
     4690,