summaryrefslogtreecommitdiff
path: root/Completion/Commands
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Commands')
-rw-r--r--Completion/Commands/_next_tags168
1 files changed, 97 insertions, 71 deletions
diff --git a/Completion/Commands/_next_tags b/Completion/Commands/_next_tags
index d9a5f08d8..a308b307c 100644
--- a/Completion/Commands/_next_tags
+++ b/Completion/Commands/_next_tags
@@ -3,30 +3,103 @@
# Main widget.
_next_tags() {
- local comp ins
+ local ins ops="$PREFIX$SUFFIX"
- if [[ -z $compstate[old_list] ]]; then
- comp=()
+ unfunction _all_labels _next_label
+
+ _all_labels() {
+ local gopt=-J len tmp pre suf ret=1 descr spec
+
+ if [[ "$1" = -([12]|)[VJ] ]]; then
+ gopt="$1"
+ shift
+ fi
+
+ tmp=${argv[(ib:4:)-]}
+ len=$#
+ if [[ tmp -lt len ]]; then
+ pre=$(( tmp-1 ))
+ suf=$tmp
+ elif [[ tmp -eq $# ]]; then
+ pre=-2
+ suf=$(( len+1 ))
+ else
+ pre=4
+ suf=5
+ fi
+
+ while comptags -A "$1" curtag spec; do
+ [[ "$_next_tags_not" = *\ ${spec}\ * ]] && continue
+ _comp_tags="$_comp_tags $spec "
+ if [[ "$curtag" = *:* ]]; then
+ zformat -f descr "${curtag#*:}" "d:$3"
+ _description "$gopt" "${curtag%:*}" "$2" "$descr"
+ curtag="${curtag%:*}"
+
+ "$4" "${(P@)2}" "${(@)argv[5,-1]}"
+ else
+ _description "$gopt" "$curtag" "$2" "$3"
+
+ "${(@)argv[4,pre]}" "${(P@)2}" "${(@)argv[suf,-1]}" && ret=0
+ fi
+ done
+
+ return ret
+ }
+
+ _next_label() {
+ local gopt=-J descr spec
+
+ if [[ "$1" = -([12]|)[VJ] ]]; then
+ gopt="$1"
+ shift
+ fi
+
+ if comptags -A "$1" curtag spec; then
+ [[ "$_next_tags_not" = *\ ${spec}\ * ]] && continue
+ _comp_tags="$_comp_tags $spec "
+ if [[ "$curtag" = *:* ]]; then
+ zformat -f descr "${curtag#*:}" "d:$3"
+ _description "$gopt" "${curtag%:*}" "$2" "$descr"
+ curtag="${curtag%:*}"
+ eval "${2}=( \${(P)2} \$argv[4,-1] )"
+ else
+ _description "$gopt" "$curtag" "$2" "$3"
+ eval "${2}=( \$argv[4,-1] \${(P)2} )"
+ fi
+
+ return 0
+ fi
+
+ return 1
+ }
+
+ if [[ "${LBUFFER%${PREFIX}}" = "$_next_tags_pre" ]]; then
+ PREFIX="$_next_tags_pfx"
+ SUFFIX="$_next_tags_sfx"
else
- comp=(_complete)
+ _next_tags_pre="${LBUFFER%${PREFIX}}"
+ if [[ "$LASTWIDGET" = (_next_tags|list-*|*complete*) ]]; then
+ PREFIX="$_lastcomp[prefix]"
+ SUFFIX="$_lastcomp[suffix]"
+ fi
fi
- (( $+_sort_tags )) || _next_tags_not=
-
- _sort_tags=_next_tags_sort
- _next_tags_pre="${LBUFFER%${PREFIX}}"
_next_tags_not="$_next_tags_not $_lastcomp[tags]"
+ _next_tags_pfx="$PREFIX"
+ _next_tags_sfx="$SUFFIX"
if [[ -n "$compstate[old_insert]" ]]; then
- PREFIX="$_lastcomp[prefix]"
- SUFFIX="$_lastcomp[suffix]"
ins=1
+ else
+ ins=unambiguous
fi
- _main_complete "$comp[@]"
+ _main_complete _complete _next_tags_completer
- [[ $compstate[insert] = automenu ]] &&
- compstate[insert]=automenu-unambiguous
+ [[ $compstate[insert] = automenu ]] && compstate[insert]=automenu-unambiguous
+ [[ $compstate[insert] = *unambiguous && -n "$ops" &&
+ -z "$_lastcomp[unambiguous]" ]] && compadd -Uns "$SUFFIX" - "$PREFIX"
compstate[insert]="$ins"
compstate[list]='list force'
@@ -34,11 +107,19 @@ _next_tags() {
compprefuncs=( "$compprefuncs[@]" _next_tags_pre )
}
+# Completer, for wrap-around.
+
+_next_tags_completer() {
+ _next_tags_not=
+
+ _complete
+}
+
# Pre-completion function.
_next_tags_pre() {
- # Probably `remove' our sort function. A better test would be nice, but
+ # Probably `remove' our label functions. A better test would be nice, but
# I think one should still be able to edit the current word between
# attempts to complete it.
@@ -47,65 +128,10 @@ _next_tags_pre() {
compstate[insert]=menu:2
return 0
elif [[ ${LBUFFER%${PREFIX}} != ${_next_tags_pre}* ]]; then
- unset _sort_tags
+ unfunction _all_labels _next_label
+ autoload -U _all_labels _next_label
else
compprefuncs=( "$compprefuncs[@]" _next_tags_pre )
- [[ -n "$compstate[old_list]" && -n "$_next_tags_reset" ]] &&
- _next_tags_not= _next_tags_reset=
- fi
-}
-
-# Helper function for sorting tags. Most of this is copied from _tags.
-
-_next_tags_sort() {
- local order tags tag nodef tmp
-
- zstyle -a ":completion:${curcontext}:" tag-order order ||
- order=('arguments values' options)
-
- # But we also remove the tags we've already tried...
-
- tags=( "${(@)order:#(${(j:|:)~${=_next_tags_not}})(|:*)}" )
-
- # ... unless that would remove all offered tags.
-
- if [[ $funcstack[4] = _files ]]; then
- if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then
- [[ "$tags" = *${${tmp[-1]##[^\\]:}%:*}* ]] &&
- tags=( $order ) _next_tags_reset=yes
- else
- [[ "$tags" = *all-files* ]] && tags=( $order ) _next_tags_reset=yes
- fi
- else
- [[ $#tags -ne $#order && "$tags" != *(${(j:|:)~argv})* ]] &&
- tags=( $order ) _next_tags_reset=yes
- fi
- for tag in $tags; do
- case $tag in
- -) nodef=yes;;
- *\(\)) "${${tag%%[ ]#\(\)}##[ ]#}" "$@";;
- \!*) comptry "${(@)argv:#(${(j:|:)~${=~tag[2,-1]}})}";;
- ?*) comptry -m "$tag";;
- esac
- done
-
- if [[ -z "$nodef" ]]; then
- if [[ $funcstack[4] = _files ]]; then
- if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then
- [[ "$argv" = *${${tmp[-1]#*[^\\]:}%:*}* ]] && _next_tags_reset=yes
- else
- [[ "$argv" = *all-files* ]] && _next_tags_reset=yes
- fi
- fi
- tmp=( "${(@)argv:#(${(j:|:)~${=_next_tags_not}})(|:*)}" )
-
- # $prev is set in _tags!
-
- if [[ -n "$prev" && ( $#tmp -ne 0 || $funcstack[4] = _files ) ]]; then
- comptry "$tmp[@]"
- else
- comptry "$argv[@]"
- fi
fi
}