Allow sending more than a screenful of output from a kitten

Also Fixes #4866
This commit is contained in:
Kovid Goyal 2022-03-23 14:33:53 +05:30
parent 49c335972f
commit 1be1864657
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 16 additions and 24 deletions

View File

@ -95,22 +95,15 @@ def launch(args: List[str]) -> None:
print(reset_mode(Mode.ALTERNATE_SCREEN) + clear_screen(), end='') print(reset_mode(Mode.ALTERNATE_SCREEN) + clear_screen(), end='')
if result is not None: if result is not None:
import json import json
data = json.dumps(result) import base64
print('OK:', len(data), data) 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.stderr.flush()
sys.stdout.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: def run_kitten(kitten: str, run_name: str = '__main__') -> None:
import runpy import runpy
original_kitten_name = kitten original_kitten_name = kitten

View File

@ -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] 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) 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( def _run_kitten(
self, self,
kitten: str, kitten: str,
@ -1462,9 +1453,7 @@ class Boss:
source_window: Window, source_window: Window,
default_data: Optional[Dict[str, Any]] = None default_data: Optional[Dict[str, Any]] = None
) -> None: ) -> None:
output = self.get_output(source_window, num_lines=None) data = getattr(source_window, 'kitten_result', None)
from kittens.runner import deserialize
data = deserialize(output)
if data is None: if data is None:
data = default_data data = default_data
if data is not None: if data is not None:

View File

@ -1082,6 +1082,7 @@ dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
Py_DECREF(msg); \ Py_DECREF(msg); \
} else PyErr_Clear(); } 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-print|", screen_handle_print)
} else IF_SIMPLE_PREFIX("kitty-echo|", screen_handle_echo) } else IF_SIMPLE_PREFIX("kitty-echo|", screen_handle_echo)
} else IF_SIMPLE_PREFIX("kitty-ssh|", screen_handle_ssh) } else IF_SIMPLE_PREFIX("kitty-ssh|", screen_handle_ssh)

View File

@ -2129,6 +2129,10 @@ screen_handle_askpass(Screen *self, PyObject *msg) {
CALLBACK("handle_remote_askpass", "O", msg); CALLBACK("handle_remote_askpass", "O", msg);
} }
void
screen_handle_kitten_result(Screen *self, PyObject *msg) {
CALLBACK("handle_kitten_result", "O", msg);
}
void void
screen_request_capabilities(Screen *self, char c, PyObject *q) { screen_request_capabilities(Screen *self, char c, PyObject *q) {

View File

@ -212,6 +212,7 @@ void screen_handle_print(Screen *, PyObject *cmd);
void screen_handle_echo(Screen *, PyObject *cmd); void screen_handle_echo(Screen *, PyObject *cmd);
void screen_handle_ssh(Screen *, PyObject *cmd); void screen_handle_ssh(Screen *, PyObject *cmd);
void screen_handle_askpass(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_designate_charset(Screen *, uint32_t which, uint32_t as);
void screen_use_latin1(Screen *, bool); void screen_use_latin1(Screen *, bool);
void set_title(Screen *self, PyObject*); void set_title(Screen *self, PyObject*);

View File

@ -936,6 +936,10 @@ class Window:
for line in get_ssh_data(msg, f'{os.getpid()}-{self.id}'): for line in get_ssh_data(msg, f'{os.getpid()}-{self.id}'):
self.write_to_child(line) 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: def handle_remote_askpass(self, msg: str) -> None:
from .shm import SharedMemory from .shm import SharedMemory
with SharedMemory(name=msg, readonly=True) as shm: with SharedMemory(name=msg, readonly=True) as shm: