Simplify the protocol for the send-text remote command

This commit is contained in:
Kovid Goyal 2020-03-12 07:14:47 +05:30
parent 2ebdf738ca
commit 21707171bb
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -2,9 +2,10 @@
# vim:fileencoding=utf-8 # vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net> # License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
import base64
import os import os
import sys import sys
from typing import TYPE_CHECKING, Generator, Dict from typing import TYPE_CHECKING, Dict, Generator
from kitty.config import parse_send_text_bytes from kitty.config import parse_send_text_bytes
@ -20,8 +21,7 @@ if TYPE_CHECKING:
class SendText(RemoteCommand): class SendText(RemoteCommand):
''' '''
text+: The text being sent data+: The data being sent. Can be either: text: followed by text or base64: followed by standard base64 encoded bytes
is_binary+: If False text is interpreted as a python string literal instead of plain text
match: A string indicating the window to send text to match: A string indicating the window to send text to
match_tab: A string indicating the tab to send text to match_tab: A string indicating the tab to send text to
''' '''
@ -49,7 +49,7 @@ are sent as is, not interpreted for escapes.
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType: def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
limit = 1024 limit = 1024
ret = {'match': opts.match, 'is_binary': False, 'match_tab': opts.match_tab} ret = {'match': opts.match, 'data': '', 'match_tab': opts.match_tab}
def pipe() -> Generator[Dict, None, None]: def pipe() -> Generator[Dict, None, None]:
if sys.stdin.isatty(): if sys.stdin.isatty():
@ -67,32 +67,30 @@ are sent as is, not interpreted for escapes.
if '\x04' in decoded_data: if '\x04' in decoded_data:
decoded_data = decoded_data[:decoded_data.index('\x04')] decoded_data = decoded_data[:decoded_data.index('\x04')]
keep_going = False keep_going = False
ret['text'] = decoded_data ret['data'] = 'text:' + decoded_data
yield ret yield ret
else: else:
ret['is_binary'] = True
while True: while True:
data = sys.stdin.buffer.read(limit) data = sys.stdin.buffer.read(limit)
if not data: if not data:
break break
ret['text'] = data[:limit] ret['data'] = 'base64:' + base64.standard_b64encode(data).decode('ascii')
yield ret yield ret
def chunks(text: str) -> Generator[Dict, None, None]: def chunks(text: str) -> Generator[Dict, None, None]:
ret['is_binary'] = False data = parse_send_text_bytes(text).decode('utf-8')
while text: while data:
ret['text'] = text[:limit] ret['data'] = 'text:' + data[:limit]
yield ret yield ret
text = text[limit:] data = data[limit:]
def file_pipe(path: str) -> Generator[Dict, None, None]: def file_pipe(path: str) -> Generator[Dict, None, None]:
ret['is_binary'] = True with open(path, 'rb') as f:
with open(path, encoding='utf-8') as f:
while True: while True:
data = f.read(limit) data = f.read(limit)
if not data: if not data:
break break
ret['text'] = data ret['data'] = 'base64:' + base64.standard_b64encode(data).decode('ascii')
yield ret yield ret
sources = [] sources = []
@ -123,8 +121,13 @@ are sent as is, not interpreted for escapes.
raise MatchError(payload_get('match_tab'), 'tabs') raise MatchError(payload_get('match_tab'), 'tabs')
for tab in tabs: for tab in tabs:
windows += tuple(tab) windows += tuple(tab)
data = payload_get('text').encode('utf-8') if payload_get('is_binary') else parse_send_text_bytes( encoding, _, q = payload_get('data').partition(':')
payload_get('text')) if encoding == 'text':
data = q.encode('utf-8')
elif encoding == 'base64':
data = base64.standard_b64decode(q)
else:
raise TypeError(f'Invalid encoding for send-text data: {encoding}')
for window in windows: for window in windows:
if window is not None: if window is not None:
window.write_to_child(data) window.write_to_child(data)