Find a zsh
solution first, followed by a bash
solution.
Update: Turns out that a zsh
implementation (based on builtin compctl
) is much simpler than the bash
implementation (based on builtin complete
).
Save the code of interest to a file (e.g., frontend
) and source it (e.g., . ./frontend
); either interactively or, preferably, from your bash/zsh profile.
Once in place, auto-completion of subdirectory names in ~/Desktop/Work/Frontend
will work as follows:
- Type, for instance,
frontend myProject
and press TAB. myProject
is then prefix-matched against the names of the subdirectories in~/Desktop/Work/Frontend
:- If there's only 1 match,
myProject
will instantly expand to the full subdirectory name. - Otherwise, a beep sounds to indicate that there are multiple matches:
zsh
: The names of all matching subdirectories are listed right away.bash
: Press TAB again to list the names of all matching subdirectories- Continue typing until the prefix match is unambiguous, then press TAB again.
- If there's only 1 match,
Note: In bash
, to also only require pressing TAB once to list multiple matches, add the following to your shell profile bind "set show-all-if-ambiguous on"
.
zsh solution:
# Define the shell function.
frontend(){
cd ~/Desktop/Work/Frontend/"${1:-}"
}
# Tell zsh to autocomplete directory names in the same directory as
# the function's when typing a command based on the shell function.
compctl -/ -W ~/Desktop/Work/Frontend frontend
bash solution:
Note: complete -o dirnames
doesn't take an argument, unfortunately - it always auto-completes for the current directory. Thus, a custom shell function that returns the potential matches, combined with -o filenames
, is required.
# Define the main shell function.
frontend(){
local BASEDIR=~/Desktop/Work/Frontend
cd "$BASEDIR/${1:-}"
}
# Define the custom completion function.
_frontend_completions() {
local BASEDIR=~/Desktop/Work/Frontend
# Initialize the array variable through which
# completions must be passed out.
COMPREPLY=()
# Find all matching directories in the base folder that start
# with the name prefix typed so far and return them.
for f in "$BASEDIR/${COMP_WORDS[COMP_CWORD]}"*; do
[[ -d $f ]] && COMPREPLY+=( "$(basename "$f")" )
done
}
# Tell bash to autocomplete directory names as returned by the
# _frontend_completions() helper functoin when typing a command
# based on the main shell function.
complete -o filenames -F _frontend_completions frontend fe