This is a neat question. We can do this by defining a couple of functions to extend the aliases, and then use the preexec hook to run the functions before they are executed.
I took the answer here .
1. Rate all aliases
_aliases="$(alias -Lr 2>/dev/null || alias)" alias_for() { [[ $1 =~ '[[:punct:]]' ]] && return local found="$( echo "$_aliases" | sed -nE "/^alias ${1}='?(.+)/s//\\1/p" )" [[ -n $found ]] && echo "${found%\'}" }
First save all aliases in a variable. alias -r prints all regular aliases (not global or suffix), and alias -L prints them "in a way suitable for use in startup scripts." The alias_for() function does some cleaning, removing quotation marks, and placing alias in front of lines. When we do echo ${_aliases} , we get something like this:
alias history='fc -l 1' alias ls='ls -F -G' alias lsdf='ls -1l ~/.*(@)' alias mv='mv -v'
Compare this to the alias output:
history='fc -l 1' ls='ls -F -G' lsdf='ls -1l ~/.*(@)' mv='mv -v'
2. Function to check if an alias has been entered.
If an alias has been entered, we can detect it and thus print it:
expand_command_line() { [[ $# -eq 0 ]] && return # If there no input, return. Else... local found_alias="$(alias_for $1)" # Check if there an alias for the comand. if [[ -n $found_alias ]]; then # If there was echo ${found_alias} # Print it. fi }
3. Running this run every time a command is entered
The preexec function preexec perfect for this. This is a function that:
It is executed right after the command has been read and is going to execute it. If the history mechanism is active (and the line was not dropped from the history buffer), the line that the user enters is passed as the first argument, otherwise it is an empty line. The actual command to be executed (including extended aliases) is passed in two different forms: the second argument is a single-line, limited-sized version of the command (with things like functional bodies); the third argument contains the full text that is executed.
from the zsh manual, chapter 9 .
Please note: we could just use the preeexec function to display what is being executed.
To add our function to preexec, we use hook in this example :
autoload -U add-zsh-hook
To remove the hook later, we can use:
# add-zsh-hook -d preexec expand_command_line
My shell
This is what my shell looks like at startup:
$ 1 cd - $ rake bundle exec rake ^C $ chmod usage: chmod [-fhv] [-R [-H | -L | -P]] [-a | +a | =a [i][# [ n]]] mode|entry file ... chmod [-fhv] [-R [-H | -L | -P]] [-E | -C | -N | -i | -I] file ... $ git lg1 fatal: Not a git repository (or any of the parent directories): .git
Errors (or "features")
As you can see from the example of my shell, when a command that is not an alias is launched (for example, chmod ), the full command is not displayed. When an aliased command is executed (e.g. 1 or rake ), the full command is displayed.
When a git alias is executed (e.g. git lg1 ), the git alias is not extended . If you look at my first link , the full example uses the git alias extension - you have to accept this and change if git aliases are important to you.