Implement session command to set layout state

This commit is contained in:
Kovid Goyal 2025-08-06 20:30:00 +05:30
parent bc8fc6642c
commit 97f1d7f436
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
3 changed files with 14 additions and 3 deletions

View file

@ -354,6 +354,7 @@ class Tall(Layout):
def set_layout_state(self, layout_state: dict[str, Any], map_group_id: WindowMapper) -> bool:
self.main_bias = layout_state['main_bias']
self.biased_map = layout_state['biased_map']
self.layout_opts = TallLayoutOpts(layout_state['opts'])
return True

View file

@ -1,13 +1,14 @@
#!/usr/bin/env python
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
import json
import os
import shlex
import sys
from collections.abc import Callable, Generator, Iterator, Mapping
from contextlib import suppress
from functools import partial
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, Any, Optional, Union
from .cli_stub import CLIOptions
from .layout.interface import all_layouts
@ -58,6 +59,7 @@ class Tab:
self.active_window_idx = 0
self.enabled_layouts = opts.enabled_layouts
self.layout = (self.enabled_layouts or ['tall'])[0]
self.layout_state: dict[str, Any] | None = None
self.cwd: str | None = None
self.next_title: str | None = None
@ -101,6 +103,9 @@ class Session:
raise ValueError(f'{val} is not a valid layout')
self.tabs[-1].layout = val
def set_layout_state(self, val: str) -> None:
self.tabs[-1].layout_state = json.loads(val)
def add_window(self, cmd: None | str | list[str], expand: Callable[[str], str] = lambda x: x) -> None:
from .launch import parse_launch_args
needs_expandvars = False
@ -185,7 +190,7 @@ def parse_session(raw: str, opts: Options, environ: Mapping[str, str] | None = N
else:
cmd, rest = parts
cmd, rest = cmd.strip(), rest.strip()
if cmd != 'launch':
if cmd not in ('launch', 'set_layout_state'):
rest = expand(rest)
if cmd == 'new_tab':
ans.add_tab(opts, rest)
@ -220,6 +225,8 @@ def parse_session(raw: str, opts: Options, environ: Mapping[str, str] | None = N
ans.resize_window(rest.split())
elif cmd == 'focus_matching_window':
ans.focus_matching_window(rest)
elif cmd == 'set_layout_state':
ans.set_layout_state(rest)
else:
raise ValueError(f'Unknown command in session file: {cmd}')
yield finalize_session(ans)

View file

@ -237,7 +237,7 @@ class Tab: # {{{
self._current_layout_name = layout_name
self.mark_tab_bar_dirty()
def startup(self, session_tab: 'SessionTab') -> None:
def startup(self, session_tab: SessionTab) -> None:
target_tab = self
boss = get_boss()
for window in session_tab.windows:
@ -264,6 +264,9 @@ class Tab: # {{{
with suppress(IndexError):
self.windows.set_active_window_group_for(self.windows.all_windows[session_tab.active_window_idx])
if session_tab.layout_state:
if self.current_layout.unserialize(session_tab.layout_state, self.windows):
self.relayout()
def serialize_state(self) -> dict[str, Any]:
return {