Problem: Dropping modifier when putting a character back in typeahead.
Solution: Add modifier to ins_char_typebuf(). (closes #6158)
* 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);
}
}
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;
}
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;
}
// 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;
}
* 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
{
// 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
}
if (c == ':' && ex_cmd)
{
retval = dfltbutton;
- ins_char_typebuf(':');
+ ins_char_typebuf(':', 0);
break;
}
// 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
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);
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;
source shared.vim
source term_util.vim
+source view_util.vim
func Test_messages()
let oldmore = &more
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
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 839,
/**/
838,
/**/