aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2000-04-02 17:23:08 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2000-04-02 17:23:08 +0000
commit427ace542736d7b2d4fcf28268a884f867ac3baf (patch)
tree97f4f242d9e8fe1888add4e5034c17318ca75a3c
parent48525452555a24b9d41748f26b4b77f160f01220 (diff)
downloadzsh-427ace542736d7b2d4fcf28268a884f867ac3baf.tar.gz
zsh-427ace542736d7b2d4fcf28268a884f867ac3baf.tar.xz
zsh-427ace542736d7b2d4fcf28268a884f867ac3baf.zip
Removed renamed files for tag labels
-rw-r--r--Completion/Core/_loop44
-rw-r--r--Completion/Core/_try24
-rw-r--r--Completion/Core/compinstall1627
3 files changed, 1322 insertions, 373 deletions
diff --git a/Completion/Core/_loop b/Completion/Core/_loop
deleted file mode 100644
index fa7118ec4..000000000
--- a/Completion/Core/_loop
+++ /dev/null
@@ -1,44 +0,0 @@
-#autoload
-
-local gopt=-J len tmp pre suf tloop ret=1 descr
-
-if [[ "$1" = -t ]]; then
- tloop=yes
- shift
-fi
-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 [[ -z "$tloop" ]] || comptags -N; do
- while comptags -A "$1" curtag; do
- 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
- [[ -z "$tloop" || ret -eq 0 ]] && break
-done
-
-return ret
diff --git a/Completion/Core/_try b/Completion/Core/_try
deleted file mode 100644
index e309e53ea..000000000
--- a/Completion/Core/_try
+++ /dev/null
@@ -1,24 +0,0 @@
-#autoload
-
-local gopt=-J descr
-
-if [[ "$1" = -([12]|)[VJ] ]]; then
- gopt="$1"
- shift
-fi
-
-if comptags -A "$1" curtag; then
- 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
diff --git a/Completion/Core/compinstall b/Completion/Core/compinstall
index ad05cb5a1..d557a86b4 100644
--- a/Completion/Core/compinstall
+++ b/Completion/Core/compinstall
@@ -1,361 +1,1378 @@
-# This script is to be run by a user to set up the new function based
-# completion system. The functions themselves are assumed to be already
-# available in some directory; they should have been installed with the
-# the shell. If they have been, the commands `autoload -U compinit; compinit'
-# in the shell startup file should be enough, although you can run
-# compinstall for more configuration choices.
+emulate -L zsh
+setopt extendedglob
+
+local key
+
+__ci_tidyup() {
+ unfunction -m __ci_\* 2>/dev/null
+ unfunction compinstall
+ autoload -U compinstall
+}
+
+__ci_newline() {
+ read -k \
+ key"?${1:---- Hit newline to continue or \`q' to exit without saving --- }"
+ print
+ if [[ $key = [qQ] ]]; then
+ print "compinstall aborted."
+ __ci_tidyup
+ return 1
+ else
+ return 0
+ fi
+}
+
+typeset startline='# The following lines were added by compinstall'
+typeset endline='# End of lines added by compinstall'
+typeset ifile=${ZDOTDIR:-~}/.zshrc line fpath_line
+typeset -A styles
+typeset match mbegin mend matchers warn_unknown warn_old warn_comment
+integer lines_found
+matchers=()
+
#
-# Simply run this script as a function and answer the questions.
-# Normally it will alter ~/.zshrc (or wherever ZDOTDIR puts it), but you
-# can make that unwritable and it will leave the lines in a temporary file
-# instead. It doesn't matter if .zshrc didn't exist before. If your
-# .zshrc usually exits before the end, then you should take the code added
-# by compinstall and put it (including the comment lines at the start and
-# end) at the point you want it to be executed. If you run compinstall
-# again it will find and replace those lines, so you can use this script to
-# modify what compinstall previously added to ~/.zshrc.
+# Check the user's .zshrc, if any.
#
-# It is safe to abort with ^C any time you are being prompted for
-# information; your .zshrc will not be altered.
+# This relies on the stuff we find being only minimally edited from
+# the stuff we originally saved. A better way of doing this would
+# almost certianly be to use the style mechanism directly: save the
+# current styles in a variable, delete all styles, read in and evaluate
+# any styles found, manipulate styles directly using zstyle, write out
+# using zstyle -L, and if necessary restore the original styles. One
+# day I may even do that.
#
-# To do:
-# - Should probably offer to set different options for _approximate than
-# for _complete if both are used.
-# - Could add code for setting other completers and options.
-# - Could add keys for context-sensitive help.
-
-
-emulate -L zsh
-typeset _ci_options _ci_f _ci_fdir _ci_files _ci_dumpfile _ci_lines
-typeset _ci_type _ci_completer _ci_accept _ci_cprompt _ci_startline
-typeset _ci_endline _ci_ifile _ci_tmpf _ci_compstyle _ci_warn
-typeset _ci_dtype _ci_existing _ci_line _ci_end
-
-# Look for the defaults.
-_ci_startline='# The following lines were added by compinstall'
-_ci_endline='# End of lines added by compinstall'
-
-_ci_ifile=${ZDOTDIR:-~}/.zshrc
-_ci_lines=''
-_ci_existing=''
-
-typeset -A _ci_defaults
-
-if [[ -f $_ci_ifile ]]; then
- # This assumes the lines haven't been altered by the user too much
- # after they were added.
- _ci_compstyle=0
- sed -n "/^$_ci_startline/,/^$_ci_endline/p" $_ci_ifile |
- while read -rA _ci_line; do
- if (( $_ci_compstyle )); then
- # parse a compstyle component as first argument
- if [[ $_ci_line[-1] != \\ ]]; then
- _ci_end=-1
- _ci_compstyle=0
- else
- _ci_end=-2
- fi
- if [[ $_ci_line[1] = *=* ]]; then
- _ci_f="${${_ci_line[1,$_ci_end]}#*=}"
- if [[ $_ci_f = \'*\' ]]; then
- # strip quotes
- _ci_f=${_ci_f[2,-2]//\'\\\'\'/\'}
- fi
- _ci_defaults[${_ci_line[1]%%\=*}]=$_ci_f
- fi
- _ci_existing="${_ci_existing} $_ci_line
-"
- elif [[ $_ci_line[1] = compinit ]]; then
- # parse the line running compinit
- [[ $_ci_line[2] = -f ]] && _ci_fdir=$_ci_line[3]
- [[ $_ci_line[-2] = -d ]] && _ci_dumpfile=$_ci_line[-1]
- elif [[ $_ci_line[1] = _compdir=* ]]; then
- _ci_fdir=${_ci_line[1]##_compdir=}
- elif [[ $_ci_line[1] = compstyle ]]; then
- # parse a compstyle component as second argument (should be completer)
- [[ $_ci_line[3] = completer ]] &&
- _ci_completer=${_ci_line[3,-1]}
- [[ $_ci_line[-1] == \\ ]] && _ci_compstyle=1
- _ci_existing="${_ci_existing}$_ci_line
-"
- elif [[ $_ci_line[1] != \#* && $_ci_line[1] != (autoload|\[\[) ]]; then
- if [[ -z $_ci_warn ]]; then
- _ci_warn=1
- print "Warning: existing lines in compinstall setup not understood:"
+if [[ -f $ifile ]]; then
+ sed -n "/^[ ]*$startline/,/^[ ]*$endline/p" $ifile |
+ # Use the default read behaviour to handle any continuation lines.
+ while read line; do
+ (( lines_found++ ))
+ if [[ $line = *'$fpath'* ]]; then
+ fpath_line=$line
+ if [[ $line != *\) ]]; then
+ while read -r line; do
+ fpath_line="$fpath_line
+$line"
+ [[ $line = *\) ]] && break
+ done
fi
- print - $_ci_line
- _ci_existing="${_ci_existing}$_ci_line
-"
+ elif [[ $line = (#b)[[:blank:]]#zstyle[[:blank:]]##(\'[^\']#\')\
+[[:blank:]]##([^[:blank:]]##)[[:blank:]]##(*) ]]; then
+ styles[$match[2]]="${styles[$match[2]]:+${styles[$match[2]]}
+}${(Q)match[1]}
+${match[3]}"
+ elif [[ $line = [[:blank:]]#compconf* ]]; then
+ warn_old=1
+ elif [[ $line = [[:blank:]]#\#* ]]; then
+ warn_comment=1
+ elif [[ $line != [[:blank:]]# &&
+ $line != [[:blank:]]#'autoload -U compinit' &&
+ $line != [[:blank:]]#compinit ]]; then
+ warn_unknown="${warn_unknown:+$warn_unknown
+}$line"
fi
done
fi
+#
+# Print warnings about what we found in .zshrc.
+#
+
+if [[ -n $warn_old ]]; then
+ print "\
+WARNING: your configuration appears to contain commands for the 3.1.6
+configuration system. You will have to reconfigure from scratch and the
+existing configuration commands will be overwritten. If you wish to preserve
+the old commands, you should quit, copy them somewhere else, then rerun
+compinstall. Sorry."
+elif [[ -n $warn_unknown ]]; then
+ print "\
+WARNING: your configuration contains bits not understood by compinstall,
+which will not be retained (shown below). If you wish to retain these, you
+should quit, copy them somewhere else, and then rerun compinstall.
+
+$warn_unknown"
+elif [[ -n $warn_comment ]]; then
+ print "All the comments in your configuration section will be lost.
+If you want to keep them, you should copy them somewhere else first."
+elif (( ! $lines_found )); then
+ print -n "Starting a new completion configuration from scratch.
+This will be "
+ if [[ ! -f $ifile ]]; then
+ print "written to the new file $ifile."
+ elif [[ ! -w $ifile ]]; then
+ print "written to the file ~/.compinstall for copying to $ifile."
+ ifile=$HOME/.compinstall
+ else
+ print "appended to the file $ifile. It is up to you to ensure
+that these lines are actually executed. They will not be if your .zshrc
+usually returns before the end."
+ fi
+fi
+
+__ci_newline || return 1
-# Find out where the completion functions are kept.
-if [[ -z $_ci_fdir || ! -f ${~_ci_fdir}/compinit ||
- ! -f ${~_ci_fdir}/compdump ]]; then
- for _ci_f in $fpath; do
- if [[ $_ci_f != . && -f $_ci_f/compinit && -f $_ci_f/compdump ]]; then
- _ci_fdir=$_ci_f
- break
- elif [[ $_ci_f != . && -f $_ci_f/Core/compinit &&
- -f $_ci_f/Core/compdump ]]
- then
- _ci_fdir=$_ci_f/Core
- break
+typeset d compdir subdirs lines
+
+#
+# Make sure we have the completion functions in $fpath.
+#
+
+__ci_set_compdir() {
+ for d in $*; do
+ # If we find both the functions more than once, assume the later
+ # one is the standard set.
+ if [[ -f $d/compinit && -f $d/compdump ]]; then
+ compdir=$d
fi
done
+}
+
+__ci_set_compdir $fpath
+
+if [[ $compdir = */Core && -d $compdir/../Base ]]; then
+ subdirs=1
+ compdir=${compdir:h}
fi
-if [[ -z $_ci_fdir || ! -d ${~_ci_fdir} ]]; then
- print \
-"Please edit the name of the directory where the completion functions are
-installed. If they are not installed, you will need to find them in the
-Completion/* directories of the zsh distribution and install them yourself,
-or insult your system manager for incompetence."
- vared -c _ci_fdir
- while [[ ! -d ${~_ci_fdir} ||
- ((! -f ${~_ci_fdir}/compinit || ! -f ${~_ci_fdir}/compdump) &&
- (! -f ${~_ci_fdir}/Core/compinit || ! -f ${~_ci_fdir}/Core/compdump)) ]]
- do
- print "I can't find them in that directory. Try again or abort."
- vared _ci_fdir
- done
- if [[ -f ${~_ci_fdir}/Core/compinit && ! -f ${~_ci_fdir}/compinit ]]; then
- _ci_fdir=$_ci_fdir/Core
+if [[ -z $compdir ]]; then
+ # Start up a new zsh and get its default fpath. If some swine has
+ # tinkered with this in /etc/zshenv we're out of luck.
+ lines=${(f)"$(zsh -fc 'print -l $ZSH_VERSION $fpath')"}
+ lines=$lines[1]
+ shift lines
+ # If the zsh in that path isn't right, maybe the user's shell is elsewhere.
+ if [[ $line != $ZSH_VERSION && -x $SHELL ]]; then
+ lines=${(f)"$($SHELL -fc 'print -l $ZSH_VERSION $fpath' 2>/dev/null)"}
+ lines=$lines[1]
+ shift lines
+ fi
+ if [[ $line != $ZSH_VERSION ]]; then
+ print "Hmmm, the zsh in your path is not what's running, nor is \$SHELL.
+That's bad.
+"
+ fi
+ __ci_set_compdir $lines
+ if [[ -n $compdir ]]; then
+ print "\
+I've found the completion directories and will add them to your \$fpath,
+but they should already be there at shell startup, so something (probably
+an unconditional assignment in a startup file) is taking them out. You
+might want to check this, although what I'm doing should work."
+ if [[ -n $fpath_line ]]; then
+ print "\
+
+What's more, there is already an \$fpath assignment in your completion
+setup. This gives me cause for concern. I will override this, but don't
+be surprised if it doesn't go according to plan. If you have not
+initialised completion in this shell, you should do so, then run
+compinstall again."
+ fi
+ fi
+ if [[ -n $subdirs ]]; then
+ fpath_line=($compdir/[A-Z]*)
+ fpath_line="fpath=($fpath ${(F)fpath_line})"
fi
else
- print "Keeping existing completion directiory $_ci_fdir"
+ if [[ -n $subdirs ]]; then
+ print "Completion directories $compdir/*
+are already in your \$fpath, good."
+ else
+ print "Completion directory $compdir is already in your \$fpath, good."
+ fi
+ if [[ -n $fpath_line ]]; then
+ print "I shall keep the existing \$fpath=( ... ) assignment."
+ fi
fi
-if [[ ${~_ci_fdir} != /* ]]; then
- _ci_fdir=$(cd $_ci_fdir;builtin pwd)
-fi
+if [[ -z $compdir ]]; then
+ print "\
+The zsh in your path doesn't seem to have completion directories in the
+function autoload path (\$fpath). This suggests the shell wasn't installed
+for completion. If you want to use it, you will need to locate all the
+completion functions yourself and install them in your \$fpath. I will
+continue, but don't expect this to have much effect until you do.
-# Check if this is in fpath already, else put it there (with ~'s expanded).
-_ci_f=${~_ci_fdir}
-[[ -z ${fpath[(r)$_ci_f]} ]] && fpath=($fpath $_ci_f)
-
-# Contract $HOME to ~ in the parameter to be used for writing.
-_ci_fdir=${_ci_fdir/#$HOME/\~}
-
-# Now check the fpath, ignoring the directory .
-_ci_files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
-if [[ $#_ci_files -lt 20 ]]; then
- print "
-Hmmm, completion functions seem a bit thin on the ground. There should
-be lots of files with names beginning with an underscore (_). You should
-look and see what's happened to these.
-[Hit return to continue]"
- read
+If you are planning to continue using the old compctl system for
+completion, compinstall won't do you any good anyway."
fi
+__ci_newline || return 1
-# Set up the dumpfile
-_ci_dtype=existing
-if [[ -z $_ci_dumpfile ]]; then
- _ci_dumpfile="${ZDOTDIR:-$HOME}/.zcompdump"
- _ci_dtype=standard
-fi
-if [[ -w ${~_ci_dumpfile:h} && ( ! -f ${~_ci_dumpfile} ||
- -w ${~_ci_dumpfile} ) ]]
-then
- print "
-Using $_ci_dtype dumpfile
- ${_ci_dumpfile}
-to speed up initialisation.
-[Hit return to continue]"
- read
-else
- print "
-I will force completion to dump its status, which will speed up the shell's
-start-up considerably. However, I can't write the file I'd like to, namely
-${_ci_dumpfile}. Please edit a replacement."
- vared _ci_dumpfile
- while ! touch ${~_ci_dumpfile} >& /dev/null; do
- print "Sorry, I can't write that either. Try again."
- vared _ci_dumpfile
+#
+# Code for changing styles
+#
+
+typeset defcontext=":completion:*"
+typeset curcontext=$defcontext
+
+#
+# Utility functions
+#
+
+#
+# Get the style $1 for $curcontext into $2.
+#
+__ci_get_this_style() {
+ typeset -A tassoc
+ local style=$1 scalar=$2
+
+ tassoc=(${(f)styles[$style]})
+ eval "$scalar=\${tassoc[\$curcontext]}"
+}
+
+#
+# Set the style $1 for $curcontext using scalar $2 for the value for this
+# context. If $2 is null, delete the context (this may not be correct for
+# all styles). Don't do any extra quotation.
+# $2 gives the name of the scalar for symmetry with __ci_get_this_style.
+#
+__ci_set_this_style() {
+ local style=$1 scalar=$2 k
+ typeset -A tassoc
+ tassoc=(${(f)styles[$style]})
+
+ if [[ -n ${(P)scalar} ]]; then
+ tassoc[$curcontext]=${(P)scalar}
+ else
+ unset "tassoc[$curcontext]"
+ fi
+
+ styles[$style]=
+ for k in ${(ko)tassoc}; do
+ styles[$style]="${styles[$style]:+$styles[$style]
+}$k
+${tassoc[$k]}"
done
- [[ -s $_ci_dumpfile ]] || rm -f $_ci_dumpfile
-fi
+}
-_ci_lines="${_ci_lines}_compdir=$_ci_fdir
-[[ -z \$fpath[(r)\$_compdir] ]] && fpath=(\$fpath \$_compdir)
-autoload -U compinit
-compinit"
-[[ $_ci_dtype != standard ]] && _ci_lines="${_ci_lines} $_ci_dumpfile"
-_ci_lines="${_ci_lines}
+#
+# Functions displaying menus
+#
+
+__ci_change_context() {
+ clear
+ print "\
+ *** compinstall: change context ***
+
+The context tells the completion system under what circumstances your
+value will be used. It has this form:
+ :completion:<function-name>:<completer>:<command>:<argument>:<tag>
+See the documentation for more detail on each of these components. The
+default context \`$defcontext' matches everywhere in completion, unless you
+define a more specific pattern which matches the completion context being
+used. \`More specific' means either a string instead of a pattern, or a
+longer pattern instead of a shorter pattern.
+
+Edit a new context, or leave the line blank to reset the context to the
+default value. Note that you do not require quotes around the context,
+which will automatically be added later. Line editing and history are
+available.
"
+ vared -eh -p 'context> ' curcontext
+ [[ -z $curcontext ]] && curcontext=$defcontext
+}
-print "
-Would you like to set some more advanced options? Otherwise, you
-can re-run compinstall later to set these. [n]"
-
-# The whole of the next part should be indented, but I can't be bothered.
-if read -q; then
-
- print "
-In addition to completion, zsh can also perform correction of the
-current word, or approximate completion, i.e. completion where the part of
-the word typed so far can be corrected; or it can try correction, then
-approximate completion if that fails. Would you like:
- 0: Just ordinary completion
- C: Correction
- A: Approximate completion
- B: Both"
- if [[ -n $_ci_completer ]]; then
- print " Default: use the current completers:\n$_ci_completer"
+
+__ci_toggle_completer() {
+ # used locally within __ci_do_completers
+ if [[ -n $completers[$1] ]]; then
+ completers[$1]=
else
- print "Please type one of the keys above."
+ completers[$1]=1
fi
- while read -k _ci_type; do
+}
+
+__ci_do_minor_completer_options() {
+ # Set the options for the minor completers.
+ local key cond word olist omenu moriginal aspace
+ __ci_get_this_style condition cond
+ [[ -n $cond ]] && cond=${(Q)cond}
+ __ci_get_this_style word word
+ __ci_get_this_style old-list olist
+ __ci_get_this_style old-menu omenu
+ __ci_get_this_style match-original moriginal
+ __ci_get_this_style add-space aspace
+
+ while true; do
+
+ # insert-unambiguous can be handled somewhere else.
+ clear
+ print "\
+ *** compinstall: minor completer options ***
+
+Current context: $curcontext
+
+l. Set options for _list: condition for delay and comparison.
+o. Set options for _oldlist: when to keep old list.
+m. Set options for _match: whether to assume a \`*' at the cursor.
+p. Set options for _prefix: whether to add a space before the suffix.
+
+q. Return to the without saving.
+0. Done setting completer options.
+"
+
+ read -k key'?--- Hit selection --- '
+ print
+
+ [[ $key = 0 ]] && break
+
+ case $key in
+ [lL]) print "\
+You can set a condition under which the _list completer will delay completion
+until the second keypress. It should evaluate to a number; a non-zero value
+turns this behaviour on. It can include parameters, in particular NUMERIC
+to refer to a numeric argument. For example, \`NUMERIC != 1' forces the
+delay unless you give an argument 1 to the command. Leave it blank to
+assume the condition is true."
+ vared -eh -c -p 'condition> ' cond
+ print -n "
+_list will usually compare the contents of the entire line with its previous
+contents to decided if it has been changed since the last keypress. You
+can instead perform this comparison on just the current word, ignoring
+the rest of the command line. Do you want to do this? (y/n) [n] ? "
+ word=
+ read -q key && word=true
+ print
+ ;;
+ [oO]) print "\
+_oldlist can keep a generated completion list for reshowing in the usual
+way, e.g. with ^D, even if the list was generated by some special completion
+command. The default behaviour of _oldlist is to show this list if it was
+not already visible, otherwise to generate the standard completion listing,
+but you can force it always to be shown, or make it never shown. Choose:
+
+d. Default behaviour.
+a. Always show old list.
+n. Never show old list."
+ while true; do
+ read -k key'?--- Hit selection --- '
+ print
+ case $key in
+ [dD]) olist=
+ ;;
+ [aA]) olist=always
+ ;;
+ [nN]) olist=never
+ ;;
+ *) print "Type one of d, a or n."
+ continue
+ ;;
+ esac
+ break
+ done
+
+ print -n "
+_oldlist can keep the old completion list for use in menu completion, e.g. by
+repeatedly hitting tab, even if the list was generated by some special
+completion command. This is the default behaviour of _oldlist, but
+you can turn it off, so that hitting tab would use the standard completion
+list.
+
+Do you want to turn it off? (y/n) [n] "
+ omenu=
+ read -q key && omenu=false
+ ;;
+ [mM]) print "\
+The _match completer will usually assume there is a \`*' at the cursor
+position when trying pattern matches. For example, \`f*n<TAB>e' would
+be able to complete to \`filename', not just to patterns matching \`f*ne'.
+(Note that this assumes you have the option COMPLETE_IN_WORD set, else all
+completion takes place at the end of the word.) You can tell _match not
+to assume there is a \`*', or to try first without the \`*', then with it.
+Type one of:
+
+a. Always assume \`*' at cursor position.
+n. Never assume \`*' at cursor position.
+w. Try without the \`*', then with it if that fails."
+ while true; do
+ read -k key'?--- Hit selection --- '
+ print
+ case $key in
+ a) moriginal=
+ ;;
+ n) moriginal=only
+ ;;
+ w) moriginal=both
+ ;;
+ *) print "Type one of a, n or w."
+ continue
+ ;;
+ esac
+ break
+ done
+ ;;
+ [pP]) print -n "\
+The _prefix completer completes only what is behind the cursor, ignoring
+completely what is after, even if there is no space at the cursor position.
+However, you can force it to add a space between the resulting completion
+and the part ignored. For example, \`f<TAB>bar' might expand to \`filebar'
+without this, and to \`file bar' with it. Do wish _prefix to add the
+space? (y/n) [n] "
+ aspace=
+ read -q key && aspace=true
+ ;;
+ [qQ]) return 1
+ ;;
+ esac
+
+ done
+
+ [[ -n $cond && $cond != [[:alnum:]]## ]] && cond=${(qq)cond}
+ __ci_set_this_style condition cond
+ __ci_set_this_style word word
+ __ci_set_this_style old-list olist
+ __ci_set_this_style old-menu omenu
+ __ci_set_this_style match-original moriginal
+ __ci_set_this_style add-space aspace
+
+ return 0
+}
+
+__ci_do_minor_completers() {
+ # Set the minor completers not handled by __ci_do_completers.
+ # Called within __ci_do_completers, so inherits the environment.
+ # It's only divided off to keep the menus short.
+
+ local key
+
+ while true; do
+
+ clear
+ print "\
+ *** compinstall: minor completer menu ***
+
+Current context: $curcontext
+
+The following completers are available. Those marked \`(*)' are already
+set for the context shown above. Note none of these are required for
+normal completion behaviour.
+
+1. ${${completers[_list]:+(*)}:- } _list: $ckeys[_list]
+2. ${${completers[_oldlist]:+(*)}:- } _oldlist: $ckeys[_oldlist]
+3. ${${completers[_match]:+(*)}:- } _match: $ckeys[_match]
+4. ${${completers[_prefix]:+(*)}:- } _prefix: $ckeys[_prefix]
+
+o. Set options for the completers above.
+q. Return without saving.
+0. Done setting minor completers.
+"
+ read -k key'?--- Hit selection --- '
print
- case $_ci_type in
- 0*) _ci_completer=_complete
- break
- ;;
- [cC]*) _ci_completer='_complete _correct'
- break
- ;;
- [aA]*) _ci_completer='_complete _approximate'
- break;
- ;;
- [bB]*) _ci_completer='_complete _correct _approximate'
- break
- ;;
- *) [[ -n $_ci_completer ]] && break
- print Try again
+
+ [[ $key = 0 ]] && break
+
+ case $key in
+ 1) __ci_toggle_completer _list
+ ;;
+ 2) __ci_toggle_completer _oldlist
+ ;;
+ 3) __ci_toggle_completer _match
+ ;;
+ 4) __ci_toggle_completer _prefix
+ ;;
+ o) __ci_do_minor_completer_options
+ ;;
+ q) return 1
;;
esac
+
done
- _ci_lines="${_ci_lines}zstyle ':completion*' completer $_ci_completer"
+ return 0
+}
+__ci_do_completer_options() {
+ # Set options for the main completers; called from __ci_do_completers.
- if [[ $_ci_completer = *(correct|approx)* ]]; then
- _ci_accept=${_ci_defaults[correct_accept]}
- _ci_cprompt=${_ci_defaults[correct_prompt]}
- print "
-Correction and approximation will allow up to ${${_ci_accept:-2}%%[^0-9]*} \
-errors. "
- case $_ci_accept in
- *n*!*|*!*n) print "A numeric prefix, if not 1, will cause correction \
-not to be done."
- ;;
- *n*) print "A numeric prefix gives the maximum number of errors which \
-will be accepted."
- ;;
- *) print "The numeric prefix will not be used."
+ local maxe errors prompt glob subst compl cond
+
+ __ci_get_this_style max-errors errors
+ __ci_get_this_style prompt prompt
+ [[ -n $prompt ]] && prompt=${(Q)prompt}
+ __ci_get_this_style glob glob
+ [[ -n $glob ]] && glob=${(Q)glob}
+ __ci_get_this_style substitute subst
+ [[ -n $subst ]] && subst=${(Q)subst}
+ __ci_get_this_style completions compl
+ [[ -n $compl ]] && compl=${(Q)compl}
+
+ while true; do
+
+ clear
+ print "\
+ *** compinstall: completer options ***
+
+Current context: $curcontext
+
+The following options are available. Note that these require the relevant
+completers to be present, as set in the menu above this one.
+
+a. Set options for approximation or correction.
+e. Set options for expansion.
+q. Return without saving.
+
+0. Done setting options.
+"
+
+ read -k key'?--- Hit selection --- '
+ print
+
+ # We handle approximation and correction together to avoid having
+ # to be too particular about context.
+ case $key in
+ a) clear
+ print "\
+Approximation and correction can correct the errors in what you have typed,
+up to a maximum number of errors which you can specify. Each \`error'
+is the omission of a character, the addition of a superfluous character,
+the substitution of one character by an incorrect one, or transposition of
+two different characters.
+
+Current context: $curcontext
+
+To have different values for approximation and correction, you should
+change the context appropriately. For approximation, use
+\`:completion:*:approxima2te:*' and for correction use
+\`:completion:*:correct:*'.
+
+Enter maximum number of errors allowed:
+"
+ maxe=
+ while true; do
+ vared -eh -c -p "number> " maxe
+ [[ $maxe = [[:digit:]]## ]] && break
+ print "Please enter a number"
+ maxe=
+ done
+ while true; do
+ print "\nSelect behaviour of numeric prefix.
+
+1. Numeric prefix is not used by approximation or completion.
+2. Numeric prefix, if provided, gives max number of errors allowed,
+ replacing the number you just typed for that one completion.
+3. Numeric prefix, if provided, prevents approximation or completion
+ from taking place at all for that one completion.
+"
+ read -k -- key'?--- Hit selection --- '
+ print
+ [[ $key = [123] ]] || continue
+ case $key in
+ 2) maxe="$maxe numeric"
+ ;;
+ 3) maxe="$maxe not-numeric"
+ ;;
+ esac
+ print "
+You can edit a prompt which will appear above lists of corrections. The
+string \`%e' inside the prompt will be replaced with the number of errors
+found. Leave blank for no prompt. Quotation marks will be added
+automatically."
+ vared -eh -c -p "prompt> " prompt
+ break
+ done
+ errors=$maxe
+ ;;
+ e) while true; do
+ clear
+ print "\
+The _expand completer can be tuned to perform any of globbing (filename
+generation), substitution (anything with a \`\$' or backquote), or
+normal completion (which is useful for inserting all possible completions
+into the command line). For each feature, a 1 turns it on, while a 0 turns
+it off; if the feature is unset, that expansion will *not* be performed.
+
+You can also give more complicated mathematical expressions, which can use
+the parameter NUMERIC to refer to the numeric argument. For example, the
+expression \`NUMERIC == 2' means that the expansion takes effect if you
+type ESC-2 (Emacs mode) or 2 (Vi command mode) before the expansion.
+Quotes will be added automatically as needed.
+
+g. Set condition to perform globbing: ${glob:-unset}
+s. Set condition to perform substitution: ${subst:-unset}
+c. Set condition to perform completion: ${compl:-unset}
+0. Done setting conditions (will not be saved until you leave options)
+"
+ read -k key'?--- Enter selection --- '
+ print
+
+ case $key in
+ g) vared -eh -c -p 'globbing condition> ' glob
+ ;;
+ s) vared -eh -c -p 'substituion condition> ' subst
+ ;;
+ c) vared -eh -c -p 'completion condition> ' compl
+ ;;
+ esac
+
+ [[ $key = 0 ]] && break
+
+ done
+ ;;
+ q) return 1
+ ;;
esac
-print "The correction prompt is \`${_ci_cprompt:-correct to:}'.
-Do you want to change any of this? [n]"
- if read -q; then
- print "Number of errors to accept normally (0 is OK):"
- _ci_accept=${_ci_accept%%[^0-9]*}
- vared _ci_accept
- while [[ $_ci_accept != <-> ]]; do
- print "Please enter a number:"
- vared _ci_accept
- done
- print \
-"How would you like the numeric prefix to be treated:
- 0: Not used by correction
- U: The number gives the largest number of errors which will be
- accepted when correcting
- I: If present, and not 1, do not perform correction?
-Please type one of the keys above:"
- while read -k _ci_type; do
+
+ [[ $key = 0 ]] && break
+ done
+
+ __ci_set_this_style max-errors errors
+ [[ -n $prompt ]] && prompt=${(qq)prompt}
+ __ci_set_this_style prompt prompt
+ [[ -n $glob && $glob != [[:alnum:]]## ]] && glob=${(qq)glob}
+ __ci_set_this_style glob glob
+ [[ -n $subst && $subst != [[:alnum:]]## ]] && subst=${(qq)subst}
+ __ci_set_this_style substitute subst
+ [[ -n $compl && $compl != [[:alnum:]]## ]] && compl=${(qq)compl}
+ __ci_set_this_style completions compl
+
+ key=
+ return 0
+}
+
+__ci_do_completers() {
+ # Set the completers for the current context.
+ # This is mostly done via a series of toggles.
+
+ typeset -A completers ckeys
+ local c clist newc
+ __ci_get_this_style completer newc
+ for c in ${=newc}; do
+ completers[$c]=1
+ done
+ clist=(_list _oldlist _menu _expand _complete _match _correct _approximate
+ _prefix)
+
+ # TODO: these are a bit brief, so could provide some more detailed help.
+ ckeys=(_complete 'Basic completion.'
+ _approximate
+'Approximate completion: completion with correction of existing word.'
+ _correct
+'Correction: correct existing word, no completion.'
+ _expand
+'Expansion: use globbing and parameter substituion, if possible.'
+
+ _list
+'Only list matches until the second time you hit TAB.'
+ _oldlist
+'Keep matches generated by special completion functions.'
+ _match
+'If completion fails, retry with pattern matching.'
+ _prefix
+'If completion fails, retry ignoring the part after the cursor.'
+ )
+
+ # TODO: You'll need to handle the bindkey to make _expand work.
+ # TODO: _prefix completer should make sure completeinword is set.
+
+ while true; do
+
+ clear
+ print "\
+ *** compinstall: completer menu ***
+
+Current context: $curcontext
+
+The following completers are available. Those marked \`(*)' are already
+set for the context shown above. If none are selected, the completers will
+not be set for this context at all.
+
+1. ${${completers[_complete]:+(*)}:- } $ckeys[_complete]
+2. ${${completers[_approximate]:+(*)}:- } $ckeys[_approximate]
+3. ${${completers[_correct]:+(*)}:- } $ckeys[_correct]
+4. ${${completers[_expand]:+(*)}:- } $ckeys[_expand]
+
+o. Set options for the completers above.
+m. Set completers that modify the behaviour of the four main ones above.
+q. Return without saving.
+0. Done setting completers.
+"
+ read -k key'?--- Hit selection --- '
+ print
+
+ case $key in
+ 1) __ci_toggle_completer _complete
+ ;;
+ 2) __ci_toggle_completer _approximate
+ ;;
+ 3) __ci_toggle_completer _correct
+ ;;
+ 4) __ci_toggle_completer _expand
+ ;;
+ [mM]) __ci_do_minor_completers || return
+ continue
+ ;;
+ [oO]) __ci_do_completer_options || return
+ continue
+ ;;
+ q) return 1
+ ;;
+ esac
+
+ [[ $key = 0 ]] && break
+ done
+
+ newc=
+ for c in $clist; do
+ [[ -n $completers[$c] ]] && newc="${newc:+$newc }$c"
+ done
+ [[ -z $newc ]] && newc="''"
+ __ci_set_this_style completer newc
+}
+
+__ci_toggle_matcher() {
+ # Toggle on/off the matcher in array $1 for element $2
+ if