summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-05-29 22:41:41 +0200
committerBram Moolenaar <Bram@vim.org>2020-05-29 22:41:41 +0200
commitb42c0d54279b1fdb79652db0c84171e213458809 (patch)
treee2357934da698d1fb980de7cbfb8ccbd62d982cb
parent09307e3bc1423d5e8a05464b94717a948d6c059a (diff)
downloadvim-git-b42c0d54279b1fdb79652db0c84171e213458809.tar.gz
patch 8.2.0839: dropping modifier when putting a character back in typeaheadv8.2.0839
Problem: Dropping modifier when putting a character back in typeahead. Solution: Add modifier to ins_char_typebuf(). (closes #6158)
-rw-r--r--src/getchar.c36
-rw-r--r--src/globals.h7
-rw-r--r--src/message.c4
-rw-r--r--src/normal.c2
-rw-r--r--src/proto/getchar.pro2
-rw-r--r--src/terminal.c2
-rw-r--r--src/testdir/test_messages.vim9
-rw-r--r--src/version.c2
8 files changed, 50 insertions, 14 deletions
diff --git a/src/getchar.c b/src/getchar.c
index e9eef25ad..312f3c1db 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1101,18 +1101,29 @@ ins_typebuf(
* the char.
*/
void
-ins_char_typebuf(int c)
+ins_char_typebuf(int c, int modifier)
{
- char_u buf[MB_MAXBYTES + 1];
- if (IS_SPECIAL(c))
+ char_u buf[MB_MAXBYTES + 4];
+ int idx = 0;
+
+ if (modifier != 0)
{
buf[0] = K_SPECIAL;
- buf[1] = K_SECOND(c);
- buf[2] = K_THIRD(c);
+ buf[1] = KS_MODIFIER;
+ buf[2] = modifier;
buf[3] = NUL;
+ idx = 3;
+ }
+ if (IS_SPECIAL(c))
+ {
+ buf[idx] = K_SPECIAL;
+ buf[idx + 1] = K_SECOND(c);
+ buf[idx + 2] = K_THIRD(c);
+ buf[idx + 3] = NUL;
+ idx += 3;
}
else
- buf[(*mb_char2bytes)(c, buf)] = NUL;
+ buf[(*mb_char2bytes)(c, buf + idx) + idx] = NUL;
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
}
@@ -1640,8 +1651,11 @@ vgetc(void)
}
else
{
- mod_mask = 0x0;
+ mod_mask = 0;
+ vgetc_mod_mask = 0;
+ vgetc_char = 0;
last_recorded_len = 0;
+
for (;;) // this is done twice if there are modifiers
{
int did_inc = FALSE;
@@ -1835,9 +1849,15 @@ vgetc(void)
}
if (!no_reduce_keys)
+ {
// A modifier was not used for a mapping, apply it to ASCII
// keys. Shift would already have been applied.
+ // Remember the character and mod_mask from before, in some
+ // cases they are put back in the typeahead buffer.
+ vgetc_mod_mask = mod_mask;
+ vgetc_char = c;
c = merge_modifyOtherKeys(c);
+ }
break;
}
@@ -2192,7 +2212,7 @@ parse_queued_messages(void)
// If the current window or buffer changed we need to bail out of the
// waiting loop. E.g. when a job exit callback closes the terminal window.
if (curwin->w_id != old_curwin_id || curbuf->b_fnum != old_curbuf_fnum)
- ins_char_typebuf(K_IGNORE);
+ ins_char_typebuf(K_IGNORE, 0);
--entered;
}
diff --git a/src/globals.h b/src/globals.h
index f0716c506..387c62e71 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -120,7 +120,12 @@ EXTERN int screen_Columns INIT(= 0); // actual size of ScreenLines[]
* When vgetc() is called, it sets mod_mask to the set of modifiers that are
* held down based on the MOD_MASK_* symbols that are read first.
*/
-EXTERN int mod_mask INIT(= 0x0); // current key modifiers
+EXTERN int mod_mask INIT(= 0); // current key modifiers
+
+// The value of "mod_mask" and the unomdified character before calling
+// merge_modifyOtherKeys().
+EXTERN int vgetc_mod_mask INIT(= 0);
+EXTERN int vgetc_char INIT(= 0);
/*
* Cmdline_row is the row where the command line starts, just below the
diff --git a/src/message.c b/src/message.c
index 04dc4014f..45217e2c8 100644
--- a/src/message.c
+++ b/src/message.c
@@ -1258,7 +1258,7 @@ wait_return(int redraw)
{
// Put the character back in the typeahead buffer. Don't use the
// stuff buffer, because lmaps wouldn't work.
- ins_char_typebuf(c);
+ ins_char_typebuf(vgetc_char, vgetc_mod_mask);
do_redraw = TRUE; // need a redraw even though there is
// typeahead
}
@@ -3712,7 +3712,7 @@ do_dialog(
if (c == ':' && ex_cmd)
{
retval = dfltbutton;
- ins_char_typebuf(':');
+ ins_char_typebuf(':', 0);
break;
}
diff --git a/src/normal.c b/src/normal.c
index 690bb0081..48e1c71ae 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -595,7 +595,7 @@ normal_cmd(
// restart automatically.
// Insert the typed character in the typeahead buffer, so that it can
// be mapped in Insert mode. Required for ":lmap" to work.
- ins_char_typebuf(c);
+ ins_char_typebuf(vgetc_char, vgetc_mod_mask);
if (restart_edit != 0)
c = 'd';
else
diff --git a/src/proto/getchar.pro b/src/proto/getchar.pro
index 9ff662029..57d78b594 100644
--- a/src/proto/getchar.pro
+++ b/src/proto/getchar.pro
@@ -25,7 +25,7 @@ int start_redo_ins(void);
void stop_redo_ins(void);
int noremap_keys(void);
int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, int silent);
-void ins_char_typebuf(int c);
+void ins_char_typebuf(int c, int modifier);
int typebuf_changed(int tb_change_cnt);
int typebuf_typed(void);
int typebuf_maplen(void);
diff --git a/src/terminal.c b/src/terminal.c
index 52f8105ca..59bf03995 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -3467,7 +3467,7 @@ term_channel_closed(channel_T *ch)
redraw_statuslines();
// Need to break out of vgetc().
- ins_char_typebuf(K_IGNORE);
+ ins_char_typebuf(K_IGNORE, 0);
typebuf_was_filled = TRUE;
term = curbuf->b_term;
diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim
index e07624160..b74ad2cb5 100644
--- a/src/testdir/test_messages.vim
+++ b/src/testdir/test_messages.vim
@@ -2,6 +2,7 @@
source shared.vim
source term_util.vim
+source view_util.vim
func Test_messages()
let oldmore = &more
@@ -305,4 +306,12 @@ func Test_null()
endif
endfunc
+func Test_mapping_at_hit_return_prompt()
+ nnoremap <C-B> :echo "hit ctrl-b"<CR>
+ call feedkeys(":ls\<CR>", "xt")
+ call feedkeys("\<C-B>", "xt")
+ call assert_match('hit ctrl-b', Screenline(&lines - 1))
+ nunmap <C-B>
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index f0383244a..a1b6a7d8b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 839,
+/**/
838,
/**/
837,