From f399f5f085049c3bf3d654ab8cf84206544e8b25 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sun, 12 May 2024 16:21:04 +0100 Subject: [PATCH] feat(shell): add alias to function helpers These can be useful to convert aliases to shell functions, which can help resolve shell completion issues in some situations. --- zshrc | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/zshrc b/zshrc index 6412138..af486f9 100644 --- a/zshrc +++ b/zshrc @@ -107,6 +107,74 @@ setup-completions() { fi } +# Convert a bash/zsh alias to a function. It prints the unalias command and the +# function definition, meaning the output needs to be evaluated to take effect. +# +# Arguments: +# $1: The alias to convert. Should be a single line like "alias ll='ls -alF'" +# or "ll='ls -alF'". +# +# Example: +# alias brew="op plugin run -- brew" +# convert_alias_to_function "$(alias brew)" +# +# This will print: +# unalias brew +# brew() { +# op plugin run -- brew "$@" +# } +convert-alias-source-to-function-source() { + local line="$1" + + # Remove Bash's "alias " prefix if present. + line=${line#alias } + + # Extract the alias name and the raw command. + local alias_name="$(echo "$line" | cut -d'=' -f1)" + local raw_command="$(echo "$line" | cut -d'=' -f2)" + + # Evaluate the raw command to ensure we get the correct command, with any + # quotes or shell escape characters handled correctly. + local command + eval "command=$raw_command" + + # Abort if the command is empty. + if [ -z "$command" ]; then + echo "Error: Empty command for alias $alias_name" >&2 + return 1 + fi + + # Print the unalias command and the function definition. + echo -e "unalias ${alias_name}" + echo -e "${alias_name}() {\n ${command} \"\$@\"\n}" +} + +# Convert a bash/zsh alias to a function. It replaces the alias with a function +# definition in the current shell that has the same behavior as the alias. +# +# Arguments: +# $1: The alias to convert. Should be the name of the alias. +# +# Example: +# alias brew="op plugin run -- brew" +# convert-alias-to-function brew +# +# This will replace the alias "brew" with a function that has the same behavior. +convert-alias-to-function() { + local alias_name="$1" + + # Get the alias source. + local alias_source="$(alias "$alias_name")" + + # Abort if the alias does not exist. + if [ -z "$alias_source" ]; then + echo "Error: Alias $alias_name does not exist" >&2 + return 1 + fi + + eval "$(convert-alias-source-to-function-source "$alias_source")" +} + # ============================================================================== # Edit command line # ==============================================================================