Skip to content

Commit 92ff8f9

Browse files
committed
kitty @ ls output session
1 parent 9a2de7b commit 92ff8f9

File tree

3 files changed

+51
-22
lines changed

3 files changed

+51
-22
lines changed

kitty/rc/ls.py

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
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
14+
from ..launch import is_excluded_env_var
1115

1216
if TYPE_CHECKING:
1317
from kitty.cli_stub import LSRCOptions as CLIOptions
@@ -19,6 +23,7 @@ class LS(RemoteCommand):
1923
match/str: Window to change colors in
2024
match_tab/str: Tab to change colors in
2125
self/bool: Boolean indicating whether to list only the window the command is run in
26+
output_format/str: Output in json or session format
2227
'''
2328

2429
short_desc = 'List tabs/windows'
@@ -41,6 +46,13 @@ class LS(RemoteCommand):
4146
--self
4247
type=bool-set
4348
Only list the window this command is run in.
49+
50+
51+
--output-format
52+
type=choices
53+
choices=json,session
54+
default=json
55+
Output in json or session format
4456
''' + '\n\n' + MATCH_WINDOW_OPTION + '\n\n' + MATCH_TAB_OPTION.replace('--match -m', '--match-tab -t', 1)
4557

4658
def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: ArgsType) -> PayloadType:
@@ -49,6 +61,7 @@ def message_to_kitty(self, global_opts: RCOptions, opts: 'CLIOptions', args: Arg
4961
def response_from_kitty(self, boss: Boss, window: Window | None, payload_get: PayloadGetType) -> ResponseType:
5062
tab_filter: Callable[[Tab], bool] | None = None
5163
window_filter: Callable[[Window], bool] | None = None
64+
output_session: bool = False
5265

5366
if payload_get('self'):
5467
def wf(w: Window) -> bool:
@@ -59,26 +72,32 @@ def wf(w: Window) -> bool:
5972
def wf(w: Window) -> bool:
6073
return w.id in window_ids
6174
window_filter = wf
62-
data = list(boss.list_os_windows(window, tab_filter, window_filter))
63-
if not payload_get('all_env_vars'):
64-
all_env_blocks: list[dict[str, str]] = []
65-
common_env_vars: set[tuple[str, str]] = set()
66-
for osw in data:
67-
for tab in osw.get('tabs', ()):
68-
for w in tab.get('windows', ()):
69-
env: dict[str, str] = w.get('env', {})
70-
frozen_env = set(env.items())
71-
if all_env_blocks:
72-
common_env_vars &= frozen_env
73-
else:
74-
common_env_vars = frozen_env
75-
all_env_blocks.append(env)
76-
if common_env_vars and len(all_env_blocks) > 1:
77-
remove_env_vars = {k for k, v in common_env_vars}
78-
for env in all_env_blocks:
79-
for r in remove_env_vars:
80-
env.pop(r, None)
81-
return json.dumps(data, indent=2, sort_keys=True)
75+
elif payload_get('output_format') == 'session':
76+
output_session = True
77+
78+
if not output_session:
79+
data = list(boss.list_os_windows(window, tab_filter, window_filter))
80+
if not payload_get('all_env_vars'):
81+
all_env_blocks: list[dict[str, str]] = []
82+
common_env_vars: set[tuple[str, str]] = set()
83+
for osw in data:
84+
for tab in osw.get('tabs', ()):
85+
for w in tab.get('windows', ()):
86+
env: dict[str, str] = w.get('env', {})
87+
frozen_env = set(env.items())
88+
if all_env_blocks:
89+
common_env_vars &= frozen_env
90+
else:
91+
common_env_vars = frozen_env
92+
all_env_blocks.append(env)
93+
if common_env_vars and len(all_env_blocks) > 1:
94+
remove_env_vars = {k for k, v in common_env_vars}
95+
for env in all_env_blocks:
96+
for r in remove_env_vars:
97+
env.pop(r, None)
98+
return json.dumps(data, indent=2, sort_keys=True)
99+
else:
100+
return "\n".join(boss.serialize_state_as_session())
82101

83102

84103
ls = LS()

kitty/tabs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python
22
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
33

4+
import json
45
import os
56
import re
67
import stat
@@ -304,6 +305,7 @@ def serialize_state_as_session(self) -> list[str]:
304305
if lc:
305306
gw.append(shlex.join(lc))
306307
launch_cmds.extend(gw)
308+
launch_cmds.append(f'set_layout_state {json.dumps(self.serialize_state()["layout_state"])}\n')
307309
return (ans + launch_cmds) if launch_cmds else []
308310

309311
def active_window_changed(self) -> None:
@@ -1170,7 +1172,7 @@ def list_tabs(
11701172
'is_active': tab is active_tab,
11711173
'title': tab.name or tab.title,
11721174
'layout': str(tab.current_layout.name),
1173-
'layout_state': tab.current_layout.layout_state(),
1175+
'layout_state': tab.current_layout.serialize(tab.windows),
11741176
'layout_opts': tab.current_layout.layout_opts.serialized(),
11751177
'enabled_layouts': tab.enabled_layouts,
11761178
'windows': windows,

kitty/window.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ class WindowDict(TypedDict):
233233
id: int
234234
is_focused: bool
235235
is_active: bool
236+
is_actions_on_close: bool
237+
is_actions_on_focus_change: bool
238+
is_actions_on_removal: bool
236239
title: str
237240
pid: int | None
238241
cwd: str
@@ -821,6 +824,9 @@ def as_dict(self, is_focused: bool = False, is_self: bool = False, is_active: bo
821824
'id': self.id,
822825
'is_focused': is_focused,
823826
'is_active': is_active,
827+
'is_actions_on_close': self in self.actions_on_close,
828+
'is_actions_on_focus_change': self in self.actions_on_focus_change,
829+
'is_actions_on_removal': self in self.actions_on_removal,
824830
'title': self.title,
825831
'pid': self.child.pid,
826832
'cwd': self.child.current_cwd or self.child.cwd,
@@ -1978,6 +1984,8 @@ def as_launch_command(self, is_overlay: bool = False) -> list[str]:
19781984
ans.append('--hold-after-ssh')
19791985
for k, v in self.user_vars.items():
19801986
ans.append(f'--var={k}={v}')
1987+
if 'kitty_serialize_window_id' not in self.user_vars:
1988+
ans.append(f'--var=kitty_serialize_window_id={self.id}')
19811989
ans.extend(self.padding.as_launch_args())
19821990
ans.extend(self.margin.as_launch_args('margin'))
19831991
if self.override_title:

0 commit comments

Comments
 (0)