Skip to content

Commit d06ef1c

Browse files
committed
generate session
1 parent 5ed241f commit d06ef1c

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

kitty/boss.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,15 +477,14 @@ def add_os_panel(self, cfg: LayerShellConfig, wclass: str | None = appname, wnam
477477
def list_os_windows(
478478
self, self_window: Window | None = None,
479479
tab_filter: Callable[[Tab], bool] | None = None,
480-
window_filter: Callable[[Window], bool] | None = None,
481-
output_session: bool | None = None,
480+
window_filter: Callable[[Window], bool] | None = None
482481
) -> Iterator[OSWindowDict]:
483482
with cached_process_data():
484483
active_tab_manager = self.active_tab_manager
485484
focused_wid = current_focused_os_window_id()
486485
last_focused = last_focused_os_window_id()
487486
for os_window_id, tm in self.os_window_map.items():
488-
tabs = list(tm.list_tabs(self_window, tab_filter, window_filter, output_session))
487+
tabs = list(tm.list_tabs(self_window, tab_filter, window_filter))
489488
if tabs:
490489
bo = background_opacity_of(os_window_id)
491490
if bo is None:

kitty/rc/ls.py

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
33

44
import json
5+
import os
56
from collections.abc import Callable
6-
from typing import TYPE_CHECKING
7+
from typing import TYPE_CHECKING, Sequence
78

89
from kitty.constants import appname
910

1011
from .base import MATCH_TAB_OPTION, MATCH_WINDOW_OPTION, ArgsType, Boss, PayloadGetType, PayloadType, RCOptions, RemoteCommand, ResponseType, Tab, Window
12+
from ..boss import OSWindowDict
13+
from ..child import ProcessDesc
1114

1215
if TYPE_CHECKING:
1316
from kitty.cli_stub import LSRCOptions as CLIOptions
@@ -19,7 +22,7 @@ class LS(RemoteCommand):
1922
match/str: Window to change colors in
2023
match_tab/str: Tab to change colors in
2124
self/bool: Boolean indicating whether to list only the window the command is run in
22-
output_session/bool: Output session
25+
output_format/str: Output in json or session format
2326
'''
2427

2528
short_desc = 'List tabs/windows'
@@ -44,9 +47,11 @@ class LS(RemoteCommand):
4447
Only list the window this command is run in.
4548
4649
47-
--output-session
48-
type=bool-set
49-
Output session
50+
--output-format
51+
type=choices
52+
choices=json,session
53+
default=json
54+
Output in json or session format
5055
''' + '\n\n' + MATCH_WINDOW_OPTION + '\n\n' + MATCH_TAB_OPTION.replace('--match -m', '--match-tab -t', 1)
5156

5257
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
@@ -55,7 +60,7 @@ def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: Arg
5560
def response_from_kitty(self, boss: Boss, window: Window | None, payload_get: PayloadGetType) -> ResponseType:
5661
tab_filter: Callable[[Tab], bool] | None = None
5762
window_filter: Callable[[Window], bool] | None = None
58-
output_session: bool | None = None
63+
output_session: bool = False
5964

6065
if payload_get('self'):
6166
def wf(w: Window) -> bool:
@@ -66,9 +71,9 @@ def wf(w: Window) -> bool:
6671
def wf(w: Window) -> bool:
6772
return w.id in window_ids
6873
window_filter = wf
69-
elif payload_get('output_session'):
74+
elif payload_get('output_format') == 'session':
7075
output_session = True
71-
data = list(boss.list_os_windows(window, tab_filter, window_filter, output_session))
76+
data = list(boss.list_os_windows(window, tab_filter, window_filter))
7277
if not payload_get('all_env_vars'):
7378
all_env_blocks: list[dict[str, str]] = []
7479
common_env_vars: set[tuple[str, str]] = set()
@@ -87,7 +92,51 @@ def wf(w: Window) -> bool:
8792
for env in all_env_blocks:
8893
for r in remove_env_vars:
8994
env.pop(r, None)
90-
return json.dumps(data, indent=2, sort_keys=True)
95+
if not output_session:
96+
return json.dumps(data, indent=2, sort_keys=True)
97+
return self.convert_to_session(data)
98+
99+
def convert_to_session(self, data: list[OSWindowDict]) -> str:
100+
'''Convert a kitty session dict, into a kitty session file and output it.'''
101+
session = []
102+
first = True
103+
for osw in data:
104+
if first:
105+
first = False
106+
else:
107+
session.append('\nnew_os_window\n')
108+
109+
for tab in osw['tabs']:
110+
session.append(f'new_tab {tab["title"]}\n')
111+
session.append(f'layout {tab["layout"]}\n')
112+
session.append('\n')
113+
114+
for w in tab['windows']:
115+
session.append(f'cd {w["cwd"]}\n')
116+
session.append(f'launch --var=kitty_serialize_window_id={w["id"]} {self.env_to_str(w["env"])}\n')
117+
if w['is_focused']:
118+
session.append('focus\n')
119+
session.append('\n')
120+
layout_state = json.dumps(tab['layout_state'])
121+
session.append(f'set_layout_state {layout_state}\n')
122+
return ''.join(session)
123+
124+
def env_to_str(self, env: dict[str, str]):
125+
'''Convert an env list to a series of '--env key=value' parameters and return as a string.'''
126+
s = ''
127+
for key in env:
128+
s += f'--env "{key}={env[key]}" '
129+
130+
return s.strip()
131+
132+
def cmdline_to_str(self, cmdline: Sequence[str] | None):
133+
'''Convert a cmdline list to a space separated string.'''
134+
s = ''
135+
if cmdline:
136+
for e in cmdline:
137+
s += f'{e} '
138+
139+
return s.strip()
91140

92141

93142
ls = LS()

kitty/tabs.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,8 +1120,7 @@ def __len__(self) -> int:
11201120
def list_tabs(
11211121
self, self_window: Window | None = None,
11221122
tab_filter: Callable[[Tab], bool] | None = None,
1123-
window_filter: Callable[[Window], bool] | None = None,
1124-
output_session: bool | None = None,
1123+
window_filter: Callable[[Window], bool] | None = None
11251124
) -> Generator[TabDict, None, None]:
11261125
active_tab = self.active_tab
11271126
for tab in self:
@@ -1134,7 +1133,7 @@ def list_tabs(
11341133
'is_active': tab is active_tab,
11351134
'title': tab.name or tab.title,
11361135
'layout': str(tab.current_layout.name),
1137-
'layout_state': tab.current_layout.serialize(tab.windows) if output_session else tab.current_layout.layout_state(),
1136+
'layout_state': tab.current_layout.serialize(tab.windows),
11381137
'layout_opts': tab.current_layout.layout_opts.serialized(),
11391138
'enabled_layouts': tab.enabled_layouts,
11401139
'windows': windows,

0 commit comments

Comments
 (0)