mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 08:26:56 +00:00
Implement unserialization for splits layout
Also cleanup the serialization code.
This commit is contained in:
parent
f64182e16c
commit
c4ed1d3b69
5 changed files with 68 additions and 24 deletions
|
|
@ -10,7 +10,7 @@ from kitty.borders import BorderColor
|
|||
from kitty.fast_data_types import Region, set_active_window, viewport_for_window
|
||||
from kitty.options.types import Options
|
||||
from kitty.types import Edges, WindowGeometry
|
||||
from kitty.typing_compat import TypedDict, WindowType
|
||||
from kitty.typing_compat import TypedDict, WindowMapper, WindowType
|
||||
from kitty.window_list import WindowGroup, WindowList
|
||||
|
||||
|
||||
|
|
@ -436,3 +436,17 @@ class Layout:
|
|||
|
||||
def layout_state(self) -> dict[str, Any]:
|
||||
return {}
|
||||
|
||||
def set_layout_state(self, layout_state: dict[str, Any], map_window_id: WindowMapper) -> bool:
|
||||
return True
|
||||
|
||||
def serialize(self) -> dict[str, Any]:
|
||||
ans = self.layout_state()
|
||||
ans['opts'] = self.layout_opts.serialized()
|
||||
ans['class'] = self.__class__.__name__
|
||||
return ans
|
||||
|
||||
def unserialize(self, s: dict[str, Any], map_window_id: WindowMapper) -> bool:
|
||||
if s.get('class') != self.__class__.__name__:
|
||||
return False
|
||||
return self.set_layout_state(s, map_window_id)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from collections.abc import Collection, Generator, Sequence
|
||||
from typing import Any, NamedTuple, Optional, Union
|
||||
from typing import Any, NamedTuple, Optional, TypedDict, Union
|
||||
|
||||
from kitty.borders import BorderColor
|
||||
from kitty.types import Edges, WindowGeometry
|
||||
from kitty.typing_compat import EdgeLiteral, WindowType
|
||||
from kitty.typing_compat import EdgeLiteral, WindowMapper, WindowType
|
||||
from kitty.window_list import WindowGroup, WindowList
|
||||
|
||||
from .base import BorderLine, Layout, LayoutOpts, NeighborsMap, blank_rects_for_window, lgd, window_geometry_from_layouts
|
||||
|
|
@ -17,6 +17,13 @@ class Extent(NamedTuple):
|
|||
end: int = 0
|
||||
|
||||
|
||||
class SerializedPair(TypedDict, total=False):
|
||||
horizontal: bool # default to True if absent
|
||||
bias: float # default to 0.5 if absent
|
||||
one: Union[int, 'SerializedPair'] # default to None if absent
|
||||
two: Union[int, 'SerializedPair'] # default to None if absent
|
||||
|
||||
|
||||
class Pair:
|
||||
|
||||
def __init__(self, horizontal: bool = True):
|
||||
|
|
@ -28,6 +35,34 @@ class Pair:
|
|||
self.between_borders: list[Edges] = []
|
||||
self.first_extent = self.second_extent = Extent()
|
||||
|
||||
def serialize(self) -> SerializedPair:
|
||||
ans: SerializedPair = {}
|
||||
if not self.horizontal:
|
||||
ans['horizontal'] = False
|
||||
if self.bias != 0.5:
|
||||
ans['bias'] = self.bias
|
||||
if self.one is not None:
|
||||
ans['one'] = self.one.serialize() if isinstance(self.one, Pair) else self.one
|
||||
if self.two is not None:
|
||||
ans['two'] = self.two.serialize() if isinstance(self.two, Pair) else self.two
|
||||
return ans
|
||||
|
||||
def unserialize(self, s: SerializedPair, map_window_id: WindowMapper) -> None:
|
||||
self.bias = s.get('bias', 0.5)
|
||||
self.horizontal = s.get('horizontal', True)
|
||||
|
||||
def unserialize(x: int | SerializedPair | None) -> int | Pair | None:
|
||||
if x is None:
|
||||
return None
|
||||
if isinstance(x, int):
|
||||
w = map_window_id(x)
|
||||
return None if w is None else w.id
|
||||
ans = Pair()
|
||||
ans.unserialize(x, map_window_id)
|
||||
return ans if ans.one or ans.two else None
|
||||
self.one = unserialize(s.get('one'))
|
||||
self.two = unserialize(s.get('two'))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return 'Pair(horizontal={}, bias={:.2f}, one={}, two={}, between_borders={})'.format(
|
||||
self.horizontal, self.bias, self.one, self.two, self.between_borders)
|
||||
|
|
@ -673,19 +708,13 @@ class Splits(Layout):
|
|||
return None
|
||||
|
||||
def layout_state(self) -> dict[str, Any]:
|
||||
return {'pairs': self.pairs_root.serialize(), 'opts': self.layout_opts.serialized()}
|
||||
|
||||
def add_pair(p: Pair) -> dict[str, Any]:
|
||||
ans: dict[str, Any] = {}
|
||||
ans['horizontal'] = p.horizontal
|
||||
ans['bias'] = p.bias
|
||||
if isinstance(p.one, Pair):
|
||||
ans['one'] = add_pair(p.one)
|
||||
elif p.one is not None:
|
||||
ans['one'] = p.one
|
||||
if isinstance(p.two, Pair):
|
||||
ans['two'] = add_pair(p.two)
|
||||
elif p.two is not None:
|
||||
ans['two'] = p.two
|
||||
return ans
|
||||
|
||||
return {'pairs': add_pair(self.pairs_root)}
|
||||
def set_layout_state(self, layout_state: dict[str, Any], map_window_id: WindowMapper) -> bool:
|
||||
new_root = Pair()
|
||||
new_root.unserialize(layout_state['pairs'], map_window_id)
|
||||
if new_root.one or new_root.two:
|
||||
self.pairs_root = new_root
|
||||
self.layout_opts = SplitsLayoutOpts(layout_state['opts'])
|
||||
return True
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -272,8 +272,7 @@ class Tab: # {{{
|
|||
'window_list': self.windows.serialize_state(),
|
||||
'current_layout': self._current_layout_name,
|
||||
'last_used_layout': self._last_used_layout,
|
||||
'layout_opts': self.current_layout.layout_opts,
|
||||
'layout_state': self.current_layout.layout_state,
|
||||
'layout_state': self.current_layout.serialize(),
|
||||
'enabled_layouts': self.enabled_layouts,
|
||||
'name': self.name,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ ScreenSize = KittensKeyActionType = MouseEvent = MouseButton = AbstractEventLoop
|
|||
TermManagerType = LoopType = Debug = GraphicsCommandType = object
|
||||
ReadableBuffer = WriteableBuffer = bytearray
|
||||
|
||||
CompletedProcess = tuple
|
||||
CompletedProcess = object
|
||||
TypedDict = dict
|
||||
EdgeLiteral = str
|
||||
UnderlineLiteral = str
|
||||
|
|
@ -21,5 +21,6 @@ PowerlineStyle = str
|
|||
MatchType = str
|
||||
Protocol = object
|
||||
OptionsProtocol = object
|
||||
NotRequired = tuple
|
||||
NotRequired = object
|
||||
CoreTextFont = FontConfigPattern = dict
|
||||
WindowMapper = object
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from socket import AddressFamily as AddressFamily
|
|||
from socket import socket as Socket
|
||||
from subprocess import CompletedProcess as CompletedProcess
|
||||
from subprocess import Popen as PopenType
|
||||
from typing import Literal
|
||||
from typing import Callable, Literal
|
||||
from typing import NotRequired as NotRequired
|
||||
from typing import Protocol as Protocol
|
||||
from typing import TypedDict as TypedDict
|
||||
|
|
@ -54,6 +54,7 @@ GRT_C = Literal[0, 1]
|
|||
GRT_d = Literal['a', 'A', 'c', 'C', 'i', 'I', 'p', 'P', 'q', 'Q', 'x', 'X', 'y', 'Y', 'z', 'Z', 'f', 'F']
|
||||
ReadableBuffer = bytes | bytearray | memoryview | array.array[int] | mmap.mmap
|
||||
WriteableBuffer = bytearray | memoryview | array.array[int] | mmap.mmap
|
||||
WindowMapper = Callable[[int], WindowType | None]
|
||||
|
||||
|
||||
|
||||
|
|
@ -71,5 +72,5 @@ __all__ = (
|
|||
'KeyActionType', 'KeyMap', 'KittyCommonOpts', 'AliasMap', 'CoreTextFont', 'WindowSystemMouseEvent',
|
||||
'FontConfigPattern', 'ScreenType', 'StartupCtx', 'KeyEventType', 'LayoutType', 'PowerlineStyle',
|
||||
'RemoteCommandType', 'SessionType', 'SessionTab', 'SpecialWindowInstance', 'TabType', 'ScreenSize', 'WindowType',
|
||||
'ReadableBuffer', 'WriteableBuffer',
|
||||
'ReadableBuffer', 'WriteableBuffer', 'WindowMapper',
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue