aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/getchar.c39
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/message.c4
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/terminal.c2
5 files changed, 29 insertions, 20 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index f2b0b9a8a9..ef590adb3a 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -973,27 +973,35 @@ int ins_typebuf(char_u *str, int noremap, int offset, bool nottyped, bool silent
* Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
* the char.
*/
-void ins_char_typebuf(int c)
+void 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] = (char_u)K_SECOND(c);
- buf[2] = (char_u)K_THIRD(c);
+ buf[1] = KS_MODIFIER;
+ buf[2] = (char_u)modifier;
buf[3] = NUL;
+ idx = 3;
+ }
+ if (IS_SPECIAL(c)) {
+ buf[idx] = K_SPECIAL;
+ buf[idx + 1] = (char_u)K_SECOND(c);
+ buf[idx + 2] = (char_u)K_THIRD(c);
+ buf[idx + 3] = NUL;
} else {
- buf[utf_char2bytes(c, buf)] = NUL;
- char_u *p = buf;
- while (*p) {
+ char_u *p = buf + idx;
+ int char_len = utf_char2bytes(c, p);
+ // If the character contains K_SPECIAL bytes they need escaping.
+ for (int i = char_len; --i >= 0; p++) {
if ((uint8_t)(*p) == K_SPECIAL) {
- memmove(p + 3, p + 1, STRLEN(p + 1) + 1);
+ memmove(p + 3, p + 1, (size_t)i);
*p++ = K_SPECIAL;
*p++ = KS_SPECIAL;
- *p++ = KE_FILLER;
- } else {
- p++;
+ *p = KE_FILLER;
}
}
+ *p = NUL;
}
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
}
@@ -1433,8 +1441,9 @@ int vgetc(void)
mouse_row = old_mouse_row;
mouse_col = old_mouse_col;
} else {
- mod_mask = 0x0;
+ mod_mask = 0;
last_recorded_len = 0;
+
for (;;) { // this is done twice if there are modifiers
bool did_inc = false;
if (mod_mask) { // no mapping after modifier has been read
@@ -1560,8 +1569,8 @@ int vgetc(void)
if (!no_mapping && KeyTyped && !(State & TERM_FOCUS)
&& (mod_mask == MOD_MASK_ALT || mod_mask == MOD_MASK_META)) {
mod_mask = 0;
- ins_char_typebuf(c);
- ins_char_typebuf(ESC);
+ ins_char_typebuf(c, 0);
+ ins_char_typebuf(ESC, 0);
continue;
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 40c61d01b5..31a09b3969 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -127,7 +127,7 @@ typedef off_t off_T;
// 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
// Cmdline_row is the row where the command line starts, just below the
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 39b023132e..17ccef37f1 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1215,7 +1215,7 @@ void wait_return(int redraw)
} else if (vim_strchr((char_u *)"\r\n ", c) == NULL && c != Ctrl_C) {
// 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(c, mod_mask);
do_redraw = true; // need a redraw even though there is
// typeahead
}
@@ -3497,7 +3497,7 @@ int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfl
}
if (c == ':' && ex_cmd) {
retval = dfltbutton;
- ins_char_typebuf(':');
+ ins_char_typebuf(':', 0);
break;
}
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 2b5b47c0b3..c3b7e81d17 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1010,7 +1010,7 @@ static int normal_execute(VimState *state, int key)
// 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(s->c);
+ ins_char_typebuf(s->c, mod_mask);
if (restart_edit != 0) {
s->c = 'd';
} else {
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 70a5c7aa08..a2d855244c 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1299,7 +1299,7 @@ static bool send_mouse_event(Terminal *term, int c)
}
end:
- ins_char_typebuf(c);
+ ins_char_typebuf(c, mod_mask);
return true;
}