diff --git a/kittens/runner.py b/kittens/runner.py index 6fa5e9016..22752702c 100644 --- a/kittens/runner.py +++ b/kittens/runner.py @@ -95,22 +95,15 @@ def launch(args: List[str]) -> None: print(reset_mode(Mode.ALTERNATE_SCREEN) + clear_screen(), end='') if result is not None: import json - data = json.dumps(result) - print('OK:', len(data), data) + import base64 + data = base64.b85encode(json.dumps(result).encode('utf-8')) + sys.stdout.buffer.write(b'\x1bP@kitty-kitten-result|') + sys.stdout.buffer.write(data) + sys.stdout.buffer.write(b'\x1b\\') sys.stderr.flush() sys.stdout.flush() -def deserialize(output: str) -> Any: - import json - if output.startswith('OK: '): - try: - prefix, sz, rest = output.split(' ', 2) - return json.loads(rest[:int(sz)]) - except Exception: - raise ValueError(f'Failed to parse kitten output: {output!r}') - - def run_kitten(kitten: str, run_name: str = '__main__') -> None: import runpy original_kitten_name = kitten diff --git a/kitty/boss.py b/kitty/boss.py index 67aae6f43..7cfe0484f 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -1364,15 +1364,6 @@ class Boss: cmd = [kitty_exe(), '+runpy', 'import os, sys, time; time.sleep(0.05); os.execvp(sys.argv[1], sys.argv[1:])'] + get_editor(get_options()) + [confpath] self.new_os_window(*cmd) - def get_output(self, source_window: Window, num_lines: Optional[int] = 1) -> str: - output = '' - s = source_window.screen - if num_lines is None: - num_lines = s.lines - for i in range(min(num_lines, s.lines)): - output += str(s.linebuf.line(i)) - return output - def _run_kitten( self, kitten: str, @@ -1462,9 +1453,7 @@ class Boss: source_window: Window, default_data: Optional[Dict[str, Any]] = None ) -> None: - output = self.get_output(source_window, num_lines=None) - from kittens.runner import deserialize - data = deserialize(output) + data = getattr(source_window, 'kitten_result', None) if data is None: data = default_data if data is not None: diff --git a/kitty/parser.c b/kitty/parser.c index 1b7ea3993..1e488c58d 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -1082,6 +1082,7 @@ dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) { Py_DECREF(msg); \ } else PyErr_Clear(); + } else IF_SIMPLE_PREFIX("kitty-kitten-result|", screen_handle_kitten_result) } else IF_SIMPLE_PREFIX("kitty-print|", screen_handle_print) } else IF_SIMPLE_PREFIX("kitty-echo|", screen_handle_echo) } else IF_SIMPLE_PREFIX("kitty-ssh|", screen_handle_ssh) diff --git a/kitty/screen.c b/kitty/screen.c index 8ab43e287..c8f761c79 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -2129,6 +2129,10 @@ screen_handle_askpass(Screen *self, PyObject *msg) { CALLBACK("handle_remote_askpass", "O", msg); } +void +screen_handle_kitten_result(Screen *self, PyObject *msg) { + CALLBACK("handle_kitten_result", "O", msg); +} void screen_request_capabilities(Screen *self, char c, PyObject *q) { diff --git a/kitty/screen.h b/kitty/screen.h index c081b2518..8349ecad7 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -212,6 +212,7 @@ void screen_handle_print(Screen *, PyObject *cmd); void screen_handle_echo(Screen *, PyObject *cmd); void screen_handle_ssh(Screen *, PyObject *cmd); void screen_handle_askpass(Screen *, PyObject *cmd); +void screen_handle_kitten_result(Screen *, PyObject *cmd); void screen_designate_charset(Screen *, uint32_t which, uint32_t as); void screen_use_latin1(Screen *, bool); void set_title(Screen *self, PyObject*); diff --git a/kitty/window.py b/kitty/window.py index 7accc33d6..6ec01db6b 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -936,6 +936,10 @@ class Window: for line in get_ssh_data(msg, f'{os.getpid()}-{self.id}'): self.write_to_child(line) + def handle_kitten_result(self, msg: str) -> None: + import base64 + self.kitten_result: Dict[str, Any] = json.loads(base64.b85decode(msg)) + def handle_remote_askpass(self, msg: str) -> None: from .shm import SharedMemory with SharedMemory(name=msg, readonly=True) as shm: