4141
4242THEFUZZ_MATCH_RATIO_THRESHOLD = 50
4343NUM_FILTERED_MATCHES_TO_SHOW = 10
44+ HISTORY_FILE = "/tmp/tbots_history"
45+ HISTORY_MAX_ENTRIES = 50
46+
47+
48+ def load_history () -> list [str ]:
49+ if not os .path .exists (HISTORY_FILE ):
50+ return []
51+ with open (HISTORY_FILE ) as f :
52+ lines = [line .strip () for line in f .readlines ()]
53+ return [l for l in lines if l ]
54+
55+
56+ def save_to_history (cmd_str : str ):
57+ history = load_history ()
58+ history = [h for h in history if h != cmd_str ]
59+ history .append (cmd_str )
60+ history = history [- HISTORY_MAX_ENTRIES :]
61+ with open (HISTORY_FILE , "w" ) as f :
62+ f .write ("\n " .join (history ) + "\n " )
4463
4564
4665@dataclass
@@ -298,6 +317,7 @@ def execute_command(command: list[str], print_only: bool = False):
298317 print (cmd_str )
299318 else :
300319 print (f"\n { '=' * 33 } Running: { '=' * 38 } \n \n { cmd_str } \n \n { '=' * 81 } \n " )
320+ save_to_history (cmd_str )
301321 code = os .system (cmd_str )
302322 sys .exit (1 if code != 0 else 0 )
303323
@@ -314,12 +334,29 @@ def start_interactive_cli():
314334 config = BuildConfig (action = ActionArgument .run ) # Default action
315335 extra_args = []
316336
337+ history = load_history ()
338+ choices = CATEGORY_CHOICES
339+ if history :
340+ choices = ["Repeat a past command" ] + CATEGORY_CHOICES
341+
317342 category = questionary .select (
318343 "What would you like to do?" ,
319- choices = CATEGORY_CHOICES ,
344+ choices = choices ,
320345 style = INTERACTIVE_STYLE ,
321346 ).unsafe_ask ()
322347
348+ if category == "Repeat a past command" :
349+ past_cmd = questionary .select (
350+ "Select a command to re-run:" ,
351+ choices = list (reversed (history )),
352+ ).ask ()
353+ if not past_cmd :
354+ return
355+ print (f"\n { '=' * 33 } Running: { '=' * 38 } \n \n { past_cmd } \n \n { '=' * 81 } \n " )
356+ save_to_history (past_cmd )
357+ code = os .system (past_cmd )
358+ sys .exit (1 if code != 0 else 0 )
359+
323360 match category :
324361 case "Run thunderscope" :
325362 config .action = ActionArgument .run
0 commit comments