#!/usr/bin/env python3 #coding: utf-8 import os import json import sys import subprocess #!---------- aliasmenu.py ---------- # Reads all aliases in a zshrc and allows using them via an ncurses menu. #-----------------------------------! #----------! CLASSES class Bindings: def __init__(self, bindings_dict): """ Initialize the Bindings object. :param bindings_dict: A dictionary with names as keys and commands as values. """ self.bindings = {} for i, (name, command) in enumerate(bindings_dict.items()): self.bindings[int(i)] = (name, command) def __len__(self): """ Get the number of bindings. :return: The number of bindings. """ return len(self.bindings) def check_input(self, input: int) -> bool: return 0 <= input < len(self.bindings) def print_json(self, pretty=True): """ Print Bindings in JSON format. :param pretty: If True (default), output will be formatted for readability. Otherwise, it will be a compact JSON string. """ if pretty: print(json.dumps({i: {"name": name, "command": command} for i, (name, command) in self.bindings.items()}, indent=4)) else: print(json.dumps({i: {"name": name, "command": command} for i, (name, command) in self.bindings.items()})) #----------! FUNC def read_aliases() -> dict: """ Reads all aliases from the .zshrc file and returns them as a dictionary. """ # Read the .zshrc file with open(os.path.expanduser('~/.zshrc'), 'r') as f: content = f.read() result = {} for line in content.split('\n'): if line.startswith('alias'): splitted = line.split('=') alias = splitted[0].replace('alias ', '') value = splitted[1].replace('"', '').replace("'", "") result[alias] = value return result def print_separator(sep: str="-"): """ Prints a separator line the width of the terminal. """ cols, rows = os.get_terminal_size() print(sep * cols) def print_menu(bindings: Bindings) -> int: """ Prints a menu of all available aliases and returns the index of the selected alias. """ choice = 9999999 print_separator() for index in bindings.bindings.keys(): print(f"{index:<2} |{bindings.bindings[index][0]:<15} |{bindings.bindings[index][1]:<20}") while not bindings.check_input(choice): choice = input("Choose an alias: ") try: choice = int(choice) except: choice = 9999999 command = bindings.bindings[choice][1] return choice def command_to_shell(choice: int, bindings: Bindings) -> None: """ Writes the command to the shell. """ command = bindings.bindings[choice][1] # Get the current working directory cwd = os.getcwd() args = input(f"> {command}") full = command + args # Run the command in the same shell using subprocess try: subprocess.run(full, cwd=cwd, shell=True) except Exception as e: print(f"Error running command: {e}") #----------! MAIN def main(): aliases = read_aliases() bindings = Bindings(aliases) bindings.print_json() choice = print_menu(bindings) command_to_shell(choice, bindings) if __name__ == "__main__": main()