mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-11-04 07:21:06 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			1830 lines
		
	
	
	
		
			54 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			1830 lines
		
	
	
	
		
			54 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
emulate -L zsh
 | 
						|
setopt extendedglob
 | 
						|
 | 
						|
local key
 | 
						|
local compcontext=-default-
 | 
						|
 | 
						|
__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 line fpath_line compinit_args
 | 
						|
typeset -A styles
 | 
						|
typeset match mbegin mend warn_unknown warn_old warn_comment
 | 
						|
integer lines_found
 | 
						|
 | 
						|
#
 | 
						|
# Check the user's .zshrc, if any.
 | 
						|
#
 | 
						|
# 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 certainly 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.
 | 
						|
#
 | 
						|
 | 
						|
__ci_test_ifile() {
 | 
						|
  [[ -f $1 ]] && grep "$endline" $1 >/dev/null 2>&1
 | 
						|
}
 | 
						|
 | 
						|
local foundold=false
 | 
						|
if zstyle -s :compinstall filename ifile &&
 | 
						|
  __ci_test_ifile $ifile; then
 | 
						|
  foundold=true
 | 
						|
else
 | 
						|
  ifile=${ZDOTDIR:-~}/.zshrc
 | 
						|
  if __ci_test_ifile ${ZDOTDIR:-~}/.compinstall; then
 | 
						|
    ifile=${ZDOTDIR:-~}/.compinstall
 | 
						|
    foundold=true
 | 
						|
  elif __ci_test_ifile $ifile; then
 | 
						|
    foundold=true
 | 
						|
  fi
 | 
						|
fi
 | 
						|
 | 
						|
local newifile=$ifile
 | 
						|
if [[ $foundold = true ]]; then
 | 
						|
  print "I have found completion definitions in $ifile.
 | 
						|
If you want me to read these, just hit return.  Otherwise, edit the file
 | 
						|
name to look for definitions somewhere else, or delete the whole line
 | 
						|
in order not to use existing definitions."
 | 
						|
  vared -ch -p 'file> ' newifile
 | 
						|
  [[ -z $newifile ]] && foundold=false
 | 
						|
else
 | 
						|
  print "I haven't found any existing completion definitions.
 | 
						|
If you have some already defined by compinstall, edit the name of the
 | 
						|
file where these can be found.  Note that this will only work if they
 | 
						|
are exactly the form in which compinstall inserted them.  If you leave
 | 
						|
the line as it is, or empty, I won't search."
 | 
						|
  while true;  do
 | 
						|
    vared -ch -p 'file> ' newifile || break
 | 
						|
    if [[ -n $newifile && $ifile != $newifile ]]; then
 | 
						|
      if __ci_test_ifile $newifile; then
 | 
						|
        foundold=true
 | 
						|
	break
 | 
						|
      fi
 | 
						|
      print "I couldn't find any definitions there.  Edit a new filename, or
 | 
						|
leave the line blank to ignore it."
 | 
						|
    else
 | 
						|
      break
 | 
						|
    fi
 | 
						|
  done
 | 
						|
fi
 | 
						|
ifile=$newifile
 | 
						|
 | 
						|
if [[ $foundold = true ]]; 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
 | 
						|
    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 == $startline || $line == $endline ]]; then
 | 
						|
      # no-op
 | 
						|
    elif [[ $line = [[:blank:]]#\#* ]]; then
 | 
						|
      warn_comment=1
 | 
						|
    elif [[ $line = [[:blank:]]#compinit[[:blank:]]##(#b)([^[:blank:]]*) ]]
 | 
						|
    then
 | 
						|
      compinit_args=$match[1]
 | 
						|
    elif [[ $line != [[:blank:]]# &&
 | 
						|
      $line != [[:blank:]]#'autoload -U compinit' &&
 | 
						|
      $line != [[:blank:]]#compinit &&
 | 
						|
      $line != [[:blank:]]#zstyle[[:blank:]]#:compinstall* ]]; 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 "Starting a new completion configuration from scratch."
 | 
						|
  if [[ -n $ifile && ! -d $ifile ]]; then
 | 
						|
    print -n "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
 | 
						|
fi
 | 
						|
print "Note that you will be given a chance to save the new setup
 | 
						|
somewhere else at the end."
 | 
						|
 | 
						|
 | 
						|
__ci_newline || return 1
 | 
						|
 | 
						|
 | 
						|
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 [[ -d $compdir/Base ]]; then
 | 
						|
  subdirs=1
 | 
						|
  ### compdir=${compdir:h}
 | 
						|
fi
 | 
						|
 | 
						|
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
 | 
						|
  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 [[ -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.
 | 
						|
 | 
						|
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
 | 
						|
 | 
						|
 | 
						|
#
 | 
						|
# 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
 | 
						|
}
 | 
						|
 | 
						|
#
 | 
						|
# 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
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
__ci_toggle_completer() {
 | 
						|
  # used locally within __ci_do_completers
 | 
						|
  if [[ -n $completers[$1] ]]; then
 | 
						|
    completers[$1]=
 | 
						|
  else
 | 
						|
    completers[$1]=1
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
__ci_do_minor_completer_options() {
 | 
						|
  # Set the options for the minor completers.
 | 
						|
  local key cond word olist omenu moriginal aspace tmparr
 | 
						|
  __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.
 | 
						|
Alternatively, you can specify a list of completers for which _oldlist will
 | 
						|
be used.  Choose:
 | 
						|
 | 
						|
d.    Default behaviour.
 | 
						|
a.    Always show old list.
 | 
						|
n.    Never show old list.
 | 
						|
s.    Specify a list of completers.
 | 
						|
"
 | 
						|
 | 
						|
            while true; do
 | 
						|
	      read -k key'?--- Hit selection --- '
 | 
						|
	      print
 | 
						|
	      case $key in
 | 
						|
		[dD]) olist=
 | 
						|
		   ;;
 | 
						|
		[aA]) olist=always
 | 
						|
		      ;;
 | 
						|
		[nN]) olist=never
 | 
						|
		      ;;
 | 
						|
		[sS]) olist=
 | 
						|
		      tmparr=(_complete _approximate _correct _match _expand)
 | 
						|
		      while true; do 
 | 
						|
			clear
 | 
						|
			print "\
 | 
						|
     *** compinstall:  choosing completers to have _oldlist behaviour ***
 | 
						|
 | 
						|
Type any of:
 | 
						|
 | 
						|
1.  _complete
 | 
						|
2.  _approximate
 | 
						|
3.  _correct
 | 
						|
4.  _match
 | 
						|
5.  _expand
 | 
						|
 | 
						|
or 0 to end, or - to delete the last choice."
 | 
						|
			if [[ -n $olist ]]; then
 | 
						|
			  print "\
 | 
						|
Current choices:
 | 
						|
  $olist"
 | 
						|
			fi
 | 
						|
			read -k key'?--- Hit selection --- '
 | 
						|
			print
 | 
						|
			case $key in
 | 
						|
			  0) break
 | 
						|
			     ;;
 | 
						|
			  -) olist=(${olist[1,-2]})
 | 
						|
			     ;;
 | 
						|
			  [1-5]) olist=($olist $tmparr[$key])
 | 
						|
			         ;;
 | 
						|
			esac
 | 
						|
                      done
 | 
						|
		      ;;
 | 
						|
		*) print "Type one of d, a, n or s."
 | 
						|
		   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[_ignored]:+(*)}:-   } _ignored: $ckeys[_ignored]
 | 
						|
2. ${${completers[_list]:+(*)}:-   } _list:    $ckeys[_list]
 | 
						|
3. ${${completers[_oldlist]:+(*)}:-   } _oldlist: $ckeys[_oldlist]
 | 
						|
4. ${${completers[_match]:+(*)}:-   } _match:   $ckeys[_match]
 | 
						|
5. ${${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
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
 | 
						|
    case $key in
 | 
						|
      1) __ci_toggle_completer _ignored
 | 
						|
	 if [[ -n $completers[_ignored] ]]; then
 | 
						|
	   print "\
 | 
						|
I am inserting the \`ignored' completer immediately after normal
 | 
						|
completion.  You can move it later in the list by hand, if you prefer, so
 | 
						|
that ignored completions are only used after, for example, approximations.
 | 
						|
To do this, edit $ifile, look for the zstyle ... completers line, and
 | 
						|
move \`_ignored' to where you want it.  This will be retained if you use
 | 
						|
compinstall again provided you don't go into the completers menu.
 | 
						|
"
 | 
						|
	   # TODO: we could be more careful about keeping the user's
 | 
						|
	   # order, particularly with multiple completers.
 | 
						|
           read -k key'?--- Hit any key to continue --- '
 | 
						|
	   print
 | 
						|
	 fi
 | 
						|
	 ;;
 | 
						|
      2) __ci_toggle_completer _list
 | 
						|
	 ;;
 | 
						|
      3) __ci_toggle_completer _oldlist
 | 
						|
	 ;;
 | 
						|
      4) __ci_toggle_completer _match
 | 
						|
	 ;;
 | 
						|
      5) __ci_toggle_completer _prefix
 | 
						|
	 ;;
 | 
						|
      o) __ci_do_minor_completer_options
 | 
						|
	 ;;
 | 
						|
      q) return 1
 | 
						|
	 ;;
 | 
						|
    esac
 | 
						|
 | 
						|
  done
 | 
						|
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
__ci_do_completer_options() {
 | 
						|
  # Set options for the main completers; called from __ci_do_completers.
 | 
						|
 | 
						|
  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:*:approximate:*' 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 'substitution condition> ' subst
 | 
						|
		;;
 | 
						|
	     c) vared -eh -c -p 'completion condition> ' compl
 | 
						|
		;;
 | 
						|
	   esac
 | 
						|
 | 
						|
	   [[ $key = 0 ]] && break
 | 
						|
 | 
						|
         done
 | 
						|
	 ;;
 | 
						|
      q) return 1
 | 
						|
	 ;;
 | 
						|
    esac
 | 
						|
 | 
						|
    [[ $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 _ignored 
 | 
						|
         _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 substitution, if possible.'
 | 
						|
 | 
						|
	 _ignored
 | 
						|
'Use patterns that were previously ignored if no matches so far.'
 | 
						|
         _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 [[ ${${(P)1}[$2]} = ' ' ]]; then
 | 
						|
    # toggle on
 | 
						|
    eval "${1}[$2]=$2"
 | 
						|
    if [[ $1 = n* ]]; then
 | 
						|
      # no matcher turned on, turn off the others
 | 
						|
      c_list[$2]=' '
 | 
						|
      C_list[$2]=' '
 | 
						|
      p_list[$2]=' '
 | 
						|
      s_list[$2]=' '
 | 
						|
    else
 | 
						|
      # something else turned on, turn off no matcher
 | 
						|
      n_list[$2]=' '
 | 
						|
    fi
 | 
						|
    return 0
 | 
						|
  else
 | 
						|
    # toggle off
 | 
						|
    eval "${1}[$2]=' '"
 | 
						|
    if [[ $c_list[$2] == ' ' && $C_list[$2] == ' ' && \
 | 
						|
	  $p_list[$2] == ' ' && $s_list[$2] == ' ' ]]; then
 | 
						|
      a_or_r[$2]=' '
 | 
						|
    fi
 | 
						|
    return 1
 | 
						|
  fi
 | 
						|
}
 | 
						|
 | 
						|
__ci_do_matchers() {
 | 
						|
  # Set matchers via the matcher-list style.
 | 
						|
  # We just offer a pre-programmed set of possible matchers, but these
 | 
						|
  # cover the most common usages for matchers in a general context.
 | 
						|
  # More specific use of matchers is usually covered by completion functions.
 | 
						|
 | 
						|
  local mlist m_ci m_pw m_sub c_list C_list p_list s_list pw_seps key key2 elt
 | 
						|
  local pw_dstar a_or_r i
 | 
						|
  integer eltcnt lastnz
 | 
						|
 | 
						|
  __ci_get_this_style matcher-list mlist
 | 
						|
  # $mlist is the once and future list of matchers.  We don't quote it
 | 
						|
  # until the end; the eval effectively does de-quoting.
 | 
						|
  eval "mlist=($mlist)"
 | 
						|
  # ?_list say whether the four possible matchers are set for passes 1,
 | 
						|
  # 2, 3, 4, in an easy-to-read manner, i.e. the Nth part of the string
 | 
						|
  # is one of N (on) or space (off).
 | 
						|
  a_or_r="    "                 # replace by default
 | 
						|
  n_list="    "			# null completion, i.e. standard
 | 
						|
  c_list="    "			# case match one way
 | 
						|
  C_list="    "			# case match both ways
 | 
						|
  p_list="    "			# partial word completion
 | 
						|
  s_list="    "			# substring completion
 | 
						|
  # $pw_seps gives the separators used for partial-word completion
 | 
						|
  # by element of the matcher list; these can be edited separately.
 | 
						|
  pw_seps=('._-' '._-' '._-' '._-')
 | 
						|
  pw_dstar=('' '' '' '')
 | 
						|
 | 
						|
  # See what's in the matcher initially.  If these have been edited,
 | 
						|
  # we're in trouble, but that's pretty much true of everything.
 | 
						|
  for (( eltcnt = 1; eltcnt <= $#mlist; eltcnt++ )); do
 | 
						|
    [[ $mlist[eltcnt] == "+"* ]] && a_or_r[$eltcnt]='+'
 | 
						|
    [[ -z $mlist[$eltcnt] ]] && n_list[$eltcnt]=$eltcnt
 | 
						|
    [[ $mlist[$eltcnt] = *"m:{a-z}={A-Z}"* ]] && c_list[$eltcnt]=$eltcnt
 | 
						|
    [[ $mlist[$eltcnt] = *"m:{a-zA-Z}={A-Za-z}"* ]] && C_list[$eltcnt]=$eltcnt
 | 
						|
    # For partial word stuff, we use backreferences to find out what
 | 
						|
    # the set of separators was.
 | 
						|
    if [[ $mlist[$eltcnt] = (#b)*"r:|["([^\]]#)"]=*"#" r:|=*"* ]]; then
 | 
						|
      p_list[$eltcnt]=$eltcnt
 | 
						|
      pw_seps[$eltcnt]=${match[1]}
 | 
						|
      [[ $mlist[$eltcnt] = *"=**"* ]] && pw_dstar[$eltcnt]='*'
 | 
						|
    fi
 | 
						|
    # Just look for the left matcher for substring, since the right matcher
 | 
						|
    # might have been handled as part of a partial-word spec.
 | 
						|
    [[ $mlist[$eltcnt] = *"l:|=*"* ]] && s_list[$eltcnt]=$eltcnt
 | 
						|
  done
 | 
						|
 | 
						|
  while true; do
 | 
						|
    clear
 | 
						|
    print "\
 | 
						|
              *** compinstall: matcher menu ***
 | 
						|
 | 
						|
\`Matchers' compare the completion code with the possible matches in some
 | 
						|
special way.  Numbers in parentheses show matchers to be tried and the order.
 | 
						|
The same number can be assigned to different matchers, meaning apply at the
 | 
						|
same time.  Omit a sequence number to try normal matching at that point.
 | 
						|
A \`+' in the first line indicates the element is added to preceding matchers
 | 
						|
instead of replacing them; toggle this with \`t'.  You don't need to set
 | 
						|
all four, or indeed any matchers --- then the style will not be set.
 | 
						|
 | 
						|
   ($a_or_r)\
 | 
						|
   \`+' indicates add to previous matchers, else replace
 | 
						|
n. ($n_list)\
 | 
						|
 No matchers; you may want to try this as the first choice.
 | 
						|
c. ($c_list)\
 | 
						|
 Case-insensitive completion (lowercase matches uppercase)
 | 
						|
C. ($C_list)\
 | 
						|
 Case-insensitive completion (lower/uppercase match each other)
 | 
						|
p. ($p_list)\
 | 
						|
 Partial-word completion:  expand 'f.b' to 'foo.bar', etc., in one go.
 | 
						|
          You can choose the separators (here \`.') used each time.
 | 
						|
s. ($s_list)\
 | 
						|
 Substring completion:  complete on substrings, not just initial
 | 
						|
          strings.  Warning: it is recommended this not be used for element 1.
 | 
						|
 | 
						|
t.        Toggle replacing previous matchers (\` ' at top) or add (\`+')
 | 
						|
q.        Return without saving.
 | 
						|
0.        Done setting matchers.
 | 
						|
"
 | 
						|
 | 
						|
    read -k key'?--- Hit selection --- '
 | 
						|
    print
 | 
						|
 | 
						|
    if [[ $key = [nNcCpPsS] ]]; then
 | 
						|
      while true; do
 | 
						|
	read -k key2'?Set/unset for element number (1234)? '
 | 
						|
	print
 | 
						|
	[[ $key2 = [1234] ]] && break
 | 
						|
	print "Only 1, 2, 3 and 4 are handled."
 | 
						|
      done
 | 
						|
    fi
 | 
						|
 | 
						|
    case $key in
 | 
						|
      [nN]) __ci_toggle_matcher n_list $key2
 | 
						|
         if [[ $n_list[$key2] != ' ' ]]; then
 | 
						|
	 fi
 | 
						|
         ;;
 | 
						|
      c) __ci_toggle_matcher c_list $key2
 | 
						|
	 ;;
 | 
						|
      C) __ci_toggle_matcher C_list $key2
 | 
						|
	 ;;
 | 
						|
      [pP]) if __ci_toggle_matcher p_list $key2; then
 | 
						|
	      print "\
 | 
						|
Edit the set of characters which terminate partial words.  Typically
 | 
						|
these are punctuation characters, such as \`.', \`_' and \`-'.
 | 
						|
The expression will automatically be quoted.
 | 
						|
"
 | 
						|
              vared -eh -p 'characters> ' -c 'pw_seps['$key2']'
 | 
						|
	      # Paranoia: we don't know if there's a ']' in that string,
 | 
						|
	      # which will wreck the spec unless it's at the start.  Other
 | 
						|
	      # quotes are OK, since they are picked up at the ${(qq)...}
 | 
						|
	      # step.
 | 
						|
	      if [[ $pw_seps[$key2] = *']'* ]]; then
 | 
						|
		pw_seps[$key2]="]${pw_seps[$key2]//\\\]}"
 | 
						|
	      fi
 | 
						|
	      print -n "
 | 
						|
You can allow the partial-word terminators to be matched in the pattern,
 | 
						|
too:  then  for example \`c.u' would expand to \`comp.source.unix', whereas
 | 
						|
usually you would need to type an extra intervening dot.  Do you wish the
 | 
						|
terminators to be matched in this way? (y/n) [n] "
 | 
						|
              pw_dstar[$key2]=
 | 
						|
	      read -q key && pw_dstar[$key2]='*'
 | 
						|
	    fi
 | 
						|
	    ;;
 | 
						|
      [tT])
 | 
						|
	    read -k key2'?Toggle augment/replace for elements number (1234)? '
 | 
						|
	    if [[ $key2 == [1234] ]]; then
 | 
						|
	      if [[ $a_or_r[$key2] == ' ' ]]; then
 | 
						|
	        a_or_r[$key2]='+'
 | 
						|
	      else
 | 
						|
	        a_or_r[$key2]=' '
 | 
						|
	      fi
 | 
						|
	    else
 | 
						|
	      print "Only 1, 2, 3 and 4 are handled."
 | 
						|
	    fi
 | 
						|
	    ;;
 | 
						|
      [sS]) __ci_toggle_matcher s_list $key2
 | 
						|
	    ;;
 | 
						|
      [qQ]) return 1
 | 
						|
	 ;;
 | 
						|
    esac
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
  done
 | 
						|
 | 
						|
  # Keep track of the last element which was non-empty; all the rest
 | 
						|
  # are junked.
 | 
						|
  lastnz=0
 | 
						|
 | 
						|
  # Now we just reverse the first for-loop, looking for set matchers
 | 
						|
  # and reconstructing the elements of the matcher array.
 | 
						|
  for (( eltcnt = 1; eltcnt <= 4; eltcnt++ )); do
 | 
						|
    elt=
 | 
						|
    [[ $c_list[$eltcnt] != ' ' ]] && elt="${elt:+$elt }m:{a-z}={A-Z}"
 | 
						|
    [[ $C_list[$eltcnt] != ' ' ]] && elt="${elt:+$elt }m:{a-zA-Z}={A-Za-z}"
 | 
						|
    [[ $p_list[$eltcnt] != ' ' ]] &&
 | 
						|
      elt="${elt:+$elt }r:|[${pw_seps[$eltcnt]}]=*${pw_dstar[$eltcnt]}\
 | 
						|
 r:|=*${pw_dstar[$eltcnt]}"
 | 
						|
    if [[ $s_list[$eltcnt] != ' ' ]]; then
 | 
						|
      if [[ $elt = *"r:|=*"* ]]; then
 | 
						|
	elt="${elt:+$elt }l:|=*"
 | 
						|
      else
 | 
						|
	elt="${elt:+$elt }l:|=* r:|=*"
 | 
						|
      fi
 | 
						|
    fi
 | 
						|
    [[ $a_or_r[$eltcnt] != ' ' ]] && elt="+$elt"
 | 
						|
    [[ -n $elt || $n_list[$eltcnt] != ' ' ]] && lastnz=$eltcnt
 | 
						|
    mlist[$eltcnt]=$elt
 | 
						|
  done
 | 
						|
 | 
						|
  if (( ! $lastnz )); then
 | 
						|
    # No matchers set, so just make the style empty: __ci_set_this_style
 | 
						|
    # will omit it completely.
 | 
						|
    mlist=
 | 
						|
  else
 | 
						|
    # Quote the entire list: this correctly quotes element by element,
 | 
						|
    # praise be to Sven.
 | 
						|
    mlist=(${(qq)mlist[1,$lastnz]})
 | 
						|
    # Make it a scalar just for safety's sake.
 | 
						|
    mlist="$mlist"
 | 
						|
  fi
 | 
						|
  __ci_set_this_style matcher-list mlist
 | 
						|
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
__ci_do_list_format() {
 | 
						|
  local key format groupn verbose listp autod haslistp
 | 
						|
  __ci_get_this_style format format
 | 
						|
  [[ -n $format ]] && format=${(Q)format}
 | 
						|
  __ci_get_this_style group-name groupn
 | 
						|
  __ci_get_this_style verbose verbose
 | 
						|
  __ci_get_this_style list-prompt listp
 | 
						|
  [[ -n $listp ]] && haslistp=1
 | 
						|
  listp=${(Q)listp}
 | 
						|
  __ci_get_this_style auto-description autod
 | 
						|
  [[ -n $autod ]] && autod=${(Q)autod}
 | 
						|
 | 
						|
  while true; do
 | 
						|
    clear
 | 
						|
    print "\
 | 
						|
       *** compinstall: order and descriptions in completion lists ***
 | 
						|
Type the appropriate number for more information on how this would affect
 | 
						|
listings.
 | 
						|
 | 
						|
1.  Print a message above completion lists describing what is being
 | 
						|
    completed.
 | 
						|
 | 
						|
2.  Make different types of completion appear in separate lists.
 | 
						|
 | 
						|
3.  Make completion verbose, using option descriptions etc. (on by default).
 | 
						|
 | 
						|
4.  Make single-valued options display the value's description as
 | 
						|
    part of the option's description.
 | 
						|
 | 
						|
q.  Return without saving.
 | 
						|
0.  Done setting options for formatting of completion lists.
 | 
						|
"
 | 
						|
 | 
						|
    read -k key'?--- Hit selection --- '
 | 
						|
    print
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
 | 
						|
    case $key in
 | 
						|
      1) print "\
 | 
						|
You can set a string which is displayed on a line above the list of matches
 | 
						|
for completions.  A \`%d' in this string will be replaced by a brief
 | 
						|
description of the type of completion.  For example, if you set the
 | 
						|
string to \`Completing %d', and type ^D to show a list of files, the line
 | 
						|
\`Completing files' will appear above that list.  Enter an empty line to
 | 
						|
turn this feature off.  If you enter something which doesn't include \`%d',
 | 
						|
then \`%d' will be appended.  Quotation will be added automatically.
 | 
						|
"
 | 
						|
         vared -eh -p 'description> ' -c format
 | 
						|
	 if [[ -n $format && $format != *%d* ]]; then
 | 
						|
	   [[ $format = *[[:blank:]] ]] || format="$format "
 | 
						|
	   format="$format%d"
 | 
						|
	 fi
 | 
						|
	 ;;
 | 
						|
      2) print "\
 | 
						|
Normally, all possible completions are listed together in a single list, and
 | 
						|
if you have set a description with 1) above, the descriptions are listed
 | 
						|
together above that.  However, you can specify that different types of
 | 
						|
completion appear in separate lists; any description appears above its
 | 
						|
own list.  For example, external commands and shell functions would appear
 | 
						|
in separate lists when you are completing a command name.  Do you
 | 
						|
want to turn this on?
 | 
						|
"
 | 
						|
         while true; do
 | 
						|
           read -k key'?[y]es, [n]o, [k]eep old setting? '
 | 
						|
	   print
 | 
						|
	   [[ $key = [yYnNkK] ]] && break
 | 
						|
	 done
 | 
						|
	 case $key in
 | 
						|
	   [yY]) groupn="''"
 | 
						|
		 ;;
 | 
						|
	   [nN]) groupn=
 | 
						|
		 ;;
 | 
						|
	 esac
 | 
						|
	 ;;
 | 
						|
      3) print "By default, completion uses a \`verbose' setting.  This
 | 
						|
affects different completions in different ways.  For example,  many
 | 
						|
well-known commands have short, uninformative option names; in some cases,
 | 
						|
completion will indicate what the options do when offering to complete them.
 | 
						|
If you prefer shorter listings you can turn this off.  What setting to
 | 
						|
you want?
 | 
						|
"
 | 
						|
          while true; do
 | 
						|
            read -k key'?[v]erbose, [n]ot verbose, [k]eep old setting? '
 | 
						|
            print
 | 
						|
            [[ $key = [vVnNkK] ]] && break
 | 
						|
          done
 | 
						|
          case $key in
 | 
						|
	    # might as well be explicit, particularly since it's
 | 
						|
	    # the only way to override an existing `false' value.
 | 
						|
	    [vV]) verbose=true
 | 
						|
		  ;;
 | 
						|
	    [nN]) verbose=false
 | 
						|
		  ;;
 | 
						|
          esac
 | 
						|
	 ;;
 | 
						|
      4) print "\
 | 
						|
Many commands have options which take a single argument.  In some cases,
 | 
						|
completion is not set up to describe the option even though it has a
 | 
						|
description for the argument.  You can enter a string containing \`%d',
 | 
						|
which will be replaced by the description for the option.  For
 | 
						|
example, if you enter the string \`specify: %d', and an option -ifile
 | 
						|
exists which has an argument whose description is \`input file', then the
 | 
						|
description \`specify: input file' will appear when the option itself
 | 
						|
is listed.  As this long explanation suggests, this is only occasionally
 | 
						|
useful.  Enter an empty line to turn this feature off.  If you enter
 | 
						|
something which doesn't include \`%d', then \`%d' will be appended.
 | 
						|
Quotation will be added automatically.
 | 
						|
"
 | 
						|
         vared -eh -p 'auto-description> ' -c autod
 | 
						|
         if [[ -n $autod && $autod != *%d* ]]; then
 | 
						|
	   [[ $autod = *[[:blank:]] ]] || autod="$autod "
 | 
						|
	   autod="$autod%d"
 | 
						|
         fi
 | 
						|
	 ;;
 | 
						|
      q) return 1
 | 
						|
	 ;;
 | 
						|
    esac
 | 
						|
  done
 | 
						|
 | 
						|
  [[ -n $format ]] && format=${(qq)format}
 | 
						|
  __ci_set_this_style format format
 | 
						|
  __ci_set_this_style group-name groupn
 | 
						|
  __ci_set_this_style verbose verbose
 | 
						|
  [[ -n $autod ]] && autod=${(qq)autod}
 | 
						|
  __ci_set_this_style auto-description autod
 | 
						|
}
 | 
						|
 | 
						|
__ci_do_insertion() {
 | 
						|
  local key insertu original # sort
 | 
						|
 | 
						|
  __ci_get_this_style insert-unambiguous insertu
 | 
						|
  __ci_get_this_style original original
 | 
						|
 | 
						|
  while true; do
 | 
						|
    clear
 | 
						|
    print "\
 | 
						|
          *** compinstall: options for inserting completions ***
 | 
						|
 | 
						|
1.   In completers that change what you have already typed, insert any
 | 
						|
     unambiguous prefix rather than go straight to menu completion.
 | 
						|
 | 
						|
2.   In completers which correct what you have typed, keep what you
 | 
						|
     originally typed as one of the list of possible completions.
 | 
						|
 | 
						|
q.   Return with saving.
 | 
						|
0.   Done setting options for insertion.
 | 
						|
"
 | 
						|
    read -k key'?-- Hit selection --- '
 | 
						|
    print
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
 | 
						|
    case $key in
 | 
						|
      1) print "\
 | 
						|
The completers which do pattern matching and correction often alter the
 | 
						|
string which is already on the line, in the first case because it was a
 | 
						|
pattern and in the second case because what you typed was wrong.
 | 
						|
Since the possible completions can bear little or no resemblance to one
 | 
						|
another in those cases, so that typing extra characters to resolve the
 | 
						|
completion doesn't make much sense, menu completion is usually turned on
 | 
						|
straight away to allow you to pick the completion you want.  This style
 | 
						|
tells completion that if there is a common, unambiguous prefix in this
 | 
						|
case, you would prefer that to be inserted rather than going straight
 | 
						|
to menu completion.  Do you want this?
 | 
						|
"
 | 
						|
         while true; do
 | 
						|
           read -k key'?[y]es, [n]o, [k]eep old setting? '
 | 
						|
	   print
 | 
						|
	   [[ $key = [yYnNkK] ]] && break
 | 
						|
	 done
 | 
						|
	 case $key in
 | 
						|
	   [yY]) insertu=true
 | 
						|
	         ;;
 | 
						|
	   [nN]) insertu=false
 | 
						|
		 ;;
 | 
						|
	 esac
 | 
						|
	 ;;
 | 
						|
      2) print "\
 | 
						|
For completers which correct what you have typed, you sometimes want
 | 
						|
to keep the original string instead, so if the correction was ambiguous
 | 
						|
the original string is always listed as a possible completion.  However,
 | 
						|
if there was just one completion it is usually accepted.  You can
 | 
						|
force completion to offer the original string as a possibility even in
 | 
						|
this case.  Do you want this?
 | 
						|
"
 | 
						|
         while true; do
 | 
						|
	   read -k key'?[y]es, [n]o, [k]eep old setting? '
 | 
						|
	   print
 | 
						|
	   [[ $key = [yYnNkK] ]] && break
 | 
						|
	 done
 | 
						|
	 case $key in
 | 
						|
	   [yY]) original=true
 | 
						|
	         ;;
 | 
						|
           [nN]) original=false
 | 
						|
	         ;;
 | 
						|
	 esac
 | 
						|
	 ;;
 | 
						|
      [qQ]) return 1
 | 
						|
	      ;;
 | 
						|
    esac
 | 
						|
 | 
						|
  done
 | 
						|
 | 
						|
  __ci_set_this_style insert-unambiguous insertu
 | 
						|
  __ci_set_this_style original original
 | 
						|
  # __ci_set_this_style sort sort
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
__ci_do_selection() {
 | 
						|
  local key listc menu select amenu elt listp selectp haslistp hasselectp
 | 
						|
  integer num
 | 
						|
 | 
						|
  __ci_get_this_style list-colors listc
 | 
						|
  __ci_get_this_style menu menu
 | 
						|
  __ci_get_this_style list-prompt listp
 | 
						|
  [[ -n $listp ]] && haslistp=1
 | 
						|
  listp=${(Q)listp}
 | 
						|
  __ci_get_this_style select-prompt selectp
 | 
						|
  [[ -n $selectp ]] && hasselectp=1
 | 
						|
  selectp=${(Q)selectp}
 | 
						|
 | 
						|
  while true; do
 | 
						|
    clear
 | 
						|
    print "\
 | 
						|
     *** compinstall: options for colouring and selecting in lists ***
 | 
						|
 | 
						|
1.   Use coloured lists for listing completions.
 | 
						|
 | 
						|
2.   Use cursor keys to select completions from completion lists.
 | 
						|
 | 
						|
3.   Allow scrolling of long selection lists and set the prompt.
 | 
						|
 | 
						|
q.   Return without saving.
 | 
						|
0.   Done setting options for insertion.
 | 
						|
"
 | 
						|
    read -k key'?--- Hit selection --- '
 | 
						|
    print
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
 | 
						|
    case $key in
 | 
						|
      1) print "\
 | 
						|
Zsh can produce coloured completion listings where different file types
 | 
						|
etc. appear in different colours.  If you want to tailor that to your
 | 
						|
own needs, you will have to edit ~/.zshrc.  Here you have the choice of:
 | 
						|
 | 
						|
1.  Using the default colours.
 | 
						|
2.  Using the colours already set up for GNU ls via the \$LS_COLORS
 | 
						|
    environment variable.  Note this must be set before the completion
 | 
						|
    configuration code is executed.
 | 
						|
3.  Turn colouring off.
 | 
						|
0.  Leave the setting the way it is.  Choose this if you have a custom
 | 
						|
    setting and you don't want to lose it.
 | 
						|
"
 | 
						|
         while true; do
 | 
						|
	   read -k key'?Enter 1, 2, 3, 0: '
 | 
						|
	   print
 | 
						|
	   [[ $key = [1230] ]] && break
 | 
						|
	 done
 | 
						|
	 case $key in
 | 
						|
	   1) listc="''"
 | 
						|
	      ;;
 | 
						|
	   2) listc='${(s.:.)LS_COLORS}'
 | 
						|
	      ;;
 | 
						|
	   3) listc=
 | 
						|
	      ;;
 | 
						|
	 esac
 | 
						|
	 ;;
 | 
						|
      2) print "\
 | 
						|
If you use zsh's menu completion and the feature that all short completion
 | 
						|
lists appear below the line on which you are editing, you can enable
 | 
						|
\`menu selection', which lets you pick a completion with the cursor keys:
 | 
						|
the choice is highlighted, and hitting return accepts it.  Note that
 | 
						|
this only happens when you are already using menu completion.  This
 | 
						|
feature can be set so that it is only enabled when there are a certain
 | 
						|
number of completions.  Please enter:
 | 
						|
 | 
						|
- 0 or 1, to turn this feature on unconditionally
 | 
						|
- a higher number to turn this feature on when there are that many
 | 
						|
  completions
 | 
						|
- an \`l' for \`long' to turn it on for listings which don't fit on the
 | 
						|
  screen.
 | 
						|
- an \`ll' for \`long list' to turn it on for completions which don't fit
 | 
						|
  on the screen, even for commands which only do listing of completions.
 | 
						|
  This may be combined with a number which will be used in ordinary selection.
 | 
						|
- a negative number to turn this feature off
 | 
						|
- an empty line to leave the setting the way it is.
 | 
						|
"
 | 
						|
	 # Better to parse and display the current setting.
 | 
						|
         while true; do
 | 
						|
           vared -eh -p 'value> ' select
 | 
						|
	   [[ -z $select || $select = ((-|)<->|l|<->#ll<->#) ]] && break;
 | 
						|
	   print "Type a number, l, ll, ll<num>, or an empty line." >&2
 | 
						|
	 done
 | 
						|
	 amenu=(${=menu})
 | 
						|
	 elt=${amenu[(i)*select*]}
 | 
						|
	 [[ $elt -gt $#amenu ]] && elt=
 | 
						|
	 case $select in
 | 
						|
	   <->) if [[ -n $elt ]]; then
 | 
						|
		  amenu[$elt]="select=$select"
 | 
						|
		else
 | 
						|
		  amenu=($amenu "select=$select")
 | 
						|
	        fi
 | 
						|
		menu="$amenu"
 | 
						|
		;;
 | 
						|
	   *ll*) num=${(RS)select##ll}
 | 
						|
	         select="select=long-list"
 | 
						|
		 [[ -n $num ]] && select="$select select=$num"
 | 
						|
		 if [[ -n $elt ]]; then
 | 
						|
		   amenu[$elt]=$select
 | 
						|
		 else
 | 
						|
		   amenu=($amenu $select)
 | 
						|
		 fi
 | 
						|
		 menu="$amenu"
 | 
						|
		 ;;
 | 
						|
	   l#) if [[ -n $elt ]]; then
 | 
						|
                 amenu[$elt]="select=long"
 | 
						|
               else
 | 
						|
                 amenu=($amenu "select=long")
 | 
						|
               fi
 | 
						|
	       menu="$amenu"
 | 
						|
               ;;
 | 
						|
	   -<->) if [[ -n $elt ]]; then
 | 
						|
		    # i never liked the way indexing was done anyway
 | 
						|
		    if [[ $elt -eq 1 ]]; then
 | 
						|
		      amenu=($amenu[$elt+1,-1])
 | 
						|
		    else
 | 
						|
		      amenu=($amenu[1,$elt-1] $amenu[$elt+1,-1])
 | 
						|
		    fi
 | 
						|
		 fi
 | 
						|
		 menu="$amenu"
 | 
						|
		 ;;
 | 
						|
	 esac
 | 
						|
	 if [[ $menu = *select* ]]; then
 | 
						|
	   print "\
 | 
						|
You can also set a prompt to use for menu selection when it would scroll
 | 
						|
off the screen.  Unless this is set, you won't see a prompt, but the feature
 | 
						|
is still enabled.
 | 
						|
 | 
						|
Edit a prompt below.  It can contain \`%l' to show the number of matches
 | 
						|
as \`current_number/total_number', \`%p' to show the fraction of
 | 
						|
the way down the list, or font-control sequences such as %B, %U, %S and
 | 
						|
the corresponding %b, %u, %s; quotes will be added automatically.  Delete
 | 
						|
the whole line to turn it off.  Hit return to keep the current value.
 | 
						|
"
 | 
						|
	   [[ -z $hasselectp ]] &&
 | 
						|
	     selectp='%SScrolling active: current selection at %p%s'
 | 
						|
	   vared -eh -p 'prompt> ' -c selectp
 | 
						|
	   [[ -z $selectp ]] && hasselectp=
 | 
						|
	 fi
 | 
						|
         ;;
 | 
						|
      3) print "\
 | 
						|
You can make completion lists scroll when they don't fit on the screen.
 | 
						|
Note this is different from scrolling in menu selection --- a more basic
 | 
						|
pager is used which should work even with fairly stupid terminals.
 | 
						|
 | 
						|
To enable this, edit a prompt to show when scrolling is active; an empty 
 | 
						|
string turns this feature off.  It can contain \`%l' to show the number of
 | 
						|
matches as \`current_number/total_number', \`%p' to show the fraction of
 | 
						|
the way down the list, or font-control sequences such as %B, %U, %S and the
 | 
						|
corresponding %b, %u, %s; quotes will be added automatically.  Delete the
 | 
						|
whole line to turn this behaviour off, in which case the display of
 | 
						|
completions which don't fit on the screen is controlled by the LISTMAX
 | 
						|
parameter (currently ${LISTMAX:-unset}), which specifies the maximum number
 | 
						|
to show without asking.  Hit return to keep the current value.
 | 
						|
"
 | 
						|
         [[ -z $haslistp ]] &&
 | 
						|
	   listp='%SAt %p: Hit TAB for more, or the character to insert%s'
 | 
						|
	 vared -eh -p 'prompt> ' -c listp
 | 
						|
	 [[ -z $listp ]] && haslistp=
 | 
						|
	 ;;
 | 
						|
      q) return 1
 | 
						|
         ;;
 | 
						|
    esac
 | 
						|
  done
 | 
						|
 | 
						|
  __ci_set_this_style list-colors listc
 | 
						|
  __ci_set_this_style menu menu
 | 
						|
  [[ -n $haslistp ]] && listp=${(qq)listp}
 | 
						|
  __ci_set_this_style list-prompt listp
 | 
						|
  [[ -n $hasselectp ]] && selectp=${(qq)selectp}
 | 
						|
  __ci_set_this_style select-prompt selectp
 | 
						|
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
__ci_do_display() {
 | 
						|
  local key usec
 | 
						|
 | 
						|
  __ci_get_this_style use-compctl usec
 | 
						|
 | 
						|
  while true; do
 | 
						|
    clear
 | 
						|
    print "\
 | 
						|
         *** compinstall: display and insertion options ***
 | 
						|
 | 
						|
1.  Change appearance of completion lists:  allows descriptions of
 | 
						|
    completions to appear and sorting of different types of completions.
 | 
						|
 | 
						|
2.  Change how completions are inserted: includes options for sorting,
 | 
						|
    and keeping the original or an unambiguous prefix with correction etc.
 | 
						|
 | 
						|
3.  Configure coloured/highlighted completion lists, selection of items
 | 
						|
    and scrolling.
 | 
						|
 | 
						|
4.  Change whether old-style \`compctl' completions will be used.
 | 
						|
 | 
						|
q.  Return without saving.
 | 
						|
0.  Done setting display and insertion options.
 | 
						|
"
 | 
						|
 | 
						|
    read -k key'?--- Hit selection --- '
 | 
						|
    print
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
 | 
						|
    case $key in
 | 
						|
      1) __ci_do_list_format
 | 
						|
	 ;;
 | 
						|
      2) __ci_do_insertion
 | 
						|
	 ;;
 | 
						|
      3)  __ci_do_selection
 | 
						|
	 ;;
 | 
						|
      4) print "\
 | 
						|
Completions defined by the new completion system (the one you are
 | 
						|
configuring) always take precedence over the old sort defined with compctl.
 | 
						|
You can choose whether or not you want to search for a compctl-defined
 | 
						|
completion if no new completion was found for a command.  The default
 | 
						|
behaviour is only to check for compctl-defined completions if the required
 | 
						|
library, zsh/compctl, is already loaded.  (If not, this implies that
 | 
						|
compctl has not been called.)  Do you want to test for compctl-defined
 | 
						|
completions?
 | 
						|
"
 | 
						|
         while true; do
 | 
						|
	   read -k key'?[y]es, [n]o, if [l]oaded, [k]eep old setting? '
 | 
						|
	   print
 | 
						|
	   [[ $key = [yYnNlLkK] ]] && break
 | 
						|
	 done
 | 
						|
	 case $key in
 | 
						|
	   [yY]) usec=true
 | 
						|
	         ;;
 | 
						|
	   [nN]) usec=false
 | 
						|
	         ;;
 | 
						|
	   [lL]) usec=
 | 
						|
	         ;;
 | 
						|
	 esac
 | 
						|
	 ;;
 | 
						|
      q) return 1
 | 
						|
	 ;;
 | 
						|
    esac
 | 
						|
 | 
						|
  done
 | 
						|
 | 
						|
  __ci_set_this_style use-compctl usec
 | 
						|
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#       file-sort, special-dirs, ignore-parents,
 | 
						|
#       squeeze-slashes,
 | 
						|
__ci_do_file_styles() {
 | 
						|
  local key files cursor expand speciald ignorep squeezes select
 | 
						|
 | 
						|
  __ci_get_this_style file-sort files
 | 
						|
  __ci_get_this_style ignore-parents ignorep
 | 
						|
  __ci_get_this_style special-dirs speciald
 | 
						|
  __ci_get_this_style squeeze-slashes squeezes
 | 
						|
 | 
						|
  while true; do
 | 
						|
    clear
 | 
						|
    print "\
 | 
						|
      *** compinstall: options for filename completion ***
 | 
						|
 | 
						|
1.  Choose how to sort the displayed list of filename matches.
 | 
						|
 | 
						|
2.  In expressions with .., don't include directories already implied.
 | 
						|
 | 
						|
3.  Allow completion of . and .. for the bone idle.
 | 
						|
 | 
						|
4.  When expanding paths, \`foo//bar' is treated as \`foo/bar'.
 | 
						|
 | 
						|
q.  Return without saving.
 | 
						|
0.  Done setting options for filename completion.
 | 
						|
"
 | 
						|
    read -k key'?--- Hit selection --- '
 | 
						|
    print
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
 | 
						|
    case $key in
 | 
						|
      (1) print "\
 | 
						|
Filenames listed as possible completions are usually displayed in
 | 
						|
alphabetical order.  You can alternatively choose:
 | 
						|
  s  File size
 | 
						|
  l  Number of (hard) links
 | 
						|
  m  Modification time
 | 
						|
  a  Access time
 | 
						|
  i  Inode change time
 | 
						|
  n  File name
 | 
						|
  k  Keep the current setting
 | 
						|
You can also specify the reverse of any of the above orders (except \`k'):  to
 | 
						|
do this, type the appropriate letter in upper case.
 | 
						|
"
 | 
						|
         while true; do
 | 
						|
           read -k key'?--- Hit selection --- '
 | 
						|
	   print
 | 
						|
	   [[ $key = [sSlLmMaAiInNkK] ]] && break
 | 
						|
	 done
 | 
						|
	 case $key in
 | 
						|
	   ([sS]) files=size;;
 | 
						|
	   ([lL]) files=links;;
 | 
						|
	   ([mM]) files=modification;;
 | 
						|
	   ([aA]) files=access;;
 | 
						|
	   ([iI]) files=inode;;
 | 
						|
	   ([nN]) files=name;;
 | 
						|
	 esac
 | 
						|
	 if [[ $key = [SLAMIN] ]]; then
 | 
						|
	   # slam it into reverse
 | 
						|
	   files="$files reverse"
 | 
						|
	 fi
 | 
						|
	 ;;
 | 
						|
      (2) print "\
 | 
						|
When you type an expression containing \`..', you may usually not want to
 | 
						|
be offered certain directories for completion.
 | 
						|
  p   Don't offer parents:  in \`foo/bar/../', don't make \`bar' a completion.
 | 
						|
  c   Don't offer the current directory, e.g. after \`../'.
 | 
						|
  o   Only perform the two tests if there is a real \`..' in the word so far.
 | 
						|
  d   Only perform the two tests when completing directory names.
 | 
						|
  0   None of the above; use normal completion.
 | 
						|
  k   Keep the current settings.
 | 
						|
You may specify any combination of p, c, o, d including at least one of p
 | 
						|
and c, or you may specify either 0 or k.  Note that the _ignored completer
 | 
						|
functions in the normal way, i.e. you would be able to complete the
 | 
						|
directories in question if nothing else matched.
 | 
						|
"
 | 
						|
          while true; do
 | 
						|
	    vared -eh -p 'selection> ' select
 | 
						|
	    [[ ( $select = [pPcCoOdD]# && $select = *[pPcC]* )
 | 
						|
		    || $select = [0kK] ]] && break
 | 
						|
	    print "Type any combination of p, c, o, d, or type 0 or k"
 | 
						|
	  done
 | 
						|
	  case $select in
 | 
						|
	    (0) ignorep=
 | 
						|
		;;
 | 
						|
	    ([pPcCoOdD]#)
 | 
						|
		ignorep=()
 | 
						|
		[[ $select = *[pP]* ]] && ignorep=($ignorep parent)
 | 
						|
		[[ $select = *[cC]* ]] && ignorep=($ignorep pwd)
 | 
						|
		[[ $select = *[oO]* ]] && ignorep=($ignorep ..)
 | 
						|
		[[ $select = *[dD]* ]] && ignorep=($ignorep directory)
 | 
						|
		;;
 | 
						|
	  esac
 | 
						|
	  ;;
 | 
						|
      (3) print "\
 | 
						|
Filename completion does not usually offer the directory names \`.' and
 | 
						|
\`..' as choices.  However, some immensely lazy people can't even be
 | 
						|
bothered to type these.  Do you wish to be offered \`.' and \`..' as
 | 
						|
choices ([y]es, [n]o, [k]eep current setting)?
 | 
						|
"
 | 
						|
          while true; do
 | 
						|
            read -k key'?--- Hit selection --- '
 | 
						|
	    [[ $key = [yYnNkK] ]] && break
 | 
						|
	    print "Type y, n or k."
 | 
						|
	  done
 | 
						|
	  case $key in
 | 
						|
	    ([yY]) speciald=true;;
 | 
						|
	    ([nN]) speciald=;;
 | 
						|
	  esac
 | 
						|
	  ;;
 | 
						|
      (4) print "\
 | 
						|
Filename completion can complete sets of path segments at once, for example
 | 
						|
\`/u/X/l/X' to \`/usr/X11R6/lib/X11'.  Normally this means that multiple
 | 
						|
slashes in filenames are treated as matching multiple directories.  For
 | 
						|
example, \`foo//bar' could expand to \`foo/datthe/bar'.  You can, however,
 | 
						|
stick to the usual UNIX convention that multiple slashes are treated as
 | 
						|
a single slash.  Do you wish to treat multiple slashes the same as just
 | 
						|
one ([y]es, [n]o, [k]eep current setting)?
 | 
						|
"
 | 
						|
          while true; do
 | 
						|
	    read -k key'?--- Hit selection --- '
 | 
						|
	    [[ $key = [yYnNkK] ]] && break
 | 
						|
	    print "Type one of y, n or k."
 | 
						|
	  done
 | 
						|
	  case $key in
 | 
						|
	    ([yY]) squeezes=true;;
 | 
						|
	    ([nN]) squeezes=;;
 | 
						|
	  esac
 | 
						|
          ;;
 | 
						|
      (q) return 1
 | 
						|
	 ;;
 | 
						|
    esac
 | 
						|
 | 
						|
  done
 | 
						|
 | 
						|
  __ci_set_this_style file-sort files
 | 
						|
  __ci_set_this_style ignore-parents ignorep
 | 
						|
  __ci_set_this_style special-dirs speciald
 | 
						|
  __ci_set_this_style squeeze-slashes squeezes
 | 
						|
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
# TODO: history completion, jobs, prefix-needed 'n' stuff.
 | 
						|
__ci_do_misc() {
 | 
						|
  local key
 | 
						|
 | 
						|
  while true; do
 | 
						|
    clear
 | 
						|
    print "\
 | 
						|
      *** compinstall: options for particular types of completion ***
 | 
						|
 | 
						|
1.  Options for file completion.
 | 
						|
 | 
						|
q.  Return without saving.
 | 
						|
0.  Done setting options for particular completions.
 | 
						|
"
 | 
						|
    read -k key'?--- Hit selection --- '
 | 
						|
    print
 | 
						|
 | 
						|
    [[ $key = 0 ]] && break
 | 
						|
 | 
						|
    case $key in
 | 
						|
      1) __ci_do_file_styles
 | 
						|
	 ;;
 | 
						|
      q) return 1
 | 
						|
	 ;;
 | 
						|
    esac
 | 
						|
 | 
						|
  done
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
# TODO: it should probably be possible to set completion options via
 | 
						|
#         compinstall, even though they've been around for years.
 | 
						|
 | 
						|
while true; do
 | 
						|
  clear
 | 
						|
  print "\
 | 
						|
               *** compinstall: main menu ***
 | 
						|
Note that hitting \`q' in menus does not abort the set of changes from
 | 
						|
lower level menus.  However, quitting at top level will ensure that nothing
 | 
						|
at all is actually written out.
 | 
						|
 | 
						|
1.  Completers:  choose completion behaviour for tasks such as
 | 
						|
    approximation, spell-checking, expansion.
 | 
						|
 | 
						|
2.  Matching control: set behaviour for case-insensitive matching,
 | 
						|
    extended (partial-word) matching and substring matching.
 | 
						|
 | 
						|
3.  Styles for changing the way completions are displayed and inserted.
 | 
						|
 | 
						|
4.  Styles for particular completions.
 | 
						|
 | 
						|
c.  Change context (plus more information on contexts).
 | 
						|
 | 
						|
q.  Return without saving.
 | 
						|
0.  Save and exit.
 | 
						|
"
 | 
						|
 | 
						|
  __ci_newline \
 | 
						|
    "--- Hit choice --- " || return 1
 | 
						|
 | 
						|
  # note this is a string test:  we require the `0' to have been typed.
 | 
						|
  [[ $key = 0 ]] && break
 | 
						|
 | 
						|
  case $key in
 | 
						|
    1) __ci_do_completers
 | 
						|
       ;;
 | 
						|
    2) __ci_do_matchers
 | 
						|
       ;;
 | 
						|
    3) __ci_do_display
 | 
						|
       ;;
 | 
						|
    4) __ci_do_misc
 | 
						|
       ;;
 | 
						|
    c) __ci_change_context
 | 
						|
       ;;
 | 
						|
  esac
 | 
						|
done
 | 
						|
 | 
						|
 | 
						|
local output
 | 
						|
 | 
						|
if (( $#styles )); then
 | 
						|
  typeset style stylevals context values
 | 
						|
  for style in ${(ko)styles}; do
 | 
						|
    stylevals=(${(f)styles[$style]})
 | 
						|
    while (( $#stylevals )); do
 | 
						|
      output="$output
 | 
						|
zstyle ${(qq)stylevals[1]} $style $stylevals[2]"
 | 
						|
      shift 2 stylevals
 | 
						|
    done
 | 
						|
  done
 | 
						|
fi
 | 
						|
 | 
						|
if [[ -z $ifile || -d $ifile ]] ||
 | 
						|
  ! read -q key"?Save new settings to $ifile? "; then
 | 
						|
   print "Enter file to save in (~ will be expanded), or return to abort:"
 | 
						|
   ifile=
 | 
						|
   vared -ch -p 'file> ' ifile
 | 
						|
   ifile=${~ifile}
 | 
						|
fi
 | 
						|
 | 
						|
local tmpout=${TMPPREFIX:-/tmp/zsh}compinstall$$
 | 
						|
#
 | 
						|
# Assemble the complete set of lines to
 | 
						|
# insert.
 | 
						|
#
 | 
						|
{ print -r "$startline
 | 
						|
$output"
 | 
						|
  if [[ -n $ifile ]]; then
 | 
						|
    line="zstyle :compinstall filename ${(qq)ifile}"
 | 
						|
    print -r "$line"
 | 
						|
    eval "$line"
 | 
						|
  fi
 | 
						|
 | 
						|
  [[ -n $fpath_line ]] && print -r "$fpath_line"
 | 
						|
 | 
						|
  print -r "
 | 
						|
autoload -U compinit
 | 
						|
compinit${compinit_args:+ $compinit_args}"
 | 
						|
 | 
						|
  print -r "$endline"
 | 
						|
} >$tmpout
 | 
						|
 | 
						|
if [[ -n $ifile ]]; then
 | 
						|
  if [[ $ifile != *(zshrc|zlogin|zshenv) ]]; then 
 | 
						|
    print "\
 | 
						|
If you want this file to be run automatically, you should add
 | 
						|
  . $ifile
 | 
						|
to your .zshrc.  compinstall will remember the name of this file for
 | 
						|
future use."
 | 
						|
    __ci_newline || return 1
 | 
						|
  fi
 | 
						|
  #
 | 
						|
  # Now use sed to update the file.
 | 
						|
  #
 | 
						|
  if [[ -f $ifile ]]; then
 | 
						|
    cp $ifile ${ifile}\~ &&
 | 
						|
    print "Copied old file to ${ifile}~."
 | 
						|
  else
 | 
						|
    touch $ifile
 | 
						|
  fi
 | 
						|
  if { { grep "$endline" $ifile >/dev/null 2>&1 &&
 | 
						|
         sed -e "/^[ 	]*$endline/r $tmpout
 | 
						|
/^[ 	]*$startline/,/^[ 	]*$endline/d" $ifile >${tmpout}2 } || 
 | 
						|
        { cp $ifile ${tmpout}2 && cat $tmpout >>${tmpout}2 } } &&
 | 
						|
  cp ${tmpout}2 $ifile && rm -f ${tmpout}2; then
 | 
						|
    print "\nSuccessfully added compinstall lines to $ifile."
 | 
						|
    rm -f $tmpout
 | 
						|
  else
 | 
						|
    print "\nFailure adding lines to $ifile.  Lines left in \`$tmpout'"
 | 
						|
  fi
 | 
						|
  rm -f ${tmpout}2
 | 
						|
elif read -q key'?Print them to stdout instead? '; then
 | 
						|
  cat $tmpout
 | 
						|
  rm -f $tmpout
 | 
						|
fi
 | 
						|
 | 
						|
if read -q key'?Set new styles for immediate use? '; then
 | 
						|
  eval $output
 | 
						|
  print "The new settings are now in effect.  Note this will not remove old
 | 
						|
styles you have deleted until you restart the shell."
 | 
						|
fi
 | 
						|
 | 
						|
__ci_tidyup
 | 
						|
return 0
 |