Get kitty building with the new VT parser

This commit is contained in:
Kovid Goyal
2023-10-29 13:13:11 +05:30
parent b083ad9038
commit 5f809bf249
20 changed files with 1482 additions and 2136 deletions

View File

@@ -11,9 +11,10 @@ from typing import IO, Callable, Dict, List, Mapping, NamedTuple, Optional, Tupl
from .conf.utils import uniq
from .constants import supports_primary_selection
from .fast_data_types import (
ESC_OSC,
GLFW_CLIPBOARD,
GLFW_PRIMARY_SELECTION,
OSC,
find_in_memoryview,
get_boss,
get_clipboard_mime,
get_options,
@@ -335,11 +336,17 @@ class ClipboardRequestManager:
self.currently_asking_permission_for: Optional[ReadRequest] = None
self.in_flight_write_request: Optional[WriteRequest] = None
def parse_osc_5522(self, data: str) -> None:
def parse_osc_5522(self, data: memoryview) -> None:
import base64
from .notify import sanitize_id
metadata, _, epayload = data.partition(';')
idx = find_in_memoryview(data, ord(b';'))
if idx > -1:
metadata = str(data[:idx], "utf-8", "replace")
epayload = data[idx+1:]
else:
metadata = str(data, "utf-8", "replace")
epayload = data[len(data):]
m: Dict[str, str] = {}
for record in metadata.split(':'):
try:
@@ -381,12 +388,12 @@ class ClipboardRequestManager:
wr.add_base64_data(epayload, mime)
except OSError:
if w is not None:
w.screen.send_escape_code_to_child(OSC, wr.encode_response(status='EIO'))
w.screen.send_escape_code_to_child(ESC_OSC, wr.encode_response(status='EIO'))
self.in_flight_write_request = None
raise
except Exception:
if w is not None:
w.screen.send_escape_code_to_child(OSC, wr.encode_response(status='EINVAL'))
w.screen.send_escape_code_to_child(ESC_OSC, wr.encode_response(status='EINVAL'))
self.in_flight_write_request = None
raise
else:
@@ -394,18 +401,24 @@ class ClipboardRequestManager:
wr.commit()
self.in_flight_write_request = None
if w is not None:
w.screen.send_escape_code_to_child(OSC, wr.encode_response(status='DONE'))
w.screen.send_escape_code_to_child(ESC_OSC, wr.encode_response(status='DONE'))
def parse_osc_52(self, data: str, is_partial: bool = False) -> None:
where, text = data.partition(';')[::2]
if text == '?':
def parse_osc_52(self, data: memoryview, is_partial: bool = False) -> None:
idx = find_in_memoryview(data, ord(b';'))
if idx > -1:
where = str(data[idx:], "utf-8", 'replace')
data = data[idx+1:]
else:
where = str(data, "utf-8", 'replace')
data = data[len(data):]
if len(data) == 1 and data.tobytes() == b'?':
rr = ReadRequest(is_primary_selection=ClipboardType.from_osc52_where_field(where) is ClipboardType.primary_selection)
self.handle_read_request(rr)
else:
wr = self.in_flight_write_request
if wr is None:
wr = self.in_flight_write_request = WriteRequest(ClipboardType.from_osc52_where_field(where) is ClipboardType.primary_selection)
wr.add_base64_data(text)
wr.add_base64_data(data)
if is_partial:
return
self.in_flight_write_request = None
@@ -426,7 +439,7 @@ class ClipboardRequestManager:
if not allowed or not cp.enabled:
self.in_flight_write_request = None
if w is not None:
w.screen.send_escape_code_to_child(OSC, wr.encode_response(status='EPERM' if not allowed else 'ENOSYS'))
w.screen.send_escape_code_to_child(ESC_OSC, wr.encode_response(status='EPERM' if not allowed else 'ENOSYS'))
def fulfill_legacy_write_request(self, wr: WriteRequest, allowed: bool = True) -> None:
cp = get_boss().primary_selection if wr.is_primary_selection else get_boss().clipboard
@@ -455,12 +468,12 @@ class ClipboardRequestManager:
return
cp = get_boss().primary_selection if rr.is_primary_selection else get_boss().clipboard
if not cp.enabled:
w.screen.send_escape_code_to_child(OSC, rr.encode_response(status='ENOSYS'))
w.screen.send_escape_code_to_child(ESC_OSC, rr.encode_response(status='ENOSYS'))
return
if not allowed:
w.screen.send_escape_code_to_child(OSC, rr.encode_response(status='EPERM'))
w.screen.send_escape_code_to_child(ESC_OSC, rr.encode_response(status='EPERM'))
return
w.screen.send_escape_code_to_child(OSC, rr.encode_response(status='OK'))
w.screen.send_escape_code_to_child(ESC_OSC, rr.encode_response(status='OK'))
current_mime = ''
@@ -468,7 +481,7 @@ class ClipboardRequestManager:
assert w is not None
mv = memoryview(data)
while mv:
w.screen.send_escape_code_to_child(OSC, rr.encode_response(payload=mv[:4096], mime=current_mime))
w.screen.send_escape_code_to_child(ESC_OSC, rr.encode_response(payload=mv[:4096], mime=current_mime))
mv = mv[4096:]
for mime in rr.mime_types:
@@ -477,20 +490,20 @@ class ClipboardRequestManager:
payload = ' '.join(cp.get_available_mime_types_for_paste()).encode('utf-8')
if payload:
payload += b'\n'
w.screen.send_escape_code_to_child(OSC, rr.encode_response(payload=payload, mime=current_mime))
w.screen.send_escape_code_to_child(ESC_OSC, rr.encode_response(payload=payload, mime=current_mime))
continue
try:
cp.get_mime(mime, write_chunks)
except Exception as e:
log_error(f'Failed to read requested mime type {mime} with error: {e}')
w.screen.send_escape_code_to_child(OSC, rr.encode_response(status='DONE'))
w.screen.send_escape_code_to_child(ESC_OSC, rr.encode_response(status='DONE'))
def reject_read_request(self, rr: ReadRequest) -> None:
if rr.protocol_type is ProtocolType.osc_52:
return self.fulfill_legacy_read_request(rr, False)
w = get_boss().window_id_map.get(self.window_id)
if w is not None:
w.screen.send_escape_code_to_child(OSC, rr.encode_response(status='EPERM'))
w.screen.send_escape_code_to_child(ESC_OSC, rr.encode_response(status='EPERM'))
def fulfill_legacy_read_request(self, rr: ReadRequest, allowed: bool = True) -> None:
cp = get_boss().primary_selection if rr.is_primary_selection else get_boss().clipboard
@@ -500,7 +513,7 @@ class ClipboardRequestManager:
if cp.enabled and allowed:
text = cp.get_text()
loc = 'p' if rr.is_primary_selection else 'c'
w.screen.send_escape_code_to_child(OSC, encode_osc52(loc, text))
w.screen.send_escape_code_to_child(ESC_OSC, encode_osc52(loc, text))
def ask_to_read_clipboard(self, rr: ReadRequest) -> None:
if rr.mime_types == (TARGETS_MIME,):