1010
1111from .. import config , util
1212from ..workspacebuilder import freeze
13- from .utils import _validate_choices , get_config_dir , prompt , prompt_yes_no
13+ from .utils import get_config_dir , prompt , prompt_choices , prompt_yes_no
14+
15+ if t .TYPE_CHECKING :
16+ from typing_extensions import Literal , TypeAlias , TypeGuard
17+
18+ CLIOutputFormatLiteral : TypeAlias = Literal ["yaml" , "json" ]
19+
20+
21+ class CLIFreezeNamespace (argparse .Namespace ):
22+ session_name : str
23+ socket_name : t .Optional [str ]
24+ socket_path : t .Optional [str ]
25+ config_format : t .Optional ["CLIOutputFormatLiteral" ]
26+ save_to : t .Optional [str ]
27+ answer_yes : t .Optional [bool ]
28+ quiet : t .Optional [bool ]
29+ force : t .Optional [bool ]
1430
1531
1632def session_completion (ctx , params , incomplete ):
17- t = Server ()
18- choices = [session .name for session in t .list_sessions ()]
33+ server = Server ()
34+ choices = [session .name for session in server .list_sessions ()]
1935 return sorted (str (c ) for c in choices if str (c ).startswith (incomplete ))
2036
2137
@@ -69,28 +85,20 @@ def create_freeze_subparser(
6985
7086
7187def command_freeze (
72- session_name : t .Optional [str ] = None ,
73- socket_name : t .Optional [str ] = None ,
74- config_format : t .Optional [str ] = None ,
75- save_to : t .Optional [str ] = None ,
76- socket_path : t .Optional [str ] = None ,
77- answer_yes : t .Optional [bool ] = None ,
78- quiet : t .Optional [bool ] = None ,
79- force : t .Optional [bool ] = None ,
88+ args : CLIFreezeNamespace ,
8089 parser : t .Optional [argparse .ArgumentParser ] = None ,
8190) -> None :
8291 """Snapshot a session into a config.
8392
8493 If SESSION_NAME is provided, snapshot that session. Otherwise, use the
8594 current session."""
86-
87- t = Server (socket_name = socket_name , socket_path = socket_path )
95+ server = Server (socket_name = args .socket_name , socket_path = args .socket_path )
8896
8997 try :
90- if session_name :
91- session = t .find_where ({"session_name" : session_name })
98+ if args . session_name :
99+ session = server .find_where ({"session_name" : args . session_name })
92100 else :
93- session = util .get_session (t )
101+ session = util .get_session (server )
94102
95103 if not session :
96104 raise TmuxpException ("Session not found." )
@@ -102,54 +110,67 @@ def command_freeze(
102110 newconfig = config .inline (sconf )
103111 configparser = ConfigReader (newconfig )
104112
105- if not quiet :
113+ if not args . quiet :
106114 print (
107115 "---------------------------------------------------------------"
108116 "\n "
109117 "Freeze does its best to snapshot live tmux sessions.\n "
110118 )
111119 if not (
112- answer_yes
120+ args . answer_yes
113121 or prompt_yes_no (
114122 "The new config *WILL* require adjusting afterwards. Save config?"
115123 )
116124 ):
117- if not quiet :
125+ if not args . quiet :
118126 print (
119127 "tmuxp has examples in JSON and YAML format at "
120128 "<http://tmuxp.git-pull.com/examples.html>\n "
121129 "View tmuxp docs at <http://tmuxp.git-pull.com/>."
122130 )
123131 sys .exit ()
124132
125- dest = save_to
133+ dest = args . save_to
126134 while not dest :
127135 save_to = os .path .abspath (
128136 os .path .join (
129137 get_config_dir (),
130- "{}.{}" .format (sconf .get ("session_name" ), config_format or "yaml" ),
138+ "{}.{}" .format (sconf .get ("session_name" ), args . config_format or "yaml" ),
131139 )
132140 )
133141 dest_prompt = prompt (
134142 "Save to: %s" % save_to ,
135143 default = save_to ,
136144 )
137- if not force and os .path .exists (dest_prompt ):
145+ if not args . force and os .path .exists (dest_prompt ):
138146 print ("%s exists. Pick a new filename." % dest_prompt )
139147 continue
140148
141149 dest = dest_prompt
142150 dest = os .path .abspath (os .path .relpath (os .path .expanduser (dest )))
151+ config_format = args .config_format
152+
153+ valid_config_formats : t .List ["CLIOutputFormatLiteral" ] = ["json" , "yaml" ]
154+
155+ def is_valid_ext (stem : t .Optional [str ]) -> "TypeGuard[CLIOutputFormatLiteral]" :
156+ return stem in valid_config_formats
157+
158+ if not is_valid_ext (config_format ):
159+
160+ def extract_config_format (val : str ) -> t .Optional ["CLIOutputFormatLiteral" ]:
161+ suffix = pathlib .Path (val ).suffix
162+ if isinstance (suffix , str ):
163+ suffix = suffix .lower ().lstrip ("." )
164+ if is_valid_ext (suffix ):
165+ return suffix
166+ return None
143167
144- if config_format is None or config_format == "" :
145- valid_config_formats = ["json" , "yaml" ]
146- _ , config_format = os .path .splitext (dest )
147- config_format = config_format [1 :].lower ()
148- if config_format not in valid_config_formats :
149- config_format = prompt (
168+ config_format = extract_config_format (dest )
169+ if not is_valid_ext (config_format ):
170+ config_format = prompt_choices (
150171 "Couldn't ascertain one of [%s] from file name. Convert to"
151172 % ", " .join (valid_config_formats ),
152- value_proc = _validate_choices ([ "yaml" , "json" ]) ,
173+ choices = valid_config_formats ,
153174 default = "yaml" ,
154175 )
155176
@@ -160,13 +181,13 @@ def command_freeze(
160181 elif config_format == "json" :
161182 newconfig = configparser .dump (format = "json" , indent = 2 )
162183
163- if answer_yes or prompt_yes_no ("Save to %s?" % dest ):
184+ if args . answer_yes or prompt_yes_no ("Save to %s?" % dest ):
164185 destdir = os .path .dirname (dest )
165186 if not os .path .isdir (destdir ):
166187 os .makedirs (destdir )
167188 buf = open (dest , "w" )
168189 buf .write (newconfig )
169190 buf .close ()
170191
171- if not quiet :
192+ if not args . quiet :
172193 print ("Saved to %s." % dest )
0 commit comments