summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-04-05 13:17:01 +0100
committerBram Moolenaar <Bram@vim.org>2022-04-05 13:17:01 +0100
commit0f68e6c07aaf62c034a242f183b93c1bb44e7f93 (patch)
tree6d4066cdf09d7830138a499bc75c2881115a98d3
parentca9d8d2cb9fc6b9240f2a74ccd36f9d966488294 (diff)
downloadvim-git-0f68e6c07aaf62c034a242f183b93c1bb44e7f93.tar.gz
patch 8.2.4692: no test for what 8.2.4691 fixesv8.2.4692
Problem: No test for what 8.2.4691 fixes. Solution: Add a test. Use a more generic sotlution. (closes #10090)
-rw-r--r--src/getchar.c28
-rw-r--r--src/mouse.c5
-rw-r--r--src/testdir/test_mapping.vim33
-rw-r--r--src/version.c2
4 files changed, 52 insertions, 16 deletions
diff --git a/src/getchar.c b/src/getchar.c
index 34a33ac40..b81f64a65 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1419,6 +1419,14 @@ static int old_char = -1; // character put back by vungetc()
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);
diff --git a/src/mouse.c b/src/mouse.c
index b81aff248..42963341c 100644
--- 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;
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index 6421058b0..a002126f1 100644
--- 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
diff --git a/src/version.c b/src/version.c
index 9e50d2fac..4451f7d91 100644
--- 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,