From efdd24a698326a3c9ed257ca7c1b719a4b3355ac Mon Sep 17 00:00:00 2001 From: justine Date: Thu, 2 Jan 2025 12:50:42 +0100 Subject: [PATCH] First --- README.md | 8 +++ aliasmenu.py | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 README.md create mode 100755 aliasmenu.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..877aecf --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# AliasMenu +A simple script to run your aliases. + +I don't really know if this is useful, but it exists. + +## What it does +Reads your .zshrc to get the aliases, show them in a menu, lets you choose one and add things after it, and runs it. +It came to me that I was using a lot of aliases and probably forgetting about them. Having a swiss army knife of your making can be something useful, and I think the idea could evolve. \ No newline at end of file diff --git a/aliasmenu.py b/aliasmenu.py new file mode 100755 index 0000000..3e66951 --- /dev/null +++ b/aliasmenu.py @@ -0,0 +1,148 @@ +#!/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 get_name(self, index): + """ + Get the name associated with a given index. + + :param index: The index of the binding to retrieve. + :return: The name associated with the given index. + :raises IndexError: If the index is out of range. + """ + if not (0 <= index < len(self.bindings)): + raise IndexError("Index out of range") + return self.bindings[index][0] + + def get_command(self, index): + """ + Get the command associated with a given index. + + :param index: The index of the binding to retrieve. + :return: The command associated with the given index. + :raises IndexError: If the index is out of range. + """ + if not (0 <= index < len(self.bindings)): + raise IndexError("Index out of range") + return self.bindings[index][1] + + 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() \ No newline at end of file