WIP: completion for pytest

This commit is contained in:
Daniel Hahler 2016-10-07 13:54:02 +02:00
parent f0438a05ed
commit 4f789ffb98
1 changed files with 112 additions and 0 deletions

112
src/_pytest Normal file
View File

@ -0,0 +1,112 @@
#compdef pytest py.test
local ret=1
local context state state_descr line
typeset -A opt_args
_pytest_caching_policy () {
# rebuild if cache is more than a week old
local -a oldp
oldp=( "$1"(Nm+7) )
(( $#oldp ))
}
local -a pytest_options
_pytest_options() {
# this function calls py.test and loops over the list of apps and options
# and constructs the help menu with it
local cache_policy
zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
if [[ -z "$cache_policy" ]]; then
zstyle ":completion:${curcontext}:" cache-policy _pytest_caching_policy
fi
if _cache_invalid pytest_options || ! _retrieve_cache pytest_options; then
zle -M "Querying pytest options..."
# TODO:
# - start sections with '^reporting:' etc.
local line
local _words opts i desc
local opt
local in_desc
_call_program commands py.test --help | while IFS='' read line; do
# add dashed options for completion only
if [[ $line[1,3] == ' -' ]] || [[ -z "$line" ]]; then
desc="${(L)desc[1]}${desc[2,-1]}"
desc="${desc%.}"
if (( $#opts )); then
if (( $#opts > 1 )); then
for opt in $opts; do
pytest_options+=("(${opts})${opt}[${desc}]")
done
else
pytest_options+=("${opts}[$desc]")
fi
fi
opts=()
desc=
in_desc=0
[[ -z "$line" ]] && continue
elif (( in_desc )); then
shortdesc=${line## #}
# TODO: punctuation
# if [[ "$shortdesc" != "$desc" ]]; then
# in_desc=0
# fi
desc="$desc ${${shortdesc:gs/[/\\[}:gs/]/\\]}"
continue
fi
_words=($=line)
# [[ ${_words[1][1]} == '-' ]] || continue
i=0
for w in $_words; do
(( i++ ))
if [[ $w[1] == '-' ]]; then
opt="${w%,}"
# Remove `=` operator example values from the help output
opt="${opt%%=*}"
# -k is defined manually.
[[ "$opt" == "-k" ]] && break
opts+=($opt)
else
desc=${_words[i,-1]}
if [[ -z "$desc" ]]; then
in_desc=1
break
fi
desc=${${desc:gs/[/\\[}:gs/]/\\]}
in_desc=1
# TODO: do not split on "e.g.": look at end and ". " only?!
# shortdesc=${desc%%.*}
# if [[ "$shortdesc" == "$desc" ]]; then
# in_desc=1
# fi
# desc="$shortdesc"
break
fi
done
done
pytest_options+=('-k[only run tests matching the substring expression]:tag:_complete_tag')
_store_cache pytest_options pytest_options
fi
}
_pytest_options
_arguments -C \
':file:_files' \
$pytest_options \
'*::options:->options' && ret=0
_pytest_options
return $ret