Skip to content

Instantly share code, notes, and snippets.

@azat
Created April 1, 2019 21:47
Show Gist options
  • Save azat/3ddb2205cac3fe528d8fc37ad414cce6 to your computer and use it in GitHub Desktop.
Save azat/3ddb2205cac3fe528d8fc37ad414cce6 to your computer and use it in GitHub Desktop.
# Completion for bash, that support:
# - bin --help
# - tinytest --list-tests
#
# Execute as:
# source scripts/bash_completion
#
# Also you may like:
# bind "set completion-ignore-case on"
# bind "set show-all-if-ambiguous on"
#
# Known to work with bash 3.* with programmable completion and extended
# pattern matching enabled (use 'shopt -s extglob progcomp' to enable
# these if they are not already enabled).
shopt -s extglob
function _le_bin_exist()
{ [ -x "$1" ] || command -v $1 >& /dev/null; }
function _quote()
{
local quoted=${1//\'/\'\\\'\'};
printf "'%s'" "$quoted"
}
function _get_options()
{
$* --help 2>&1 | fgrep -a -- - \
| awk '{for (i=1; i<=NF; i++) print $i}' \
| awk -F= '{for (i=1; i<=NF; i++) print $i}' \
| tr -d '[],.()' \
| tr '|' $'\n' \
| grep -a -- ^- | grep -a -v ^-$ | grep -a -v ^--$ \
| sort -u
}
function _search_bin()
{
local bin="$1"
local IFS=":"
if [ -x "$bin" ]; then
readlink -f "$bin"
return
fi
for path in $PATH; do
if [ -x "$path/$bin" ]; then
readlink -f "$path/$bin"
return
fi
done
}
function _cmpl_prepend()
{
local i pref=$1 && shift
for i in "$@"; do echo "$pref$i"; done
}
function _complete_le_tinytest_list_tests()
{ "$@" --list-tests | awk '/^ / { print $NF }'; }
function _complete_for_le_tinytest()
{
local cur prev
eval local cmd=$( _quote "$1" )
_le_bin_exist $cmd || return 0
COMPREPLY=()
_get_comp_words_by_ref cur prev
COMPREPLY=( $(compgen -W "$(
_get_options $cmd
_complete_le_tinytest_list_tests $cmd
)" -- $cur) )
return 0
}
function _complete_for_le_bin()
{
local cur prev
eval local cmd=$( _quote "$1" )
_le_bin_exist $cmd || return 0
COMPREPLY=()
_get_comp_words_by_ref cur prev
case "$prev" in
# Argh... This looks like a bash bug...
# Redirections are passed to the completion function
# although it is managed by the shell directly...
'<'|'>'|'>>'|[12]'>'|[12]'>>')
return
;;
esac
COMPREPLY=( $(compgen -W "$(_get_options $cmd)" -- $cur) )
return 0
}
function _complete_le()
{
local bin=$1 && shift
local f=${1:-_complete_for_le_bin}
local o=(
-o default
-o bashdefault
-o nospace
-F $f
$bin
)
complete "${o[@]}"
}
function _complete_le_main()
{
# Do not know how to complete in this bash environment
type _get_comp_words_by_ref >& /dev/null || return 0
local bin
# libevent
local utils=(
https-client
)
for bin in "${utils[@]}"; do
_complete_le $bin
done
_complete_le regress _complete_for_le_tinytest
}
_complete_le_main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment