input: Do not set high-bit; preserve ALT modifier.

Background: Vim internally prefers to represent ALT/META chords as
single-byte keys, by setting the high bit of the key byte.
extract_modifiers() _discards_ the meta/alt modifier, but we need it for
libvterm and libtermkey.

Closes #2440
Closes #3727
Closes #2017
References #2277
References #2254

https://github.com/neovim/neovim/issues/2017#issuecomment-140423557
> We [not libtermkey] are setting the high bit for some reason

https://github.com/neovim/neovim/issues/176#issuecomment-77834715
> libvtermkey requires the leading esc to parse alt/meta

https://github.com/neovim/neovim/pull/3246#issuecomment-136328450
> A program could do better than the current logic on some terminals, by
> asking for pure 8bit mode (S8C1T) and then immediately querying the
> mode again. If the result comes back as an 8bit single-byte CSI, then
> it can presume the mode setting was successful, and now the ESC prefix
> byte won't be seen in multibyte sequences; only as an Alt- prefix or
> a real Escape key. On such a terminal, it could therefore avoid
> needing to use that waiting timeout.
This commit is contained in:
Justin M. Keyes
2016-01-10 16:23:24 -05:00
parent dd8812c7cb
commit 317d5ca7b0
3 changed files with 46 additions and 33 deletions

View File

@@ -18,6 +18,9 @@
#include "nvim/strings.h"
#include "nvim/mouse.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "keymap.c.generated.h"
#endif
/*
* Some useful tables.
@@ -637,11 +640,11 @@ find_special_key (
key = DEL;
}
/*
* Normal Key with modifier: Try to make a single byte code.
*/
if (!IS_SPECIAL(key))
// Normal Key with modifier:
// Try to make a single byte code (except for Alt/Meta modifiers).
if (!IS_SPECIAL(key)) {
key = extract_modifiers(key, &modifiers);
}
*modp = modifiers;
*srcp = end_of_name;
@@ -652,11 +655,9 @@ find_special_key (
return 0;
}
/*
* Try to include modifiers in the key.
* Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
*/
int extract_modifiers(int key, int *modp)
/// Try to include modifiers (except alt/meta) in the key.
/// Changes "Shift-a" to 'A', "Ctrl-@" to <Nul>, etc.
static int extract_modifiers(int key, int *modp)
{
int modifiers = *modp;
@@ -665,19 +666,12 @@ int extract_modifiers(int key, int *modp)
modifiers &= ~MOD_MASK_SHIFT;
}
if ((modifiers & MOD_MASK_CTRL)
&& ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))
) {
&& ((key >= '?' && key <= '_') || ASCII_ISALPHA(key))) {
key = Ctrl_chr(key);
modifiers &= ~MOD_MASK_CTRL;
/* <C-@> is <Nul> */
if (key == 0)
if (key == 0) { // <C-@> is <Nul>
key = K_ZERO;
}
if ((modifiers & MOD_MASK_ALT) && key < 0x80
&& !enc_dbcs /* avoid creating a lead byte */
) {
key |= 0x80;
modifiers &= ~MOD_MASK_ALT; /* remove the META modifier */
}
}
*modp = modifiers;