From 121de4193029b2a1b4825fb0bad3a088d812b595 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 17 Nov 2017 01:25:58 +0530 Subject: [PATCH] Make send_text a normal keybaord shortcut action Uses the new support for arguments to shortcut actions. Fixes #173 --- kitty/config.py | 10 ++++++++-- kitty/kitty.conf | 8 +++++--- kitty/window.py | 14 +++++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/kitty/config.py b/kitty/config.py index 49dce121a..cd5f653c3 100644 --- a/kitty/config.py +++ b/kitty/config.py @@ -107,6 +107,8 @@ def parse_key_action(action): sep, rest = rest.split(' ', 1) parts = re.split(r'\s*' + re.escape(sep) + r'\s*', rest) args = tuple(map(parse_key_action, filter(None, parts))) + elif func == 'send_text': + args = rest.split(' ', 1) elif func in shlex_actions: args = shlex.split(rest) return KeyAction(func, args) @@ -169,6 +171,10 @@ def parse_symbol_map(val): return symbol_map +def parse_send_text_bytes(text): + return ast.literal_eval("'''" + text + "'''").encode('utf-8') + + def parse_send_text(val): parts = val.split(' ') @@ -187,7 +193,7 @@ def parse_send_text(val): mods, key = parse_shortcut(sc.strip()) if key is None: return abort('Invalid shortcut') - text = ast.literal_eval("'''" + text + "'''").encode('utf-8') + text = parse_send_text_bytes(text) if not text: return abort('Empty text') @@ -325,7 +331,7 @@ with open( defaults = parse_config(f.readlines(), check_keys=False) Options = namedtuple('Defaults', ','.join(defaults.keys())) defaults = Options(**defaults) -actions = frozenset(a.func for a in defaults.keymap.values()) | frozenset({'combine'}) +actions = frozenset(a.func for a in defaults.keymap.values()) | frozenset({'combine', 'send_text'}) no_op_actions = frozenset({'noop', 'no-op', 'no_op'}) diff --git a/kitty/kitty.conf b/kitty/kitty.conf index c50d0ab97..aaaced882 100644 --- a/kitty/kitty.conf +++ b/kitty/kitty.conf @@ -285,7 +285,7 @@ map ctrl+shift+f11 toggle_fullscreen # Sending arbitrary text on shortcut key presses # You can tell kitty to send arbitrary (UTF-8) encoded text to # the client program when pressing specified shortcut keys. For example: -# send_text all ctrl+alt+a Special text +# map ctrl+alt+a send_text all Special text # This will send "Special text" when you press the Ctrl+Alt+a key combination. # The text to be sent is a python string literal so you can use escapes like # \x1b to send control codes or \u21fb to send unicode characters (or you can @@ -296,8 +296,10 @@ map ctrl+shift+f11 toggle_fullscreen # the DECCKM cursor key mode for terminals, and kitty refers to the special kitty # extended keyboard protocol. Another example, that outputs a word and then moves the cursor # to the start of the line (same as pressing the Home key): -# send_text normal ctrl+alt+a Word\x1b[H -# send_text application ctrl+alt+a Word\x1bOH +# map ctrl+alt+a send_text normal Word\x1b[H +# map ctrl+alt+a send_text application Word\x1bOH +# There is also a legacy syntax for send_text, which looks like: +# send_text all ctrl+alt+a some text # Symbol mapping (special font for specified unicode code points). Map the # specified unicode codepoints to a particular font. Useful if you need special diff --git a/kitty/window.py b/kitty/window.py index e4c63af9b..e9044a60e 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -8,7 +8,7 @@ from collections import deque from enum import Enum from itertools import count -from .config import build_ansi_color_table +from .config import build_ansi_color_table, parse_send_text_bytes from .constants import ( ScreenGeometry, WindowGeometry, appname, cell_size, get_boss, viewport_size, wakeup @@ -21,6 +21,7 @@ from .fast_data_types import ( glfw_post_empty_event, init_cell_program, init_cursor_program, remove_vao, set_window_render_data, update_window_title, update_window_visibility ) +from .keys import keyboard_mode_name from .rgb import to_color from .terminfo import get_capabilities from .utils import color_as_int, load_shaders, parse_color_set, sanitize_title, open_url, open_cmd @@ -143,6 +144,17 @@ class Window: boss.gui_close_window(self) self.screen = None + def send_text(self, *args): + mode = keyboard_mode_name(self.screen) + required_mode, text = args[-2:] + required_mode = frozenset(required_mode.split(',')) + if not required_mode & {mode, 'all'}: + return True + data = parse_send_text_bytes(text) + if not data: + return True + self.write_to_child(data) + def write_to_child(self, data): if data: if get_boss().child_monitor.needs_write(self.id, data) is not True: