Merge pull request #2601 from 1ace/feature/completion
Add completion scripts for Bash and Zshpull/5023/head
commit
ee863d33c1
4 changed files with 461 additions and 4 deletions
@ -0,0 +1,441 @@ |
||||
_meson() { |
||||
command="${COMP_WORDS[1]}" |
||||
case "$command" in |
||||
setup |\ |
||||
configure |\ |
||||
install |\ |
||||
introspect |\ |
||||
init |\ |
||||
test |\ |
||||
wrap |\ |
||||
subprojects |\ |
||||
help) |
||||
_meson-$command "${COMP_WORDS[@]:1}" |
||||
;; |
||||
*) |
||||
_meson-setup "${COMP_WORDS[@]}" |
||||
;; |
||||
esac |
||||
} && |
||||
complete -F _meson meson |
||||
|
||||
_meson_complete_option() { |
||||
option_string=$1 |
||||
|
||||
if [[ $# -eq 2 ]] && ! [[ "$option_string" == *=* ]]; then |
||||
option_string="$option_string=$2" |
||||
fi |
||||
|
||||
if [[ "$option_string" == *=* ]]; then |
||||
_meson_complete_option_value "$option_string" |
||||
else |
||||
_meson_complete_option_name "$option_string" |
||||
fi |
||||
} |
||||
|
||||
_meson_complete_option_name() { |
||||
option=$1 |
||||
options=($(python3 -c 'import sys, json |
||||
for option in json.load(sys.stdin): |
||||
print(option["name"]) |
||||
' <<< "$(_meson_get_options)")) |
||||
compopt -o nospace |
||||
COMPREPLY=($(compgen -W '${options[@]}' -S= -- "$option")) |
||||
} |
||||
|
||||
_meson_complete_option_value() { |
||||
cur=$1 |
||||
option_name=${cur%%=*} |
||||
option_value=${cur#*=} |
||||
|
||||
if _meson_complete_filedir "$option_name" "$option_value"; then |
||||
return |
||||
fi |
||||
|
||||
# TODO: support all the option types |
||||
options=($(python3 -c 'import sys, json |
||||
for option in json.load(sys.stdin): |
||||
if option["name"] != "'$option_name'": |
||||
continue |
||||
choices = [] |
||||
if option["type"] == "boolean": |
||||
choices.append("true") |
||||
choices.append("false") |
||||
elif option["type"] == "combo": |
||||
for choice in option["choices"]: |
||||
choices.append(choice) |
||||
for choice in choices: |
||||
if choice.startswith("'$cur'"): |
||||
print(choice) |
||||
' <<< "$(_meson_get_options)")) |
||||
COMPREPLY=("${options[@]}") |
||||
} |
||||
|
||||
_meson_get_options() { |
||||
local options |
||||
for builddir in "${COMP_WORDS[@]}"; do |
||||
if [ -d "$builddir" ]; then |
||||
break |
||||
fi |
||||
builddir=. |
||||
done |
||||
options=$(meson introspect "$builddir" --buildoptions 2>/dev/null) && |
||||
echo "$options" || |
||||
echo '[]' |
||||
} |
||||
|
||||
_meson_complete_filedir() { |
||||
_filedir_in() { |
||||
pushd "$1" &>/dev/null |
||||
local COMPREPLY=() |
||||
_filedir |
||||
echo "${COMPREPLY[@]}" |
||||
popd &>/dev/null |
||||
} |
||||
|
||||
option=$1 |
||||
cur=$2 |
||||
case $option in |
||||
prefix |\ |
||||
libdir |\ |
||||
libexecdir |\ |
||||
bindir |\ |
||||
sbindir |\ |
||||
includedir |\ |
||||
datadir |\ |
||||
mandir |\ |
||||
infodir |\ |
||||
localedir |\ |
||||
sysconfdir |\ |
||||
localstatedir |\ |
||||
sharedstatedir) |
||||
_filedir -d |
||||
;; |
||||
cross-file) |
||||
_filedir |
||||
COMPREPLY+=($(_filedir_in "$XDG_DATA_DIRS"/meson/cross)) |
||||
COMPREPLY+=($(_filedir_in /usr/local/share/meson/cross)) |
||||
COMPREPLY+=($(_filedir_in /usr/share/meson/cross)) |
||||
COMPREPLY+=($(_filedir_in "$XDG_DATA_HOME"/meson/cross)) |
||||
COMPREPLY+=($(_filedir_in ~/.local/share/meson/cross)) |
||||
;; |
||||
*) |
||||
return 1;; |
||||
esac |
||||
return 0 |
||||
} |
||||
|
||||
_meson-setup() { |
||||
|
||||
shortopts=( |
||||
h |
||||
D |
||||
v |
||||
) |
||||
|
||||
longopts=( |
||||
help |
||||
prefix |
||||
libdir |
||||
libexecdir |
||||
bindir |
||||
sbindir |
||||
includedir |
||||
datadir |
||||
mandir |
||||
infodir |
||||
localedir |
||||
sysconfdir |
||||
localstatedir |
||||
sharedstatedir |
||||
backend |
||||
buildtype |
||||
strip |
||||
unity |
||||
werror |
||||
layout |
||||
default-library |
||||
warnlevel |
||||
stdsplit |
||||
errorlogs |
||||
cross-file |
||||
version |
||||
wrap-mode |
||||
) |
||||
|
||||
local cur prev |
||||
if _get_comp_words_by_ref cur prev &>/dev/null && |
||||
[ "${prev:0:2}" = '--' ] && _meson_complete_option "${prev:2}" "$cur"; then |
||||
return |
||||
elif _get_comp_words_by_ref cur prev &>/dev/null && |
||||
[ "${prev:0:1}" = '-' ] && [ "${prev:1:2}" != '-' ] && _meson_complete_option "${prev:1}"; then |
||||
return |
||||
elif _get_comp_words_by_ref -n '=' cur prev &>/dev/null; then |
||||
if [ $prev == -D ]; then |
||||
_meson_complete_option "$cur" |
||||
return |
||||
fi |
||||
else |
||||
cur="${COMP_WORDS[COMP_CWORD]}" |
||||
fi |
||||
|
||||
if [[ "$cur" == "--"* ]]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
elif [[ "$cur" == "-"* ]]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}")) |
||||
else |
||||
_filedir -d |
||||
if [ -z "$cur" ]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}')) |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}')) |
||||
fi |
||||
|
||||
if [ $COMP_CWORD -eq 1 ]; then |
||||
COMPREPLY+=($(compgen -W 'setup configure test introspect' -- "$cur")) |
||||
fi |
||||
fi |
||||
} |
||||
|
||||
_meson-configure() { |
||||
|
||||
shortopts=( |
||||
h |
||||
D |
||||
) |
||||
|
||||
longopts=( |
||||
help |
||||
clearcache |
||||
) |
||||
|
||||
local cur prev |
||||
if _get_comp_words_by_ref -n '=' cur prev &>/dev/null; then |
||||
if [ $prev == -D ]; then |
||||
_meson_complete_option "$cur" |
||||
return |
||||
fi |
||||
else |
||||
cur="${COMP_WORDS[COMP_CWORD]}" |
||||
fi |
||||
|
||||
if [[ "$cur" == "--"* ]]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
elif [[ "$cur" == "-"* ]]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}")) |
||||
else |
||||
for dir in "${COMP_WORDS[@]}"; do |
||||
if [ -d "$dir" ]; then |
||||
break |
||||
fi |
||||
dir=. |
||||
done |
||||
if [ ! -d "$dir/meson-private" ]; then |
||||
_filedir -d |
||||
fi |
||||
|
||||
if [ -z "$cur" ]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}')) |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}')) |
||||
fi |
||||
fi |
||||
} |
||||
|
||||
_meson-test() { |
||||
shortopts=( |
||||
q |
||||
v |
||||
t |
||||
C |
||||
) |
||||
|
||||
longopts=( |
||||
quiet |
||||
verbose |
||||
timeout-multiplier |
||||
repeat |
||||
no-rebuild |
||||
gdb |
||||
list |
||||
wrapper --wrap |
||||
no-suite |
||||
suite |
||||
no-stdsplit |
||||
print-errorlogs |
||||
benchmark |
||||
logbase |
||||
num-processes |
||||
setup |
||||
test-args |
||||
) |
||||
|
||||
local cur prev |
||||
if _get_comp_words_by_ref -n ':' cur prev &>/dev/null; then |
||||
case $prev in |
||||
--repeat) |
||||
# number, can't be completed |
||||
return |
||||
;; |
||||
--wrapper) |
||||
_command_offset $COMP_CWORD |
||||
return |
||||
;; |
||||
-C) |
||||
_filedir -d |
||||
return |
||||
;; |
||||
--suite | --no-suite) |
||||
for i in "${!COMP_WORDS[@]}"; do |
||||
opt="${COMP_WORDS[i]}" |
||||
dir="${COMP_WORDS[i+1]}" |
||||
case "$opt" in |
||||
-C) |
||||
break |
||||
;; |
||||
esac |
||||
dir=. |
||||
done |
||||
suites=($(python3 -c 'import sys, json; |
||||
for test in json.load(sys.stdin): |
||||
for suite in test["suite"]: |
||||
print(suite) |
||||
' <<< "$(meson introspect "$dir" --tests)")) |
||||
# TODO |
||||
COMPREPLY+=($(compgen -W "${suites[*]}" -- "$cur")) |
||||
return |
||||
;; |
||||
--logbase) |
||||
# free string, can't be completed |
||||
return |
||||
;; |
||||
--num-processes) |
||||
# number, can't be completed |
||||
return |
||||
;; |
||||
-t | --timeout-multiplier) |
||||
# number, can't be completed |
||||
return |
||||
;; |
||||
--setup) |
||||
# TODO |
||||
return |
||||
;; |
||||
--test-args) |
||||
return |
||||
;; |
||||
esac |
||||
else |
||||
cur="${COMP_WORDS[COMP_CWORD]}" |
||||
fi |
||||
|
||||
if [[ "$cur" == "--"* ]]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
elif [[ "$cur" == "-"* && ${#cur} -gt 1 ]]; then |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}")) |
||||
else |
||||
for dir in "${COMP_WORDS[@]}"; do |
||||
if [ -d "$dir" ]; then |
||||
break |
||||
fi |
||||
dir=. |
||||
done |
||||
if [ ! -d "$dir/meson-private" ]; then |
||||
_filedir -d |
||||
fi |
||||
|
||||
for i in "${!COMP_WORDS[@]}"; do |
||||
opt="${COMP_WORDS[i]}" |
||||
dir="${COMP_WORDS[i+1]}" |
||||
case "$opt" in |
||||
-C) |
||||
break |
||||
;; |
||||
esac |
||||
dir=. |
||||
done |
||||
tests=($(python3 -c 'import sys, json; |
||||
for test in json.load(sys.stdin): |
||||
print(test["name"]) |
||||
' <<< "$(meson introspect "$dir" --tests)")) |
||||
COMPREPLY+=($(compgen -W "${tests[*]}" -- "$cur")) |
||||
|
||||
if [ -z "$cur" ]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}")) |
||||
fi |
||||
fi |
||||
} |
||||
|
||||
_meson-introspect() { |
||||
shortopts=( |
||||
h |
||||
) |
||||
|
||||
longopts=( |
||||
targets |
||||
installed |
||||
target-files |
||||
buildsystem-files |
||||
buildoptions |
||||
tests |
||||
benchmarks |
||||
dependencies |
||||
projectinfo |
||||
) |
||||
|
||||
local cur prev |
||||
if _get_comp_words_by_ref cur prev &>/dev/null; then |
||||
case $prev in |
||||
--target-files) |
||||
for i in "${!COMP_WORDS[@]}"; do |
||||
opt="${COMP_WORDS[i]}" |
||||
dir="${COMP_WORDS[i+1]}" |
||||
case "$opt" in |
||||
-C) |
||||
break |
||||
;; |
||||
esac |
||||
dir=. |
||||
done |
||||
tests_json=$(meson introspect "$dir" --targets) |
||||
if [ $? -eq 0 ]; then |
||||
tests=$(python3 -c 'import sys, json |
||||
for target in json.load(sys.stdin): |
||||
print(target["id"]) |
||||
' <<< "$tests_json") |
||||
COMPREPLY=($(compgen -W '$tests' -- "$cur")) |
||||
fi |
||||
return |
||||
;; |
||||
esac |
||||
else |
||||
cur="${COMP_WORDS[COMP_CWORD]}" |
||||
fi |
||||
|
||||
if [[ "$cur" == "--"* ]]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
elif [[ "$cur" == "-"* ]]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}' -- "${cur:2}")) |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}' -- "${cur:1}")) |
||||
else |
||||
for dir in "${COMP_WORDS[@]}"; do |
||||
if [ -d "$dir" ]; then |
||||
break |
||||
fi |
||||
dir=. |
||||
done |
||||
if [ ! -d "$dir/meson-private" ]; then |
||||
_filedir -d |
||||
fi |
||||
|
||||
if [ -z "$cur" ]; then |
||||
COMPREPLY+=($(compgen -P '--' -W '${longopts[*]}')) |
||||
COMPREPLY+=($(compgen -P '-' -W '${shortopts[*]}')) |
||||
fi |
||||
fi |
||||
} |
||||
|
||||
_meson-wrap() { |
||||
: TODO |
||||
} |
Loading…
Reference in new issue