2
2
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
3
3
4
4
import json
5
+ import os
5
6
from collections .abc import Callable
6
- from typing import TYPE_CHECKING
7
+ from typing import TYPE_CHECKING , Sequence
7
8
8
9
from kitty .constants import appname
9
10
10
11
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
11
14
12
15
if TYPE_CHECKING :
13
16
from kitty .cli_stub import LSRCOptions as CLIOptions
@@ -19,7 +22,7 @@ class LS(RemoteCommand):
19
22
match/str: Window to change colors in
20
23
match_tab/str: Tab to change colors in
21
24
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
23
26
'''
24
27
25
28
short_desc = 'List tabs/windows'
@@ -44,9 +47,11 @@ class LS(RemoteCommand):
44
47
Only list the window this command is run in.
45
48
46
49
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
50
55
''' + '\n \n ' + MATCH_WINDOW_OPTION + '\n \n ' + MATCH_TAB_OPTION .replace ('--match -m' , '--match-tab -t' , 1 )
51
56
52
57
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
55
60
def response_from_kitty (self , boss : Boss , window : Window | None , payload_get : PayloadGetType ) -> ResponseType :
56
61
tab_filter : Callable [[Tab ], bool ] | None = None
57
62
window_filter : Callable [[Window ], bool ] | None = None
58
- output_session : bool | None = None
63
+ output_session : bool = False
59
64
60
65
if payload_get ('self' ):
61
66
def wf (w : Window ) -> bool :
@@ -66,9 +71,9 @@ def wf(w: Window) -> bool:
66
71
def wf (w : Window ) -> bool :
67
72
return w .id in window_ids
68
73
window_filter = wf
69
- elif payload_get ('output_session' ) :
74
+ elif payload_get ('output_format' ) == 'session' :
70
75
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 ))
72
77
if not payload_get ('all_env_vars' ):
73
78
all_env_blocks : list [dict [str , str ]] = []
74
79
common_env_vars : set [tuple [str , str ]] = set ()
@@ -87,7 +92,51 @@ def wf(w: Window) -> bool:
87
92
for env in all_env_blocks :
88
93
for r in remove_env_vars :
89
94
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 ('\n new_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 ()
91
140
92
141
93
142
ls = LS ()
0 commit comments