Skip to content

WIP: completion for pytest #454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions src/_pytest
Original file line number Diff line number Diff line change
@@ -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