Refactor the bash completion script
The script was lacking structure and had grown a number of one-off hacks that would be better as reusable functions. So, - give each subcommand that has completions it's own function - move completion of formulae, installed brews, and outdated brews into reusable functions - introduce a general __brewcomp() function that takes a string of tab, space, and/or newline separated items and converts all seperators to newlines, and then generates a reply with compgen(). These changes should allow for easier addition of new features in the future. As a bonus, completion for `brew log` will include git-log options if the git completion script is also loaded. _brew_to_completion() is kept around for compatiblity. Signed-off-by: Jack Nagel <jacknagel@gmail.com>
This commit is contained in:
parent
ab19242d04
commit
ba69e17073
@ -1,236 +1,335 @@
|
||||
# Bash completion script for brew(1)
|
||||
#
|
||||
# To use, edit your .bashrc and add:
|
||||
# source `brew --prefix`/Library/Contributions/brew_bash_completion.sh
|
||||
# To use, add the following to your .bashrc:
|
||||
#
|
||||
# . $(brew --repository)/Library/Contributions/brew_bash_completion.sh
|
||||
#
|
||||
# Alternatively, if you have installed the bash-completion package,
|
||||
# you can create a symlink to this file in one of the following directories:
|
||||
#
|
||||
# $(brew --prefix)/etc/bash_completion.d
|
||||
# $(brew --prefix)/share/bash-completion/completions
|
||||
#
|
||||
# and bash-completion will source it automatically.
|
||||
#
|
||||
# The __brew_ps1() function can be used to annotate your PS1 with
|
||||
# Homebrew debugging information; it behaves similarly to the __git_ps1()
|
||||
# function provided by the git's bash completion script.
|
||||
#
|
||||
# For example, the prompt string
|
||||
#
|
||||
# PS1='\u@\h \W $(__brew_ps1 "(%s)") $'
|
||||
#
|
||||
# would result in a prompt like
|
||||
#
|
||||
# user@hostname cwd $
|
||||
#
|
||||
# but if you are currently engaged in an interactive or debug install,
|
||||
# (i.e., you invoked `brew install` with either '-i' or '-d'), then the
|
||||
# prompt would look like
|
||||
# user@hostname cwd (formula_name|DEBUG) $
|
||||
#
|
||||
# user@hostname cwd (<formula_name>|DEBUG) $
|
||||
#
|
||||
# You can customize the output string, e.g. $(__brew_ps1 "[%s]") would
|
||||
# output "[formula_name|DEBUG]". The default (if you do not provide a
|
||||
# format argument) is to print "(formula_name|DEBUG)" prefixed with a
|
||||
# output "[<formula_name>|DEBUG]". The default (if you do not provide a
|
||||
# format argument) is to print "(<formula_name>|DEBUG)" prefixed with a
|
||||
# single space.
|
||||
|
||||
_brew_to_completion()
|
||||
__brewcomp_words_include ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
local i=1
|
||||
while [[ $i -lt $COMP_CWORD ]]; do
|
||||
if [[ "${COMP_WORDS[i]}" = "$1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
i=$((++i))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Subcommand list
|
||||
[[ ${COMP_CWORD} -eq 1 ]] && {
|
||||
local actions="--cache --cellar --config --env --prefix --repository audit cat cleanup
|
||||
configure create deps diy doctor edit fetch help home info install link list log options
|
||||
outdated prune remove search test uninstall unlink update upgrade uses versions"
|
||||
local ext=$(\ls $(brew --repository)/Library/Contributions/examples 2> /dev/null |
|
||||
sed -e "s/\.rb//g" -e "s/brew-//g")
|
||||
COMPREPLY=( $(compgen -W "${actions} ${ext}" -- ${cur}) )
|
||||
return
|
||||
}
|
||||
# Find the previous non-switch word
|
||||
__brewcomp_prev ()
|
||||
{
|
||||
local idx=$((COMP_CWORD - 1))
|
||||
local prv="${COMP_WORDS[idx]}"
|
||||
while [[ $prv == -* ]]; do
|
||||
idx=$((--idx))
|
||||
prv="${COMP_WORDS[idx]}"
|
||||
done
|
||||
echo "$prv"
|
||||
}
|
||||
|
||||
# some flags take arguments
|
||||
# kind of pointless to use a case statement here, but it's cleaner
|
||||
# than a bunch of string comparisons and leaves room for future
|
||||
# expansion
|
||||
case "${COMP_WORDS[1]}" in
|
||||
# flags that take a formula
|
||||
--cache|--cellar|--prefix)
|
||||
local ff=$(\ls $(brew --repository)/Library/Formula 2> /dev/null | sed "s/\.rb//g")
|
||||
local af=$(\ls $(brew --repository)/Library/Aliases 2> /dev/null | sed "s/\.rb//g")
|
||||
COMPREPLY=( $(compgen -W "${ff} ${af}" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brewcomp ()
|
||||
{
|
||||
# break $1 on space, tab, and newline characters,
|
||||
# and turn it into a newline separated list of words
|
||||
local list s sep=$'\n' IFS=$' '$'\t'$'\n'
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
# Find the previous non-switch word
|
||||
local prev_index=$((COMP_CWORD - 1))
|
||||
local prev="${COMP_WORDS[prev_index]}"
|
||||
while [[ $prev == -* ]]; do
|
||||
prev_index=$((--prev_index))
|
||||
prev="${COMP_WORDS[prev_index]}"
|
||||
done
|
||||
for s in $1; do
|
||||
__brewcomp_words_include "$s" && continue
|
||||
list="$list$s$sep"
|
||||
done
|
||||
|
||||
# handle subcommand options
|
||||
if [[ "$cur" == --* ]]; then
|
||||
case "${COMP_WORDS[1]}" in
|
||||
cleanup)
|
||||
local opts=$([[ "${COMP_WORDS[*]}" =~ "--force" ]] || echo "--force")
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
create)
|
||||
local opts=$(
|
||||
local opts=(--autotools --cmake --no-fetch)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
deps)
|
||||
local opts=$(
|
||||
local opts=(--1 --all --tree)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
diy|configure)
|
||||
local opts=$(
|
||||
local opts=(--set-version --set-name)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
fetch)
|
||||
local opts=$(
|
||||
local opts=(--deps --force --HEAD)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
info|abv)
|
||||
local opts=$(
|
||||
local opts=(--all --github)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
install)
|
||||
local opts=$(
|
||||
local opts=(--force --verbose --debug --use-clang --use-gcc
|
||||
--use-llvm --ignore-dependencies --build-from-source --HEAD
|
||||
--interactive --fresh --devel $(brew options --compact "$prev"))
|
||||
IFS=$sep
|
||||
COMPREPLY=($(compgen -W "$list" -- "$cur"))
|
||||
}
|
||||
|
||||
# options that make sense with '--interactive'
|
||||
if [[ "${COMP_WORDS[*]}" =~ "--interactive" ]]; then
|
||||
opts=(--force --git --use-clang --use-gcc --use-llvm --HEAD --devel)
|
||||
fi
|
||||
# Don't use __brewcomp() in any of the __brew_complete_foo functions, as
|
||||
# it is too slow and is not worth it just for duplicate elimination.
|
||||
__brew_complete_formulae ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
local ff=$(\ls $(brew --repository)/Library/Formula 2>/dev/null | sed 's/\.rb//g')
|
||||
local af=$(\ls $(brew --repository)/Library/Aliases 2>/dev/null | sed 's/\.rb//g')
|
||||
COMPREPLY=($(compgen -W "$ff $af" -- "$cur"))
|
||||
}
|
||||
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
list|ls)
|
||||
local opts=$(
|
||||
local opts=(--unbrewed --verbose --versions)
|
||||
__brew_complete_installed ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
local inst=$(\ls $(brew --cellar))
|
||||
COMPREPLY=($(compgen -W "$inst" -- "$cur"))
|
||||
}
|
||||
|
||||
# the three options for list are mutually exclusive
|
||||
for o in ${opts[*]}; do
|
||||
if [[ "${COMP_WORDS[*]}" =~ "$o" ]]; then
|
||||
opts=()
|
||||
else
|
||||
echo "$o"
|
||||
fi
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
options)
|
||||
local opts=$(
|
||||
local opts=(--all --compact --installed)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
outdated)
|
||||
local opts=$([[ "${COMP_WORDS[*]}" =~ "--quiet" ]] || echo "--quiet")
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
search|-S)
|
||||
local opts=$(
|
||||
local opts=(--fink --macports)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
uninstall|remove|rm)
|
||||
local opts=$([[ "${COMP_WORDS[*]}" =~ "--force" ]] || echo "--force")
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
update)
|
||||
local opts=$(
|
||||
local opts=(--rebase --verbose)
|
||||
for o in ${opts[*]}; do
|
||||
[[ "${COMP_WORDS[*]}" =~ "$o" ]] || echo "$o"
|
||||
done
|
||||
)
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
uses)
|
||||
local opts=$([[ "${COMP_WORDS[*]}" =~ "--installed" ]] || echo "--installed")
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
versions)
|
||||
local opts=$([[ "${COMP_WORDS[*]}" =~ "--compact" ]] || echo "--compact")
|
||||
COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
__brew_complete_outdated ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
local od=$(brew outdated --quiet)
|
||||
COMPREPLY=($(compgen -W "$od" -- "$cur"))
|
||||
}
|
||||
|
||||
# find the index of the *first* non-switch word
|
||||
# we can use this to allow completion for multiple formula arguments
|
||||
local cmd_index=1
|
||||
while [[ ${COMP_WORDS[cmd_index]} == -* ]]; do
|
||||
cmd_index=$((++cmd_index))
|
||||
done
|
||||
_brew_cleanup ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--force"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_installed
|
||||
}
|
||||
|
||||
case "${COMP_WORDS[cmd_index]}" in
|
||||
# Commands that take a formula
|
||||
audit|cat|deps|edit|fetch|home|homepage|info|install|log|missing|options|uses|versions)
|
||||
local ff=$(\ls $(brew --repository)/Library/Formula 2> /dev/null | sed "s/\.rb//g")
|
||||
local af=$(\ls $(brew --repository)/Library/Aliases 2> /dev/null | sed "s/\.rb//g")
|
||||
COMPREPLY=( $(compgen -W "${ff} ${af}" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
# Commands that take an existing brew
|
||||
abv|cleanup|link|list|ln|ls|remove|rm|test|uninstall|unlink)
|
||||
COMPREPLY=( $(compgen -W "$(\ls $(brew --cellar))" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
# Commands that take an outdated brew
|
||||
upgrade)
|
||||
COMPREPLY=( $(compgen -W "$(brew outdated --quiet)" -- ${cur}) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
_brew_create ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--autotools --cmake --no-fetch"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_brew_deps ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--1 --all --tree"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
_brew_diy ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--set-name --set-version"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_brew_fetch ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--deps --force --HEAD"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
_brew_info ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--all --github"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
_brew_install ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
local prv=$(__brewcomp_prev)
|
||||
|
||||
case "$cur" in
|
||||
--*)
|
||||
if __brewcomp_words_include "--interactive"; then
|
||||
__brewcomp "
|
||||
--devel
|
||||
--force
|
||||
--git
|
||||
--HEAD
|
||||
--use-clang
|
||||
--use-gcc
|
||||
--use-llvm
|
||||
"
|
||||
else
|
||||
__brewcomp "
|
||||
--build-from-source
|
||||
--debug
|
||||
--devel
|
||||
--force
|
||||
--fresh
|
||||
--HEAD
|
||||
--ignore-dependencies
|
||||
--interactive
|
||||
--use-clang
|
||||
--use-gcc
|
||||
--use-llvm
|
||||
--verbose
|
||||
$(brew options --compact "$prv")
|
||||
"
|
||||
fi
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
_brew_list ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
# options to brew-list are mutually exclusive
|
||||
if __brewcomp_words_include "--unbrewed"; then
|
||||
return
|
||||
elif __brewcomp_words_include "--verbose"; then
|
||||
return
|
||||
elif __brewcomp_words_include "--versions"; then
|
||||
return
|
||||
else
|
||||
__brewcomp "--unbrewed --verbose --versions"
|
||||
return
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
__brew_complete_installed
|
||||
}
|
||||
|
||||
_brew_log ()
|
||||
{
|
||||
# if git-completion is loaded, then we complete git-log options
|
||||
declare -F _git_log >/dev/null || return
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "
|
||||
$__git_log_common_options
|
||||
$__git_log_shortlog_options
|
||||
$__git_log_gitk_options
|
||||
$__git_diff_common_options
|
||||
--walk-reflogs --graph --decorate
|
||||
--abbrev-commit --oneline --reverse
|
||||
"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
_brew_options ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--all --compact --installed"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
_brew_outdated ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--quiet"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_brew_search ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--fink --macports"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_brew_uninstall ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--force"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_installed
|
||||
}
|
||||
|
||||
_brew_update ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--rebase --verbose"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_brew_uses ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--installed"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
_brew_versions ()
|
||||
{
|
||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
case "$cur" in
|
||||
--*)
|
||||
__brewcomp "--compact"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
__brew_complete_formulae
|
||||
}
|
||||
|
||||
__brew_ps1 ()
|
||||
@ -239,4 +338,94 @@ __brew_ps1 ()
|
||||
printf "${1:- (%s)}" "$HOMEBREW_DEBUG_INSTALL|DEBUG"
|
||||
}
|
||||
|
||||
complete -o bashdefault -o default -F _brew_to_completion brew
|
||||
_brew ()
|
||||
{
|
||||
local i=1 cmd
|
||||
|
||||
# find the subcommand
|
||||
while [[ $i -lt $COMP_CWORD ]]; do
|
||||
local s="${COMP_WORDS[i]}"
|
||||
case "$s" in
|
||||
--*) cmd="$s"
|
||||
break
|
||||
;;
|
||||
-*) ;;
|
||||
*) cmd="$s"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
i=$((++i))
|
||||
done
|
||||
|
||||
if [[ $i -eq $COMP_CWORD ]]; then
|
||||
local ext=$(\ls $(brew --repository)/Library/Contributions/examples \
|
||||
2>/dev/null | sed -e "s/\.rb//g" -e "s/brew-//g")
|
||||
__brewcomp "
|
||||
--cache --cellar --config
|
||||
--env --prefix --repository
|
||||
audit
|
||||
cat
|
||||
cleanup
|
||||
create
|
||||
deps
|
||||
diy configure
|
||||
doctor
|
||||
edit
|
||||
fetch
|
||||
help
|
||||
home
|
||||
info abv
|
||||
install
|
||||
link ln
|
||||
list ls
|
||||
log
|
||||
options
|
||||
outdated
|
||||
prune
|
||||
search
|
||||
test
|
||||
uninstall remove rm
|
||||
unlink
|
||||
update
|
||||
upgrade
|
||||
uses
|
||||
versions
|
||||
$ext
|
||||
"
|
||||
return
|
||||
fi
|
||||
|
||||
# subcommands have their own completion functions
|
||||
case "$cmd" in
|
||||
--cache|--cellar|--prefix)
|
||||
__brew_complete_formulae ;;
|
||||
audit|cat|edit|home) __brew_complete_formulae ;;
|
||||
link|ln|test|unlink) __brew_complete_installed ;;
|
||||
upgrade) __brew_complete_outdated ;;
|
||||
cleanup) _brew_cleanup ;;
|
||||
create) _brew_create ;;
|
||||
deps) _brew_deps ;;
|
||||
diy|configure) _brew_diy ;;
|
||||
fetch) _brew_fetch ;;
|
||||
info|abv) _brew_info ;;
|
||||
install) _brew_install ;;
|
||||
list|ls) _brew_list ;;
|
||||
log) _brew_log ;;
|
||||
options) _brew_options ;;
|
||||
outdated) _brew_outdated ;;
|
||||
search|-S) _brew_search ;;
|
||||
uninstall|remove|rm) _brew_uninstall ;;
|
||||
update) _brew_update ;;
|
||||
uses) _brew_uses ;;
|
||||
versions) _brew_versions ;;
|
||||
*) ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# keep around for compatibility
|
||||
_brew_to_completion ()
|
||||
{
|
||||
_brew
|
||||
}
|
||||
|
||||
complete -o bashdefault -o default -F _brew brew
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user