From 9e361700d231356445827337acba39c530b78590 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 7 Jan 2018 16:17:42 +0530 Subject: [PATCH] Handle reading of RC response via stdin --- kitty/boss.py | 2 +- kitty/remote_control.py | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index 8c51b35aa..5e745061b 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -130,7 +130,7 @@ class Boss: if self.opts.allow_remote_control: pass else: - response = {'ok': False, 'err': 'NOT_ALLOWED'} + response = {'ok': False, 'error': 'Remote control is disabled. Add allow_remote_control yes to your kitty.conf'} if response is not None: if window is not None: window.send_cmd_response(response) diff --git a/kitty/remote_control.py b/kitty/remote_control.py index 08626e142..5ada9b5c5 100644 --- a/kitty/remote_control.py +++ b/kitty/remote_control.py @@ -3,11 +3,13 @@ # License: GPL v3 Copyright: 2018, Kovid Goyal import json +import re import sys from functools import partial from kitty.cli import emph, parse_args from kitty.constants import appname, version +from kitty.utils import read_with_timeout def cmd(short_desc, desc=None, options_spec=None): @@ -36,6 +38,30 @@ global_options_spec = partial('''\ '''.format, appname=appname) +def read_from_stdin(send): + send = ('@kitty-cmd' + json.dumps(send)).encode('ascii') + if not sys.stdout.isatty(): + raise SystemExit('stdout is not a terminal') + sys.stdout.buffer.write(b'\x1bP' + send + b'\x1b\\') + sys.stdout.flush() + + received = b'' + dcs = re.compile(br'\x1bP@kitty-cmd([^\x1b]+)\x1b\\') + match = None + + def more_needed(data): + nonlocal received, match + received += data + match = dcs.search(received) + return match is None + + read_with_timeout(more_needed) + if match is None: + raise SystemExit('Failed to receive response from ' + appname) + response = json.loads(match.group(1).decode('ascii')) + return response + + def main(args): cmap = {k[4:]: v for k, v in globals().items() if k.startswith('cmd_')} all_commands = tuple(sorted(cmap)) @@ -66,8 +92,8 @@ def main(args): } if payload is not None: send['payload'] = payload - send = ('@kitty-cmd' + json.dumps(send)).encode('ascii') - if not sys.stdout.isatty(): - raise SystemExit('stdout is not a terminal') - sys.stdout.buffer.write(b'\x1bP' + send + b'\x1b\\') - sys.stdout.flush() + response = read_from_stdin(send) + if not response.get('ok'): + if response.get('tb'): + print(response['tb'], file=sys.stderr) + raise SystemExit(response['error'])