kitty/kittens/show_key/main.py
2023-01-09 16:47:42 +05:30

89 lines
2.5 KiB
Python

#!/usr/bin/env python
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
import os
import sys
from typing import List
from kittens.tui.operations import raw_mode, styled
from kitty.cli import parse_args
from kitty.cli_stub import ShowKeyCLIOptions
ctrl_keys = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'
def print_key(raw: bytearray) -> None:
unix = ''
for ch in raw:
if ch < len(ctrl_keys):
unix += f'^{ctrl_keys[ch]}'
elif ch == 127:
unix += '^?'
else:
unix += chr(ch)
print(unix + '\t\t', end='')
for ch in raw:
x = chr(ch).encode('utf-8')
print(styled(repr(x)[2:-1], fg='yellow'), end='')
print(end='\r\n', flush=True)
def read_keys() -> None:
fd = sys.stdin.fileno()
while True:
try:
raw = bytearray(os.read(fd, 64))
except OSError as err:
print(err, file=sys.stderr, flush=True)
break
if not raw:
break
print_key(raw)
if len(raw) == 1 and raw[0] == 4:
break
def legacy_main() -> None:
print('Press any keys - Ctrl+D will terminate this program', end='\r\n', flush=True)
print(styled('UNIX', italic=True, fg='green'), styled('send_text', italic=True, fg='green'), sep='\t\t', end='\r\n')
with raw_mode():
read_keys()
OPTIONS = r'''
--key-mode -m
default=normal
type=choices
choices=normal,application,kitty,unchanged
The keyboard mode to use when showing keys. :code:`normal` mode is with DECCKM
reset and :code:`application` mode is with DECCKM set. :code:`kitty` is the full
kitty extended keyboard protocol.
'''.format
help_text = 'Show the codes generated by the terminal for key presses in various keyboard modes'
usage = ''
def main(args: List[str]) -> None:
cli_opts, items = parse_args(args[1:], OPTIONS, '', help_text, 'kitty +kitten show_key', result_class=ShowKeyCLIOptions)
if cli_opts.key_mode == 'kitty':
from .kitty_mode import main as kitty_main
return kitty_main()
if cli_opts.key_mode != 'unchanged':
print(end='\x1b[?1' + ('l' if cli_opts.key_mode == 'normal' else 'h'), flush=True)
try:
return legacy_main()
finally:
if cli_opts.key_mode != 'unchanged':
print(end='\x1b[?1l', flush=True)
if __name__ == '__main__':
main(sys.argv)
elif __name__ == '__doc__':
cd = sys.cli_docs # type: ignore
cd['usage'] = usage
cd['options'] = OPTIONS
cd['help_text'] = help_text