mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-06 16:05:05 +02:00
DRYer
This commit is contained in:
@@ -757,7 +757,7 @@ Key Value Default Description
|
||||
**Keys for animation frame composition**
|
||||
-----------------------------------------------------------
|
||||
|
||||
``c`` Positive integer ``0`` The 1-based frame number of the frame whose image data serves as the base data
|
||||
``c`` Positive integer ``0`` The 1-based frame number of the frame whose image data serves as the overlaid data
|
||||
``r`` Positive integer ``0`` The 1-based frame number of the frame that is being edited.
|
||||
``x`` Positive integer ``0`` The left edge (in pixels) of the destination rectangle
|
||||
``y`` Positive integer ``0`` The top edge (in pixels) of the destination rectangle
|
||||
|
||||
@@ -11,8 +11,8 @@ from contextlib import suppress
|
||||
from enum import IntEnum
|
||||
from itertools import count
|
||||
from typing import (
|
||||
Any, Callable, DefaultDict, Deque, Dict, Iterator, List, Optional,
|
||||
Sequence, Tuple, Union
|
||||
Any, Callable, ClassVar, DefaultDict, Deque, Dict, Generic, Iterator, List,
|
||||
Optional, Sequence, Tuple, Type, TypeVar, Union, cast
|
||||
)
|
||||
|
||||
from kitty.conf.utils import positive_float, positive_int
|
||||
@@ -299,310 +299,75 @@ def can_display_images() -> bool:
|
||||
|
||||
ImageKey = Tuple[str, int, int]
|
||||
SentImageKey = Tuple[int, int, int]
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
class Alias(Generic[T]):
|
||||
|
||||
currently_processing: ClassVar[str] = ''
|
||||
|
||||
def __init__(self, defval: T) -> None:
|
||||
self.name = ''
|
||||
self.defval = defval
|
||||
|
||||
def __get__(self, instance: Optional['GraphicsCommand'], cls: Optional[Type['GraphicsCommand']] = None) -> T:
|
||||
if instance is None:
|
||||
return self.defval
|
||||
return cast(T, instance._actual_values.get(self.name, self.defval))
|
||||
|
||||
def __set__(self, instance: 'GraphicsCommand', val: T) -> None:
|
||||
if val == self.defval:
|
||||
instance._actual_values.pop(self.name, None)
|
||||
else:
|
||||
instance._actual_values[self.name] = val
|
||||
|
||||
def __set_name__(self, owner: Type['GraphicsCommand'], name: str) -> None:
|
||||
if len(name) == 1:
|
||||
Alias.currently_processing = name
|
||||
self.name = Alias.currently_processing
|
||||
|
||||
|
||||
class GraphicsCommand:
|
||||
a: GRT_a = 't' # action
|
||||
q: int = 0 # suppress responses
|
||||
f: GRT_f = 32 # image data format
|
||||
t: GRT_t = 'd' # transmission medium
|
||||
s: int = 0 # sent image width
|
||||
v: int = 0 # sent image height
|
||||
S: int = 0 # size of data to read from file
|
||||
O: int = 0 # offset of data to read from file
|
||||
i: int = 0 # image id
|
||||
I: int = 0 # image number
|
||||
p: int = 0 # placement id
|
||||
o: Optional[GRT_o] = None # type of compression
|
||||
m: GRT_m = 0 # 0 or 1 whether there is more chunked data
|
||||
x: int = 0 # left edge of image area to display
|
||||
y: int = 0 # top edge of image area to display
|
||||
w: int = 0 # image width to display
|
||||
h: int = 0 # image height to display
|
||||
X: int = 0 # X-offset within cell
|
||||
Y: int = 0 # Y-offset within cell
|
||||
c: int = 0 # number of cols to display image over
|
||||
r: int = 0 # number of rows to display image over
|
||||
z: int = 0 # z-index
|
||||
C: GRT_C = 0 # cursor movement policy/composition mode
|
||||
d: GRT_d = 'a' # what to delete
|
||||
|
||||
@property
|
||||
def action(self) -> GRT_a:
|
||||
return self.a
|
||||
|
||||
@action.setter
|
||||
def action(self, val: GRT_a) -> None:
|
||||
self.a = val
|
||||
|
||||
@property
|
||||
def transmission_type(self) -> GRT_t:
|
||||
return self.t
|
||||
|
||||
@transmission_type.setter
|
||||
def transmission_type(self, val: GRT_t) -> None:
|
||||
self.t = val
|
||||
|
||||
@property
|
||||
def compressed(self) -> Optional[GRT_o]:
|
||||
return self.o
|
||||
|
||||
@compressed.setter
|
||||
def compressed(self, val: Optional[GRT_o]) -> None:
|
||||
self.o = val
|
||||
|
||||
@property
|
||||
def delete_action(self) -> Optional[GRT_d]:
|
||||
return self.d
|
||||
|
||||
@delete_action.setter
|
||||
def delete_action(self, val: GRT_d) -> None:
|
||||
self.d = val
|
||||
|
||||
@delete_action.setter
|
||||
def delete_action(self, val: GRT_d) -> None:
|
||||
self.d = val
|
||||
|
||||
@property
|
||||
def format(self) -> GRT_f:
|
||||
return self.f
|
||||
|
||||
@format.setter
|
||||
def format(self, val: GRT_f) -> None:
|
||||
self.f = val
|
||||
|
||||
@property
|
||||
def more(self) -> GRT_m:
|
||||
return self.m
|
||||
|
||||
@more.setter
|
||||
def more(self, val: GRT_m) -> None:
|
||||
self.m = val
|
||||
|
||||
@property
|
||||
def image_id(self) -> int:
|
||||
return self.i
|
||||
|
||||
@image_id.setter
|
||||
def image_id(self, val: int) -> None:
|
||||
self.i = val
|
||||
|
||||
@property
|
||||
def image_number(self) -> int:
|
||||
return self.I
|
||||
|
||||
@image_number.setter
|
||||
def image_number(self, val: int) -> None:
|
||||
self.I = val # noqa
|
||||
|
||||
@property
|
||||
def placement_id(self) -> int:
|
||||
return self.p
|
||||
|
||||
@placement_id.setter
|
||||
def placement_id(self, val: int) -> None:
|
||||
self.p = val
|
||||
|
||||
@property
|
||||
def data_size(self) -> int:
|
||||
return self.S
|
||||
|
||||
@data_size.setter
|
||||
def data_size(self, val: int) -> None:
|
||||
self.S = val
|
||||
|
||||
@property
|
||||
def data_offset(self) -> int:
|
||||
return self.O
|
||||
|
||||
@data_offset.setter
|
||||
def data_offset(self, val: int) -> None:
|
||||
self.O = val # noqa
|
||||
|
||||
@property
|
||||
def quiet(self) -> int:
|
||||
return self.q
|
||||
|
||||
@quiet.setter
|
||||
def quiet(self, val: int) -> None:
|
||||
self.q = val
|
||||
|
||||
@property
|
||||
def width(self) -> int:
|
||||
return self.w
|
||||
|
||||
@width.setter
|
||||
def width(self, val: int) -> None:
|
||||
self.w = val
|
||||
|
||||
@property
|
||||
def height(self) -> int:
|
||||
return self.h
|
||||
|
||||
@height.setter
|
||||
def height(self, val: int) -> None:
|
||||
self.h = val
|
||||
|
||||
@property
|
||||
def left_edge(self) -> int:
|
||||
return self.x
|
||||
|
||||
@left_edge.setter
|
||||
def left_edge(self, val: int) -> None:
|
||||
self.x = val
|
||||
|
||||
@property
|
||||
def top_edge(self) -> int:
|
||||
return self.y
|
||||
|
||||
@top_edge.setter
|
||||
def top_edge(self, val: int) -> None:
|
||||
self.y = val
|
||||
|
||||
@property
|
||||
def cursor_movement(self) -> GRT_C:
|
||||
return self.C
|
||||
|
||||
@cursor_movement.setter
|
||||
def cursor_movement(self, val: GRT_C) -> None:
|
||||
self.C = val
|
||||
|
||||
@property
|
||||
def compose_mode(self) -> GRT_C:
|
||||
return self.C
|
||||
|
||||
@compose_mode.setter
|
||||
def compose_mode(self, val: GRT_C) -> None:
|
||||
self.C = val
|
||||
|
||||
@property
|
||||
def cell_x_offset(self) -> int:
|
||||
return self.X
|
||||
|
||||
@cell_x_offset.setter
|
||||
def cell_x_offset(self, val: int) -> None:
|
||||
self.X = val
|
||||
|
||||
@property
|
||||
def blend_mode(self) -> int:
|
||||
return self.X
|
||||
|
||||
@blend_mode.setter
|
||||
def blend_mode(self, val: int) -> None:
|
||||
self.X = val
|
||||
|
||||
@property
|
||||
def cell_y_offset(self) -> int:
|
||||
return self.Y
|
||||
|
||||
@cell_y_offset.setter
|
||||
def cell_y_offset(self, val: int) -> None:
|
||||
self.Y = val
|
||||
|
||||
@property
|
||||
def bgcolor(self) -> int:
|
||||
return self.Y
|
||||
|
||||
@bgcolor.setter
|
||||
def bgcolor(self, val: int) -> None:
|
||||
self.Y = val
|
||||
|
||||
@property
|
||||
def data_width(self) -> int:
|
||||
return self.s
|
||||
|
||||
@data_width.setter
|
||||
def data_width(self, val: int) -> None:
|
||||
self.s = val
|
||||
|
||||
@property
|
||||
def animation_state(self) -> int:
|
||||
return self.s
|
||||
|
||||
@animation_state.setter
|
||||
def animation_state(self, val: int) -> None:
|
||||
self.s = val
|
||||
|
||||
@property
|
||||
def data_height(self) -> int:
|
||||
return self.v
|
||||
|
||||
@data_height.setter
|
||||
def data_height(self, val: int) -> None:
|
||||
self.v = val
|
||||
|
||||
@property
|
||||
def loop_count(self) -> int:
|
||||
return self.v
|
||||
|
||||
@loop_count.setter
|
||||
def loop_count(self, val: int) -> None:
|
||||
self.v = val
|
||||
|
||||
@property
|
||||
def num_lines(self) -> int:
|
||||
return self.r
|
||||
|
||||
@num_lines.setter
|
||||
def num_lines(self, val: int) -> None:
|
||||
self.r = val
|
||||
|
||||
@property
|
||||
def frame_number(self) -> int:
|
||||
return self.r
|
||||
|
||||
@frame_number.setter
|
||||
def frame_number(self, val: int) -> None:
|
||||
self.r = val
|
||||
|
||||
@property
|
||||
def num_cells(self) -> int:
|
||||
return self.c
|
||||
|
||||
@num_cells.setter
|
||||
def num_cells(self, val: int) -> None:
|
||||
self.c = val
|
||||
|
||||
@property
|
||||
def other_frame_number(self) -> int:
|
||||
return self.c
|
||||
|
||||
@other_frame_number.setter
|
||||
def other_frame_number(self, val: int) -> None:
|
||||
self.c = val
|
||||
|
||||
@property
|
||||
def z_index(self) -> int:
|
||||
return self.z
|
||||
|
||||
@z_index.setter
|
||||
def z_index(self, val: int) -> None:
|
||||
self.z = val
|
||||
|
||||
@property
|
||||
def gap(self) -> int:
|
||||
return self.z
|
||||
|
||||
@gap.setter
|
||||
def gap(self, val: int) -> None:
|
||||
self.z = val
|
||||
a = action = Alias(cast(GRT_a, 't'))
|
||||
q = quiet = Alias(0)
|
||||
f = format = Alias(32)
|
||||
t = transmission_type = Alias(cast(GRT_t, 'd'))
|
||||
s = data_width = animation_state = Alias(0)
|
||||
v = data_height = loop_count = Alias(0)
|
||||
S = data_size = Alias(0)
|
||||
O = data_offset = Alias(0) # noqa
|
||||
i = image_id = Alias(0)
|
||||
I = image_number = Alias(0) # noqa
|
||||
p = placement_id = Alias(0)
|
||||
o = compression = Alias(cast(Optional[GRT_o], None))
|
||||
m = more = Alias(cast(GRT_m, 0))
|
||||
x = left_edge = Alias(0)
|
||||
y = top_edge = Alias(0)
|
||||
w = width = Alias(0)
|
||||
h = height = Alias(0)
|
||||
X = cell_x_offset = blend_mode = Alias(0)
|
||||
Y = cell_y_offset = bgcolor = Alias(0)
|
||||
c = columns = other_frame_number = Alias(0)
|
||||
r = rows = frame_number = Alias(0)
|
||||
z = z_index = gap = Alias(0)
|
||||
C = cursor_movement = compose_mode = Alias(cast(GRT_C, 0))
|
||||
d = delete_action = Alias(cast(GRT_d, 'a'))
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._actual_values: Dict[str, Any] = {}
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return self.serialize().decode('ascii').replace('\033', '^]')
|
||||
|
||||
def clone(self) -> 'GraphicsCommand':
|
||||
ans = GraphicsCommand()
|
||||
for k in GraphicsCommand.__annotations__:
|
||||
setattr(ans, k, getattr(self, k))
|
||||
ans._actual_values = self._actual_values.copy()
|
||||
return ans
|
||||
|
||||
def serialize(self, payload: Union[bytes, str] = b'') -> bytes:
|
||||
items = []
|
||||
for k in GraphicsCommand.__annotations__:
|
||||
val: Union[str, None, int] = getattr(self, k)
|
||||
defval: Union[str, None, int] = getattr(GraphicsCommand, k)
|
||||
if val != defval and val is not None:
|
||||
items.append('{}={}'.format(k, val))
|
||||
for k, val in self._actual_values.items():
|
||||
items.append('{}={}'.format(k, val))
|
||||
|
||||
ans: List[bytes] = []
|
||||
w = ans.append
|
||||
@@ -617,9 +382,7 @@ class GraphicsCommand:
|
||||
return b''.join(ans)
|
||||
|
||||
def clear(self) -> None:
|
||||
for k in GraphicsCommand.__annotations__:
|
||||
defval: Union[str, None, int] = getattr(GraphicsCommand, k)
|
||||
setattr(self, k, defval)
|
||||
self._actual_values = {}
|
||||
|
||||
def iter_transmission_chunks(self, data: Optional[bytes] = None, level: int = -1, compression_threshold: int = 1024) -> Iterator[bytes]:
|
||||
if data is None:
|
||||
|
||||
Reference in New Issue
Block a user