summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Base/Completer/.distfiles17
-rw-r--r--Completion/Base/Completer/_user_expand141
-rw-r--r--Doc/Zsh/compsys.yo43
4 files changed, 195 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 31f4d6a45..7438d1e81 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2009-03-25 Peter Stephenson <pws@csr.com>
+ * 26783: Doc/Zsh/compsys.yo, Completion/Base/Completer/.distfiles,
+ Completion/Base/Completer/_user_expand: new _user_expand completer.
+
* Jon Strait: 26778, 26781: Doc/Zsh/mod_pcre.yo,
Src/Modules/pcre.c: a couple of extra options for PCRE matching.
@@ -11490,5 +11493,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4637 $
+* $Revision: 1.4638 $
*****************************************************
diff --git a/Completion/Base/Completer/.distfiles b/Completion/Base/Completer/.distfiles
index 5fd0e6071..3030142de 100644
--- a/Completion/Base/Completer/.distfiles
+++ b/Completion/Base/Completer/.distfiles
@@ -1,6 +1,17 @@
DISTFILES_SRC='
.distfiles
-_all_matches _correct _history _match _prefix
-_approximate _expand _ignored _menu
-_complete _expand_alias _list _oldlist
+_all_matches
+_approximate
+_complete
+_correct
+_expand
+_expand_alias
+_history
+_ignored
+_list
+_match
+_menu
+_oldlist
+_prefix
+_user_expand
'
diff --git a/Completion/Base/Completer/_user_expand b/Completion/Base/Completer/_user_expand
new file mode 100644
index 000000000..049cc31ef
--- /dev/null
+++ b/Completion/Base/Completer/_user_expand
@@ -0,0 +1,141 @@
+#autoload
+
+# This completer function is an addition to the _expand completer that
+# allows the user to define their own expansions. It does not replace
+# the _expand completer.
+#
+# This function will allow other completer functions to be called if
+# the expansions done produce no result or do not change the original
+# word from the line.
+
+setopt localoptions nonomatch
+
+[[ _matcher_num -gt 1 ]] && return 1
+
+local exp word sort expr expl subd suf=" " asp tmp spec
+local -a specs reply
+
+if [[ "$funcstack[2]" = _prefix ]]; then
+ word="$IPREFIX$PREFIX$SUFFIX"
+else
+ word="$IPREFIX$PREFIX$SUFFIX$ISUFFIX"
+fi
+
+# In exp we will collect the expansions.
+
+exp=("$word")
+
+# Now look for user completions.
+
+zstyle -a ":completion:${curcontext}" user-expand specs || return 1
+
+for spec in $specs; do
+ case $spec in
+ ('$'[[:IDENT:]]##)
+ # Spec is an associative array with explicit keys.
+ # Surely there's a better way of doing an associative array
+ # lookup from its name?
+ eval tmp='${'$spec[2,-1]'[$word]}'
+ if [[ -n $tmp ]]; then
+ exp=("$tmp")
+ break
+ fi
+ ;;
+
+ ('_'*)
+ reply=()
+ $spec $word
+ if (( ${#reply} )); then
+ exp=("${reply[@]}")
+ break
+ fi
+ ;;
+ esac
+done
+
+[[ $#exp -eq 1 && "$exp[1]" = "$word" ]] && return 1
+
+# Now add as matches whatever the user requested.
+
+zstyle -s ":completion:${curcontext}:" sort sort
+
+[[ "$sort" = (yes|true|1|on) ]] && exp=( "${(@o)exp}" )
+
+if zstyle -s ":completion:${curcontext}:" add-space tmp; then
+ if [[ "$tmp" != *subst* || "$word" != *\$* || "$exp[1]" = *\$* ]]; then
+ [[ "$tmp" = *file* ]] && asp=file
+ [[ "$tmp" = *(yes|true|1|on|subst)* ]] && asp="yes$asp"
+ fi
+else
+ asp=file
+fi
+
+# If there is only one expansion, add a suitable suffix
+
+if (( $#exp == 1 )); then
+ if [[ -d ${exp[1]} && "$exp[1]" != */ ]]; then
+ suf=/
+ elif [[ "$asp" = yes* ||
+ ( "$asp" = *file && -f "${exp[1]}" ) ]]; then
+ suf=' '
+ else
+ suf=
+ fi
+fi
+
+if [[ -z "$compstate[insert]" ]] ;then
+ if [[ "$sort" = menu ]]; then
+ _description expansions expl expansions "o:$word"
+ else
+ _description -V expansions expl expansions "o:$word"
+ fi
+
+ compadd "$expl[@]" -UQ -qS "$suf" -a exp
+else
+ _tags all-expansions expansions original
+
+ if [[ $#exp -gt 1 ]] && _requested expansions; then
+ local i j normal space dir
+
+ if [[ "$sort" = menu ]]; then
+ _description expansions expl expansions "o:$word"
+ else
+ _description -V expansions expl expansions "o:$word"
+ fi
+ normal=()
+ space=()
+ dir=()
+
+ for i in "$exp[@]"; do
+ j="${i}"
+ if [[ -d "$j" && "$i" != */ ]]; then
+ dir=( "$dir[@]" "$i" )
+ elif [[ "$asp" = yes* || ( "$asp" = *file && -f "$j" ) ]]; then
+ space=( "$space[@]" "$i" )
+ else
+ normal=( "$normal[@]" "$i" )
+ fi
+ done
+ (( $#dir )) && compadd "$expl[@]" -UQ -qS/ -a dir
+ (( $#space )) && compadd "$expl[@]" -UQ -qS " " -a space
+ (( $#normal )) && compadd "$expl[@]" -UQ -qS "" -a normal
+ fi
+ if _requested all-expansions expl 'all expansions'; then
+ local disp dstr
+
+ if [[ "${#${exp}}" -ge COLUMNS ]]; then
+ disp=( -ld dstr )
+ dstr=( "${(r:COLUMNS-5:)exp} ..." )
+ else
+ disp=()
+ fi
+ [[ -o multios ]] && exp=($exp[1] $compstate[redirect]${^exp[2,-1]})
+ compadd "$disp[@]" "$expl[@]" -UQ -qS "$suf" - "$exp"
+ fi
+
+ _requested original expl original && compadd "$expl[@]" -UQ - "$word"
+
+ compstate[insert]=menu
+fi
+
+return 0
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index 3bd5f008a..f7e47b1e1 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -202,6 +202,13 @@ to tt(fpath) as necessary. To force a check of exactly the directories
currently named in tt(fpath), set tt(_compdir) to an empty string before
calling tt(compaudit) or tt(compinit).
+findex(bashcompinit)
+The function tt(bashcompinit) compatibility with bash's programmable
+completion system. When run it will define the functions, tt(compgen) and
+tt(complete) which correspond to the bash builtins with the same names.
+It will then be possible to use completion specifications and functions
+written for bash.
+
subsect(Autoloaded files)
cindex(completion system, autoloaded functions)
@@ -3096,13 +3103,35 @@ tt(COMPLETE_IN_WORD) option is set; otherwise, the cursor will
be moved to the end of the current word before the completion code is
called and hence there will be no suffix.
)
-findex(bashcompinit)
-item(tt(bashcompinit))(
-This function provides compatibility with bash's programmable completion
-system. When run it will define the functions, tt(compgen) and
-tt(complete) which correspond to the bash builtins with the same names.
-It will then be possible to use completion specifications and functions
-written for bash.
+findex(_user_expand)
+item(tt(_user_expand))(
+This completer behaves similarly to the tt(_expand) completer but
+instead performs expansions defined by users. The styles tt(add-space) and
+tt(sort) styles specific to the tt(_expand) completer are usable with
+tt(_user_expand) in addition to other styles handled more generally by
+the completion system. The tag tt(all-expansions) is also available.
+
+The expansion depends on the array style tt(user-expand) being defined
+for the current context; remember that the context for completers is less
+specific than that for contextual completion as the full context has not
+yet been determined. Elements of the array may have one of the following
+forms:
+startsitem()
+sitem(tt($)var(hash))(
+var(hash) is the name of an associative array. Note this is not a full
+parameter expression, merely a tt($), suitably quoted to prevent immediate
+expansion, followed by the name of an associative array. If the trial
+expansion word matches a key in var(hash), the resulting expansion is the
+corresponding value.
+)
+sitem(var(_func))(
+var(_func) is the name of a shell function whose name must begin with
+tt(_) but is not otherwise special to the completion system. The function
+is called with the trial word as an argument. If the word is to be
+expanded, the function should set the array tt(reply) to a list of
+expansions. The return status of the function is irrelevant.
+)
+endsitem()
)
enditem()