1212
1313from cecli .commands .utils .base_command import BaseCommand
1414from cecli .commands .utils .helpers import format_command_result
15+ from cecli .decoding import safe_open
1516
1617
1718class TerminalSetupCommand (BaseCommand ):
@@ -177,7 +178,7 @@ def _update_alacritty(cls, path, io, dry_run=False):
177178 data = {
178179 "keyboard" : {"bindings" : [{"key" : "Return" , "mods" : "Shift" , "chars" : "\n " }]}
179180 }
180- with open (path , "w" , encoding = "utf-8 " ) as f :
181+ with safe_open (path , "w" ) as f :
181182 tomlkit .dump (data , f )
182183 io .tool_output ("Created Alacritty config with shift+enter binding." )
183184 return True
@@ -189,7 +190,7 @@ def _update_alacritty(cls, path, io, dry_run=False):
189190 io .tool_output (f"DRY-RUN: Would check Alacritty config at { path } " )
190191 io .tool_output (f"DRY-RUN: Would add binding: { new_binding } " )
191192 try :
192- with open (path , "r" , encoding = "utf-8 " ) as f :
193+ with safe_open (path , "r" ) as f :
193194 data = tomlkit .load (f )
194195
195196 # Check if binding already exists
@@ -222,7 +223,7 @@ def _update_alacritty(cls, path, io, dry_run=False):
222223 cls ._backup_file (path , io )
223224
224225 try :
225- with open (path , "r" , encoding = "utf-8 " ) as f :
226+ with safe_open (path , "r" ) as f :
226227 data = tomlkit .load (f )
227228
228229 # Ensure keyboard section exists
@@ -253,7 +254,7 @@ def _update_alacritty(cls, path, io, dry_run=False):
253254 data ["keyboard" ]["bindings" ].append (new_binding )
254255
255256 # Write back to file
256- with open (path , "w" , encoding = "utf-8 " ) as f :
257+ with safe_open (path , "w" ) as f :
257258 tomlkit .dump (data , f )
258259
259260 io .tool_output ("Updated Alacritty config." )
@@ -280,7 +281,7 @@ def _update_kitty(cls, path, io, dry_run=False):
280281 else :
281282 io .tool_output (f"Creating Kitty config at { path } " )
282283 # Create Kitty config with shift+enter binding
283- with open (path , "w" , encoding = "utf-8 " ) as f :
284+ with safe_open (path , "w" ) as f :
284285 f .write (cls .KITTY_BINDING )
285286 io .tool_output ("Created Kitty config with shift+enter binding." )
286287 return True
@@ -290,7 +291,7 @@ def _update_kitty(cls, path, io, dry_run=False):
290291 io .tool_output (f"DRY-RUN: Would append binding:\n { cls .KITTY_BINDING .strip ()} " )
291292 # Simulate checking for duplicates
292293 try :
293- with open (path , "r" , encoding = "utf-8 " ) as f :
294+ with safe_open (path , "r" ) as f :
294295 content = f .read ()
295296 if "map shift+enter send_text all \\ n" in content :
296297 io .tool_output ("DRY-RUN: Kitty already configured." )
@@ -304,14 +305,14 @@ def _update_kitty(cls, path, io, dry_run=False):
304305
305306 cls ._backup_file (path , io )
306307
307- with open (path , "r" , encoding = "utf-8 " ) as f :
308+ with safe_open (path , "r" ) as f :
308309 content = f .read ()
309310
310311 if "map shift+enter send_text all \\ n" in content :
311312 io .tool_output ("Kitty already configured." )
312313 return False
313314
314- with open (path , "a" , encoding = "utf-8 " ) as f :
315+ with safe_open (path , "a" ) as f :
315316 f .write (cls .KITTY_BINDING )
316317 io .tool_output ("Updated Kitty config." )
317318 return True
@@ -336,7 +337,7 @@ def _update_konsole(cls, path, io, dry_run=False):
336337 return False
337338
338339 try :
339- with open (path , "r" , encoding = "utf-8 " ) as f :
340+ with safe_open (path , "r" ) as f :
340341 content = f .read ()
341342
342343 import re
@@ -359,7 +360,7 @@ def _update_konsole(cls, path, io, dry_run=False):
359360
360361 cls ._backup_file (path , io )
361362 new_content = re .sub (pattern , new_rule , content , flags = re .MULTILINE )
362- with open (path , "w" , encoding = "utf-8 " ) as f :
363+ with safe_open (path , "w" ) as f :
363364 f .write (new_content )
364365 io .tool_output ("Updated Konsole keytab rule." )
365366 return True
@@ -369,7 +370,7 @@ def _update_konsole(cls, path, io, dry_run=False):
369370 return True
370371
371372 cls ._backup_file (path , io )
372- with open (path , "a" , encoding = "utf-8 " ) as f :
373+ with safe_open (path , "a" ) as f :
373374 f .write (f"\n { new_rule } \n " )
374375 io .tool_output ("Added Konsole Return+Shift rule." )
375376 return True
@@ -399,7 +400,7 @@ def _update_windows_terminal(cls, path, io, dry_run=False):
399400 io .tool_output (f"Creating Windows Terminal config at { path } " )
400401 # Create minimal Windows Terminal config with shift+enter binding
401402 data = {"actions" : [cls .WT_ACTION ], "keybindings" : [cls .WT_KEYBINDING ]}
402- with open (path , "w" , encoding = "utf-8 " ) as f :
403+ with safe_open (path , "w" ) as f :
403404 json .dump (data , f , indent = 4 )
404405 io .tool_output ("Created Windows Terminal config with shift+enter binding." )
405406 return True
@@ -412,7 +413,7 @@ def _update_windows_terminal(cls, path, io, dry_run=False):
412413 )
413414 # Simulate checking for duplicates
414415 try :
415- with open (path , "r" , encoding = "utf-8 " ) as f :
416+ with safe_open (path , "r" ) as f :
416417 data = json .load (f )
417418
418419 # Check if already configured
@@ -451,7 +452,7 @@ def _update_windows_terminal(cls, path, io, dry_run=False):
451452 return False
452453
453454 try :
454- with open (path , "r" , encoding = "utf-8 " ) as f :
455+ with safe_open (path , "r" ) as f :
455456 data = json .load (f )
456457
457458 # Check if already configured
@@ -493,7 +494,7 @@ def _update_windows_terminal(cls, path, io, dry_run=False):
493494
494495 cls ._backup_file (path , io )
495496
496- with open (path , "w" , encoding = "utf-8 " ) as f :
497+ with safe_open (path , "w" ) as f :
497498 json .dump (data , f , indent = 4 )
498499 io .tool_output ("Updated Windows Terminal config." )
499500 return True
@@ -522,7 +523,7 @@ def _update_vscode(cls, path, io, dry_run=False):
522523 io .tool_output (f"Creating VS Code keybindings.json at { path } " )
523524 # Create file with our binding
524525 data = [cls .VSCODE_SHIFT_ENTER_BINDING ]
525- with open (path , "w" , encoding = "utf-8 " ) as f :
526+ with safe_open (path , "w" ) as f :
526527 json .dump (data , f , indent = 4 )
527528 io .tool_output ("Created VS Code config with shift+enter binding." )
528529 return True
@@ -536,7 +537,7 @@ def _update_vscode(cls, path, io, dry_run=False):
536537 # Simulate checking for duplicates
537538 try :
538539 content = ""
539- with open (path , "r" , encoding = "utf-8 " ) as f :
540+ with safe_open (path , "r" ) as f :
540541 content = f .read ()
541542
542543 # Strip comments before parsing
@@ -580,7 +581,7 @@ def _update_vscode(cls, path, io, dry_run=False):
580581
581582 try :
582583 content = ""
583- with open (path , "r" , encoding = "utf-8 " ) as f :
584+ with safe_open (path , "r" ) as f :
584585 content = f .read ()
585586
586587 # Strip comments before parsing
@@ -618,7 +619,7 @@ def _update_vscode(cls, path, io, dry_run=False):
618619 data .append (cls .VSCODE_SHIFT_ENTER_BINDING )
619620
620621 # Write back to file
621- with open (path , "w" , encoding = "utf-8 " ) as f :
622+ with safe_open (path , "w" ) as f :
622623 json .dump (data , f , indent = 4 )
623624
624625 io .tool_output ("Updated VS Code config." )
@@ -647,7 +648,7 @@ def _update_vscode_settings(cls, keybindings_path, io, dry_run=False):
647648 try :
648649 if settings_path .exists ():
649650 content = ""
650- with open (settings_path , "r" , encoding = "utf-8 " ) as f :
651+ with safe_open (settings_path , "r" ) as f :
651652 content = f .read ()
652653
653654 content_no_comments = cls ._strip_json_comments (content )
@@ -703,7 +704,7 @@ def _update_vscode_settings(cls, keybindings_path, io, dry_run=False):
703704 if settings_path .exists ():
704705 cls ._backup_file (settings_path , io )
705706 content = ""
706- with open (settings_path , "r" , encoding = "utf-8 " ) as f :
707+ with safe_open (settings_path , "r" ) as f :
707708 content = f .read ()
708709
709710 # Strip comments before parsing
@@ -770,7 +771,7 @@ def _update_vscode_settings(cls, keybindings_path, io, dry_run=False):
770771 ]
771772
772773 # Write back to file
773- with open (settings_path , "w" , encoding = "utf-8 " ) as f :
774+ with safe_open (settings_path , "w" ) as f :
774775 json .dump (data , f , indent = 4 )
775776
776777 io .tool_output ("Updated VS Code settings." )
0 commit comments