From e43d894dda413c154737ef863d195c552dd08a2f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 19 Aug 2025 21:53:49 +0530 Subject: [PATCH] Add a --match argument to limit what windows are saved by save_as_session --- kitty/boss.py | 3 ++- kitty/session.py | 7 +++++++ kitty/tabs.py | 11 ++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index f25c1e0e0..b7de57897 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -504,10 +504,11 @@ def list_os_windows( def serialize_state_as_session(self, session_path: str = '', ser_opts: SaveAsSessionOptions | None = None) -> Iterator[str]: if ser_opts is None: ser_opts = default_save_as_session_opts() + matched_windows = frozenset(self.match_windows(ser_opts.match)) if ser_opts.match else None s = {current_focused_os_window_id(): 2, last_focused_os_window_id(): 1} for i, os_window_id in enumerate(sorted(self.os_window_map, key=lambda wid: s.get(wid, 0))): tm = self.os_window_map[os_window_id] - yield from tm.serialize_state_as_session(session_path, is_first=i==0, ser_opts=ser_opts) + yield from tm.serialize_state_as_session(session_path, matched_windows, is_first=i==0, ser_opts=ser_opts) @property def all_tab_managers(self) -> Iterator[TabManager]: diff --git a/kitty/session.py b/kitty/session.py index 0fa5855a0..4e5b2809d 100644 --- a/kitty/session.py +++ b/kitty/session.py @@ -510,6 +510,13 @@ def save_as_session_options() -> str: When saving the working directory for windows, do so as paths relative to the directory in which the session file will be saved. This allows the session file to work even when its containing directory is moved elsewhere. + + +--match +If specified, only save all windows (and their parent tabs/OS Windows) that match the specified +search expression. See :ref:`search_syntax` for details on the search language. In particular if +you want to only save windows that are present in the currently active session, +use :code:`--match=session:.`. ''' diff --git a/kitty/tabs.py b/kitty/tabs.py index e1f08c691..63ad8e4d9 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -295,7 +295,7 @@ def serialize_state(self) -> dict[str, Any]: 'name': self.name, } - def serialize_state_as_session(self, session_path: str, ser_opts: SaveAsSessionOptions) -> list[str]: + def serialize_state_as_session(self, session_path: str, matched_windows: frozenset[Window] | None, ser_opts: SaveAsSessionOptions) -> list[str]: import shlex launch_cmds = [] active_idx = self.windows.active_group_idx @@ -311,6 +311,8 @@ def make_relative(cwd: str) -> str: for i, g in enumerate(groups): gw: list[str] = [] for window in g: + if matched_windows is not None and window not in matched_windows: + continue cwd = cwds[window.id] lc = window.as_launch_command(ser_opts, '' if cwd == most_common_cwd else cwd, is_overlay=bool(gw)) if lc: @@ -1227,7 +1229,10 @@ def serialize_state(self) -> dict[str, Any]: 'active_tab_idx': self.active_tab_idx, } - def serialize_state_as_session(self, session_path: str, ser_opts: SaveAsSessionOptions, is_first: bool = False) -> list[str]: + def serialize_state_as_session( + self, session_path: str, matched_windows: frozenset[Window] | None, ser_opts: SaveAsSessionOptions, + is_first: bool = False + ) -> list[str]: ans = [] hmap = {tab_id: i for i, tab_id in enumerate(self.active_tab_history)} if (at := self.active_tab) is not None: @@ -1235,7 +1240,7 @@ def serialize_state_as_session(self, session_path: str, ser_opts: SaveAsSessionO def skey(tab: Tab) -> int: return hmap.get(tab.id, -1) for tab in sorted(self, key=skey): - ans.extend(tab.serialize_state_as_session(session_path, ser_opts)) + ans.extend(tab.serialize_state_as_session(session_path, matched_windows, ser_opts)) if ans: prefix = [] if is_first else ['', '', 'new_os_window'] if self.wm_class and self.wm_class != appname: