A simple action to remap key presses sent to programs running in kitty

This commit is contained in:
Kovid Goyal 2023-12-03 13:08:53 +05:30
parent f1fc2126bc
commit 74388b4183
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
5 changed files with 49 additions and 24 deletions

View file

@ -48,6 +48,9 @@ Detailed list of changes
- A new option :opt:`notify_on_cmd_finish` to show a desktop notification when a long running command finishes (:pull:`6817`)
- A new action :ac:`send_key` to simplify mapping key presses to other keys without needing :ac:`send_text`
0.31.0 [2023-11-08]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -389,20 +389,14 @@ How do I map key presses in kitty to different keys in the terminal program?
This is accomplished by using ``map`` with :sc:`send_text <send_text>` in :file:`kitty.conf`.
For example::
map alt+s send_text normal,application \x13
map alt+s send_key ctrl+s
This maps :kbd:`alt+s` to :kbd:`ctrl+s`. To figure out what bytes to use for
the :sc:`send_text <send_text>` you can use the ``show_key`` kitten. Run::
This causes the program running in kitty to receive the :kbd:`ctrl+s` key when
you press the :kbd:`alt+s` key. To see this in action, run::
kitten show_key
kitten show-key -m kitty
Then press the key you want to emulate. Note that this kitten will only show
keys that actually reach the terminal program, in particular, keys mapped to
actions in kitty will not be shown. To check those first map them to
:ac:`no_op`. You can also start a kitty instance without any shortcuts to
interfere::
kitty -o clear_all_shortcuts=yes kitten show_key
Which will print out what key events it receives.
How do I open a new window or tab with the same working directory as the current window?

View file

@ -215,23 +215,16 @@ also simulate pressing the enter key which is ``\r``. For example::
Now, if you press :kbd:`f1` when at shell prompt it will run the ``echo Hello,
world!`` command.
To have one key press send another key press::
To have one key press send another key press, use :ac:`send_key`::
map alt+s send_text normal,application \x13
map alt+s send_key ctrl+s
This maps :kbd:`alt+s` to :kbd:`ctrl+s`. To figure out what bytes to use for
the :sc:`send_text <send_text>` you can use the ``show_key`` kitten. Run::
This causes the program running in kitty to receive the :kbd:`ctrl+s` key when
you press the :kbd:`alt+s` key. To see this in action, run::
kitten show_key
kitten show-key -m kitty
Then press the key you want to emulate. Note that this kitten will only show
keys that actually reach the terminal program, in particular, keys mapped to
actions in kitty will not be shown. To check those first unmap them.
You can also start a kitty instance without any shortcuts to interfere:
.. code-block:: sh
kitty -o clear_all_shortcuts=yes kitten show_key
Which will print out what key events it receives.
All mappable actions
------------------------

View file

@ -89,6 +89,11 @@ def send_text_parse(func: str, rest: str) -> FuncArgsType:
return func, [mode, data]
@func_with_args('send_key')
def send_key(func: str, rest: str) -> FuncArgsType:
return func, rest.split()
@func_with_args('run_kitten', 'run_simple_kitten', 'kitten')
def kitten_parse(func: str, rest: str) -> FuncArgsType:
if func == 'kitten':

View file

@ -46,6 +46,8 @@
CURSOR_UNDERLINE,
DCS,
GLFW_MOD_CONTROL,
GLFW_PRESS,
GLFW_RELEASE,
NO_CURSOR_SHAPE,
OSC,
SCROLL_FULL,
@ -871,6 +873,34 @@ def send_text(self, *args: str) -> bool:
self.write_to_child(text)
return False
@ac(
'misc', '''
Send the specified keys to the active window.
Note that the key will be sent only if the current keyboard mode of the program running in the terminal supports it.
Both key press and key release are sent. First presses for all specified keys and then releases in reverse order.
To send a pattern of press and release for multiple keys use the :ac:`combine` action. For example::
map f1 send_key ctrl+x alt+y
map f1 combine : send_key ctrl+x : send_key ctrl+y
''')
def send_key(self, *args: str) -> bool:
from .options.utils import parse_shortcut
km = get_options().kitty_mod
passthrough = True
events = []
for human_key in args:
sk = parse_shortcut(human_key)
if sk.is_native:
raise ValueError(f'Native key codes not allowed in send_key: {human_key}')
sk = sk.resolve_kitty_mod(km)
events.append(KeyEvent(key=sk.key, mods=sk.mods, action=GLFW_PRESS))
for ev in events + [KeyEvent(key=x.key, mods=x.mods, action=GLFW_RELEASE) for x in reversed(events)]:
enc = self.encoded_key(ev)
if enc:
self.write_to_child(enc)
passthrough = False
return passthrough
@ac('debug', 'Show a dump of the current lines in the scrollback + screen with their line attributes')
def dump_lines_with_attrs(self) -> None:
strings: List[str] = []