aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-04-05 21:38:53 +0800
committerGitHub <noreply@github.com>2022-04-05 21:38:53 +0800
commit969d600f2a107507c60e4ac3f3a8c03210662f96 (patch)
tree8acb7a2c9e766b07a8e321ea18e48e9ecc1a6544 /src
parente135adcb8c4f32332ba87ea6681f41330b909e1c (diff)
downloadrneovim-969d600f2a107507c60e4ac3f3a8c03210662f96.tar.gz
rneovim-969d600f2a107507c60e4ac3f3a8c03210662f96.tar.bz2
rneovim-969d600f2a107507c60e4ac3f3a8c03210662f96.zip
vim-patch:8.2.{4692,4691,4690}: fix Insert mode <LeftDrag> mapping bug (#17999)
vim-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 vim/vim#10090) https://github.com/vim/vim/commit/0f68e6c07aaf62c034a242f183b93c1bb44e7f93 Test cannot be used because it must use test_setmouse(). Use a Lua test. Reverted patches: vim-patch:8.2.4691: solution for <Cmd> in a mapping causes trouble Problem: Solution for <Cmd> in a mapping causes trouble. Solution: Use another solution: put back CTRL-O after reading the <Cmd> sequence. https://github.com/vim/vim/commit/ca9d8d2cb9fc6b9240f2a74ccd36f9d966488294 vim-patch:8.2.4689: using <Cmd> in a mapping does not work for mouse keys Problem: Using <Cmd> in a mapping does not work for mouse keys in Insert mode. (Sergey Vlasov) Solution: When reading the <Cmd> argument do not use the stuff buffer. (closes vim/vim#10080) https://github.com/vim/vim/commit/d0fb2d804183c2786578b4c32ba5b92938f93d0e
Diffstat (limited to 'src')
-rw-r--r--src/nvim/getchar.c16
-rw-r--r--src/nvim/normal.c9
-rw-r--r--src/nvim/testdir/test_mapping.vim34
3 files changed, 53 insertions, 6 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 669d181364..eddd5ccd14 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -1253,7 +1253,14 @@ static int old_mod_mask; // mod_mask for ungotten character
static int old_mouse_grid; // mouse_grid related to old_char
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 bool can_get_old_char(void)
+{
+ // 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.
@@ -1454,7 +1461,7 @@ int 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;
mod_mask = old_mod_mask;
@@ -1660,7 +1667,7 @@ int plain_vgetc(void)
*/
int vpeekc(void)
{
- if (old_char != -1) {
+ if (can_get_old_char()) {
return old_char;
}
return vgetorpeek(false);
@@ -2052,7 +2059,9 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth)
return map_result_nomatch;
}
-// unget one character (can only be done once!)
+/// 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)
{
old_char = c;
@@ -2060,6 +2069,7 @@ void vungetc(int c)
old_mouse_grid = mouse_grid;
old_mouse_row = mouse_row;
old_mouse_col = mouse_col;
+ old_KeyStuffed = KeyStuffed;
}
/// Gets a byte:
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 5e46bd468d..9cee2de0c5 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1517,9 +1517,12 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
for (;;) {
which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag);
if (is_drag) {
- /* If the next character is the same mouse event then use that
- * one. Speeds up dragging the status line. */
- if (vpeekc() != NUL) {
+ // If the next character is the same mouse event then use that
+ // one. Speeds up dragging the status line.
+ // 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_grid = mouse_grid;
int save_mouse_row = mouse_row;
diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim
index 98440ccdd7..a8dd0ca286 100644
--- a/src/nvim/testdir/test_mapping.vim
+++ b/src/nvim/testdir/test_mapping.vim
@@ -676,4 +676,38 @@ func Test_plug_remap()
%bw!
endfunc
+" Test for mapping <LeftDrag> in Insert mode
+func Test_mouse_drag_insert_map()
+ CheckFunction test_setmouse
+ 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