Add tests for legacy letter key encodings
This commit is contained in:
parent
78d45eb161
commit
c519013b20
@ -1,12 +1,16 @@
|
||||
A protocol for comprehensive keyboard handling in terminals
|
||||
=================================================================
|
||||
|
||||
There are various problems with the current state of keyboard handling. They
|
||||
include:
|
||||
There are various problems with the current state of keyboard handling in
|
||||
terminals. They include:
|
||||
|
||||
* No way to use modifiers other than ``Ctrl`` and ``Alt``
|
||||
* No way to use modifiers other than ``ctrl`` and ``alt``
|
||||
|
||||
* No way to reliably use multiple modifier keys, other than, ``Shift+Alt``.
|
||||
* No way to reliably use multiple modifier keys, other than, ``shift+alt`` and
|
||||
``ctrl+alt``.
|
||||
|
||||
* Many of the existing escape codes used to encode these events are ambiguous
|
||||
with different key presses mapping to the same escape code.
|
||||
|
||||
* No way to handle different types of keyboard events, such as press, release or repeat
|
||||
|
||||
@ -22,6 +26,8 @@ advanced usages. The protocol is based on initial work in `fixterms
|
||||
issues in that proposal, listed at the :ref:`bottom of this document
|
||||
<fixterms_bugs>`.
|
||||
|
||||
.. versionadded:: 0.20.0
|
||||
|
||||
A basic overview
|
||||
------------------
|
||||
|
||||
@ -302,6 +308,34 @@ distinguish these, use the :ref:`disambiguate <disambiguate>` flag.
|
||||
Legacy text keys
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For legacy compatibility, the keys
|
||||
:kbd:`a-z 0-9 \` - = [ ] \ ; ' , . /` with the modifiers
|
||||
:kbd:`shift, alt, ctrl, shift+alt, ctrl+alt` are output using the
|
||||
following algorithm:
|
||||
|
||||
#. If the :kbd:`alt` key is pressed output the byte for ``ESC (0x1b)``
|
||||
#. If the :kbd:`ctrl` modifier is pressed mask the seventh bit ``(& 0b111111)`` in the key's ASCII code number and output that
|
||||
#. Otherwise, if the :kbd:`shift` modifier is pressed, output the shifted key, for example, ``A`` for ``a`` and ``$`` for ``4``.
|
||||
#. Otherwise, output the key unmodified
|
||||
|
||||
Additionally, :kbd:`ctrl+space` is output as the NULL byte ``(0x0)``.
|
||||
|
||||
Any other combination of modifiers with these keys is output as the appropriate
|
||||
``CSI u`` escape code.
|
||||
|
||||
.. csv-table:: Example encodings
|
||||
:header: "Key", "Plain", "shift", "alt", "ctrl", "shift+alt", "alt+ctrl", "ctrl+shift"
|
||||
|
||||
"i", "i (105)", "I (73)", "ESC i", ") (41)", "ESC I", "ESC )", "CSI 105; 6 u"
|
||||
"3", "3 (51)", "# (35)", "ESC 3", "3 (51)", "ESC #", "ESC 3", "CSI 51; 6 u"
|
||||
";", "; (59)", ": (58)", "ESC ;", "; (59)", "ESC :", "ESC ;", "CSI 59; 6 u"
|
||||
|
||||
.. note::
|
||||
Many of the legacy escape codes are ambiguous with multiple different key
|
||||
presses yielding the same escape code(s), for example, :kbd:`ctrl+i` is the
|
||||
same as :kbd:`tab`, :kbd:`ctrl+m` is the same as :kbd:`Enter`, :kbd:`alt+[ 2
|
||||
shift+\`` is the same :kbd:`Insert`, etc. To resolve these use the
|
||||
:ref:`disambiguate progressive enhancement <disambiguate>`.
|
||||
|
||||
|
||||
.. _functional:
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import string
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
functional_key_defs = '''# {{{
|
||||
# kitty XKB macOS
|
||||
escape Escape -
|
||||
@ -113,6 +113,8 @@ raise_volume XF86AudioRaiseVolume -
|
||||
mute_volume XF86AudioMute -
|
||||
''' # }}}
|
||||
|
||||
shift_map = {x[0]: x[1] for x in '`~ 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ [{ ]} \\| ;: \'" ,< .> /?'.split()}
|
||||
shift_map.update({x: x.upper() for x in string.ascii_lowercase})
|
||||
functional_encoding_overrides = {
|
||||
'insert': 2, 'delete': 3, 'page_up': 5, 'page_down': 6,
|
||||
'home': 7, 'end': 8, 'tab': 9, 'f1': 11, 'f2': 12, 'enter': 13, 'f4': 14,
|
||||
@ -220,10 +222,46 @@ def generate_functional_table() -> None:
|
||||
patch_file('kitty/key_encoding.c', 'special numbers', '\n'.join(enc_lines))
|
||||
|
||||
|
||||
def generate_legacy_text_key_maps() -> None:
|
||||
tests = []
|
||||
tp = ' ' * 8
|
||||
shift, alt, ctrl = 1, 2, 4
|
||||
|
||||
lines = []
|
||||
for c, s in shift_map.items():
|
||||
if c in '\\\'':
|
||||
c = '\\' + c
|
||||
lines.append(f" case '{c}': return '{s}';")
|
||||
patch_file('kitty/key_encoding.c', 'shifted key map', '\n'.join(lines))
|
||||
|
||||
def simple(c: str) -> None:
|
||||
shifted = shift_map.get(c, c)
|
||||
ctrled = chr(ord(c) & 0b111111)
|
||||
for m in range(16):
|
||||
if m == 0:
|
||||
tests.append(f'{tp}ae(enc(ord({c!r})), {c!r})')
|
||||
elif m == shift:
|
||||
tests.append(f'{tp}ae(enc(ord({c!r}), mods=shift), {shifted!r})')
|
||||
elif m == alt:
|
||||
tests.append(f'{tp}ae(enc(ord({c!r}), mods=alt), "\\x1b" + {c!r})')
|
||||
elif m == ctrl:
|
||||
tests.append(f'{tp}ae(enc(ord({c!r}), mods=ctrl), {ctrled!r})')
|
||||
elif m == shift | alt:
|
||||
tests.append(f'{tp}ae(enc(ord({c!r}), mods=shift | alt), "\\x1b" + {shifted!r})')
|
||||
elif m == ctrl | alt:
|
||||
tests.append(f'{tp}ae(enc(ord({c!r}), mods=ctrl | alt), "\\x1b" + {ctrled!r})')
|
||||
|
||||
for k in shift_map:
|
||||
simple(k)
|
||||
|
||||
patch_file('kitty_tests/keys.py', 'legacy letter tests', '\n'.join(tests), start_marker='# ', end_marker='')
|
||||
|
||||
|
||||
def main() -> None:
|
||||
generate_glfw_header()
|
||||
generate_xkb_mapping()
|
||||
generate_functional_table()
|
||||
generate_legacy_text_key_maps()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -138,6 +138,7 @@ encode_function_key(const KeyEvent *ev, char *output) {
|
||||
}
|
||||
}
|
||||
if (ev->mods.value == SHIFT && key_number == GLFW_FKEY_TAB) { SIMPLE("\x1b[Z"); }
|
||||
if (ev->mods.value == CTRL && key_number == GLFW_FKEY_BACKSPACE) { SIMPLE("\x08"); }
|
||||
#undef SIMPLE
|
||||
|
||||
#define S(number, trailer) key_number = number; csi_trailer = trailer; break
|
||||
@ -180,29 +181,105 @@ encode_function_key(const KeyEvent *ev, char *output) {
|
||||
return serialize(&ed, output, csi_trailer);
|
||||
}
|
||||
|
||||
static inline char
|
||||
shifted_ascii_key(const uint32_t key) {
|
||||
switch(key) {
|
||||
/* start shifted key map (auto generated by gen-key-constants.py do not edit) */
|
||||
case '`': return '~';
|
||||
case '1': return '!';
|
||||
case '2': return '@';
|
||||
case '3': return '#';
|
||||
case '4': return '$';
|
||||
case '5': return '%';
|
||||
case '6': return '^';
|
||||
case '7': return '&';
|
||||
case '8': return '*';
|
||||
case '9': return '(';
|
||||
case '0': return ')';
|
||||
case '-': return '_';
|
||||
case '=': return '+';
|
||||
case '[': return '{';
|
||||
case ']': return '}';
|
||||
case '\\': return '|';
|
||||
case ';': return ':';
|
||||
case '\'': return '"';
|
||||
case ',': return '<';
|
||||
case '.': return '>';
|
||||
case '/': return '?';
|
||||
case 'a': return 'A';
|
||||
case 'b': return 'B';
|
||||
case 'c': return 'C';
|
||||
case 'd': return 'D';
|
||||
case 'e': return 'E';
|
||||
case 'f': return 'F';
|
||||
case 'g': return 'G';
|
||||
case 'h': return 'H';
|
||||
case 'i': return 'I';
|
||||
case 'j': return 'J';
|
||||
case 'k': return 'K';
|
||||
case 'l': return 'L';
|
||||
case 'm': return 'M';
|
||||
case 'n': return 'N';
|
||||
case 'o': return 'O';
|
||||
case 'p': return 'P';
|
||||
case 'q': return 'Q';
|
||||
case 'r': return 'R';
|
||||
case 's': return 'S';
|
||||
case 't': return 'T';
|
||||
case 'u': return 'U';
|
||||
case 'v': return 'V';
|
||||
case 'w': return 'W';
|
||||
case 'x': return 'X';
|
||||
case 'y': return 'Y';
|
||||
case 'z': return 'Z';
|
||||
/* end shifted key map */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
encode_printable_ascii_key_legacy(const KeyEvent *ev, char *output) {
|
||||
if (!ev->mods.value) return snprintf(output, KEY_BUFFER_SIZE, "%c", (char)ev->key);
|
||||
if (ev->disambiguate) return 0;
|
||||
|
||||
char shifted_key = 0;
|
||||
if ('a' <= ev->key && ev->key <= 'z') shifted_key = ev->key + ('A' - 'a');
|
||||
switch(ev->key) {
|
||||
#define S(which, val) case which: shifted_key = val; break;
|
||||
S('0', ')') S('9', '(') S('8', '*') S('7', '&') S('6', '^') S('5', '%') S('4', '$') S('3', '#') S('2', '@') S('1', '!')
|
||||
S('`', '~') S('-', '_') S('=', '+') S('[', '{') S(']', '}') S('\\', '|') S(';', ':') S('\'', '"') S(',', '<') S('.', '>') S('/', '?')
|
||||
#undef S
|
||||
}
|
||||
char shifted_key = shifted_ascii_key(ev->key);
|
||||
shifted_key = (shifted_key && ev->mods.shift) ? shifted_key : (char)ev->key;
|
||||
if (ev->mods.value == SHIFT)
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "%c", shifted_key);
|
||||
if ((ev->mods.value == ALT || ev->mods.value == (SHIFT | ALT)))
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", shifted_key);
|
||||
if (ev->mods.value == CTRL && ev->key && 0x1f != ev->key)
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "%c", ev->key & 0x1f);
|
||||
if (ev->mods.value == CTRL)
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "%c", ev->key & 0x3f);
|
||||
if (ev->mods.value == (CTRL | ALT))
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", ev->key & 0x1f);
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", ev->key & 0x3f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_legacy_ascii_key(uint32_t key) {
|
||||
START_ALLOW_CASE_RANGE
|
||||
switch (key) {
|
||||
case 'a' ... 'z':
|
||||
case '0' ... '9':
|
||||
case '`':
|
||||
case '-':
|
||||
case '=':
|
||||
case '[':
|
||||
case ']':
|
||||
case '\\':
|
||||
case ';':
|
||||
case '\'':
|
||||
case ',':
|
||||
case '.':
|
||||
case '/':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
END_ALLOW_CASE_RANGE
|
||||
}
|
||||
|
||||
static int
|
||||
encode_key(const KeyEvent *ev, char *output) {
|
||||
if (!ev->report_all_event_types && ev->action == RELEASE) return 0;
|
||||
@ -211,9 +288,14 @@ encode_key(const KeyEvent *ev, char *output) {
|
||||
init_encoding_data(&ed, ev);
|
||||
bool simple_encoding_ok = !ed.add_actions && !ed.add_alternates;
|
||||
|
||||
if (32 <= ev->key && ev->key <= 126 && simple_encoding_ok) {
|
||||
if (simple_encoding_ok) {
|
||||
if (is_legacy_ascii_key(ev->key)) {
|
||||
int ret = encode_printable_ascii_key_legacy(ev, output);
|
||||
if (ret > 0) return ret;
|
||||
} else if (ev->key == ' ' && ev->mods.value == CTRL) {
|
||||
output[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (simple_encoding_ok && !ed.has_mods) return encode_utf8(ev->key, output);
|
||||
|
||||
@ -169,7 +169,7 @@ pyencode_key_for_tty(PyObject *self UNUSED, PyObject *args, PyObject *kw) {
|
||||
char output[KEY_BUFFER_SIZE+1] = {0};
|
||||
int num = encode_glfw_key_event(&ev, cursor_key_mode, key_encoding_flags, output);
|
||||
if (num == SEND_TEXT_TO_CHILD) return PyUnicode_FromString(text);
|
||||
return PyUnicode_FromString(output);
|
||||
return PyUnicode_FromStringAndSize(output, MAX(0, num));
|
||||
}
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
|
||||
@ -48,7 +48,7 @@ class TestKeys(BaseTest):
|
||||
mods_test(defines.GLFW_FKEY_ENTER, '\x0d', alt='\033\x0d', csi_num=ord('\r'))
|
||||
mods_test(defines.GLFW_FKEY_KP_ENTER, '\x0d', alt='\033\x0d', csi_num=ord('\r'))
|
||||
mods_test(defines.GLFW_FKEY_ESCAPE, '\x1b', alt='\033\033', csi_num=27)
|
||||
mods_test(defines.GLFW_FKEY_BACKSPACE, '\x7f', alt='\033\x7f', csi_num=127)
|
||||
mods_test(defines.GLFW_FKEY_BACKSPACE, '\x7f', alt='\033\x7f', ctrl='\x08', csi_num=127)
|
||||
mods_test(defines.GLFW_FKEY_TAB, '\t', alt='\033\t', shift='\x1b[Z', csi_num=ord('\t'))
|
||||
mods_test(defines.GLFW_FKEY_INSERT, csi_num=2, trailer='~')
|
||||
mods_test(defines.GLFW_FKEY_KP_INSERT, csi_num=2, trailer='~')
|
||||
@ -82,6 +82,297 @@ class TestKeys(BaseTest):
|
||||
mods_test(defines.GLFW_FKEY_LEFT, csi_num=1, trailer='D')
|
||||
mods_test(defines.GLFW_FKEY_KP_LEFT, csi_num=1, trailer='D')
|
||||
|
||||
# legacy key tests {{{
|
||||
# start legacy letter tests (auto generated by gen-key-constants.py do not edit)
|
||||
ae(enc(ord('`')), '`')
|
||||
ae(enc(ord('`'), mods=shift), '~')
|
||||
ae(enc(ord('`'), mods=alt), "\x1b" + '`')
|
||||
ae(enc(ord('`'), mods=shift | alt), "\x1b" + '~')
|
||||
ae(enc(ord('`'), mods=ctrl), ' ')
|
||||
ae(enc(ord('`'), mods=ctrl | alt), "\x1b" + ' ')
|
||||
ae(enc(ord('1')), '1')
|
||||
ae(enc(ord('1'), mods=shift), '!')
|
||||
ae(enc(ord('1'), mods=alt), "\x1b" + '1')
|
||||
ae(enc(ord('1'), mods=shift | alt), "\x1b" + '!')
|
||||
ae(enc(ord('1'), mods=ctrl), '1')
|
||||
ae(enc(ord('1'), mods=ctrl | alt), "\x1b" + '1')
|
||||
ae(enc(ord('2')), '2')
|
||||
ae(enc(ord('2'), mods=shift), '@')
|
||||
ae(enc(ord('2'), mods=alt), "\x1b" + '2')
|
||||
ae(enc(ord('2'), mods=shift | alt), "\x1b" + '@')
|
||||
ae(enc(ord('2'), mods=ctrl), '2')
|
||||
ae(enc(ord('2'), mods=ctrl | alt), "\x1b" + '2')
|
||||
ae(enc(ord('3')), '3')
|
||||
ae(enc(ord('3'), mods=shift), '#')
|
||||
ae(enc(ord('3'), mods=alt), "\x1b" + '3')
|
||||
ae(enc(ord('3'), mods=shift | alt), "\x1b" + '#')
|
||||
ae(enc(ord('3'), mods=ctrl), '3')
|
||||
ae(enc(ord('3'), mods=ctrl | alt), "\x1b" + '3')
|
||||
ae(enc(ord('4')), '4')
|
||||
ae(enc(ord('4'), mods=shift), '$')
|
||||
ae(enc(ord('4'), mods=alt), "\x1b" + '4')
|
||||
ae(enc(ord('4'), mods=shift | alt), "\x1b" + '$')
|
||||
ae(enc(ord('4'), mods=ctrl), '4')
|
||||
ae(enc(ord('4'), mods=ctrl | alt), "\x1b" + '4')
|
||||
ae(enc(ord('5')), '5')
|
||||
ae(enc(ord('5'), mods=shift), '%')
|
||||
ae(enc(ord('5'), mods=alt), "\x1b" + '5')
|
||||
ae(enc(ord('5'), mods=shift | alt), "\x1b" + '%')
|
||||
ae(enc(ord('5'), mods=ctrl), '5')
|
||||
ae(enc(ord('5'), mods=ctrl | alt), "\x1b" + '5')
|
||||
ae(enc(ord('6')), '6')
|
||||
ae(enc(ord('6'), mods=shift), '^')
|
||||
ae(enc(ord('6'), mods=alt), "\x1b" + '6')
|
||||
ae(enc(ord('6'), mods=shift | alt), "\x1b" + '^')
|
||||
ae(enc(ord('6'), mods=ctrl), '6')
|
||||
ae(enc(ord('6'), mods=ctrl | alt), "\x1b" + '6')
|
||||
ae(enc(ord('7')), '7')
|
||||
ae(enc(ord('7'), mods=shift), '&')
|
||||
ae(enc(ord('7'), mods=alt), "\x1b" + '7')
|
||||
ae(enc(ord('7'), mods=shift | alt), "\x1b" + '&')
|
||||
ae(enc(ord('7'), mods=ctrl), '7')
|
||||
ae(enc(ord('7'), mods=ctrl | alt), "\x1b" + '7')
|
||||
ae(enc(ord('8')), '8')
|
||||
ae(enc(ord('8'), mods=shift), '*')
|
||||
ae(enc(ord('8'), mods=alt), "\x1b" + '8')
|
||||
ae(enc(ord('8'), mods=shift | alt), "\x1b" + '*')
|
||||
ae(enc(ord('8'), mods=ctrl), '8')
|
||||
ae(enc(ord('8'), mods=ctrl | alt), "\x1b" + '8')
|
||||
ae(enc(ord('9')), '9')
|
||||
ae(enc(ord('9'), mods=shift), '(')
|
||||
ae(enc(ord('9'), mods=alt), "\x1b" + '9')
|
||||
ae(enc(ord('9'), mods=shift | alt), "\x1b" + '(')
|
||||
ae(enc(ord('9'), mods=ctrl), '9')
|
||||
ae(enc(ord('9'), mods=ctrl | alt), "\x1b" + '9')
|
||||
ae(enc(ord('0')), '0')
|
||||
ae(enc(ord('0'), mods=shift), ')')
|
||||
ae(enc(ord('0'), mods=alt), "\x1b" + '0')
|
||||
ae(enc(ord('0'), mods=shift | alt), "\x1b" + ')')
|
||||
ae(enc(ord('0'), mods=ctrl), '0')
|
||||
ae(enc(ord('0'), mods=ctrl | alt), "\x1b" + '0')
|
||||
ae(enc(ord('-')), '-')
|
||||
ae(enc(ord('-'), mods=shift), '_')
|
||||
ae(enc(ord('-'), mods=alt), "\x1b" + '-')
|
||||
ae(enc(ord('-'), mods=shift | alt), "\x1b" + '_')
|
||||
ae(enc(ord('-'), mods=ctrl), '-')
|
||||
ae(enc(ord('-'), mods=ctrl | alt), "\x1b" + '-')
|
||||
ae(enc(ord('=')), '=')
|
||||
ae(enc(ord('='), mods=shift), '+')
|
||||
ae(enc(ord('='), mods=alt), "\x1b" + '=')
|
||||
ae(enc(ord('='), mods=shift | alt), "\x1b" + '+')
|
||||
ae(enc(ord('='), mods=ctrl), '=')
|
||||
ae(enc(ord('='), mods=ctrl | alt), "\x1b" + '=')
|
||||
ae(enc(ord('[')), '[')
|
||||
ae(enc(ord('['), mods=shift), '{')
|
||||
ae(enc(ord('['), mods=alt), "\x1b" + '[')
|
||||
ae(enc(ord('['), mods=shift | alt), "\x1b" + '{')
|
||||
ae(enc(ord('['), mods=ctrl), '\x1b')
|
||||
ae(enc(ord('['), mods=ctrl | alt), "\x1b" + '\x1b')
|
||||
ae(enc(ord(']')), ']')
|
||||
ae(enc(ord(']'), mods=shift), '}')
|
||||
ae(enc(ord(']'), mods=alt), "\x1b" + ']')
|
||||
ae(enc(ord(']'), mods=shift | alt), "\x1b" + '}')
|
||||
ae(enc(ord(']'), mods=ctrl), '\x1d')
|
||||
ae(enc(ord(']'), mods=ctrl | alt), "\x1b" + '\x1d')
|
||||
ae(enc(ord('\\')), '\\')
|
||||
ae(enc(ord('\\'), mods=shift), '|')
|
||||
ae(enc(ord('\\'), mods=alt), "\x1b" + '\\')
|
||||
ae(enc(ord('\\'), mods=shift | alt), "\x1b" + '|')
|
||||
ae(enc(ord('\\'), mods=ctrl), '\x1c')
|
||||
ae(enc(ord('\\'), mods=ctrl | alt), "\x1b" + '\x1c')
|
||||
ae(enc(ord(';')), ';')
|
||||
ae(enc(ord(';'), mods=shift), ':')
|
||||
ae(enc(ord(';'), mods=alt), "\x1b" + ';')
|
||||
ae(enc(ord(';'), mods=shift | alt), "\x1b" + ':')
|
||||
ae(enc(ord(';'), mods=ctrl), ';')
|
||||
ae(enc(ord(';'), mods=ctrl | alt), "\x1b" + ';')
|
||||
ae(enc(ord("'")), "'")
|
||||
ae(enc(ord("'"), mods=shift), '"')
|
||||
ae(enc(ord("'"), mods=alt), "\x1b" + "'")
|
||||
ae(enc(ord("'"), mods=shift | alt), "\x1b" + '"')
|
||||
ae(enc(ord("'"), mods=ctrl), "'")
|
||||
ae(enc(ord("'"), mods=ctrl | alt), "\x1b" + "'")
|
||||
ae(enc(ord(',')), ',')
|
||||
ae(enc(ord(','), mods=shift), '<')
|
||||
ae(enc(ord(','), mods=alt), "\x1b" + ',')
|
||||
ae(enc(ord(','), mods=shift | alt), "\x1b" + '<')
|
||||
ae(enc(ord(','), mods=ctrl), ',')
|
||||
ae(enc(ord(','), mods=ctrl | alt), "\x1b" + ',')
|
||||
ae(enc(ord('.')), '.')
|
||||
ae(enc(ord('.'), mods=shift), '>')
|
||||
ae(enc(ord('.'), mods=alt), "\x1b" + '.')
|
||||
ae(enc(ord('.'), mods=shift | alt), "\x1b" + '>')
|
||||
ae(enc(ord('.'), mods=ctrl), '.')
|
||||
ae(enc(ord('.'), mods=ctrl | alt), "\x1b" + '.')
|
||||
ae(enc(ord('/')), '/')
|
||||
ae(enc(ord('/'), mods=shift), '?')
|
||||
ae(enc(ord('/'), mods=alt), "\x1b" + '/')
|
||||
ae(enc(ord('/'), mods=shift | alt), "\x1b" + '?')
|
||||
ae(enc(ord('/'), mods=ctrl), '/')
|
||||
ae(enc(ord('/'), mods=ctrl | alt), "\x1b" + '/')
|
||||
ae(enc(ord('a')), 'a')
|
||||
ae(enc(ord('a'), mods=shift), 'A')
|
||||
ae(enc(ord('a'), mods=alt), "\x1b" + 'a')
|
||||
ae(enc(ord('a'), mods=shift | alt), "\x1b" + 'A')
|
||||
ae(enc(ord('a'), mods=ctrl), '!')
|
||||
ae(enc(ord('a'), mods=ctrl | alt), "\x1b" + '!')
|
||||
ae(enc(ord('b')), 'b')
|
||||
ae(enc(ord('b'), mods=shift), 'B')
|
||||
ae(enc(ord('b'), mods=alt), "\x1b" + 'b')
|
||||
ae(enc(ord('b'), mods=shift | alt), "\x1b" + 'B')
|
||||
ae(enc(ord('b'), mods=ctrl), '"')
|
||||
ae(enc(ord('b'), mods=ctrl | alt), "\x1b" + '"')
|
||||
ae(enc(ord('c')), 'c')
|
||||
ae(enc(ord('c'), mods=shift), 'C')
|
||||
ae(enc(ord('c'), mods=alt), "\x1b" + 'c')
|
||||
ae(enc(ord('c'), mods=shift | alt), "\x1b" + 'C')
|
||||
ae(enc(ord('c'), mods=ctrl), '#')
|
||||
ae(enc(ord('c'), mods=ctrl | alt), "\x1b" + '#')
|
||||
ae(enc(ord('d')), 'd')
|
||||
ae(enc(ord('d'), mods=shift), 'D')
|
||||
ae(enc(ord('d'), mods=alt), "\x1b" + 'd')
|
||||
ae(enc(ord('d'), mods=shift | alt), "\x1b" + 'D')
|
||||
ae(enc(ord('d'), mods=ctrl), '$')
|
||||
ae(enc(ord('d'), mods=ctrl | alt), "\x1b" + '$')
|
||||
ae(enc(ord('e')), 'e')
|
||||
ae(enc(ord('e'), mods=shift), 'E')
|
||||
ae(enc(ord('e'), mods=alt), "\x1b" + 'e')
|
||||
ae(enc(ord('e'), mods=shift | alt), "\x1b" + 'E')
|
||||
ae(enc(ord('e'), mods=ctrl), '%')
|
||||
ae(enc(ord('e'), mods=ctrl | alt), "\x1b" + '%')
|
||||
ae(enc(ord('f')), 'f')
|
||||
ae(enc(ord('f'), mods=shift), 'F')
|
||||
ae(enc(ord('f'), mods=alt), "\x1b" + 'f')
|
||||
ae(enc(ord('f'), mods=shift | alt), "\x1b" + 'F')
|
||||
ae(enc(ord('f'), mods=ctrl), '&')
|
||||
ae(enc(ord('f'), mods=ctrl | alt), "\x1b" + '&')
|
||||
ae(enc(ord('g')), 'g')
|
||||
ae(enc(ord('g'), mods=shift), 'G')
|
||||
ae(enc(ord('g'), mods=alt), "\x1b" + 'g')
|
||||
ae(enc(ord('g'), mods=shift | alt), "\x1b" + 'G')
|
||||
ae(enc(ord('g'), mods=ctrl), "'")
|
||||
ae(enc(ord('g'), mods=ctrl | alt), "\x1b" + "'")
|
||||
ae(enc(ord('h')), 'h')
|
||||
ae(enc(ord('h'), mods=shift), 'H')
|
||||
ae(enc(ord('h'), mods=alt), "\x1b" + 'h')
|
||||
ae(enc(ord('h'), mods=shift | alt), "\x1b" + 'H')
|
||||
ae(enc(ord('h'), mods=ctrl), '(')
|
||||
ae(enc(ord('h'), mods=ctrl | alt), "\x1b" + '(')
|
||||
ae(enc(ord('i')), 'i')
|
||||
ae(enc(ord('i'), mods=shift), 'I')
|
||||
ae(enc(ord('i'), mods=alt), "\x1b" + 'i')
|
||||
ae(enc(ord('i'), mods=shift | alt), "\x1b" + 'I')
|
||||
ae(enc(ord('i'), mods=ctrl), ')')
|
||||
ae(enc(ord('i'), mods=ctrl | alt), "\x1b" + ')')
|
||||
ae(enc(ord('j')), 'j')
|
||||
ae(enc(ord('j'), mods=shift), 'J')
|
||||
ae(enc(ord('j'), mods=alt), "\x1b" + 'j')
|
||||
ae(enc(ord('j'), mods=shift | alt), "\x1b" + 'J')
|
||||
ae(enc(ord('j'), mods=ctrl), '*')
|
||||
ae(enc(ord('j'), mods=ctrl | alt), "\x1b" + '*')
|
||||
ae(enc(ord('k')), 'k')
|
||||
ae(enc(ord('k'), mods=shift), 'K')
|
||||
ae(enc(ord('k'), mods=alt), "\x1b" + 'k')
|
||||
ae(enc(ord('k'), mods=shift | alt), "\x1b" + 'K')
|
||||
ae(enc(ord('k'), mods=ctrl), '+')
|
||||
ae(enc(ord('k'), mods=ctrl | alt), "\x1b" + '+')
|
||||
ae(enc(ord('l')), 'l')
|
||||
ae(enc(ord('l'), mods=shift), 'L')
|
||||
ae(enc(ord('l'), mods=alt), "\x1b" + 'l')
|
||||
ae(enc(ord('l'), mods=shift | alt), "\x1b" + 'L')
|
||||
ae(enc(ord('l'), mods=ctrl), ',')
|
||||
ae(enc(ord('l'), mods=ctrl | alt), "\x1b" + ',')
|
||||
ae(enc(ord('m')), 'm')
|
||||
ae(enc(ord('m'), mods=shift), 'M')
|
||||
ae(enc(ord('m'), mods=alt), "\x1b" + 'm')
|
||||
ae(enc(ord('m'), mods=shift | alt), "\x1b" + 'M')
|
||||
ae(enc(ord('m'), mods=ctrl), '-')
|
||||
ae(enc(ord('m'), mods=ctrl | alt), "\x1b" + '-')
|
||||
ae(enc(ord('n')), 'n')
|
||||
ae(enc(ord('n'), mods=shift), 'N')
|
||||
ae(enc(ord('n'), mods=alt), "\x1b" + 'n')
|
||||
ae(enc(ord('n'), mods=shift | alt), "\x1b" + 'N')
|
||||
ae(enc(ord('n'), mods=ctrl), '.')
|
||||
ae(enc(ord('n'), mods=ctrl | alt), "\x1b" + '.')
|
||||
ae(enc(ord('o')), 'o')
|
||||
ae(enc(ord('o'), mods=shift), 'O')
|
||||
ae(enc(ord('o'), mods=alt), "\x1b" + 'o')
|
||||
ae(enc(ord('o'), mods=shift | alt), "\x1b" + 'O')
|
||||
ae(enc(ord('o'), mods=ctrl), '/')
|
||||
ae(enc(ord('o'), mods=ctrl | alt), "\x1b" + '/')
|
||||
ae(enc(ord('p')), 'p')
|
||||
ae(enc(ord('p'), mods=shift), 'P')
|
||||
ae(enc(ord('p'), mods=alt), "\x1b" + 'p')
|
||||
ae(enc(ord('p'), mods=shift | alt), "\x1b" + 'P')
|
||||
ae(enc(ord('p'), mods=ctrl), '0')
|
||||
ae(enc(ord('p'), mods=ctrl | alt), "\x1b" + '0')
|
||||
ae(enc(ord('q')), 'q')
|
||||
ae(enc(ord('q'), mods=shift), 'Q')
|
||||
ae(enc(ord('q'), mods=alt), "\x1b" + 'q')
|
||||
ae(enc(ord('q'), mods=shift | alt), "\x1b" + 'Q')
|
||||
ae(enc(ord('q'), mods=ctrl), '1')
|
||||
ae(enc(ord('q'), mods=ctrl | alt), "\x1b" + '1')
|
||||
ae(enc(ord('r')), 'r')
|
||||
ae(enc(ord('r'), mods=shift), 'R')
|
||||
ae(enc(ord('r'), mods=alt), "\x1b" + 'r')
|
||||
ae(enc(ord('r'), mods=shift | alt), "\x1b" + 'R')
|
||||
ae(enc(ord('r'), mods=ctrl), '2')
|
||||
ae(enc(ord('r'), mods=ctrl | alt), "\x1b" + '2')
|
||||
ae(enc(ord('s')), 's')
|
||||
ae(enc(ord('s'), mods=shift), 'S')
|
||||
ae(enc(ord('s'), mods=alt), "\x1b" + 's')
|
||||
ae(enc(ord('s'), mods=shift | alt), "\x1b" + 'S')
|
||||
ae(enc(ord('s'), mods=ctrl), '3')
|
||||
ae(enc(ord('s'), mods=ctrl | alt), "\x1b" + '3')
|
||||
ae(enc(ord('t')), 't')
|
||||
ae(enc(ord('t'), mods=shift), 'T')
|
||||
ae(enc(ord('t'), mods=alt), "\x1b" + 't')
|
||||
ae(enc(ord('t'), mods=shift | alt), "\x1b" + 'T')
|
||||
ae(enc(ord('t'), mods=ctrl), '4')
|
||||
ae(enc(ord('t'), mods=ctrl | alt), "\x1b" + '4')
|
||||
ae(enc(ord('u')), 'u')
|
||||
ae(enc(ord('u'), mods=shift), 'U')
|
||||
ae(enc(ord('u'), mods=alt), "\x1b" + 'u')
|
||||
ae(enc(ord('u'), mods=shift | alt), "\x1b" + 'U')
|
||||
ae(enc(ord('u'), mods=ctrl), '5')
|
||||
ae(enc(ord('u'), mods=ctrl | alt), "\x1b" + '5')
|
||||
ae(enc(ord('v')), 'v')
|
||||
ae(enc(ord('v'), mods=shift), 'V')
|
||||
ae(enc(ord('v'), mods=alt), "\x1b" + 'v')
|
||||
ae(enc(ord('v'), mods=shift | alt), "\x1b" + 'V')
|
||||
ae(enc(ord('v'), mods=ctrl), '6')
|
||||
ae(enc(ord('v'), mods=ctrl | alt), "\x1b" + '6')
|
||||
ae(enc(ord('w')), 'w')
|
||||
ae(enc(ord('w'), mods=shift), 'W')
|
||||
ae(enc(ord('w'), mods=alt), "\x1b" + 'w')
|
||||
ae(enc(ord('w'), mods=shift | alt), "\x1b" + 'W')
|
||||
ae(enc(ord('w'), mods=ctrl), '7')
|
||||
ae(enc(ord('w'), mods=ctrl | alt), "\x1b" + '7')
|
||||
ae(enc(ord('x')), 'x')
|
||||
ae(enc(ord('x'), mods=shift), 'X')
|
||||
ae(enc(ord('x'), mods=alt), "\x1b" + 'x')
|
||||
ae(enc(ord('x'), mods=shift | alt), "\x1b" + 'X')
|
||||
ae(enc(ord('x'), mods=ctrl), '8')
|
||||
ae(enc(ord('x'), mods=ctrl | alt), "\x1b" + '8')
|
||||
ae(enc(ord('y')), 'y')
|
||||
ae(enc(ord('y'), mods=shift), 'Y')
|
||||
ae(enc(ord('y'), mods=alt), "\x1b" + 'y')
|
||||
ae(enc(ord('y'), mods=shift | alt), "\x1b" + 'Y')
|
||||
ae(enc(ord('y'), mods=ctrl), '9')
|
||||
ae(enc(ord('y'), mods=ctrl | alt), "\x1b" + '9')
|
||||
ae(enc(ord('z')), 'z')
|
||||
ae(enc(ord('z'), mods=shift), 'Z')
|
||||
ae(enc(ord('z'), mods=alt), "\x1b" + 'z')
|
||||
ae(enc(ord('z'), mods=shift | alt), "\x1b" + 'Z')
|
||||
ae(enc(ord('z'), mods=ctrl), ':')
|
||||
ae(enc(ord('z'), mods=ctrl | alt), "\x1b" + ':')
|
||||
# end legacy letter tests
|
||||
# }}}
|
||||
|
||||
ae(enc(key=ord(' ')), ' ')
|
||||
ae(enc(key=ord(' '), mods=ctrl), '\0')
|
||||
ae(enc(key=ord('i'), mods=ctrl | shift), csi(ctrl | shift, ord('i')))
|
||||
|
||||
q = partial(enc, key=ord('a'))
|
||||
ae(q(), 'a')
|
||||
ae(q(text='a'), 'a')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user