This commit is contained in:
justine 2025-01-02 12:50:42 +01:00
commit efdd24a698
2 changed files with 156 additions and 0 deletions

8
README.md Normal file
View File

@ -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.

148
aliasmenu.py Executable file
View File

@ -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()