Spec for extended keyboard protocol
This commit is contained in:
parent
b6c0eb0909
commit
48a2a395c4
@ -21,7 +21,7 @@
|
||||
:sc_next_window: pass:quotes[`ctrl+shift+]`]
|
||||
:sc_ninth_window: pass:quotes[`ctrl+shift+9`]
|
||||
:sc_paste_from_clipboard: pass:quotes[`ctrl+shift+v`]
|
||||
:sc_paste_from_selection: pass:quotes[`ctrl+shift+s`]
|
||||
:sc_paste_from_selection: pass:quotes[`ctrl+shift+s` or `shift+insert`]
|
||||
:sc_previous_tab: pass:quotes[`ctrl+shift+left`]
|
||||
:sc_previous_window: pass:quotes[`ctrl+shift+[`]
|
||||
:sc_scroll_end: pass:quotes[`ctrl+shift+end`]
|
||||
|
||||
126
key_encoding.asciidoc
Normal file
126
key_encoding.asciidoc
Normal file
@ -0,0 +1,126 @@
|
||||
= Key encoding for extended keyboard protocol
|
||||
|
||||
|===
|
||||
| Name | Number |
|
||||
|
||||
| 0 | 48 |
|
||||
| 1 | 49 |
|
||||
| 2 | 50 |
|
||||
| 3 | 51 |
|
||||
| 4 | 52 |
|
||||
| 5 | 53 |
|
||||
| 6 | 54 |
|
||||
| 7 | 55 |
|
||||
| 8 | 56 |
|
||||
| 9 | 57 |
|
||||
| A | 65 |
|
||||
| APOSTROPHE | 39 |
|
||||
| B | 66 |
|
||||
| BACKSLASH | 92 |
|
||||
| BACKSPACE | 259 |
|
||||
| C | 67 |
|
||||
| CAPS_LOCK | 280 |
|
||||
| COMMA | 44 |
|
||||
| D | 68 |
|
||||
| DELETE | 261 |
|
||||
| DOWN | 264 |
|
||||
| E | 69 |
|
||||
| END | 269 |
|
||||
| ENTER | 257 |
|
||||
| EQUAL | 61 |
|
||||
| ESCAPE | 256 |
|
||||
| F | 70 |
|
||||
| F1 | 290 |
|
||||
| F10 | 299 |
|
||||
| F11 | 300 |
|
||||
| F12 | 301 |
|
||||
| F13 | 302 |
|
||||
| F14 | 303 |
|
||||
| F15 | 304 |
|
||||
| F16 | 305 |
|
||||
| F17 | 306 |
|
||||
| F18 | 307 |
|
||||
| F19 | 308 |
|
||||
| F2 | 291 |
|
||||
| F20 | 309 |
|
||||
| F21 | 310 |
|
||||
| F22 | 311 |
|
||||
| F23 | 312 |
|
||||
| F24 | 313 |
|
||||
| F25 | 314 |
|
||||
| F3 | 292 |
|
||||
| F4 | 293 |
|
||||
| F5 | 294 |
|
||||
| F6 | 295 |
|
||||
| F7 | 296 |
|
||||
| F8 | 297 |
|
||||
| F9 | 298 |
|
||||
| G | 71 |
|
||||
| GRAVE_ACCENT | 96 |
|
||||
| H | 72 |
|
||||
| HOME | 268 |
|
||||
| I | 73 |
|
||||
| INSERT | 260 |
|
||||
| J | 74 |
|
||||
| K | 75 |
|
||||
| KP_0 | 320 |
|
||||
| KP_1 | 321 |
|
||||
| KP_2 | 322 |
|
||||
| KP_3 | 323 |
|
||||
| KP_4 | 324 |
|
||||
| KP_5 | 325 |
|
||||
| KP_6 | 326 |
|
||||
| KP_7 | 327 |
|
||||
| KP_8 | 328 |
|
||||
| KP_9 | 329 |
|
||||
| KP_ADD | 334 |
|
||||
| KP_DECIMAL | 330 |
|
||||
| KP_DIVIDE | 331 |
|
||||
| KP_ENTER | 335 |
|
||||
| KP_EQUAL | 336 |
|
||||
| KP_MULTIPLY | 332 |
|
||||
| KP_SUBTRACT | 333 |
|
||||
| L | 76 |
|
||||
| LEFT | 263 |
|
||||
| LEFT_ALT | 342 |
|
||||
| LEFT_BRACKET | 91 |
|
||||
| LEFT_CONTROL | 341 |
|
||||
| LEFT_SHIFT | 340 |
|
||||
| LEFT_SUPER | 343 |
|
||||
| M | 77 |
|
||||
| MINUS | 45 |
|
||||
| N | 78 |
|
||||
| NUM_LOCK | 282 |
|
||||
| O | 79 |
|
||||
| P | 80 |
|
||||
| PAGE_DOWN | 267 |
|
||||
| PAGE_UP | 266 |
|
||||
| PAUSE | 284 |
|
||||
| PERIOD | 46 |
|
||||
| PRINT_SCREEN | 283 |
|
||||
| Q | 81 |
|
||||
| R | 82 |
|
||||
| RIGHT | 262 |
|
||||
| RIGHT_ALT | 346 |
|
||||
| RIGHT_BRACKET | 93 |
|
||||
| RIGHT_CONTROL | 345 |
|
||||
| RIGHT_SHIFT | 344 |
|
||||
| RIGHT_SUPER | 347 |
|
||||
| S | 83 |
|
||||
| SCROLL_LOCK | 281 |
|
||||
| SEMICOLON | 59 |
|
||||
| SLASH | 47 |
|
||||
| SPACE | 32 |
|
||||
| T | 84 |
|
||||
| TAB | 258 |
|
||||
| U | 85 |
|
||||
| UP | 265 |
|
||||
| V | 86 |
|
||||
| W | 87 |
|
||||
| WORLD_1 | 161 |
|
||||
| WORLD_2 | 162 |
|
||||
| X | 88 |
|
||||
| Y | 89 |
|
||||
| Z | 90 |
|
||||
|
||||
|===
|
||||
@ -109,3 +109,13 @@ def interpret_text_event(codepoint, mods):
|
||||
def get_shortcut(keymap, mods, key, scancode):
|
||||
key = get_localized_key(key, scancode)
|
||||
return keymap.get((mods & 0b1111, key))
|
||||
|
||||
|
||||
def key_integer_map():
|
||||
ans = {}
|
||||
for k in dir(defines):
|
||||
if k.startswith('GLFW_KEY_'):
|
||||
val = getattr(defines, k)
|
||||
if val < defines.GLFW_KEY_LAST and val != defines.GLFW_KEY_UNKNOWN:
|
||||
ans[k[9:]] = val
|
||||
return ans
|
||||
|
||||
@ -2,14 +2,15 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from collections import defaultdict
|
||||
|
||||
base = os.path.dirname(os.path.abspath(__file__))
|
||||
os.chdir(base)
|
||||
|
||||
|
||||
defns = defaultdict(list)
|
||||
|
||||
for line in open('kitty/kitty.conf'):
|
||||
@ -17,13 +18,32 @@ for line in open('kitty/kitty.conf'):
|
||||
_, sc, name = line.split(maxsplit=3)
|
||||
defns[name].append('`' + sc + '`')
|
||||
|
||||
defns = [':sc_{}: pass:quotes[{}]'.format(name, ' or '.join(defns[name])) for name in sorted(defns)]
|
||||
defns = [
|
||||
':sc_{}: pass:quotes[{}]'.format(name, ' or '.join(defns[name]))
|
||||
for name in sorted(defns)
|
||||
]
|
||||
defns = '\n'.join(defns)
|
||||
|
||||
raw = open('README.asciidoc').read()
|
||||
pat = re.compile(r'^// START_SHORTCUT_BLOCK$.+?^// END_SHORTCUT_BLOCK$', re.M | re.DOTALL)
|
||||
nraw = pat.sub('// START_SHORTCUT_BLOCK\n' +
|
||||
defns + '\n// END_SHORTCUT_BLOCK', raw)
|
||||
pat = re.compile(
|
||||
r'^// START_SHORTCUT_BLOCK$.+?^// END_SHORTCUT_BLOCK$', re.M | re.DOTALL
|
||||
)
|
||||
nraw = pat.sub(
|
||||
'// START_SHORTCUT_BLOCK\n' + defns + '\n// END_SHORTCUT_BLOCK', raw
|
||||
)
|
||||
if raw != nraw:
|
||||
print('Updating shortcuts block')
|
||||
open('README.asciidoc', 'w').write(nraw)
|
||||
|
||||
raw = subprocess.check_output([
|
||||
'kitty', '-c',
|
||||
'from kitty.keys import *; import json; print(json.dumps(key_integer_map()))'
|
||||
]).decode('utf-8')
|
||||
key_map = json.loads(raw)
|
||||
lines = ['|===', '| Name | Number |', '']
|
||||
for k in sorted(key_map):
|
||||
lines.append('| {:15s} | {:4d} |'.format(k, key_map[k]))
|
||||
lines += ['', '|===']
|
||||
with open('key_encoding.asciidoc', 'w') as f:
|
||||
print('= Key encoding for extended keyboard protocol\n', file=f)
|
||||
print('\n'.join(lines), file=f)
|
||||
|
||||
@ -301,3 +301,78 @@ the file repeatedly with no overhead.
|
||||
| y | _y-offset_ -- the row in the pixel data to start from (0-based)
|
||||
|
||||
|===
|
||||
|
||||
|
||||
== Keyboard handling
|
||||
|
||||
There are various problems with the current state of keyboard handling. They
|
||||
include:
|
||||
|
||||
* No way to use modifiers other than `Ctrl` and `Alt`
|
||||
* No reliable way to distinguish single `Esc` keypresses from the
|
||||
start of a escape sequence. Currently, client programs use
|
||||
fragile timing related hacks for this, leading to bugs, for example:
|
||||
link:https://github.com/neovim/neovim/issues/2035[neovim #2035]
|
||||
|
||||
There are already two distinct keyboard handling modes, _normal mode_ and
|
||||
_application mode_. These modes generate different escape sequences for the
|
||||
various special keys (arrow keys, function keys, home/end etc.) Most terminals
|
||||
start out in normal mode, however, most shell programs like `bash` switch them to
|
||||
application mode. We propose adding a third mode, named _full mode_ that addresses
|
||||
the shortcomings listed above.
|
||||
|
||||
Switching to the new _full mode_ is accomplished using the standard private
|
||||
mode DECSET escape sequence
|
||||
|
||||
```
|
||||
<ESC>[?2017h
|
||||
```
|
||||
|
||||
and to leave _full mode_, use DECRST
|
||||
|
||||
```
|
||||
<ESC>[?2017l
|
||||
```
|
||||
|
||||
The number `2017` above is not used for any existing modes, as far as I know.
|
||||
Client programs can query if the terminal emulator is in _full mode_ by using
|
||||
the standard link:http://vt100.net/docs/vt510-rm/DECRQM[DECRQM] escape sequence.
|
||||
|
||||
The new mode works as follows:
|
||||
|
||||
* All printable key presses without modifier keys are sent just as in the
|
||||
_normal mode_. This means all printable ASCII characters and in addition,
|
||||
`Enter`, `Space` and `Backspace`. Also any unicode characters generated by
|
||||
platform specific extended input modes, such as using the `AltGr` key. This
|
||||
is done so that client programs that are not aware of this mode can still
|
||||
handle basic text entry, so if a _full mode_ using program crashes and does
|
||||
not reset, the user can still issue a `reset` command in the shell to restore
|
||||
normal key handling. Note that this includes pressing the `Shift` modifier
|
||||
and printable keys.
|
||||
|
||||
* For non printable keys and key combinations including one or more modifiers,
|
||||
an escape sequence encoding the key event is sent. For details on the
|
||||
escape sequence, see below.
|
||||
|
||||
The escape sequence encodes the following properties:
|
||||
|
||||
* Type of event: `press,repeat,release`
|
||||
* Modifiers pressed at the time of the event
|
||||
* The actual key being pressed
|
||||
|
||||
```
|
||||
<ESC>_K<type><modifiers>:<key><ESC>\
|
||||
```
|
||||
|
||||
Where `<type>` is one of `p` -- press, `r` -- release and `t` -- repeat.
|
||||
Modifiers is zero or more of `c` -- Control, `a` -- Alt, `s` -- Shift and `m` -- Meta.
|
||||
`<key>` is a number corresponding to the key pressed. The key name to number mapping
|
||||
is defined in link:key_encoding.asciidoc[this table].
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
<ESC>_Kpca:88<ESC>\
|
||||
```
|
||||
|
||||
Is the key press event `<Ctrl>+<Alt>+x`.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user