1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-06-21 10:28:05 +02:00

zsh-3.1.5-pws-12

This commit is contained in:
Tanaka Akira 1999-04-15 18:20:19 +00:00
parent 7a0415cfd7
commit 04a89199d0
65 changed files with 1935 additions and 585 deletions

3
Completion/.distfiles Normal file
View file

@ -0,0 +1,3 @@
DISTFILES_SRC='
.distfiles README
'

View file

@ -0,0 +1,6 @@
DISTFILES_SRC='
.distfiles
_brace_parameter _command_names _condition _default _equal
_long_options _match_pattern _match_pattern.orig _match_test _parameter
_precommand _redirect _subscript _tilde _vars
'

View file

@ -1,7 +1,11 @@
#defcomp -command- #defcomp -command-
local nm=$compstate[nmatches] local nm=$compstate[nmatches] ret=1
compgen -c compgen -c && ret=0
[[ nm -eq compstate[nmatches] ]] && _path_files -/g "*(*)" if [[ nm -eq compstate[nmatches] ]]; then
_path_files -/g "*(*)"
else
return ret
fi

View file

@ -7,6 +7,10 @@ if [[ "$prev" = -o ]]; then
elif [[ "$prev" = -([no]t|ef) ]]; then elif [[ "$prev" = -([no]t|ef) ]]; then
_files _files
else else
_files local ret=1
compgen -v
_files && ret=0
compgen -v && ret=0
return ret
fi fi

View file

@ -9,6 +9,6 @@
# and insert the line `[[ compstate[nmatches] -eq 0 ]] || return' after # and insert the line `[[ compstate[nmatches] -eq 0 ]] || return' after
# `compcall'. # `compcall'.
compcall || return compcall || return 0
_files _files

View file

@ -0,0 +1,309 @@
#autoload
# This function tries to automatically complete long option names. For
# this it invokes the command from the line with the `--help' option
# and then parses the output to find possible option names. For
# options that get an argument after a `=', the function also tries to
# automatically find out what should be complete as the argument.
# The possible completions for option-arguments can be described with
# the arguments to this function. This is done by giving pairs of
# patterns and actions as consecutive arguments. The actions specify
# what should be done to complete arguemts of those options that match
# the pattern. The action may be a list of words in brackets or in
# parentheses, separated by spaces. A list in brackets denotes
# possible values for an optional argument, a list in parentheses
# gives words to complete for mandatory arguments. If the action does
# not start with a bracket or parentheses, it should be the name of a
# command (probably with arguments) that should be invoked to complete
# after the equal sign. E.g.:
#
# _long_options '*\*' '(yes no)' \
# '*=FILE*' '_files' \
# '*=DIR*' '_files -/'
#
# This makes `yes' and `no' be completed as the argument of options
# whose description ends in a star, file names for options that
# contain the substring `=FILE' in the description, and paths for
# options whose description contains `=DIR'. Note the last two
# patterns are not needed since this function always completes files
# for option descriptions containing `=FILE' and paths for option
# descriptions that contain `=DIR' or `=PATH'. These builtin patterns
# can be overridden by patterns given as arguments, though.
#
# This function also accepts the `-X', `-J', and `-V' options which
# are given to `compadd'. Finally, it accepts the option `-t'. If this
# is given, completion is only done on words starting with two hyphens.
local opt expl group test i name action ret=1 tmp suffix
setopt extendedglob
# Get the options.
group=()
expl=()
if [[ $1 = -*~--* ]]; then
while getopts "J:V:X:t" opt; do
case "$opt" in
[JV]) group=("-$opt" "$OPTARG");;
X) expl=(-X "$OPTARG");;
t) test=yes;;
esac
done
shift OPTIND-1
fi
# Test if we are completing after `--' if we were asked to do so.
[[ -n "$test" && "$PREFIX" != --* ]] && return 1
# We cache the information about options and the command name, see if
# we can use the cache.
if [[ "$words[1]" = (.|..)/* ]]; then
tmp="$PWD/$words[1]"
else
tmp="$words[1]"
fi
if [[ "$tmp" != $_lo_cache_cmd ]]; then
# No, store the new command name and clear the old parameters.
_lo_cache_cmd="$tmp"
(( $+_lo_cache_actions )) && unset "$_lo_cache_names[@]" _lo_cache_actions _lo_cache_names
local opts pattern anum=1 tmpo str
# Now get the long option names by calling the command with `--help'.
# The parameter expansion trickery first gets the lines as separate
# array elements. Then we select all lines whose first non-blank
# character is a hyphen. Since some commands document more than one
# option per line, separated by commas, we convert commas int
# newlines and then split the result again at newlines after joining
# the old array elements with newlines between them. Then we select
# those elements that start with two hyphens, remove anything up to
# those hyphens and anything from the space or comma after the
# option up to the end. Finally all elements with option strings
# that contain uppercase letters are removed.
opts=("--${(@)^${(@)${(@)${(@M)${(@ps:\n:j:\n:)${(@)${(@M)${(@f)$("$words[1]" --help)}:#[ ]#-*}//,/
}}:#[ ]#--*}#*--}%%[, ]*}:#(*-[A-Z]*|)}")
# The interpretation of the options is completely table driven. We
# use the positional parameters we were given and a few standard
# ones. Then we loop through this table.
set -- "$@" '*=FILE*' '_files' '*=(DIR|PATH)*' '_files -/' '*' ''
while [[ $# -gt 1 ]]; do
# First, we get the pattern and the action to use and take them
# from the positional parameters.
pattern="$1"
action="$2"
shift 2
# We get all options matching the pattern and take them from the
# list we have built. If no option matches the pattern, we
# continue with the next.
tmp=("${(@M)opts:##$~pattern}")
opts=("${(@)opts:##$~pattern}")
(( $#tmp )) || continue
# Now we collect the options for the pattern in an array. We also
# check if the options take an argument after a `=', and if this
# argument is optional. The name of the array built contains
# `_arg_' for mandatory arguments, `_optarg_' for optional
# arguments, and `_simple_' for options that don't get an
# argument. In `_lo_cache_names' we save the names of these
# arrays and in `_lo_cache_actions' the associated actions.
# If the action is a list of words in brackets, this denotes
# options that get an optional argument. If the action is a list
# of words in parentheses, the option has to get an argument.
# In both cases we just build the array name to use.
if [[ "$action[1]" = '[' ]]; then
name="_lo_cache_optarg_$anum"
elif [[ "$action[1]" = '(' ]]; then
name="_lo_cache_arg_$anum"
else
# If there are option strings with a `[=', we take make these
# get an optional argument...
tmpo=("${(@M)tmp:#*\[\=*}")
if (( $#tmpo )); then
# ...by removing them from the option list and storing them in
# an array.
tmp=("${(@)tmp:#*\[\=*}")
tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
_lo_cache_names[anum]="_lo_cache_optarg_$anum"
_lo_cache_actions[anum]="$action"
eval "_lo_cache_optarg_${anum}=(\"\$tmpo[@]\")"
(( anum++ ))
fi
# Now we do the same for option strings containing `=', these
# are options getting an argument.
tmpo=("${(@M)tmp:#*\=*}")
if (( $#tmpo )); then
tmp=("${(@)tmp:#*\=*}")
tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
_lo_cache_names[anum]="_lo_cache_arg_$anum"
_lo_cache_actions[anum]="$action"
eval "_lo_cache_arg_${anum}=(\"\$tmpo[@]\")"
(( anum++ ))
fi
# The name for the options without arguments, if any.
name="_lo_cache_simple_$anum"
fi
# Now filter out any option strings we don't like and stuff them
# in an array, if there are still some.
tmp=("${(@)${(@)tmp%%\=*}//[^a-z0-9-]}")
if (( $#tmp )); then
_lo_cache_names[anum]="$name"
_lo_cache_actions[anum]="$action"
eval "${name}=(\"\$tmp[@]\")"
(( anum++ ))
fi
done
fi
# We get the string from the line and and see if it already contains a
# equal sign.
str="$PREFIX$SUFFIX"
if [[ "$str" = *\=* ]]; then
# It contains a `=', now we ignore anything up to it, but first save
# the old contents of the special parameters we change.
local oipre opre osuf pre parto parta pat patflags anum=1
oipre="$IPREFIX"
opre="$PREFIX"
osuf="$SUFFIX"
pre="${str%%\=*}"
IPREFIX="${IPREFIX}${pre}="
PREFIX="${str#*\=}"
SUFFIX=""
# We will check if the arrays contain an option matching what's on
# the line. To do this good, we build a pattern.
[[ -n "$_comp_correct" && $#pre -le _comp_correct ]] && return 1
pat="${pre}*"
patflags=''
_match_pattern _long_options pat patflags
[[ -n "$_comp_correct" ]] && patflags="$patflags(#a$_comp_correct)"
# Then we walk through the array names. For each array we test if it
# contains the option string. If so, we `invoke' the action stored
# with the name. If the action is a list of words, we just add them,
# otherwise we invoke the command or function named.
for name in "$_lo_cache_names[@]"; do
action="$_lo_cache_actions[anum]"
if (( ${(@)${(@P)name}[(I)$pre]} )); then
if [[ "$action[1]" = (\[|\() ]]; then
compadd - ${=action[2,-2]}
elif (( $#action )); then
$=action
fi
# We found the option string, return.
return
fi
# The array did not contain the full option string, see if it
# contains a string matching the string from the line.
# If there is one, we store the option string in `parto' and the
# element from `_lo_actions' in `parta'. If we find more than one
# such option or if we already had one, we set `parto' to `-'.
tmp=("${(@M)${(@P)name}:#${~pat}}")
if [[ $#tmp -eq 1 ]]; then
if [[ -z "$parto" ]]; then
parto="$tmp[1]"
parta="$action"
else
parto=-
fi
elif (( $#tmp )); then
parto=-
fi
(( anum++ ))
done
# If we found only one matching option, we accept it and immediatly
# try to complete the string after the `='.
if [[ -n "$parto" && "$parto" != - ]]; then
IPREFIX="${parto}="
if (( $#parta )); then
if [[ "$parta[1]" = (\[|\() ]]; then
compadd - ${=parta[2,-2]}
else
$=parta
fi
else
compadd -S '' - "$PREFIX"
fi
return
fi
# The option string was not found, restore the special parameters.
IPREFIX="$oipre"
PREFIX="$opre"
SUFFIX="$osuf"
fi
# The string on the line did not contain a `=', or we couldn't
# complete the option string since there were more than one matching
# what's on the line. So we just ad the option string as possible
# matches, giving the string from the `=' on as a suffix.
if [[ "$str" = *\=* ]]; then
str="=${str#*\=}"
PREFIX="${PREFIX%%\=*}"
suffix=()
else
str=""
suffix=('-S=')
fi
anum=1
for name in "$_lo_cache_names[@]"; do
action="$_lo_cache_actions[anum]"
if [[ "$name" = *_optarg_* ]]; then
compadd -M 'r:|-=* r:|=*' -Qq "$suffix[@]" -s "$str" - \
"${(@P)name}" && ret=0
elif [[ "$name" = *_arg_* ]]; then
compadd -M 'r:|-=* r:|=*' -Q "$suffix[@]" -s "$str" - \
"${(@P)name}" && ret=0
elif [[ -z "$str" ]]; then
compadd -M 'r:|-=* r:|=*' -Q - \
"${(@P)name}" && ret=0
fi
(( anum++ ))
done
return ret

View file

@ -28,4 +28,10 @@
# like the `r:|[.-]=* r:|=*'. To make this work, the function `_match_test' # like the `r:|[.-]=* r:|=*'. To make this work, the function `_match_test'
# would have to be changed to `(( compstate[matcher] <= 2 ))' # would have to be changed to `(( compstate[matcher] <= 2 ))'
# #
# When automatic correction is used (see the file `_main_complete'), you
# probably don't want to set matching flags here as that may make the
# results slightly unpredictable. For this, change the line above to:
#
# [[ compstate[matcher] -lt 0 ]] && eval "${3}='(#l)'"
#
# The default implementation of this function is empty. # The default implementation of this function is empty.

View file

@ -1,5 +1,10 @@
#defcomp -subscript- #defcomp -subscript-
_compalso -math- local ret=1
_compalso -math- && ret=0
[[ ${(Pt)${compstate[parameter]}} = assoc* ]] && [[ ${(Pt)${compstate[parameter]}} = assoc* ]] &&
compgen -k "( ${(kP)${compstate[parameter]}} )" compgen -k "( ${(kP)${compstate[parameter]}} )" && ret=0
return ret

View file

@ -0,0 +1,7 @@
DISTFILES_SRC='
.distfiles
_aliases _arrays _autoload _bg_jobs _bindkey _builtin _cd _command
_dirs _disable _echotc _enable _fc _functions _hash _jobs _kill
_limits _sched _set _setopt _source _trap _unhash _unsetopt _vars_eq
_wait _which _zftp _zle _zmodload
'

View file

@ -1,7 +1,14 @@
#defcomp bindkey #defcomp bindkey
if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1] = -*M ]]; then # Normally, this completes names of zle widgets, whether the builtin ones
# or ones defined by the user. Note that a - allows a wildcard before it,
# so h-b-s-b will complete to history-beginning-search-backward. You
# can alter this by removing the -M ... from the second compgen.
#
# Where appropriate, will complete keymaps instead of widgets.
if [[ "$words[2]" = -*[DAN]* || "$words[CURRENT-1]" = -*M ]]; then
compgen -s '$(bindkey -l)' compgen -s '$(bindkey -l)'
else else
compgen -b compgen -b -M 'r:|-=* r:|=*'
fi fi

View file

@ -24,7 +24,7 @@ if [[ -position 3 ]]; then
rep=(${~PWD/$words[2]/*}~$PWD(-/N)) rep=(${~PWD/$words[2]/*}~$PWD(-/N))
# Now remove all the common parts of $PWD and the completions from this # Now remove all the common parts of $PWD and the completions from this
rep=(${${rep#${PWD%%$words[2]*}}%${PWD#*$words[2]}}) rep=(${${rep#${PWD%%$words[2]*}}%${PWD#*$words[2]}})
(( $#rep )) && compadd $rep (( ! $#rep )) || compadd $rep
elif [[ $words[1] = pu* && $PREFIX = [-+]* ]]; then elif [[ $words[1] = pu* && $PREFIX = [-+]* ]]; then
# pushd: just complete the numbers, but show the full directory list with # pushd: just complete the numbers, but show the full directory list with
# numbers. # numbers.
@ -34,7 +34,8 @@ elif [[ $words[1] = pu* && $PREFIX = [-+]* ]]; then
# lazy to type pushd. # lazy to type pushd.
IPREFIX=$PREFIX[1] IPREFIX=$PREFIX[1]
PREFIX=$PREFIX[2,-1] PREFIX=$PREFIX[2,-1]
local list lines local list lines ret=1
# get the list of directories with their canonical number # get the list of directories with their canonical number
lines="$(dirs -v)" lines="$(dirs -v)"
# turn the lines into an array, removing the current directory # turn the lines into an array, removing the current directory
@ -52,9 +53,11 @@ elif [[ $words[1] = pu* && $PREFIX = [-+]* ]]; then
lines="${(F)list}" lines="${(F)list}"
# get the array of numbers only # get the array of numbers only
list=(${list%%[ ]*}) list=(${list%%[ ]*})
compgen -y '$lines' -Q -k list compgen -y '$lines' -Q -k list && ret=0
[[ -z $compstate[list] ]] && compstate[list]=list [[ -z $compstate[list] ]] && compstate[list]=list && ret=0
[[ -n $compstate[insert] ]] && compstat[insert]=menu [[ -n $compstate[insert] ]] && compstat[insert]=menu && ret=0
return ret
elif [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then elif [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then
_path_files -W cdpath -/ _path_files -W cdpath -/
else else

View file

@ -1,8 +1,10 @@
#defcomp disable #defcomp disable
local prev="$words[CURRENT-1]" local prev="$words[CURRENT-1]" ret=1
[[ "$prev" = -*a* ]] && compgen -ea [[ "$prev" = -*a* ]] && compgen -ea && ret=0
[[ "$prev" = -*f* ]] && compgen -eF [[ "$prev" = -*f* ]] && compgen -eF && ret=0
[[ "$prev" = -*r* ]] && compgen -ew [[ "$prev" = -*r* ]] && compgen -ew && ret=0
[[ "$prev" != -* ]] && compgen -eB [[ "$prev" != -* ]] && compgen -eB && ret=0
return ret

View file

@ -1,8 +1,10 @@
#defcomp enable #defcomp enable
local prev="$words[CURRENT-1]" local prev="$words[CURRENT-1]" ret=1
[[ "$prev" = -*a* ]] && compgen -da [[ "$prev" = -*a* ]] && compgen -da && ret=0
[[ "$prev" = -*f* ]] && compgen -dF [[ "$prev" = -*f* ]] && compgen -dF && ret=0
[[ "$prev" = -*r* ]] && compgen -dw [[ "$prev" = -*r* ]] && compgen -dw && ret=0
[[ "$prev" != -* ]] && compgen -dB [[ "$prev" != -* ]] && compgen -dB && ret=0
return ret

View file

@ -5,7 +5,11 @@ local list
if [[ -iprefix '-' ]]; then if [[ -iprefix '-' ]]; then
compgen -k "($signals[1,-3])" compgen -k "($signals[1,-3])"
else else
compgen -P '%' -j local ret=1
compgen -P '%' -j && ret=0
list=("$(ps 2>/dev/null)") list=("$(ps 2>/dev/null)")
compgen -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' compgen -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' && ret=0
return ret
fi fi

View file

@ -1,8 +1,11 @@
#defcomp setopt #defcomp setopt
local nm=$compstate[nmatches] local nm=$compstate[nmatches] ret=1
compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \ compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
-s '$({ unsetopt kshoptionprint; unsetopt } 2>/dev/null)' -s '$({ unsetopt kshoptionprint; unsetopt } 2>/dev/null)' && ret=0
[[ compstate[nmatches] -eq nm ]] && [[ compstate[nmatches] -eq nm ]] &&
compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o && ret=0
return ret

View file

@ -1,8 +1,10 @@
#defcomp unhash #defcomp unhash
local fl="$words[2]" local fl="$words[2]" ret=1
[[ "$fl" = -*d* ]] && compgen -n [[ "$fl" = -*d* ]] && compgen -n && ret=0
[[ "$fl" = -*a* ]] && compgen -a [[ "$fl" = -*a* ]] && compgen -a && ret=0
[[ "$fl" = -*f* ]] && compgen -F [[ "$fl" = -*f* ]] && compgen -F && ret=0
[[ "$fl" != -* ]] && compgen -m [[ "$fl" != -* ]] && compgen -m && ret=0
return ret

View file

@ -1,8 +1,11 @@
#defcomp unsetopt #defcomp unsetopt
local nm=$compstate[nmatches] local nm=$compstate[nmatches] ret=1
compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \ compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
-s '$({ unsetopt kshoptionprint; setopt } 2>/dev/null)' -s '$({ unsetopt kshoptionprint; setopt } 2>/dev/null)' && ret=0
[[ compstate[nmatches] -eq nm ]] && [[ compstate[nmatches] -eq nm ]] &&
compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o compgen -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o && ret=0
return ret

View file

@ -1,7 +1,9 @@
#defcomp wait #defcomp wait
local list local list ret=1
compgen -P '%' -j compgen -P '%' -j && ret=0
list=("$(ps 2>/dev/null)") list=("$(ps 2>/dev/null)")
compgen -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' compgen -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`' && ret=0
return ret

View file

@ -45,6 +45,7 @@ case $subcom in
*) *)
# dunno... try ordinary completion after all. # dunno... try ordinary completion after all.
unset _compskip unset _compskip
return 1
;; ;;
esac esac

View file

@ -0,0 +1,3 @@
DISTFILES_SRC='
.distfiles _correct_filename _most_recent_file
'

View file

@ -0,0 +1,5 @@
DISTFILES_SRC='
.distfiles
_compalso _files _main_complete _multi_parts _normal _path_files
_sep_parts compdump compinit
'

View file

@ -7,7 +7,9 @@
# `_compalso -math-' to get the completions that would be generated for a # `_compalso -math-' to get the completions that would be generated for a
# mathematical context. # mathematical context.
local tmp local tmp ret=1
tmp="$_comps[$1]" tmp="$_comps[$1]"
[[ -z "$tmp" ]] || "$tmp" [[ -z "$tmp" ]] || "$tmp" && ret=0
return ret

View file

@ -3,10 +3,9 @@
# Utility function for completing files of a given type or any file. # Utility function for completing files of a given type or any file.
# In many cases you will want to call this one instead of _path_files(). # In many cases you will want to call this one instead of _path_files().
local nm=$compstate[nmatches] ret local nm=$compstate[nmatches] ret=1
_path_files "$@" _path_files "$@" && ret=0
ret=$?
if [[ $# -ne 0 && compstate[nmatches] -eq nm ]]; then if [[ $# -ne 0 && compstate[nmatches] -eq nm ]]; then
local opt opts local opt opts
@ -23,7 +22,7 @@ if [[ $# -ne 0 && compstate[nmatches] -eq nm ]]; then
[[ "$opt" = [PSWFJVX] ]] && opts=("$opts[@]" "-$opt" "$OPTARG") [[ "$opt" = [PSWFJVX] ]] && opts=("$opts[@]" "-$opt" "$OPTARG")
done done
_path_files "$opts[@]" _path_files "$opts[@]" && ret=0
else
return $ret
fi fi
return ret

View file

@ -3,36 +3,47 @@
# The main loop of the completion code. This is what is called when # The main loop of the completion code. This is what is called when
# completion is attempted from the command line. # completion is attempted from the command line.
# #
# This code will automatically try to correct the string on the # This code will automatically try to correct the string on the line
# line based on the strings generated for the context if the # based on the strings generated for the context if
# parameter `COMPCORRECT' is set and normal completion didn't yield # `compconfig[correct]' is set and normal completion didn't yield any
# any matches. These corrected strings will be shown in a list and # matches. These corrected strings will be shown in a list and one can
# one can cycle through them as in a menucompletion. To use this #cycle through them as in a menucompletion. To use this feature,
# feature, `COMPCORRECT' should be set to a number, specifying the #`compconfig[correct]' should be set to a number, specifying the
# maximum number of errors that should be accepted. If the string also # maximum number of errors that should be accepted. If the string also
# contains a `n' or `N', the code will use the numeric argument as the # contains a `n' or `N', the code will use the numeric argument as the
# maximum number of errors if a numeric argument was given. If no # maximum number of errors if a numeric argument was given. If no
# numeric argument was given, the number from the value of # numeric argument was given, the number from the value of
# `COMPCORRECT' will be used. E.g. with `COMPCORRECT=2n' two errors # `compconfig[correct]' will be used. E.g. with `compconfig[correct]=2n'
# will be accepted, but if the user gives another number with the # two errors will be accepted, but if the user gives another number
# numeric argument, this will be prefered. Also, with `COMPCORRECT=0n', # with the numeric argument, this will be prefered. Also, with
# normally no automatic correction will be tried, but if a numeric # `compconfig[correct]=0n',normally no automatic correction will be
# argument is given, automatic correction will be used. Once the # tried, but if a numeric argument is given, automatic correction will
# number of errors to accept is determined, the code will repeatedly # be used. Once the number of errors to accept is determined, the code
# try to generate matches by allowing one error, two errors, and so # will repeatedly try to generate matches by allowing one error, two
# on. # errors, and so on. Independent of the number of errors the user
# If the parameter `CCORIG' is set (independent of the value), the # wants to accept, the code will allow only fewer errors than there
# line will first be left unchanged and consecutive TABs cycle through # are characters in the string from the line.
# the list. # The value of `compconfig[correct_orig]' is used to determine if the
# When using automatic correction, one can also set the parameter # original string should be included in the list (and thus be
# `CCPROMPT' to a string that will be shown when multiple # presented to the user when cycling through the corrections). If it
# correction results are displayed and the code starts cycling # is set to any non-empty value, the original string will be
# through them (this string is used with the `-X' option and thus may # offered. If it contains the sub-string `last', the original string
# contain the control sequences `%n', `%B',...). # will apear as the last string when cycling through the corrections,
# otherwise it will appear as the first one (so that the command line
# does not change immediatly). Also, if the value of
# `compconfig[correct_orig]' contains the sub-string `always', the
# original string will always be included, whereas normally it is
# included only if more than one possible correction was generated.
# Finally, `compconfig[correct_prompt]' may be set to a string that
# should be printed before the list of corrected strings when cycling
# through them. This string may contain the control sequences `%n',
# `%B', etc. known from the `-X' option of `compctl'. Also, the
# sequence `%e' will be replaced by the number of errors accepted to
# generate the corrected strings.
local comp name _comp_correct comax local comp name _comp_correct _correct_prompt comax
setopt localoptions nullglob rcexpandparam globdots setopt localoptions nullglob rcexpandparam
unsetopt markdirs globsubst shwordsplit nounset ksharrays unsetopt markdirs globsubst shwordsplit nounset ksharrays
# Special completion contexts after `~' and `='. # Special completion contexts after `~' and `='.
@ -91,25 +102,30 @@ while true; do
# Use automatic correction? # Use automatic correction?
if (( $+COMPCORRECT )); then if (( $+compconfig[correct] )); then
# Do we have matches? # Do we have matches?
if (( compstate[nmatches] )); then if (( compstate[nmatches] )); then
# Yes, were they added using correction? (More than one match?) # Yes, were they added using correction? (More than one match?)
if [[ -n "$_comp_correct" && compstate[nmatches] -gt 1 ]]; then if [[ -n "$_comp_correct" &&
( "$compconfig[correct_orig]" = *always* ||
compstate[nmatches] -gt 1 ) ]]; then
# If we got more than one string from correction, we add the if [[ "$compconfig[correct_orig]" = *last* ]]; then
# original string as a possible match, let it not be shown in builtin compadd -V _correct_orig -nQ - "$PREFIX$SUFFIX"
# the list, and probably display the `CCPROMPT'. elif [[ -n "$compconfig[correct_orig]" ]]; then
builtin compadd -nQ - "$PREFIX$SUFFIX"
(( $+CCORIG )) && builtin compadd -nQ - "$PREFIX$SUFFIX" fi
# If you always want to see the list of possible corrections, # If you always want to see the list of possible corrections,
# set `compstate[list]=list' here. # set `compstate[list]=list' here.
compstate[force_list]=list
fi fi
# Since we have matches, we don't want to try again. # Since we have matches, we don't want to try again.
break break
fi fi
@ -117,25 +133,33 @@ while true; do
if [[ -n "$_comp_correct" ]]; then if [[ -n "$_comp_correct" ]]; then
# Yes, give up if we reached the maximum number of tries, # Yes, give up if we reached the maximum number of tries or the
# otherwise increment our counter. # string from the line is too short, otherwise increment our
# counter.
[[ _comp_correct -eq comax ]] && break [[ _comp_correct -eq comax ||
"${#${:-$PREFIX$SUFFIX}}" -le _comp_correct+1 ]] && break
(( _comp_correct++ )) (( _comp_correct++ ))
_correct_prompt="${compconfig[correct_prompt]//\%e/$_comp_correct}"
elif [[ compstate[matcher] -eq compstate[total_matchers] ]]; then elif [[ compstate[matcher] -eq compstate[total_matchers] ]]; then
# We don't try correction if the string is too short.
[[ "${#${:-$PREFIX$SUFFIX}}" -le 1 ]] && return
# No matches and no correction tried yet, but we just tried the # No matches and no correction tried yet, but we just tried the
# last global match specification, so let's see if we should use # last global match specification, so let's see if we should use
# correction now. First, get the maximum number of errors. # correction now. First, get the maximum number of errors.
if [[ "$COMPCORRECT" = *[nN]* && NUMERIC -ne 1 ]]; then if [[ "$compconfig[correct]" = *[nN]* && NUMERIC -ne 1 ]]; then
# Prefer the numeric argument if that has a sensible value. # Prefer the numeric argument if that has a sensible value.
comax="$NUMERIC" comax="$NUMERIC"
else else
comax="${COMPCORRECT//[^0-9]}" comax="${compconfig[correct]//[^0-9]}"
fi fi
# If the number of errors to accept is to small, give up. # If the number of errors to accept is too small, give up.
[[ "$comax" -lt 1 ]] && break [[ "$comax" -lt 1 ]] && break
@ -145,25 +169,31 @@ while true; do
# ignored prefix). # ignored prefix).
compadd() { compadd() {
[[ "$*" != *-([a-zA-Z/]#|)U* &&
"${#${:-$PREFIX$SUFFIX}}" -le _comp_correct ]] && return
if [[ "$PREFIX" = \~*/* ]]; then if [[ "$PREFIX" = \~*/* ]]; then
PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}" PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}"
else else
PREFIX="(#a${_comp_correct})$PREFIX" PREFIX="(#a${_comp_correct})$PREFIX"
fi fi
if (( $+CCPROMPT )); then if [[ -n "$_correct_prompt" ]]; then
builtin compadd -X "$CCPROMPT" -J _correct "$@" builtin compadd -X "$_correct_prompt" -J _correct "$@"
else else
builtin compadd -J _correct "$@" builtin compadd -J _correct "$@"
fi fi
} }
compgen() { compgen() {
[[ "$*" != *-([a-zA-Z/]#|)U* &&
"${#${:-$PREFIX$SUFFIX}}" -le _comp_correct ]] && return
if [[ "$PREFIX" = \~*/* ]]; then if [[ "$PREFIX" = \~*/* ]]; then
PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}" PREFIX="${PREFIX%%/*}/(#a${_comp_correct})${PREFIX#*/}"
else else
PREFIX="(#a${_comp_correct})$PREFIX" PREFIX="(#a${_comp_correct})$PREFIX"
fi fi
if (( $+CCPROMPT )); then if [[ -n "$_correct_prompt" ]]; then
builtin compgen "$@" -X "$CCPROMPT" -J _correct builtin compgen "$@" -X "$_correct_prompt" -J _correct
else else
builtin compgen "$@" -J _correct builtin compgen "$@" -J _correct
fi fi
@ -179,6 +209,8 @@ while true; do
_comp_correct=1 _comp_correct=1
compstate[matcher]=-1 compstate[matcher]=-1
_correct_prompt="${compconfig[correct_prompt]//\%e/$_comp_correct}"
# We also need to set `extendedglob' and to make the completion # We also need to set `extendedglob' and to make the completion
# code behave as if globcomplete were set. # code behave as if globcomplete were set.

View file

@ -1,6 +1,6 @@
#autoload #autoload
local comp command cmd1 cmd2 pat val name i ret local comp command cmd1 cmd2 pat val name i ret=1
# Completing in command position? If not we set up `cmd1' and `cmd2' as # Completing in command position? If not we set up `cmd1' and `cmd2' as
# two strings we have search in the completion definition arrays (e.g. # two strings we have search in the completion definition arrays (e.g.
@ -9,8 +9,9 @@ local comp command cmd1 cmd2 pat val name i ret
command="$words[1]" command="$words[1]"
if [[ CURRENT -eq 1 ]]; then if [[ CURRENT -eq 1 ]]; then
comp="$_comps[-command-]" comp="$_comps[-command-]"
[[ -z "$comp" ]] || "$comp" [[ -z "$comp" ]] || "$comp" && ret=0
return
return ret
elif [[ "$command[1]" == '=' ]]; then elif [[ "$command[1]" == '=' ]]; then
eval cmd1\=$command eval cmd1\=$command
cmd2="$command[2,-1]" cmd2="$command[2,-1]"
@ -28,11 +29,10 @@ for i in "$_patcomps[@]"; do
pat="${i% *}" pat="${i% *}"
val="${i#* }" val="${i#* }"
if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then
"$val" "$val" && ret=0
ret=$?
if (( $+_compskip )); then if (( $+_compskip )); then
unset _compskip unset _compskip
return $ret return ret
fi fi
fi fi
done done
@ -53,4 +53,6 @@ if [[ -z "$comp" ]]; then
name=-default- name=-default-
comp="$_comps[-default-]" comp="$_comps[-default-]"
fi fi
[[ -z "$comp" ]] || "$comp" [[ -z "$comp" ]] || "$comp" && ret=0
return ret

View file

@ -2,13 +2,15 @@
# Utility function for in-path completion. # Utility function for in-path completion.
# Supported arguments are: `-f', `-/', `-g <patterns>', `-J <group>', # Supported arguments are: `-f', `-/', `-g <patterns>', `-J <group>',
# `-V <group>', `-W paths', `-X explanation', and `-F <ignore>'. All but # `-V <group>', `-W paths', `-X explanation', `-P prefix', `-S suffix',
# the last have the same syntax and meaning as for `compgen'. The # `-q', `-r remove-chars', `-R remove-func', and `-F <ignore>'. All but
# `-F <ignore>' option may be used to give a list of suffixes either by # the last have the same syntax and meaning as for `compgen' or
# giving the name of an array or literally by giving them in a string # `compadd', respectively. The `-F <ignore>' option may be used to give
# surrounded by parentheses. Files with one of the suffixes thus given # a list of suffixes either by giving the name of an array or
# are treated like files with one of the suffixes in the `fignore' array # literally by giving them in a string surrounded by
# in normal completion. # parentheses. Files with one of the suffixes thus given are treated
# like files with one of the suffixes in the `fignore' array in normal
# completion.
# #
# This function uses the helper functions `_match_test' and `_match_pattern'. # This function uses the helper functions `_match_test' and `_match_pattern'.
@ -20,9 +22,10 @@ _match_test _path_files || return 1
local nm prepaths str linepath realpath donepath patstr prepath testpath rest local nm prepaths str linepath realpath donepath patstr prepath testpath rest
local tmp1 collect tmp2 suffixes i ignore matchflags opt group sopt pats gopt local tmp1 collect tmp2 suffixes i ignore matchflags opt group sopt pats gopt
local addpfx addsfx expl orig ostr nm=$compstate[nmatches] local addpfx addsfx expl orig ostr nm=$compstate[nmatches] menu remsfx patlast
local origflags mflags
setopt localoptions nullglob rcexpandparam globdots extendedglob setopt localoptions nullglob rcexpandparam extendedglob
unsetopt markdirs globsubst shwordsplit nounset unsetopt markdirs globsubst shwordsplit nounset
prepaths=('') prepaths=('')
@ -33,16 +36,21 @@ gopt=''
pats=() pats=()
addpfx=() addpfx=()
addsfx=() addsfx=()
remsfx=()
expl=() expl=()
# Get the options. # Get the options.
while getopts "P:S:W:F:J:V:X:f/g:" opt; do while getopts "P:S:qr:R:W:F:J:V:X:f/g:" opt; do
case "$opt" in case "$opt" in
P) addpfx=(-P "$OPTARG") P) addpfx=(-P "$OPTARG")
;; ;;
S) addsfx=(-S "$OPTARG") S) addsfx=(-S "$OPTARG")
;; ;;
q) tmp1=yes
;;
[rR]) remsfx=("-$opt" "$OPTARG")
;;
W) tmp1="$OPTARG" W) tmp1="$OPTARG"
if [[ "$tmp1[1]" = '(' ]]; then if [[ "$tmp1[1]" = '(' ]]; then
prepaths=( ${^=tmp1[2,-2]}/ ) prepaths=( ${^=tmp1[2,-2]}/ )
@ -76,6 +84,8 @@ while getopts "P:S:W:F:J:V:X:f/g:" opt; do
esac esac
done done
[[ -n "$tmp1" && $#addsfx -ne 0 ]] && addsfx[1]=-qS
# If we were given no file selection option, we behave as if we were given # If we were given no file selection option, we behave as if we were given
# a `-f'. # a `-f'.
@ -89,19 +99,25 @@ if [[ "$sopt" = - ]]; then
fi fi
# str holds the whole string from the command line with a `*' between # str holds the whole string from the command line with a `*' between
# the prefix and the suffix. # the prefix and the suffix. Then we see if we will do menucompletion.
if [[ -o globcomplete ]]; then if [[ $#compstate[pattern_match] -ne 0 ]]; then
str="${PREFIX}*${SUFFIX}" str="${PREFIX}*${SUFFIX}"
else else
str="${PREFIX:q}*${SUFFIX:q}" str="${PREFIX:q}*${SUFFIX:q}"
[[ "$str" = \\\~* ]] && str="$str[2,-1]"
fi fi
orig="${PREFIX}${SUFFIX}" orig="${PREFIX}${SUFFIX}"
# We will first try normal completion called with `compgen', but only if we [[ $compstate[insert] = *menu || -n "$_comp_correct" ||
# weren't given a `-F' option. ( $#compstate[pattern_match] -ne 0 &&
"$orig" != "${orig:q}" ) ]] && menu=yes
if (( ! $#ignore )); then
# We will first try normal completion called with `compgen', but only if we
# weren't given a `-F', `-r', or `-R' option.
if [[ $#ignore -eq 0 && $#remsfx -eq 0 && -z "$_comp_correct" ]]; then
# First build an array containing the `-W' option, if there is any and we # First build an array containing the `-W' option, if there is any and we
# want to use it. We don't want to use it if the string from the command line # want to use it. We don't want to use it if the string from the command line
# is a absolute path or relative to the current directory. # is a absolute path or relative to the current directory.
@ -124,12 +140,12 @@ if (( ! $#ignore )); then
# If this generated any matches, we don't want to do in-path completion. # If this generated any matches, we don't want to do in-path completion.
[[ compstate[nmatches] -eq nm ]] || return 0 [[ compstate[nmatches] -eq nm ]] || return 0
# No `-F' option, so we want to use `fignore'.
ignore=(-F fignore)
fi fi
# No `-F' option, so we want to use `fignore'.
(( $#ignore )) || ignore=(-F fignore)
# Now let's have a closer look at the string to complete. # Now let's have a closer look at the string to complete.
if [[ "$str[1]" = \~ ]]; then if [[ "$str[1]" = \~ ]]; then
@ -176,6 +192,7 @@ fi
patstr="$str" patstr="$str"
matchflags="" matchflags=""
_match_pattern _path_files patstr matchflags _match_pattern _path_files patstr matchflags
origflags="$matchflags"
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)" [[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
# We almost expect the pattern to have changed `..' into `*.*.', `/.' into # We almost expect the pattern to have changed `..' into `*.*.', `/.' into
@ -185,13 +202,40 @@ _match_pattern _path_files patstr matchflags
patstr="$patstr:gs-/-*/-:gs/*.*./../:gs-/*.-/.-:gs/**/*/:gs-.*/-./-" patstr="$patstr:gs-/-*/-:gs/*.*./../:gs-/*.-/.-:gs/**/*/:gs-.*/-./-"
# We take the last pathname component from the pattern and store it in
# `patlast', replacing `*'s in it with patterns that match any character
# but not slashes. Later we will generate matches using `patstr' with the
# patterns we were given (like `*.c') appended to it, producing all matching
# files. These filenames are then compared to `patlast' and all names not
# matching that will be removed. All this is needed to be able to correctly
# support `completeinword' as otherwise we would have something like `a*x'
# from the line (the `*' was inserted above) and appending the `-g' pattern
# `*.tex' would yield `a*x*.tex' which is not what we want.
if [[ "$patstr" = */* ]]; then
if [[ -n "$_comp_correct" && "${#orig##*/}" -le _comp_correct ]]; then
patlast="*/${origflags}${${patstr##*/}//\*/[^/]#}"
else
patlast="*/${matchflags}${${patstr##*/}//\*/[^/]#}"
fi
patstr="${patstr%/*}/"
else
if [[ -n "$_comp_correct" && "$#orig" -le _comp_correct ]]; then
patlast="${origflags}${patstr//\*/[^/]#}"
else
patlast="${matchflags}${patstr//\*/[^/]#}"
fi
patstr=""
fi
# First we skip over all pathname components in `str' which really exist in # First we skip over all pathname components in `str' which really exist in
# the file-system, so that `/usr/lib/l<TAB>' doesn't offer you `lib' and # the file-system, so that `/usr/lib/l<TAB>' doesn't offer you `lib' and
# `lib5'. Pathname components skipped this way are taken from `orig' and added # `lib5'. Pathname components skipped this way are taken from `orig' and added
# to `donepath'. # to `donepath'.
while [[ "$orig" = */* ]] do while [[ "$orig" = */* ]] do
tmp1=( ${~matchflags}$realpath$donepath${orig%%/*}/${~patstr#*/}$^pats ) tmp1=( $realpath$donepath${orig%%/*}/${~matchflags}${~patstr#*/}$^pats )
tmp1=("${(@M)tmp1:#$~patlast}")
[[ $#tmp1 -gt 0 && -e "$realpath$donepath${orig%%/*}" ]] || break [[ $#tmp1 -gt 0 && -e "$realpath$donepath${orig%%/*}" ]] || break
donepath="$donepath${orig%%/*}/" donepath="$donepath${orig%%/*}/"
orig="${orig#*/}" orig="${orig#*/}"
@ -217,8 +261,13 @@ for prepath in "$prepaths[@]"; do
# we get the globbing matches for the pathname component currently # we get the globbing matches for the pathname component currently
# handled. # handled.
if [[ -n "$_comp_correct" && "${#ostr%%/*}" -le _comp_correct ]]; then
mflags="$origflags"
else
mflags="$matchflags"
fi
rest="${str#*/}" rest="${str#*/}"
tmp1="${prepath}${realpath}${testpath}${~matchflags}${str%%/*}(-/)" tmp1="${prepath}${realpath}${testpath}${~mflags}${str%%/*}(-/)"
tmp1=( $~tmp1 ) tmp1=( $~tmp1 )
if [[ $#tmp1 -eq 0 ]]; then if [[ $#tmp1 -eq 0 ]]; then
@ -240,12 +289,19 @@ for prepath in "$prepaths[@]"; do
suffixes=( $rest$^pats ) suffixes=( $rest$^pats )
suffixes=( "${(@)suffixes:gs.**.*.}" ) suffixes=( "${(@)suffixes:gs.**.*.}" )
if [[ -n "$_comp_correct" && "${#ostr#*/}" -le _comp_correct ]]; then
mflags="$origflags"
else
mflags="$matchflags"
fi
# In the loop the prefixes from the `tmp1' array produced above and # In the loop the prefixes from the `tmp1' array produced above and
# the suffixes we just built are used to produce possible matches # the suffixes we just built are used to produce possible matches
# via globbing. # via globbing.
for i in "$tmp1[@]" ; do for i in "$tmp1[@]" ; do
tmp2=( ${~i}/${~matchflags}${~suffixes} ) tmp2=( ${~i}/${~mflags}${~suffixes} )
tmp2=("${(@M)tmp2:#$~patlast}")
[[ $#tmp2 -ne 0 ]] && collect=( $collect $i ) [[ $#tmp2 -ne 0 ]] && collect=( $collect $i )
done done
@ -255,9 +311,6 @@ for prepath in "$prepaths[@]"; do
# next `-W' path. # next `-W' path.
if [[ $#collect -eq 0 ]]; then if [[ $#collect -eq 0 ]]; then
compadd -QU "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \
-i "$IPREFIX" -p "${linepath:q}${testpath:q}" -S "/${ostr#*/}" \
-W "$tmp1" -f "$ignore[@]" - "${(@)tmp1:q}"
continue 2 continue 2
elif [[ $#collect -ne 1 ]]; then elif [[ $#collect -ne 1 ]]; then
# If we have more than one possible match, this means that the # If we have more than one possible match, this means that the
@ -270,6 +323,7 @@ for prepath in "$prepaths[@]"; do
# Now produce all matching pathnames in `collect'. # Now produce all matching pathnames in `collect'.
collect=( ${~collect}/${~matchflags}${~suffixes} ) collect=( ${~collect}/${~matchflags}${~suffixes} )
collect=("${(@M)collect:#$~patlast}")
# And then remove the common path prefix from all these matches. # And then remove the common path prefix from all these matches.
@ -282,15 +336,16 @@ for prepath in "$prepaths[@]"; do
# these are file names and that `fignore' should be used as usual # these are file names and that `fignore' should be used as usual
# (the `-f' and `-F' options). # (the `-f' and `-F' options).
if [[ $compstate[insert] = *menu ]]; then if [[ -n "$menu" ]]; then
compadd -QU "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \ compadd -QU "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \
-i "$IPREFIX" -p "${linepath:q}${testpath:q}" -S "/${ostr#*/}" \ -i "$IPREFIX" -p "$linepath${testpath:q}" \
-s "/${ostr#*/}" \
-W "$tmp1" -f "$ignore[@]" - "${(@)${(@)collect%%/*}:q}" -W "$tmp1" -f "$ignore[@]" - "${(@)${(@)collect%%/*}:q}"
else else
for i in $collect; do for i in $collect; do
compadd -U "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \ compadd -QU "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \
-i "$IPREFIX" -p "$linepath$testpath" -s "/${i#*/}" \ -i "$IPREFIX" -p "$linepath${testpath:q}" -s "/${${i#*/}:q}" \
-M 'r:|/=*' -W "$tmp1" -f "$ignore[@]" - "${i%%/*}" -M 'r:|/=*' -W "$tmp1" -f "$ignore[@]" - "${${i%%/*}:q}"
done done
fi fi
@ -299,12 +354,27 @@ for prepath in "$prepaths[@]"; do
continue 2 continue 2
fi fi
# We reach this point if only one of the path prefixes in `tmp1' # We reach this point if only one of the path prefixes in `tmp1'
# has a existing path-suffix matching the string from the line. # has a existing path-suffix matching the string from the line.
# In this case we accept this match and continue with the next # In this case we accept this match and continue with the next
# path-name component. # path-name component.
tmp1=( "$collect[1]" ) tmp1=( "$collect[1]" )
elif [[ -n "$_comp_correct" && "$mflags" = "$matchflags" ]]; then
# If we got only one match with auto-correction and if we get none
# without correction, stop now.
tmp2="${prepath}${realpath}${testpath}${~origflags}${str%%/*}(-/)"
tmp2=( $~tmp2 )
if [[ $#tmp1 -ne $#tmp2 ]]; then
compadd -QU "$addpfx[@]" -S '' "$group[@]" "$expl[@]" \
-i "$IPREFIX" -p "$linepath${testpath:q}" -s "/${ostr#*/}" \
- "${${tmp1#${prepath}${realpath}${testpath}}:q}"
continue 2
fi
fi fi
# This is also reached if the first globbing produced only one match # This is also reached if the first globbing produced only one match
# in this case we just continue with the next pathname component, too. # in this case we just continue with the next pathname component, too.
@ -320,10 +390,17 @@ for prepath in "$prepaths[@]"; do
# no path suffix, the `-W' we are currently handling, all the matches we # no path suffix, the `-W' we are currently handling, all the matches we
# can produce in this directory, if any. # can produce in this directory, if any.
if [[ -n "$_comp_correct" && "${#ostr#*/}" -le _comp_correct ]]; then
mflags="$origflags"
else
mflags="$matchflags"
fi
tmp1="$prepath$realpath$testpath" tmp1="$prepath$realpath$testpath"
suffixes=( $str$^pats ) suffixes=( $str$^pats )
suffixes=( "${(@)suffixes:gs.**.*.}" ) suffixes=( "${(@)suffixes:gs.**.*.}" )
tmp2=( ${~tmp1}${~matchflags}${~suffixes} ) tmp2=( ${~tmp1}${~matchflags}${~suffixes} )
tmp2=("${(@M)tmp2:#$~patlast}")
if [[ $#tmp2 -eq 0 ]]; then if [[ $#tmp2 -eq 0 ]]; then
# No match, insert the expanded path and add the original tail. # No match, insert the expanded path and add the original tail.
@ -334,11 +411,11 @@ for prepath in "$prepaths[@]"; do
[[ "$linepath$testpath$ostr" = "$PREFIX$SUFFIX" ]] && return 1 [[ "$linepath$testpath$ostr" = "$PREFIX$SUFFIX" ]] && return 1
compadd -QU -S '' "$group[@]" "$expl[@]" \ compadd -QU -S '' "$group[@]" "$expl[@]" \
-i "$IPREFIX" -f - "${linepath:q}${testpath:q}$ostr" -i "$IPREFIX" -f - "$linepath${testpath:q}$ostr"
else else
compadd -U "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" \ compadd -QU "$addpfx[@]" "$addsfx[@]" "$remsfx[@]" "$group[@]" "$expl[@]" \
-i "$IPREFIX" -p "$linepath$testpath" -f "$ignore[@]" \ -i "$IPREFIX" -p "$linepath${testpath:q}" -f "$ignore[@]" \
-W "$prepath$realpath$testpath" - "${(@)tmp2#$tmp1}" -W "$prepath$realpath$testpath" - "${(@)${(@)tmp2#$tmp1}:q}"
fi fi
done done

171
Completion/Core/_sep_parts Normal file
View file

@ -0,0 +1,171 @@
#autoload
# This function can be used to separately complete parts of strings
# where each part may be one of a set of matches and different parts
# have different sets.
# Arguments are alternatingly arrays and separator strings. Arrays may
# be given by name or literally as words separated by white space in
# parentheses, e.g.:
#
# _sep_parts '(foo bar)' @ hosts
#
# This will make this function complete the strings in the array
# `friends'. If the string on the line contains a `@', the substring
# after it will be completed from the array `hosts'. Of course more
# arrays may be given, each preceded by another separator string.
#
# This function understands the `-J group', `-V group', and
# `-X explanation' options.
#
# This function does part of the matching itself and calls the functions
# `_match_test' and `_match_pattern' for this.
local str arr sep test testarr tmparr prefix suffixes matchers autosuffix
local matchflags opt group expl nm=$compstate[nmatches]
# Test if we should use this function for the global matcher in use.
_match_test _sep_parts || return 1
# Get the options.
group=()
expl=()
while getopts "J:V:X:" opt; do
case "$opt" in
[JV]) group=("-$opt" "$OPTARG");;
X) expl=(-X "$OPTARG");;
esac
done
shift OPTIND-1
# Get the string from the line.
str="$PREFIX$SUFFIX"
[[ $#compstate[pattern_match] -ne 0 ]] || str="$str:q"
prefix=""
# Walk through the arguments to find the longest unambiguous prefix.
while [[ $# -gt 1 ]]; do
# Get the next array and separator.
arr="$1"
sep="$2"
if [[ "$arr[1]" == '(' ]]; then
tmparr=( ${=arr[2,-2]} )
arr=tmparr
fi
# Is the separator on the line?
[[ "$str" != *${sep}* ]] && break
# Build a pattern matching the possible matches and get all these
# matches in an array.
test="${str%%${sep}*}"
[[ -n "$_comp_correct" && $#test -le _comp_correct ]] && return 1
matchflags=""
_match_pattern _sep_parts test matchflags
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
test="${matchflags}${test}"
testarr=( "${(@M)${(@P)arr}:#${~test}*}" )
testarr=( "${(@)testarr:#}" )
# If there are no matches we give up. If there is more than one
# match, this is the part we will complete.
(( $#testarr )) || return 1
[[ $#testarr -gt 1 ]] && break
# Only one match, add it to the prefix and skip over it in `str',
# continuing with the next array and separator.
prefix="${prefix}${testarr[1]}${sep}"
str="${str#*${sep}}"
shift 2
done
# Get the array to work upon.
arr="$1"
if [[ "$arr[1]" == '(' ]]; then
tmparr=( ${=arr[2,-2]} )
arr=tmparr
fi
if [[ $# -le 1 || "$str" != *${2}* ]]; then
# No more separators, build the matches.
test="$str"
[[ -n "$_comp_correct" && $#test -le _comp_correct ]] && return 1
matchflags=""
_match_pattern _sep_parts test matchflags
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
test="${matchflags}${test}"
testarr=( "${(@M)${(@P)arr}:#${~test}*}" )
testarr=( "${(@)testarr:#}" )
fi
[[ $#testarr -eq 0 || ${#testarr[1]} -eq 0 ]] && return 1
# Now we build the suffixes to give to the completion code.
shift
matchers=()
suffixes=("")
autosuffix=()
while [[ $# -gt 0 && "$str" == *${1}* ]]; do
# Remove anything up to the the suffix.
str="${str#*${1}}"
# Again, we get the string from the line up to the next separator
# and build a pattern from it.
if [[ $# -gt 2 ]]; then
test="${str%%${3}*}"
else
test="$str"
fi
[[ -n "$_comp_correct" && $#test -le _comp_correct ]] && return 1
matchflags=""
_match_pattern _sep_parts test matchflags
[[ -n "$_comp_correct" ]] && matchflags="$matchflags(#a$_comp_correct)"
test="${matchflags}${test}"
# We incrementally add suffixes by appending to them the seperators
# and the strings from the next array that match the pattern we built.
arr="$2"
if [[ "$arr[1]" == '(' ]]; then
tmparr=( ${=arr[2,-2]} )
arr=tmparr
fi
tmparr=( "${(@M)${(@P)arr}:#${~test}*}" )
tmparr=( "${(@)tmparr:#}" )
suffixes=("${(@)^suffixes[@]}${1}${(@)^tmparr}")
# We want the completion code to generate the most specific suffix
# for us, so we collect matching specifications that allow partial
# word matching before the separators on the fly.
matchers=("$matchers[@]" "r:|${1:q}=*")
shift 2
done
# If we were given at least one more separator we make the completion
# code offer it by appending it as a autoremovable suffix.
(( $# )) && autosuffix=(-qS "$1")
# If we have collected matching specifications, we build an array
# from it that can be used as arguments to `compadd'.
[[ $#matchers -gt 0 ]] && matchers=(-M "$matchers")
# Add the matches for each of the suffixes.
for i in "$suffixes[@]"; do
compadd -U "$group[@]" "$expl[@]" "$matchers[@]" "$autosuffix[@]" \
-i "$IPREFIX" -p "$prefix" -s "$i" - "$testarr[@]"
done
# This sets the return value to indicate that we added matches (or not).
[[ nm -ne compstate[nmatches] ]]

View file

@ -15,7 +15,7 @@
# Print the number of files used for completion. This is used in compinit # Print the number of files used for completion. This is used in compinit
# to see if auto-dump should re-dump the dump-file. # to see if auto-dump should re-dump the dump-file.
_d_file=${COMPDUMP-${0:h}/compinit.dump} _d_file=${compconfig[dump_file]-${0:h}/compinit.dump}
typeset -U _d_files typeset -U _d_files
_d_files=( ${^~fpath}/_*~*~(N:t) ) _d_files=( ${^~fpath}/_*~*~(N:t) )

View file

@ -37,18 +37,24 @@
# Note that no white space is allowed between the `#' and the rest of # Note that no white space is allowed between the `#' and the rest of
# the string. # the string.
# #
# See the file `compdump' for how to speed up initialiation. # Functions that are used to generate matches should return zero if they
# were able to add matches and non-zero otherwise.
#
# See the file `compdump' for how to speed up initialisation.
# #
# If you are using global matching specifications with `compctl -M ...' # If you are using global matching specifications with `compctl -M ...'
# have a look at the files `_match_test' and `_match_pattern'. To make # have a look at the files `_match_test' and `_match_pattern'. To make
# all the example functions use matching as specified with `-M' these # all the example functions use matching as specified with `-M' these
# need some editing. # need some editing.
#
# If we got the `-d'-flag, we will automatically dump the new state (at # If we got the `-d'-flag, we will automatically dump the new state (at
# the end). # the end).
# If we were given an argument, this will be taken as the name of the
# file in which to store the dump.
if [[ "$1" = -d ]]; then if [[ "$1" = -d ]]; then
_i_autodump=1 _i_autodump=1
shift
else else
_i_autodump=0 _i_autodump=0
fi fi
@ -59,6 +65,18 @@ fi
typeset -A _comps typeset -A _comps
_patcomps=() _patcomps=()
# This is the associative array used for configuration.
typeset -A compconfig
# Standard initialisation for `compconfig'.
(( $# )) && compconfig[dump_file]="$1"
[[ -z "$compconfig[dump_file]" ]] && compconfig[dump_file]="$0.dump"
compconfig[correct_prompt]='correct to:'
# This function is used to register or delete completion functions. For # This function is used to register or delete completion functions. For
# registering completion functions, it is invoked with the name of the # registering completion functions, it is invoked with the name of the
# function as it's first argument (after the options). The other # function as it's first argument (after the options). The other
@ -197,12 +215,26 @@ compdef() {
fi fi
} }
# Functional interface to configuration. This takes its arguments
# and sets the according values in `compconfig'.
# Arguments may be `foo=bar' to set key `foo' to `bar' or `baz' to
# set key `baz' to the empty string.
compconf() {
local i name
for i; do
if [[ "$i" = *\=* ]]; then
name="${i%%\=*}"
compconfig[$name]="${i#*\=}"
else
compconfig[$i]=''
fi
done
}
# Now we automatically make the definition files autoloaded. # Now we automatically make the definition files autoloaded.
# First we get the name of a dump file if this will be used.
: ${COMPDUMP:=$0.dump}
if [[ ! -o extendedglob ]]; then if [[ ! -o extendedglob ]]; then
_i_noextglob=yes _i_noextglob=yes
setopt extendedglob setopt extendedglob
@ -215,10 +247,10 @@ _i_done=''
# If we have a dump file, load it. # If we have a dump file, load it.
if [[ -f "$COMPDUMP" ]]; then if [[ -f "$compconfig[dump_file]" ]]; then
read -rA _i_line < "$COMPDUMP" read -rA _i_line < "$compconfig[dump_file]"
if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then
builtin . "$COMPDUMP" builtin . "$compconfig[dump_file]"
_i_done=yes _i_done=yes
fi fi
unset _i_line unset _i_line

View file

@ -9,9 +9,12 @@ Core/compinit. It is recommnded that you use the -d option, which outputs
a file containing the necessary variables, bindkeys etc., making later a file containing the necessary variables, bindkeys etc., making later
loading much faster. For example, loading much faster. For example,
[[ -f ~/completion/compinit ]] && . ~/completion/compinit -d [[ -f ~/completion/compinit ]] && . ~/completion/compinit -d
The name of the file to use may be given as an extra argument.
This will rebind any keys which do completion to use the new system. This will rebind any keys which do completion to use the new system.
For more detailed instructions, including how to add new completions, see For more detailed instructions, including how to add new completions, see
the top of Core/compinit. the top of Core/compinit. For information about how to configure the code,
see the comment at the top of Core/_main_complete.
The subdirectories contain: The subdirectories contain:
@ -27,7 +30,7 @@ Core:
This dumps the completions status for faster initialisation. The This dumps the completions status for faster initialisation. The
easiest way of doing this is to use the -d option to compinit rather easiest way of doing this is to use the -d option to compinit rather
than calling compdump directly. than calling compdump directly.
_comp_parts _sep_parts
Utility used for completing words with multiple separate parts, such as Utility used for completing words with multiple separate parts, such as
`<user>@<host>' `<user>@<host>'
_multi_parts _multi_parts
@ -67,10 +70,15 @@ Base:
This handles completion of command arguments when no special function This handles completion of command arguments when no special function
exists. Usually this means completing files, but you can modify this exists. Usually this means completing files, but you can modify this
as you wish. as you wish.
_long_options
This handles options beginning with `--', as in many GNU commands.
The command must accept the --help option to list the possible options.
__long_options can also take arguments to help it decide what to
complete as the value of the option.
_match_pattern _match_pattern
_match_test _match_test
These are used by Base/_path_files (and hence also Base/_files) These are used by Base/_path_files (and hence also Base/_files)
and Base/_comp_parts for file completion with control over and Base/_sep_parts for file completion with control over
matching (whether to complete case-insensitively, or to allow matching (whether to complete case-insensitively, or to allow
insertion before `.', etc.) See _match_test for instructions. insertion before `.', etc.) See _match_test for instructions.
Note _path_files expects these files to be present. Note _path_files expects these files to be present.

View file

@ -0,0 +1,6 @@
DISTFILES_SRC='
.distfiles
_a2ps _compress _configure _dd _dvi _find _gunzip _gzip _hosts
_make _man _mh _pdf _ps _rcs _rlogin _strip _stty _tar _tar_archive
_tex _uncompress _x_options _xfig
'

View file

@ -1,22 +1,39 @@
#defcomp a2ps #defcomp a2ps
if [[ "$PREFIX[1,2]" = -- ]]; then # This is for the GNU version of a2ps.
_comp_parts '(--borders --compact --truncate-lines --interpret
--print-anyway --delegate)' '=' '(yes no)'
_comp_parts '(--major)' '=' '(rows columns)'
_comp_parts '(--end-of-line)' '=' '(r n nr rn any)'
compgen -S= -k '(--medium --columns --rows --line-numbers if [[ "$words[1]" != "$_a2ps_cache_cmd" ]]; then
--font-size --lines-per-page --chars-per-line local descr
--tabsize --non-printable-format --encoding
--title --stdin --prologue --highlight-level _a2ps_cache_cmd="$words[1]"
--strip-level --output --version-control --suffix
--printer --copies --sides --page-prefeed descr=( "${(@)${(f@)$($words[1] --list=features)//
--no-page-prefeed)' / }:#}" )
compgen -qS= -k '(--margin --header --underlay --left-title
--right-title --left-footer --footer --right-footer _a2ps_cache_values=(
--pages --pretty-print)' "${descr[(r)Known style sheets*]#* }"
compgen -k '(--landscape --portrait --catman --no-header)' "${descr[(r)Known encodings*]#* }"
else "${descr[(r)Known media*]#* }"
_files -F fignore -g "*~*.ps" "${descr[(r)Known prologues*]#* }"
"${descr[(r)Known PostScript Printer Descriptions*]#* }"
"${descr[(r)Known output destination*]#* }"
"${descr[(r)Known user options*]#* }"
"${descr[(r)Known Variables*]#* }"
)
fi fi
_long_options -t '*\*' '(yes no)' \
'*=DIRECTION' '(rows columns)' \
'*=TYPE' '(r n nr rn any)' \
'--highlight-level*' '(none normal heavy)' \
'--version-control*' '(none off t numbered nil
existing never simple)' \
'--pretty-print*' "[${_a2ps_cache_values[1]}]" \
'--encoding*' "(${_a2ps_cache_values[2]})" \
'--medium*' "[${_a2ps_cache_values[3]}]" \
'--prologue*' "[${_a2ps_cache_values[4]}]" \
'--ppd*' "[${_a2ps_cache_values[5]}]" \
'--printer*' "[${_a2ps_cache_values[6]}]" \
'--user-option*' "[${_a2ps_cache_values[7]}]" \
'--variable*' "[${_a2ps_cache_values[8]}]" ||
_files -F fignore -g '*~*.(ps|PS|eps|EPS)'

View file

@ -1,35 +1,4 @@
#defcomp configure #defcomp configure
setopt localoptions extendedglob _long_options '*=(E|)PREFIX*' '_files -/' \
'*=PROGRAM*' '_command_names'
if [[ $PREFIX = *=* ]]; then
# Complete filenames after e.g. --prefix=
IPREFIX=${PREFIX%%=*}=
PREFIX=${PREFIX#*=}
compgen -f
else
# Generate a list of options from configure --help
local -a pars
local i
pars=($($words[1] --help | awk '$1 ~ /--[a-z]*.*/ {print $1}'))
for i in $pars
do
case $i in
(--(((en|dis)able-FEATURE)|(with(out|)-PACKAGE))*)
: Skip standard help output
;;
--enable)
: Skip standard help output
;;
--*\[=* )
compadd -M 'r:|-=* r:|=*' -q -S = -- ${i%%\[=*}
;;
--*=* )
compadd -M 'r:|-=* r:|=*' -S = -- ${i%%=*}
;;
* )
compadd -M 'r:|-=* r:|=*' -- $i
;;
esac
done
fi

View file

@ -5,7 +5,7 @@ if [[ -iprefix conv= ]]; then
# test alone will have that effect. # test alone will have that effect.
[[ -string , ]] [[ -string , ]]
compgen -S, -q \ compgen -S, -q \
-k '(ascii ebcdic ibm block unblock lcase ucase swab noerror sync)' -k '(ascii ebcdic ibm block unblock lcase ucase swab noerror sync)'
elif [[ -iprefix 'if=' || -iprefix 'of=' ]]; then elif [[ -iprefix 'if=' || -iprefix 'of=' ]]; then
_files _files
else else

View file

@ -10,8 +10,12 @@ elif [[ -iprefix - ]]; then
{i,}{l,}name {no,}{user,group} path perm regex size true uid used \ {i,}{l,}name {no,}{user,group} path perm regex size true uid used \
exec {f,}print{f,0,} ok prune ls' exec {f,}print{f,0,} ok prune ls'
elif [[ -position 2 ]]; then elif [[ -position 2 ]]; then
compgen -g '. ..' local ret=1
_files -g '(-/)'
compgen -g '. ..' && ret=0
_files -g '(-/)' && ret=0
return ret
elif [[ "$prev" = -((a|c|)newer|fprint(|0|f)) ]]; then elif [[ "$prev" = -((a|c|)newer|fprint(|0|f)) ]]; then
_files _files
elif [[ "$prev" = -fstype ]]; then elif [[ "$prev" = -fstype ]]; then

View file

@ -1,7 +1,9 @@
#defcomp man #defcomp man
setopt localoptions rcexpandparam setopt localoptions rcexpandparam
local rep local rep
if [[ $words[2] = (<->*|ln) ]]; then if [[ $words[2] = (<->*|ln) ]]; then
rep=( $manpath/(man|cat)${words[2]}/$PREFIX*$SUFFIX.<->*(N:t:r) ) rep=( $manpath/(man|cat)${words[2]}/$PREFIX*$SUFFIX.<->*(N:t:r) )
else else

View file

@ -4,6 +4,7 @@
# Alter the following two to your own mh directory and the directory # Alter the following two to your own mh directory and the directory
# where standard mh library files live. (It works anyway, but this # where standard mh library files live. (It works anyway, but this
# will save a little time.) # will save a little time.)
local mymhdir=~/Mail local mymhdir=~/Mail
local mhlib=/usr/lib/mh local mhlib=/usr/lib/mh
@ -25,6 +26,7 @@ if [[ -iprefix - ]]; then
elif [[ -iprefix '+' || -iprefix '@' || "$prev" = -draftfolder ]]; then elif [[ -iprefix '+' || -iprefix '@' || "$prev" = -draftfolder ]]; then
# Complete folder names. # Complete folder names.
local mhpath local mhpath
if [[ $IPREFIX != '@' ]]; then if [[ $IPREFIX != '@' ]]; then
[[ $IPREFIX = '+' ]] || IPREFIX=+ [[ $IPREFIX = '+' ]] || IPREFIX=+
mhpath=$mymhdir mhpath=$mymhdir
@ -53,7 +55,8 @@ elif [[ "$prev" = -[rw]cache ]]; then
compadd public private never ask compadd public private never ask
else else
# Generate sequences. # Generate sequences.
local foldnam folddir f local foldnam folddir f ret
for f in $argv; do for f in $argv; do
[[ $f = [@+]* ]] && foldnam=$f [[ $f = [@+]* ]] && foldnam=$f
done done
@ -66,7 +69,10 @@ else
# leaving foldnam empty works here # leaving foldnam empty works here
fi fi
compgen -s '$(mark $foldnam 2>/dev/null | awk -F: '\''{ print $1 }'\'')' compgen -s '$(mark $foldnam 2>/dev/null | awk -F: '\''{ print $1 }'\'')' &&
compadd reply next cur prev first last all unseen ret=0
compgen -W folddir -g '<->' compadd reply next cur prev first last all unseen && ret=0
compgen -W folddir -g '<->' && ret=0
return ret
fi fi

View file

@ -6,6 +6,7 @@ local nm=$compstate[nmatches]
if [[ $compstate[nmatches] -eq nm && -d RCS && $words[1] != ci ]]; then if [[ $compstate[nmatches] -eq nm && -d RCS && $words[1] != ci ]]; then
local rep local rep
rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//)) rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//))
(( $#rep )) && compadd - $rep (( $#rep )) && compadd - $rep
fi fi

View file

@ -1,2 +1,3 @@
#defcomp strip #defcomp strip
_files -g '*(*)' _files -g '*(*)'

View file

@ -1,69 +1,125 @@
#defcomp tar #defcomp tar
# Tar completion. Features: # Tar completion. Features:
# - Assumes tar commands are in second position, tar archive is in third # - Tries to collect tar commands from second position, single letter
# e.g. tar xvzf zsh-3.0.5.tar.gz ... # option, and long options.
# Could search better. Send me the patch.
# - `tar' can be called anything, will use the correct name # - `tar' can be called anything, will use the correct name
# - Preferentially completes *.tar and *.TAR files in third position # - Uses the function `_tar_archive' to complete archive files.
# - unless z or Z appears in the commands, in which case prefer *.tar.gz # - Tries to find out if compressed archives should be used.
# and similar (GNU tar). # - Completes files inside archive. This is supposed to look pretty
# - From fourth position on, if command is x or t, completes files inside # much as if the files are in an ordinary directory hierarchy.
# archive. This is supposed to look pretty much as if the files are # Handles extraction from compressed archives (GNU tar).
# in an ordinary directory hierarchy. Handles extraction from compressed
# archives (GNU tar).
# - Anywhere -- appears, gets a list of long options to complete from # - Anywhere -- appears, gets a list of long options to complete from
# tar itself (GNU tar); this needs perl. If you have GNU tar but not # tar itself (GNU tar)
# perl: your system manager is weird.
# - Things like --directory=... are also completed correctly. # - Things like --directory=... are also completed correctly.
emulate -LR zsh emulate -LR zsh
setopt extendedglob setopt extendedglob
local nm=$NMATCHES tcmd="$words[2]" tf="$words[3]" local _tar_cmd tf tmp del
if [[ $PREFIX = *=* ]]; then # First we collect in `_tar_cmd' single letter options describing what
# For GNU tar arguments like --directory= # should be done with the archive and if it is compressed. This
IPREFIX=${PREFIX%%\=*}= # collected from options arguments that start with only one hyphen,
PREFIX=${PREFIX#*=} # from some of the possible long options, and from the second word if
if [[ $IPREFIX = --directory* ]]; then # that does not start with a hyphen.
_path_files -/
tmp=("${(@M)words:#-[^-]*}")
_tar_cmd="${(j::)tmp#-}"
(( $words[(I)--(un|)gzip] )) && _tar_cmd="z$_tar_cmd"
(( $words[(I)--(un|)compress] )) && _tar_cmd="Z$_tar_cmd"
(( $words[(I)--list] )) && _tar_cmd="t$_tar_cmd"
(( $words[(I)--(extract|get)] )) && _tar_cmd="x$_tar_cmd"
(( $words[(I)--create] )) && _tar_cmd="c$_tar_cmd"
# Other ways of finding out what we're doing: first
# look in the first argument if it's not an option
if [[ "$words[2]" = *[txcdruA]*~-* ]]; then
_tar_cmd="$words[2]$_tar_cmd"
elif [[ $_tar_cmd != *[txcdruA]* && CURRENT -gt 2 ]]; then
# look for more obscure long options: these aren't all handled.
(( $words[(I)--(diff|compare)] )) && _tar_cmd="d$_tar_cmd"
(( $words[(I)--append] )) && _tar_cmd="r$_tar_cmd"
(( $words[(I)--update] )) && _tar_cmd="u$_tar_cmd"
(( $words[(I)--(con|)catenate] )) && _tar_cmd="A$_tar_cmd"
(( $words[(I)--delete] )) && del=1
fi
# Next, we try to find the archive name and store it in `tf'. The name
# is searched after a `--file=' long option, in the third word if the
# second one didn't start with a hyphen but contained a `f', and after
# an option argument starting with only one hyphen and containing a `f'.
tmp="$words[(I)--file=*]"
if (( tmp )); then
tf="${words[tmp][8,-1]}"
_tar_cmd="f$_tar_cmd"
elif [[ "$words[2]" != -* && "$words[2]" = *f* ]]; then
tf="$words[3]"
_tar_cmd="f$_tar_cmd"
else
tmp="${words[(I)-*f*~--*]}"
if (( tmp )); then
tf="$words[tmp+1]"
_tar_cmd="f$_tar_cmd"
fi
fi
# Now we complete...
if [[ "$PREFIX" = --* ]]; then
# ...long options after `--'.
_long_options '--owner*' "_tilde" \
'*=(PROG|COMMAND)*' "_command_names" \
'*=ARCHIVE*' "_tar_archive" \
'*=CONTROL*' "[t numbered nil existing never simple]"
elif [[ ( CURRENT -gt 2 && "$words[CURRENT-1]" = -*f* &&
"$words[CURRENT-1]" != --* ) ||
( CURRENT -eq 3 && "$words[2]" = *f* && "$words[2]" != -* ) ]]; then
# ...archive files if we think they are wanted here.
_tar_archive
elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then
# ...and files from the archive if we found an archive name and tar
# commands. We run `tar t...' on the file, keeping the list of
# filenames cached, plus the name of the tarfile so we know if it
# changes.
local largs=-tf
if [[ $_tar_cmd = *z* ]]; then
largs=-tzf
elif [[ $_tar_cmd = *Z* ]]; then
largs=-tZf
else
# Some random compression program e.g. bzip2
tmp="${words[(r)--use-comp*]}"
[[ -n $tmp ]] && largs=($tmp -tf)
fi
if [[ $tf != $_tar_cache_name ]]; then
_tar_cache_list=("${(@f)$($words[1] $largs $tf)}")
_tar_cache_name=$tf
fi
_multi_parts / _tar_cache_list
else
# See if we should use a path prefix. We have to use eval as the dir can
# be any unevaluated thing which appears on the command line, including a
# parameter.
tmp=${words[(r)--dir[a-z]#=*]}
if [[ -n $tmp ]]; then
eval "tmp=(${tmp#*=})"
_path_files -W tmp
else else
_files _files
fi fi
elif [[ $PREFIX = --* ]]; then
# gnu tar, generate completions from --help
# ones followed by = get that as a suffix
local -a ownlist eqlist
local comp
$words[1] --help |
perl -ne 'while (/--[^[\s,='\'']+=?/g) { print "$&\n"; }' |
while read comp; do
if [[ $comp = *= ]]; then
eqlist[$#eqlist+1]=${comp%=}
else
ownlist[$#ownlist+1]=$comp
fi
done
compgen -S '=' -k eqlist
compgen -k ownlist
elif [[ "$tcmd" = *[tx]*f* && $CURRENT -ge 4 ]] then
# Listing or extracting a particular file. We run `tar t...'
# on the file, keeping the list of filenames cached, plus the
# name of the tarfile so we know if it changes.
local largs=-tf
[[ $words[2] = *z* ]] && largs=-tzf
[[ $words[2] = *Z* ]] && largs=-tZf
if [[ $tf != $tar_cache_name ]]; then
tar_cache_list=("${(@f)$($words[1] $largs $tf)}")
tar_cache_name=$tf
fi
_multi_parts / tar_cache_list
elif [[ "$tcmd" = *c*f* && $CURRENT -ge 4 ]] then
_files
elif [[ "$tcmd" = *[zZ]*f* && $CURRENT -eq 3 ]] then
_files -g '*.((tar|TAR).(gz|Z)|.tgz)'
elif [[ "$tcmd" = *f* && $CURRENT -eq 3 ]] then
_files -g '*.(tar|TAR)'
fi fi

View file

@ -0,0 +1,20 @@
#autoload
# This is used to generate filenames usable as a tar archive. This may
# get one argument, a collection of tar option characters that may be
# used to find out what kind of filename is needed. If no argument is
# given but the parameter `_tar_cmd' is set, that is used.
# If your version of `tar' supports this you may want to complete
# things like `host:file' or `user@host:file' here.
[[ $# -eq 0 && $+_tar_cmd -ne 0 ]] && set "$_tar_cmd"
if [[ "$1" = *[tx]* ]]; then
if [[ "$1" = *[zZ]* ]]; then
_files -g '*.((tar|TAR).(gz|GZ|Z)|.tgz)'
else
_files -g '*.(tar|TAR)'
fi
else
_files
fi

View file

@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the # This must also serve as a shell script, so do not add spaces around the
# `=' signs. # `=' signs.
VERSION=3.1.5-pws-11 VERSION=3.1.5-pws-12
VERSION_DATE='March 3, 1999' VERSION_DATE='March 11, 1999'

View file

@ -703,7 +703,8 @@ The pattern var(tpat) may also be a single star, `tt(*)'. This means
that the pattern on the command line can match any number of characters that the pattern on the command line can match any number of characters
in the trial completion. In this case the pattern must be anchored (on in the trial completion. In this case the pattern must be anchored (on
either side); the var(anchor) then determines how much of the trial either side); the var(anchor) then determines how much of the trial
completion is to be included. completion is to be included --- only the characters up to the next
appearance of the anchor will be matched.
Examples: Examples:
@ -758,7 +759,8 @@ nofill(tt(compctl -M 'r:|.=* r:|=*' \
-k '(comp.sources.unix comp.sources.misc ...)' ngroups)) -k '(comp.sources.unix comp.sources.misc ...)' ngroups))
) )
The first specification says that tt(lpat) is the empty string, while The first specification says that tt(lpat) is the empty string, while
tt(anchor) is a dot; tt(tpat) is tt(*), so this can match anything in tt(anchor) is a dot; tt(tpat) is tt(*), so this can match anything
except for the `tt(.)' from the anchor in
the trial completion word. So in tt(c.s.u), the matcher sees tt(c), the trial completion word. So in tt(c.s.u), the matcher sees tt(c),
followed by the empty string, followed by the anchor `tt(.)', and followed by the empty string, followed by the anchor `tt(.)', and
likewise for the second dot, and replaces the empty strings before the likewise for the second dot, and replaces the empty strings before the

View file

@ -176,6 +176,12 @@ tt(LIST_AMBIGUOUS) is set, respectively. Inside the completion widget
it may be set to any of these values to make the completion code as if it may be set to any of these values to make the completion code as if
the appropriate options had been set. the appropriate options had been set.
) )
item(tt(force_list))(
If the value for the tt(list) key is tt(ambiguous), the list will
normally be shown only if there are at least two matches in the
list. Setting tt(force_list) to an non-empty string makes the list be
shown even if there is only one match.
)
item(tt(insert))( item(tt(insert))(
This will be unset by the completon code if the contents of the This will be unset by the completon code if the contents of the
command line will not be changed. It is set to tt(unambiguous), command line will not be changed. It is set to tt(unambiguous),

View file

@ -43,22 +43,25 @@ whenlatex(report(ARG1)(ARG2)(ARG3))\
whenman(report(ARG1)(ARG2)(ARG3))\ whenman(report(ARG1)(ARG2)(ARG3))\
whenms(report(ARG1)(ARG2)(ARG3))\ whenms(report(ARG1)(ARG2)(ARG3))\
whensgml(report(ARG1)(ARG2)(ARG3))) whensgml(report(ARG1)(ARG2)(ARG3)))
myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(1998/10/26) myreport(Z-Shell Frequently-Asked Questions)(Peter Stephenson)(1999/02/25)
COMMENT(-- the following are for Usenet and must appear first)\ COMMENT(-- the following are for Usenet and must appear first)\
description( description(
mydit(Archive-Name:) unix-faq/shell/zsh mydit(Archive-Name:) unix-faq/shell/zsh
mydit(Last-Modified:) 1998/10/26 mydit(Last-Modified:) 1999/02/05
mydit(Submitted-By:) email(pws@amtp.liv.ac.uk (Peter Stephenson)) mydit(Submitted-By:) email(pws@ibmth.df.unipi.it (Peter Stephenson))
mydit(Version:) $Id: FAQ.yo,v 1.1.1.1 1999/04/15 18:05:37 akr Exp $ mydit(Version:) $Id: FAQ.yo,v 1.1.1.2 1999/04/15 18:20:31 akr Exp $
mydit(Frequency:) Monthly mydit(Posting-Frequency:) Monthly
mydit(Copyright:) (C) P.W. Stephenson, 1995, 1996, 1997, 1998 \ mydit(Copyright:) (C) P.W. Stephenson, 1995--1999 (see end of document)
(see end of document)
) )
bf(Changes since issue posted September 1998:) bf(Changes since issue posted January 1999:)
description( description(
mydit(2.1) Another mytt(typeset) difference turned up. mydit(1.1) deleted the bit saying startup files are not mentioned.
mydit(5.4) Slight addition to Y2K item (prompt formatting) mydit(3.2) New: about startup files.
mydit(3.7) we just found the PRINT_EIGHT_BIT option again...
mydit(3.22) New: about ${(e)...} and ${${...}}.
mydit(5.2) (In wishlist): patch exists for 3.1 to handle tying
texinputs/TEXINPUTS etc.
) )
This document contains a list of frequently-asked (or otherwise This document contains a list of frequently-asked (or otherwise
@ -99,25 +102,27 @@ Chapter 2: How does zsh differ from...?
Chapter 3: How to get various things to work Chapter 3: How to get various things to work
3.1. Why does `$var' where `var="foo bar"' not do what I expect? 3.1. Why does `$var' where `var="foo bar"' not do what I expect?
3.2. What is the difference between `export' and the ALL_EXPORT option? 3.2. In which startup file do I put...?
3.3. How do I turn off spelling correction/globbing for a single command? 3.3. What is the difference between `export' and the ALL_EXPORT option?
3.4. How do I get the meta key to work on my xterm? 3.4. How do I turn off spelling correction/globbing for a single command?
3.5. How do I automatically display the directory in my xterm title bar? 3.5. How do I get the meta key to work on my xterm?
3.6. How do I make the completion list use eight bit characters? 3.6. How do I automatically display the directory in my xterm title bar?
3.7. Why do the cursor (arrow) keys not work? 3.7. How do I make the completion list use eight bit characters?
3.8. Why does my terminal act funny in some way? 3.8. Why do the cursor (arrow) keys not work?
3.9. Why does zsh not work in an Emacs shell mode any more? 3.9. Why does my terminal act funny in some way?
3.10. Why do my autoloaded functions not autoload [the first time]? 3.10. Why does zsh not work in an Emacs shell mode any more?
3.11. How does base arithmetic work? 3.11. Why do my autoloaded functions not autoload [the first time]?
3.12. How do I get a newline in my prompt? 3.12. How does base arithmetic work?
3.13. Why does `bindkey ^a command-name' or 'stty intr ^-' do something funny? 3.13. How do I get a newline in my prompt?
3.14. Why can't I bind \C-s and \C-q any more? 3.14. Why does `bindkey ^a command-name' or 'stty intr ^-' do something funny?
3.15. How do I execute command `foo' within function `foo'? 3.15. Why can't I bind \C-s and \C-q any more?
3.16. Why do history substitutions with single bangs do something funny? 3.16. How do I execute command `foo' within function `foo'?
3.17. Why does zsh kill off all my background jobs when I logout? 3.17. Why do history substitutions with single bangs do something funny?
3.18. How do I list all my history entries? 3.18. Why does zsh kill off all my background jobs when I logout?
3.19. How does the alternative loop syntax, e.g. mytt(while {...} {...}) work? 3.19. How do I list all my history entries?
3.20. Why is my history not being saved? 3.20. How does the alternative loop syntax, e.g. mytt(while {...} {...}) work?
3.21. Why is my history not being saved?
3.22. How do I get a variable's value to be evaluated as another variable?
Chapter 4: The mysteries of completion Chapter 4: The mysteries of completion
4.1. What is completion? 4.1. What is completion?
@ -164,20 +169,23 @@ url(http://sunsite.auc.dk/zsh/FAQ/)(http://sunsite.auc.dk/zsh/FAQ/) .
posted frequently to the Usenet news groups comp.unix.questions, posted frequently to the Usenet news groups comp.unix.questions,
comp.unix.shells and comp.answers with answers to general questions comp.unix.shells and comp.answers with answers to general questions
about UNIX. The fifth of the seven articles deals with shells, about UNIX. The fifth of the seven articles deals with shells,
including zsh, with a brief description of differences. (This article including zsh, with a brief description of differences. There is
also talks about shell startup files which would otherwise rate a also a separate FAQ on shell differences and how to change your
mention here.) There is also a separate FAQ on shell differences shell. Usenet FAQs are available via FTP from rtfm.mit.edu and
and how to change your shell. Usenet FAQs are available via FTP mirrors and also on the World Wide Web; see
from rtfm.mit.edu and mirrors and also on the World Wide Web; see
description( description(
mydit(USA) url(http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html) mydit(USA) url(http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html)
(http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html) (http://www.cis.ohio-state.edu/hypertext/faq/usenet/top.html)
mydit(UK) url(http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html) mydit(UK) url(http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html)
(http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html) (http://www.lib.ox.ac.uk/internet/news/faq/comp.unix.shell.html)
mydit(Netherlands) url(http://www.cs.ruu.nl/wais/html/na-dir/unix-faq/shell/.html) mydit(Netherlands) url(http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html)
(http://www.cs.ruu.nl/wais/html/na-dir/unix-faq/shell/.html) (http://www.cs.uu.nl/wais/html/na-dir/unix-faq/shell/.html)
) )
You can also get it via email by emailing \
email(mail-server@rtfm.mit.edu)
with, in the body of the message, mytt(send faqs/unix-faq/shell/zsh).
The latest version of this FAQ is also available directly from any The latest version of this FAQ is also available directly from any
of the zsh archive sites listed in question link(1.6)(16). of the zsh archive sites listed in question link(1.6)(16).
@ -296,7 +304,7 @@ sect(What's the latest version?)
the list of incompatibilities at the end of link(5.1)(51). This is the list of incompatibilities at the end of link(5.1)(51). This is
longer than usual due to enhanced sh, ksh and POSIX compatibility. longer than usual due to enhanced sh, ksh and POSIX compatibility.
The beta version 3.1.4 is also available. Development of zsh is The beta version 3.1.5 is also available. Development of zsh is
usually patch by patch, with each intermediate version publicly usually patch by patch, with each intermediate version publicly
available. Note that this `open' development system does mean bugs available. Note that this `open' development system does mean bugs
are sometimes introduced into the most recent archived version. are sometimes introduced into the most recent archived version.
@ -352,6 +360,8 @@ url(http://www.math.technion.ac.il/mirror/ftp.zsh.org/pub/zsh/)
(ftp://ftp.tohoku.ac.jp/mirror/zsh/) (ftp://ftp.tohoku.ac.jp/mirror/zsh/)
mydit() url(ftp://ftp.nis.co.jp/pub/shells/zsh/) mydit() url(ftp://ftp.nis.co.jp/pub/shells/zsh/)
(ftp://ftp.nis.co.jp/pub/shells/zsh/) (ftp://ftp.nis.co.jp/pub/shells/zsh/)
mydit() url(ftp://ftp.win.ne.jp/pub/shell/zsh/)
(ftp://ftp.win.ne.jp/pub/shell/zsh/)
mydit(Norway) url(ftp://ftp.uit.no/pub/unix/shells/zsh/) mydit(Norway) url(ftp://ftp.uit.no/pub/unix/shells/zsh/)
(ftp://ftp.uit.no/pub/unix/shells/zsh/) (ftp://ftp.uit.no/pub/unix/shells/zsh/)
mydit(Romania) url(ftp://ftp.roedu.net/pub/mirrors/ftp.zsh.org/pub/zsh/) mydit(Romania) url(ftp://ftp.roedu.net/pub/mirrors/ftp.zsh.org/pub/zsh/)
@ -623,6 +633,7 @@ link(2.3)(23).
it()* Options are not local to functions (use LOCAL_OPTIONS; note this it()* Options are not local to functions (use LOCAL_OPTIONS; note this
may always be unset locally to propagate options settings from a may always be unset locally to propagate options settings from a
function to the calling level). function to the calling level).
it() Function definitions themselves are not local to functions.
) )
it() Traps and signals: it() Traps and signals:
itemize( itemize(
@ -720,12 +731,12 @@ label(23)
) )
can be replaced by the zsh function, can be replaced by the zsh function,
verb( verb(
cd() { builtin cd $*; echo $PWD; } cd() { builtin cd "$@"; echo $PWD; }
) )
(the `builtin' tells zsh to use its own `cd', avoiding an infinite loop) (the `builtin' tells zsh to use its own `cd', avoiding an infinite loop)
or, perhaps better, or, perhaps better,
verb( verb(
cd() { builtin cd $*; print -D $PWD; } cd() { builtin cd "$@"; print -D $PWD; }
) )
(which converts your home directory to a tt(~)). In fact, this problem is (which converts your home directory to a tt(~)). In fact, this problem is
better solved by defining the special function chpwd() (see the manual). better solved by defining the special function chpwd() (see the manual).
@ -746,7 +757,7 @@ label(23)
myeit() If the csh alias references its own name (tt(alias rm "rm -i")), myeit() If the csh alias references its own name (tt(alias rm "rm -i")),
then in a zsh function you need the "command" keyword then in a zsh function you need the "command" keyword
(function tt(rm() { command rm -i $* })), but in a zsh alias (function tt(rm() { command rm -i "$@" })), but in a zsh alias
you don't (tt(alias rm="rm -i")). you don't (tt(alias rm="rm -i")).
myeit() If you have aliases that refer to each other (tt(alias ls "ls -C"; myeit() If you have aliases that refer to each other (tt(alias ls "ls -C";
@ -799,7 +810,7 @@ label(23)
There is one other serious problem with aliases: consider There is one other serious problem with aliases: consider
verb( verb(
alias l='/bin/ls -F' alias l='/bin/ls -F'
l() { /bin/ls -la $* | more } l() { /bin/ls -la "$@" | more }
) )
mytt(l) in the function definition is in command position and is expanded mytt(l) in the function definition is in command position and is expanded
as an alias, defining mytt(/bin/ls) and mytt(-F) as functions which call as an alias, defining mytt(/bin/ls) and mytt(-F) as functions which call
@ -959,13 +970,68 @@ label(31)
Note also the tt("$@") method of word splitting is always available in zsh Note also the tt("$@") method of word splitting is always available in zsh
functions and scripts (though strictly this does array splitting, not functions and scripts (though strictly this does array splitting, not
word splitting). word splitting). This is more portable than the tt($*), since it
will work regardless of the SHWORDSPLIT setting; the other
difference is that tt($*) removes empty arguments from the array.
You can fix the first half of that objection by using tt(${==*}),
which turns off SHWORDSPLIT for the duration of the expansion.
SHWORDSPLIT is set when zsh is invoked with the names `ksh' or `sh', SHWORDSPLIT is set when zsh is invoked with the names `ksh' or `sh',
or (entirely equivalent) when mytt(emulate ksh) or mytt(emulate sh) is in or (entirely equivalent) when mytt(emulate ksh) or mytt(emulate sh) is in
effect. effect.
sect(In which startup file do I put...?)
When zsh starts up, there are four files you can change which it will
run under various circumstances: tt(.zshenv), tt(.zprofile), tt(.zshrc)
and tt(.zlogin). They are usually in your home directory, but the
variable tt($ZDOTDIR) may be set to alter that. Here are a few simple
hints about how to use them. There are also files which the system
administrator can set for all shells; you can avoid running all except
tt(/etc/zshenv) by starting zsh with the tt(-f) option --- for this
reason it is important for administrators to make sure tt(/etc/zshenv)
is as brief as possible.
The order in which the four files are searched (none of them myem(need)
to exist) is the one just given. However, tt(.zprofile) and tt(.zlogin)
are only run when the shell is a login shell --- when you first login,
of course, and whenever you start zsh with the tt(-l) option. All
login shells are interactive. The order is the only difference
between those; you should decide whether you need things set before or
after tt(.zshrc). These files are a good place to set environment
variables (i.e. mytt(export) commands), since they are passed on to
all shells without you having to set them again, and also to check
that your terminal is set up properly (except that if you want to
change settings for terminal emulator windows like tt(xterm) you will
need to put those in tt(.zshrc), since usually you do not get a login
shell here).
The only file you can alter which is started with every zsh (unless
you use the tt(-f) option) is tt(.zshenv), so this is a good place to \
put
things you want even if the shell is non-interactive: options for
changing the the syntax, like EXTENDED_GLOB, any changes to set with
mytt(limit), any more variables you want to make sure are set as for
example tt($fpath) to find functions. You almost certainly do not
want tt(.zshenv) to produce any output. Some people prefer not to
use tt(.zshenv) for setting options, as this affects scripts; but
making zsh scripts portable usually requires special handling anyway.
Finally, tt(.zshrc) is run for every interactive shell; that includes
login shells, but also any other time you start up a shell, such as
simply by typing mytt(zsh) or opening a new terminal emulator window.
This file is the place to change the editing behaviour via options or
mytt(bindkey), control how your history is saved, set aliases unless
you want to use them in scripts too, and for any other clutter which
can't be exported but you only use when interacting directly with the
shell. You probably don't want tt(.zshrc) to produce output, either,
since there are occasions when this can be a problem, such as when
using mytt(rsh) from another host. See link(3.21)(321) for what to \
put in tt(.zshrc)
to save your history.
sect(What is the difference between `export' and the ALL_EXPORT option?) sect(What is the difference between `export' and the ALL_EXPORT option?)
Normally, you would put a variable into the environment by using Normally, you would put a variable into the environment by using
@ -1019,7 +1085,7 @@ sect(How do I turn off spelling correction/globbing for a single command?)
sect(How do I get the meta key to work on my xterm?) sect(How do I get the meta key to work on my xterm?)
label(34) label(35)
As stated in the manual, zsh needs to be told about the meta key by As stated in the manual, zsh needs to be told about the meta key by
using mytt(bindkey -me) or mytt(bindkey -mv) in your .zshrc or on the using mytt(bindkey -me) or mytt(bindkey -mv) in your .zshrc or on the
@ -1071,36 +1137,12 @@ sect(How do I automatically display the directory in my xterm title bar?)
sect(How do I make the completion list use eight bit characters?) sect(How do I make the completion list use eight bit characters?)
A traditional UNIX environment (character terminal and ASCII If you are sure your terminal handles this, the easiest way is to
character sets) is not sufficient to be able to handle non-ASCII set the option PRINT_EIGHT_BIT. In principle, this will work
characters, and there are so many possible enhancements that in automatically if your computer uses the `locale' system and your
general this is hard. However, if you have something like an xterm locale variables are set properly, as zsh understands this.
using a standard character set like ISO-8859-1 (which is often the However, it is quite complicated, so if it isn't already set up,
default for xterm), read on. You should also note question trying the option is a lot easier.
link(3.4)(34) on the subject of eight bit characters.
You are probably creating files with names including non-ASCII
accented characters, and find they show up in the completion list as
verb(\M-i) or something such. This is because the library routines
(not zsh itself) which test whether a character is printable have
replied that it is not; zsh has simply found a way to show them
anyway.
The answer, under a modern POSIXy operating system, is to find a
locale where these are treated as printable characters. Zsh has
handling for locales built in and will recognise when you set a
relevant variable. You need to look in /usr/lib/locale to find one
which suits you; the subdirectories correspond to the locale names.
The simplest possibility is likely to be en_US, so that the simplest
answer to your problem is to set
verb(
LC_CTYPE=en_US
)
when your terminal is capable of showing eight bit characters. If
you only have a default domain (called C), you may need to have some
additional files installed on your system.
sect(Why do the cursor (arrow) keys not work?) sect(Why do the cursor (arrow) keys not work?)
@ -1433,6 +1475,7 @@ work?)
sect(Why is my history not being saved?) sect(Why is my history not being saved?)
label(321)
In zsh, you need to set three variables to make sure your history is In zsh, you need to set three variables to make sure your history is
written out when the shell exits. For example, written out when the shell exits. For example,
@ -1449,6 +1492,43 @@ sect(Why is my history not being saved?)
manual. manual.
sect(How do I get a variable's value to be evaluated as another variable?)
The problem is that you have a variable tt($E) containing the string
mytt(EDITOR), and a variable tt($EDITOR) containing the string mytt(emacs),
or something such. How do you get from tt($E) to emacs in one easy
stage?
There is no standard single-stage way of doing this. However, there
is a zsh idiom (available in all versions of zsh since 3.0) for this:
verb(
print ${(e)E:+\$$E}
)
Ignore the mytt((e)) for now. The mytt(:+) means: if the variable
tt($E) is set, substitute the following, i.e. mytt(\$$E). This is
expanded to mytt($EDITOR) by the normal rules. Finally, the mytt((e)) \
means:
evaluate the expression you just made. This gives mytt(emacs).
For a standard shell way of doing this, you are stuck with mytt(eval):
verb(
eval echo \$$E
)
produces the same result.
Future versions of zsh will probably allow you to do this directly,
with a new flag; mytt(${(P)E}).
As a slight aside, sometimes people note that the syntax mytt(${${E}})
is valid and expect it to have this effect. It probably ought to, but
in the early days of zsh it was found convenient to have this way of
producing different substitutions on the same parameter; for example,
mytt(${${file##**/}%.*}) removes everything up to the last slash in
mytt($file), then everything from the last dot on, inclusive (try
it, this works). So in mytt(${${E}}), the internal mytt(${...})
actually does nothing.
chapter(The mysteries of completion) chapter(The mysteries of completion)
Programmable completion using the `compctl' command is one of the most Programmable completion using the `compctl' command is one of the most
@ -1879,13 +1959,18 @@ label(52)
The shell is being maintained by various (entirely self-appointed) The shell is being maintained by various (entirely self-appointed)
subscribers to the mailing list, subscribers to the mailing list,
verb( verb(
zsh-workers@math.gatech.edu zsh-workers@sunsite.auc.dk
) )
so mail on any issues (bug reports, suggestions, complaints...) so mail on any issues (bug reports, suggestions, complaints...)
related to the development of the shell should be sent there. If related to the development of the shell should be sent there. If
you want someone to mail you directly, say so. Most patches to zsh you want someone to mail you directly, say so. Most patches to zsh
appear there first. appear there first.
Note that this location has just changed (January 1999), and the
instructions to go with it are slightly different --- in particular,
if you are already subscribed, the instructions about how to
unsubscribe are different.
Please note when reporting bugs that many exist only on certain Please note when reporting bugs that many exist only on certain
architectures, which the developers may not have access to. In architectures, which the developers may not have access to. In
this case debugging information, as detailed as possible, is this case debugging information, as detailed as possible, is
@ -1894,12 +1979,12 @@ label(52)
Two progressively lower volume lists exist, one with messages Two progressively lower volume lists exist, one with messages
concerning the use of zsh, concerning the use of zsh,
verb( verb(
zsh-users@math.gatech.edu zsh-users@sunsite.auc.dk
) )
and one just containing announcements: about releases, about major and one just containing announcements: about releases, about major
changes in the shell, or this FAQ, for example, changes in the shell, or this FAQ, for example,
verb( verb(
zsh-announce@math.gatech.edu zsh-announce@sunsite.auc.dk
) )
(posting to the last one is currently restricted). (posting to the last one is currently restricted).
@ -1913,20 +1998,16 @@ label(52)
To join zsh-workers, send email to To join zsh-workers, send email to
verb( verb(
zsh-workers-request@math.gatech.edu zsh-workers-subscribe@sunsite.auc.dk
) )
with the mybf(subject) line (this is a change from the old list) (the actual content is unimportant). Replace tt(subscribe) with
verb( tt(unsubscribe) to unsubscribe. The mailing software (tt(ezlm)) has
subscribe <your-email-address> various bells and whistles: you can retrieve archived messages.
) Mail email(zsh-workers-help@sunsite.auc.dk) for detailed information.
e.g. Adminstrative matters are best sent to
verb( email(zsh-workers-owner@sunsite.auc.dk). The list maintainer's
Subject: subscribe P.Stephenson@swansea.ac.uk real name is email(Karsten Thygesen <karthy@kom.auc.dk>).
)
and you can unsubscribe in the same way.
The list maintainer, Richard Coleman, can be reached at
email(coleman@math.gatech.edu).
The list from May 1992 to May 1995 is archived in The list from May 1992 to May 1995 is archived in
url(ftp://ftp.sterling.com/zsh/zsh-list/YY-MM) url(ftp://ftp.sterling.com/zsh/zsh-list/YY-MM)
(ftp://ftp.sterling.com/zsh/zsh-list/YY-MM) (ftp://ftp.sterling.com/zsh/zsh-list/YY-MM)
@ -1951,14 +2032,15 @@ sect(What's on the wish-list?)
of multiple functions to keystrokes, is being developed. of multiple functions to keystrokes, is being developed.
itemize( itemize(
it() Loadable module support (will be in 3.1 but much work still needs doing). it() Loadable module support (will be in 3.1 but much work still needs
doing).
it() Ksh compatibility could be improved. it() Ksh compatibility could be improved.
it() Option for glob qualifiers to follow perl syntax (a traditional item). it() Option for glob qualifiers to follow perl syntax (a traditional item).
it() Binding of shell functions to key strokes, accessing editing it() Binding of shell functions to key strokes, accessing editing
buffer from functions, executing zle functions as a command: now buffer from functions, executing zle functions as a command: now
under development for 3.1. under development for 3.1.
it() Users should be able to create their own foopath/FOOPATH array/path it() Users should be able to create their own foopath/FOOPATH array/path
combinations. combinations (now exists as a patch for 3.1).
) )
@ -1996,17 +2078,18 @@ nsect(Acknowledgments:)
Thanks to zsh-list, in particular Bart Schaefer, for suggestions Thanks to zsh-list, in particular Bart Schaefer, for suggestions
regarding this document. Zsh has been in the hands of archivists Jim regarding this document. Zsh has been in the hands of archivists Jim
Mattson, Bas de Bakker, Richard Coleman, Zoltan Hidvegi and Andrew Mattson, Bas de Bakker, Richard Coleman, Zoltan Hidvegi and Andrew
Main, and the mailing list has been run by Peter Gray, Rick Ohnemus Main, and the mailing list has been run by Peter Gray, Rick Ohnemus,
and Richard Coleman, all of whom deserve thanks. The world is Richard Coleman and Karsten Thygesen, all of whom deserve thanks. The
eternally in the debt of Paul Falstad for inventing zsh in the first world is eternally in the debt of Paul Falstad for inventing zsh in
place (though the wizzo extended completion is by Sven Wischnowsky). the first place (though the wizzo extended completion is by Sven
Wischnowsky).
nsect(Copyright Information:) nsect(Copyright Information:)
This document is copyright (C) P.W. Stephenson, 1995, 1996, 1997, This document is copyright (C) P.W. Stephenson, 1995, 1996, 1997,
1998. This text originates in the U.K. and the author asserts his 1998, 1999. This text originates in the U.K. and the author asserts
moral rights under the Copyrights, Designs and Patents Act, 1988. his moral rights under the Copyrights, Designs and Patents Act, 1988.
Permission is hereby granted, without written agreement and without Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this license or royalty fees, to use, copy, modify, and distribute this

View file

@ -311,11 +311,12 @@ struct cline {
#define CP_QUOTING (1 << 14) #define CP_QUOTING (1 << 14)
#define CP_RESTORE (1 << 15) #define CP_RESTORE (1 << 15)
#define CP_LIST (1 << 16) #define CP_LIST (1 << 16)
#define CP_INSERT (1 << 17) #define CP_FORCELIST (1 << 17)
#define CP_EXACT (1 << 18) #define CP_INSERT (1 << 18)
#define CP_EXACTSTR (1 << 19) #define CP_EXACT (1 << 19)
#define CP_PATMATCH (1 << 20) #define CP_EXACTSTR (1 << 20)
#define CP_PATMATCH (1 << 21)
#define CP_NUM 21 #define CP_NUM 22
#define CP_ALLMASK ((1 << CP_NUM) - 1) #define CP_ALLMASK ((1 << CP_NUM) - 1)

View file

@ -115,6 +115,7 @@ char **compwords,
*compquoting, *compquoting,
*comprestore, *comprestore,
*complist, *complist,
*compforcelist,
*compinsert, *compinsert,
*compexact, *compexact,
*compexactstr, *compexactstr,
@ -432,7 +433,7 @@ setup_comp1(Module m)
compprefix = compsuffix = compiprefix = compmatcherstr = compprefix = compsuffix = compiprefix = compmatcherstr =
compcontext = compparameter = compredirect = compquote = compcontext = compparameter = compredirect = compquote =
compquoting = comprestore = complist = compinsert = compquoting = comprestore = complist = compinsert =
compexact = compexactstr = comppatmatch = NULL; compexact = compexactstr = comppatmatch = compforcelist = NULL;
makecompparamsptr = NULL; makecompparamsptr = NULL;
comp_setunsetptr = NULL; comp_setunsetptr = NULL;
return 0; return 0;
@ -473,6 +474,7 @@ finish_comp1(Module m)
zsfree(compquoting); zsfree(compquoting);
zsfree(comprestore); zsfree(comprestore);
zsfree(complist); zsfree(complist);
zsfree(compforcelist);
zsfree(compinsert); zsfree(compinsert);
zsfree(compexact); zsfree(compexact);
zsfree(compexactstr); zsfree(compexactstr);

View file

@ -15,6 +15,7 @@ compctltab
compcurrent compcurrent
compexact compexact
compexactstr compexactstr
compforcelist
compinsert compinsert
compiprefix compiprefix
complist complist

View file

@ -183,7 +183,7 @@ print_gmatcher(int ac)
static Cmatcher static Cmatcher
parse_cmatcher(char *name, char *s) parse_cmatcher(char *name, char *s)
{ {
Cmatcher ret = NULL, r, n; Cmatcher ret = NULL, r = NULL, n;
Cpattern line, word, left, right; Cpattern line, word, left, right;
int fl, ll, wl, lal, ral, err; int fl, ll, wl, lal, ral, err;
@ -276,8 +276,10 @@ parse_cmatcher(char *name, char *s)
n->right = right; n->right = right;
n->ralen = ral; n->ralen = ral;
if (ret) r->next = n; if (ret)
else ret = n; r->next = n;
else
ret = n;
r = n; r = n;
} }
@ -290,7 +292,7 @@ parse_cmatcher(char *name, char *s)
static Cpattern static Cpattern
parse_pattern(char *name, char **sp, int *lp, char e, int *err) parse_pattern(char *name, char **sp, int *lp, char e, int *err)
{ {
Cpattern ret = NULL, r, n; Cpattern ret = NULL, r = NULL, n;
unsigned char *s = (unsigned char *) *sp; unsigned char *s = (unsigned char *) *sp;
int l = 0; int l = 0;
@ -1707,6 +1709,7 @@ bin_compadd(char *name, char **argv, char *ops, int func)
} }
for (p = *argv + 1; *p; p++) { for (p = *argv + 1; *p; p++) {
sp = NULL; sp = NULL;
e = NULL;
dm = 0; dm = 0;
switch (*p) { switch (*p) {
case 'q': case 'q':
@ -1864,6 +1867,7 @@ static struct compparam {
{ "quoting", PM_SCALAR, VAR(compquoting) }, { "quoting", PM_SCALAR, VAR(compquoting) },
{ "restore", PM_SCALAR, VAR(comprestore) }, { "restore", PM_SCALAR, VAR(comprestore) },
{ "list", PM_SCALAR, VAR(complist) }, { "list", PM_SCALAR, VAR(complist) },
{ "force_list", PM_SCALAR, VAR(compforcelist) },
{ "insert", PM_SCALAR, VAR(compinsert) }, { "insert", PM_SCALAR, VAR(compinsert) },
{ "exact", PM_SCALAR, VAR(compexact) }, { "exact", PM_SCALAR, VAR(compexact) },
{ "exact_string", PM_SCALAR, VAR(compexactstr) }, { "exact_string", PM_SCALAR, VAR(compexactstr) },
@ -2228,7 +2232,7 @@ cond_range(char **a, int id)
if (comp_check()) { if (comp_check()) {
char *s, **p; char *s, **p;
int i, l = arrlen(compwords), t = 0, b = 0, e = l - 1; int i, l = arrlen(compwords), t = 0, b = 0, e = l - 1;
Comp c; Comp c = NULL;
i = compcurrent - 1; i = compcurrent - 1;
if (i < 0 || i >= l) if (i < 0 || i >= l)

View file

@ -125,7 +125,7 @@ typedef void (*KeyScanFunc) _((char *, Thingy, char *, void *));
/* Standard type of suffix removal. */ /* Standard type of suffix removal. */
#define removesuffix() iremovesuffix(256) #define removesuffix() iremovesuffix(256, 0)
/* Cut/kill buffer type. The buffer itself is purely binary data, * /* Cut/kill buffer type. The buffer itself is purely binary data, *
* not NUL-terminated. len is a length count. flags uses the * * not NUL-terminated. len is a length count. flags uses the *

View file

@ -394,11 +394,13 @@ getkey(int keytmout)
return ret; return ret;
} }
static int no_restore_tty;
/* Read a line. It is returned metafied. */ /* Read a line. It is returned metafied. */
/**/ /**/
unsigned char * unsigned char *
zleread(char *lp, char *rp, int ha) zleread(char *lp, char *rp, int flags)
{ {
unsigned char *s; unsigned char *s;
int old_errno = errno; int old_errno = errno;
@ -451,7 +453,7 @@ zleread(char *lp, char *rp, int ha)
pmpt_attr = txtchange; pmpt_attr = txtchange;
rpromptbuf = promptexpand(rp, 1, NULL, NULL); rpromptbuf = promptexpand(rp, 1, NULL, NULL);
rpmpt_attr = txtchange; rpmpt_attr = txtchange;
histallowed = ha; histallowed = (flags & ZLRF_HISTORY);
PERMALLOC { PERMALLOC {
histline = curhist; histline = curhist;
#ifdef HAVE_SELECT #ifdef HAVE_SELECT
@ -486,6 +488,8 @@ zleread(char *lp, char *rp, int ha)
if (tmout) if (tmout)
alarm(tmout); alarm(tmout);
zleactive = 1; zleactive = 1;
if (flags & ZLRF_NOSETTY)
no_restore_tty = 1;
resetneeded = 1; resetneeded = 1;
errflag = retflag = 0; errflag = retflag = 0;
lastcol = -1; lastcol = -1;
@ -535,7 +539,7 @@ zleread(char *lp, char *rp, int ha)
trashzle(); trashzle();
free(lpromptbuf); free(lpromptbuf);
free(rpromptbuf); free(rpromptbuf);
zleactive = 0; zleactive = no_restore_tty = 0;
alarm(0); alarm(0);
} LASTALLOC; } LASTALLOC;
zsfree(curhistline); zsfree(curhistline);
@ -754,7 +758,7 @@ bin_vared(char *name, char **args, char *ops, int func)
PERMALLOC { PERMALLOC {
pushnode(bufstack, ztrdup(s)); pushnode(bufstack, ztrdup(s));
} LASTALLOC; } LASTALLOC;
t = (char *) zleread(p1, p2, ops['h']); t = (char *) zleread(p1, p2, ops['h'] ? ZLRF_HISTORY : 0);
if (!t || errflag) { if (!t || errflag) {
/* error in editing */ /* error in editing */
errflag = 0; errflag = 0;
@ -885,7 +889,8 @@ trashzle(void)
fprintf(shout, "%s", postedit); fprintf(shout, "%s", postedit);
fflush(shout); fflush(shout);
resetneeded = 1; resetneeded = 1;
settyinfo(&shttyinfo); if (!no_restore_tty)
settyinfo(&shttyinfo);
} }
if (errflag) if (errflag)
kungetct = 0; kungetct = 0;

View file

@ -42,7 +42,7 @@ doinsert(char *str)
int neg = zmult < 0; /* insert *after* the cursor? */ int neg = zmult < 0; /* insert *after* the cursor? */
int m = neg ? -zmult : zmult; /* number of copies to insert */ int m = neg ? -zmult : zmult; /* number of copies to insert */
iremovesuffix(c1); iremovesuffix(c1, 0);
invalidatelist(); invalidatelist();
if(insmode) if(insmode)
@ -849,7 +849,7 @@ makesuffixstr(char *f, char *s, int n)
/**/ /**/
void void
iremovesuffix(int c) iremovesuffix(int c, int keep)
{ {
if (suffixfunc) { if (suffixfunc) {
List l = getshfunc(suffixfunc); List l = getshfunc(suffixfunc);
@ -876,7 +876,8 @@ iremovesuffix(int c)
int sl = suffixlen[c]; int sl = suffixlen[c];
if(sl) { if(sl) {
backdel(sl); backdel(sl);
invalidatelist(); if (!keep)
invalidatelist();
} }
} }
fixsuffix(); fixsuffix();

View file

@ -442,8 +442,7 @@ reversemenucomplete(void)
menugrp = lmatches; menugrp = lmatches;
} while (!menugrp->mcount); } while (!menugrp->mcount);
menucur = menugrp->matches + menugrp->mcount - 1; menucur = menugrp->matches + menugrp->mcount - 1;
} } else
else
menucur--; menucur--;
metafy_line(); metafy_line();
do_single(*menucur); do_single(*menucur);
@ -464,7 +463,11 @@ acceptandmenucomplete(void)
return; return;
} }
if (brbeg && *brbeg) { if (brbeg && *brbeg) {
int l = (brscs >= 0 ? brscs : cs) - brpcs; int l;
iremovesuffix(',', 1);
l = (brscs >= 0 ? brscs : cs) - brpcs;
zsfree(brbeg); zsfree(brbeg);
brbeg = (char *) zalloc(l + 2); brbeg = (char *) zalloc(l + 2);
@ -472,11 +475,8 @@ acceptandmenucomplete(void)
brbeg[l] = ','; brbeg[l] = ',';
brbeg[l + 1] = '\0'; brbeg[l + 1] = '\0';
} else { } else {
int sl = suffixlen[' '];
cs = menupos + menulen + menuinsc; cs = menupos + menulen + menuinsc;
if (sl) iremovesuffix(' ', 1);
backdel(sl);
inststrlen(" ", 1, 1); inststrlen(" ", 1, 1);
menuinsc = menulen = 0; menuinsc = menulen = 0;
@ -894,21 +894,23 @@ docomplete(int lst)
* change the command line, do completion. */ * change the command line, do completion. */
if (olst == COMP_EXPAND_COMPLETE && if (olst == COMP_EXPAND_COMPLETE &&
!strcmp(ol, (char *)line)) { !strcmp(ol, (char *)line)) {
char *p;
cs = ocs; cs = ocs;
errflag = 0; errflag = 0;
p = s; if (!compfunc) {
if (*p == Tilde || *p == Equals) char *p;
p++;
for (; *p; p++) p = s;
if (itok(*p)) { if (*p == Tilde || *p == Equals)
if (*p != String && *p != Qstring) p++;
*p = ztokens[*p - Pound]; for (; *p; p++)
else if (p[1] == Inbrace) if (itok(*p)) {
p++, skipparens(Inbrace, Outbrace, &p); if (*p != String && *p != Qstring)
} *p = ztokens[*p - Pound];
else if (p[1] == Inbrace)
p++, skipparens(Inbrace, Outbrace, &p);
}
}
docompletion(s, lst, lincmd); docompletion(s, lst, lincmd);
} }
} else } else
@ -1244,16 +1246,20 @@ get_comp_string(void)
inpop(); inpop();
errflag = zleparse = 0; errflag = zleparse = 0;
if (parbegin != -1) { if (parbegin != -1) {
/* We are in command or process substitution */ /* We are in command or process substitution if we are not in
* a $((...)). */
if (parend >= 0 && !tmp) if (parend >= 0 && !tmp)
line = (unsigned char *) dupstring(tmp = (char *)line); line = (unsigned char *) dupstring(tmp = (char *)line);
linptr = (char *) line + ll + addedx - parbegin + 1; linptr = (char *) line + ll + addedx - parbegin + 1;
if (parend >= 0) { if ((linptr - (char *) line) < 2 ||
ll -= parend; linptr[-1] != '(' || linptr[-2] != '$') {
line[ll + addedx] = '\0'; if (parend >= 0) {
ll -= parend;
line[ll + addedx] = '\0';
}
lexrestore();
goto start;
} }
lexrestore();
goto start;
} }
if (inwhat == IN_MATH) if (inwhat == IN_MATH)
@ -1278,7 +1284,7 @@ get_comp_string(void)
*s = sav; *s = sav;
if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb) if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb)
s = NULL, inwhat = IN_MATH, insubscr = 1; s = NULL, inwhat = IN_MATH, insubscr = 1;
else if (*s == '=') { else if (*s == '=' && cs > wb + (s - tt)) {
s++; s++;
wb += s - tt; wb += s - tt;
t0 = STRING; t0 = STRING;
@ -1315,25 +1321,23 @@ get_comp_string(void)
* foo[_ wrong (note no $). If we are in a subscript, treat it * * foo[_ wrong (note no $). If we are in a subscript, treat it *
* as being in math. */ * as being in math. */
if (inwhat != IN_MATH) { if (inwhat != IN_MATH) {
int i = 0, hn = 0; int i = 0;
char *nb = (*s == String ? s + 1 : NULL), *ne = NULL; char *nb = (iident(*s) ? s : s + 1), *ne = NULL;
for (tt = s; ++tt < s + cs - wb;) for (tt = s; ++tt < s + cs - wb;)
if (*tt == String) { if (*tt == Inbrack) {
hn = 0;
nb = tt + 1;
} else if (*tt == Inbrack) {
i++; i++;
if (nb && !hn) { ne = tt;
hn = 1;
ne = tt;
}
} else if (i && *tt == Outbrack) } else if (i && *tt == Outbrack)
i--; i--;
else if (!iident(*tt)) {
nb = tt + 1;
ne = NULL;
}
if (i) { if (i) {
inwhat = IN_MATH; inwhat = IN_MATH;
insubscr = 1; insubscr = 1;
if (hn && nb && ne) { if (nb < ne) {
char sav = *ne; char sav = *ne;
*ne = '\0'; *ne = '\0';
zsfree(varname); zsfree(varname);
@ -1353,6 +1357,19 @@ get_comp_string(void)
s = zalloc(we - wb + 1); s = zalloc(we - wb + 1);
strncpy(s, (char *) line + wb, we - wb); strncpy(s, (char *) line + wb, we - wb);
s[we - wb] = '\0'; s[we - wb] = '\0';
if (wb > 2 && line[wb - 1] == '[' && iident(line[wb - 2])) {
int i = wb - 3;
unsigned char sav = line[wb - 1];
while (i >= 0 && iident(line[i]))
i--;
line[wb - 1] = '\0';
zsfree(varname);
varname = ztrdup((char *) line + i + 1);
line[wb - 1] = sav;
insubscr = 1;
}
} }
/* This variable will hold the current word in quoted form. */ /* This variable will hold the current word in quoted form. */
qword = ztrdup(s); qword = ztrdup(s);
@ -1599,8 +1616,7 @@ addtoword(char **rwp, int *rwlenp, char *nw,
memcpy(np, rw, rwlen); memcpy(np, rw, rwlen);
nw += np - rw; nw += np - rw;
zfree(rw, rwlen); zfree(rw, rwlen);
} } else
else
nw = np; nw = np;
*rwp = rw = np; *rwp = rw = np;
rwlen = nl; rwlen = nl;
@ -1609,8 +1625,7 @@ addtoword(char **rwp, int *rwlenp, char *nw,
if (prep) { if (prep) {
memmove(rw + al, rw, rwlen - al); memmove(rw + al, rw, rwlen - al);
memcpy(rw, as, al); memcpy(rw, as, al);
} } else
else
memcpy(nw, as, al); memcpy(nw, as, al);
return nw + al; return nw + al;
@ -2348,7 +2363,7 @@ join_new_pfx(Cline line, int len, char *word, int *missp)
/* The cline doesn't have a string built by reverse matching, /* The cline doesn't have a string built by reverse matching,
* so we have to work on the original substring in the cline * so we have to work on the original substring in the cline
* and the new string. */ * and the new string. */
if (line->wlen == len && strncmp(line->word, word, len)) { if (line->wlen == len && !strncmp(line->word, word, len)) {
/* They are equal, accept and return. If there was /* They are equal, accept and return. If there was
* another element in the list, shorten the list. */ * another element in the list, shorten the list. */
if (next) if (next)
@ -2793,7 +2808,7 @@ join_new_sfx(Cline line, int len, char *word, int *missp)
ret = line; ret = line;
} }
} else { } else {
if (line->wlen == len && strncmp(line->word, word - len, len)) { if (line->wlen == len && !strncmp(line->word, word - len, len)) {
if (next) if (next)
miss = 1; miss = 1;
line->next = NULL; line->next = NULL;
@ -2870,7 +2885,7 @@ bld_sfx(Cline o, Cline n)
o->suffix = join_new_sfx(o->suffix, n->wlen, n->word, &miss); o->suffix = join_new_sfx(o->suffix, n->wlen, n->word, &miss);
if (miss) if (miss)
o->flags |= CLF_MISS; o->flags |= CLF_MISS;
} else { } else if (o->wlen && n->wlen) {
char so = o->word[o->wlen], sn = n->word[n->wlen]; char so = o->word[o->wlen], sn = n->word[n->wlen];
char *new = o->word; char *new = o->word;
int newl = o->wlen, mol, mnl; int newl = o->wlen, mol, mnl;
@ -2896,7 +2911,8 @@ bld_sfx(Cline o, Cline n)
if (!o->suffix && n->wlen != o->wlen) if (!o->suffix && n->wlen != o->wlen)
o->flags |= CLF_MISS; o->flags |= CLF_MISS;
} } else
o->wlen = 0;
} }
/* Joins two Cline lists, building the most specific line string * /* Joins two Cline lists, building the most specific line string *
@ -2909,7 +2925,7 @@ join_clines(Cline o, Cline n)
Cline oo = o; Cline oo = o;
if (!o) if (!o)
/* This is the first time this was called, so just return the /* This is the first time we are being called, so just return
* the second list. In future calls we will get this list as * the second list. In future calls we will get this list as
* the first argument. */ * the first argument. */
return n; return n;
@ -3026,13 +3042,11 @@ join_clines(Cline o, Cline n)
o->word = NULL; o->word = NULL;
o->flags |= CLF_DIFF; o->flags |= CLF_DIFF;
} }
} } else {
else {
o->word = NULL; o->word = NULL;
o->flags |= CLF_DIFF; o->flags |= CLF_DIFF;
} }
} } else if (n->word)
else if (n->word)
o->flags |= CLF_DIFF; o->flags |= CLF_DIFF;
q = n->next; q = n->next;
@ -3152,8 +3166,7 @@ merge_cline(Cline lc, char *p, int pl, char *s, int sl, int psl)
pll -= sl - psl; pll -= sl - psl;
} }
sll = strlen(s) - sl; sll = strlen(s) - sl;
} } else
else
sll = 0; sll = 0;
pll -= pl; pll -= pl;
@ -3459,11 +3472,20 @@ match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp)
* characters are matched by the `*' pattern. * characters are matched by the `*' pattern.
* We do this by looping over the string * We do this by looping over the string
* and calling this function recursively. */ * and calling this function recursively. */
int i = 0, j = iw, k = lw; int i = 0, j = iw, k = lw, m = 0;
int jj = il + mp->llen, kk = ll - mp->llen; int jj = il + mp->llen, kk = ll - mp->llen;
char *p = l + mp->llen, *q = w; char *p = l + mp->llen, *q = w;
for (; k; i++, j++, k--, q++) { for (; k; i++, j++, k--, q++) {
if ((mp->flags & CMF_RIGHT) &&
(mp->right && k >= mp->ralen &&
pattern_match(mp->right, q,
NULL, NULL))) {
if (m++) {
k = 0;
break;
}
}
if (match_pfx(p, q, NULL, NULL, NULL, NULL)) if (match_pfx(p, q, NULL, NULL, NULL, NULL))
break; break;
} }
@ -3503,11 +3525,9 @@ match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp)
} }
lm = mp; lm = mp;
break; break;
} } else
else
t = 0; t = 0;
} } else
else
t = 0; t = 0;
} }
} else { } else {
@ -3687,13 +3707,23 @@ match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp)
!pattern_match(mp->left, w - mp->lalen, !pattern_match(mp->left, w - mp->lalen,
NULL, NULL)); NULL, NULL));
if (t) { if (t) {
int i = 0, j = iw, k = lw; int i = 0, j = iw, k = lw, m = 0;
int jj = il + mp->llen, kk = ll - mp->llen; int jj = il + mp->llen, kk = ll - mp->llen;
char *p = l - mp->llen - 1, *q = w - 1; char *p = l - mp->llen - 1, *q = w - 1;
for (; k; i++, j++, k--, q--) for (; k; i++, j++, k--, q--) {
if ((mp->flags & CMF_LEFT) &&
(mp->left && k >= mp->lalen &&
pattern_match(mp->left, q - mp->lalen,
NULL, NULL))) {
if (m++) {
k = 0;
break;
}
}
if (match_pfx(p, q, NULL, NULL, NULL, NULL)) if (match_pfx(p, q, NULL, NULL, NULL, NULL))
break; break;
}
if (k && i) { if (k && i) {
if (nlp) { if (nlp) {
nw = addtoword(&rw, &rwlen, nw, mp, nw = addtoword(&rw, &rwlen, nw, mp,
@ -3718,8 +3748,7 @@ match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp)
} }
lm = mp; lm = mp;
break; break;
} } else
else
t = 0; t = 0;
} }
} }
@ -3865,8 +3894,7 @@ comp_match(char *pfx, char *sfx, char *w, Cline *clp, int qu, int *bpl, int *bsl
return NULL; return NULL;
} }
} } else
else
return NULL; return NULL;
} else if (!(r = match_pfx(pfx, w, &pli, &pl, NULL, bpl))) } else if (!(r = match_pfx(pfx, w, &pli, &pl, NULL, bpl)))
/* We had only the prefix to match and that didn't match. */ /* We had only the prefix to match and that didn't match. */
@ -4205,12 +4233,14 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre,
t = s; t = s;
if (ppre) if (ppre)
t = dyncat(ppre, t); t = dyncat(ppre, t);
lc = NULL;
if (!cp && !ms && (mstack || psuf)) { if (!cp && !ms && (mstack || psuf)) {
int bl = ((aflags & CAF_MATCH) ? llpl : 0); int bl = ((aflags & CAF_MATCH) ? llpl : 0);
Cline *clp = &lc, tlc; Cline *clp = &lc, tlc;
char *ss = dupstring(s), *ee = me + (ss - s); char *ss = dupstring(s), *ee = me + (ss - s);
DPUTS(me < s || me > s + sl,
"BUG: invalid end-pointer (me)");
if (ppre && *ppre) { if (ppre && *ppre) {
*clp = tlc = getcline(NULL, 0, ppre, lpl, CLF_VAR); *clp = tlc = getcline(NULL, 0, ppre, lpl, CLF_VAR);
clp = &(tlc->next); clp = &(tlc->next);
@ -4245,9 +4275,13 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre,
lc = tlc; lc = tlc;
} }
if (psuf && *psuf) { if (psuf && *psuf) {
for (tlc = lc; tlc->next; tlc = tlc->next); if (lc) {
tlc->next = getcline(NULL, 0, psuf, lsl, for (tlc = lc; tlc->next; tlc = tlc->next);
CLF_END | CLF_VAR); tlc->next = getcline(NULL, 0, psuf, lsl,
CLF_END | CLF_VAR);
} else
lc = getcline(NULL, 0, psuf, lsl,
CLF_END | CLF_VAR);
} }
} }
if (ipre && *ipre) { if (ipre && *ipre) {
@ -4402,7 +4436,7 @@ addmatch(char *s, char *t)
return; return;
if ((addwhat == CC_FILES || if ((addwhat == CC_FILES ||
addwhat == -5) && !*psuf && !*fsuf) { addwhat == -5) && !*psuf) {
/* If this is a filename, do the fignore check. */ /* If this is a filename, do the fignore check. */
char **pt = fignore; char **pt = fignore;
int filell; int filell;
@ -4559,6 +4593,8 @@ addmatch(char *s, char *t)
Cline *clp = &lc, tlc; Cline *clp = &lc, tlc;
char *ss = dupstring(s), *ee = e + (ss - s); char *ss = dupstring(s), *ee = e + (ss - s);
DPUTS(e < s || e > s + sl, "BUG: invalid end-pointer (e)");
if (lppre && *lppre) { if (lppre && *lppre) {
*clp = str_cline(lppre, strlen(lppre), &tlc); *clp = str_cline(lppre, strlen(lppre), &tlc);
clp = &(tlc->next); clp = &(tlc->next);
@ -4628,19 +4664,16 @@ addmatch(char *s, char *t)
if (lpsuf && *lpsuf && strsfx(lpsuf, s)) { if (lpsuf && *lpsuf && strsfx(lpsuf, s)) {
s[sl - lpsl] = '\0'; s[sl - lpsl] = '\0';
cm->psuf = lpsuf; cm->psuf = lpsuf;
} } else
else
cm->psuf = NULL; cm->psuf = NULL;
if (lppre && *lppre && strpfx(lppre, s)) { if (lppre && *lppre && strpfx(lppre, s)) {
s += lppl; s += lppl;
cm->ppre = lppre; cm->ppre = lppre;
cm->prpre = (isf && prpre && *prpre ? prpre : NULL); cm->prpre = (isf && prpre && *prpre ? prpre : NULL);
} } else
else
cm->ppre = cm->prpre = NULL; cm->ppre = cm->prpre = NULL;
} } else {
else {
cm->ppre = (lppre && *lppre ? lppre : NULL); cm->ppre = (lppre && *lppre ? lppre : NULL);
cm->psuf = (lpsuf && *lpsuf ? lpsuf : NULL); cm->psuf = (lpsuf && *lpsuf ? lpsuf : NULL);
cm->prpre = (isf && prpre && *prpre ? prpre : NULL); cm->prpre = (isf && prpre && *prpre ? prpre : NULL);
@ -5013,6 +5046,8 @@ docompletion(char *s, int lst, int incmd)
(isset(LISTAMBIGUOUS) ? 3 : 2) : 0) : 1); (isset(LISTAMBIGUOUS) ? 3 : 2) : 0) : 1);
zsfree(comppatmatch); zsfree(comppatmatch);
comppatmatch = ztrdup(useglob ? "yes" : ""); comppatmatch = ztrdup(useglob ? "yes" : "");
zsfree(compforcelist);
compforcelist = ztrdup("");
haspattern = 0; haspattern = 0;
/* Make sure we have the completion list and compctl. */ /* Make sure we have the completion list and compctl. */
@ -5022,6 +5057,8 @@ docompletion(char *s, int lst, int incmd)
clearlist = 1; clearlist = 1;
goto compend; goto compend;
} }
if (comppatmatch && *comppatmatch)
haspattern = 1;
if (!useline && uselist) if (!useline && uselist)
/* All this and the guy only wants to see the list, sigh. */ /* All this and the guy only wants to see the list, sigh. */
showinglist = -2; showinglist = -2;
@ -5106,7 +5143,7 @@ callcompfunc(char *s, char *fn)
comppms = (Param *) zalloc(CP_NUM * sizeof(Param)); comppms = (Param *) zalloc(CP_NUM * sizeof(Param));
set = -1 & ~(CP_PARAMETER | CP_REDIRECT | CP_QUOTE | CP_QUOTING | set = -1 & ~(CP_PARAMETER | CP_REDIRECT | CP_QUOTE | CP_QUOTING |
CP_EXACTSTR | (useglob ? 0 : CP_PATMATCH)); CP_EXACTSTR | CP_FORCELIST | (useglob ? 0 : CP_PATMATCH));
zsfree(compcontext); zsfree(compcontext);
zsfree(compparameter); zsfree(compparameter);
zsfree(compredirect); zsfree(compredirect);
@ -5200,19 +5237,23 @@ callcompfunc(char *s, char *fn)
compquote = ztrdup(""); compquote = ztrdup("");
compquoting = ztrdup(""); compquoting = ztrdup("");
} }
untokenize(s = dupstring(s));
zsfree(compprefix); zsfree(compprefix);
zsfree(compsuffix); zsfree(compsuffix);
if (unset(COMPLETEINWORD)) { if (unset(COMPLETEINWORD)) {
compprefix = ztrdup(s); tmp = quotename(s, NULL, NULL, NULL);
untokenize(tmp);
compprefix = ztrdup(tmp);
compsuffix = ztrdup(""); compsuffix = ztrdup("");
} else { } else {
char *ss = s + offs, sav; char *ss = s + offs, sav;
tmp = quotename(s, &ss, NULL, NULL);
sav = *ss; sav = *ss;
*ss = '\0'; *ss = '\0';
compprefix = ztrdup(s); untokenize(tmp);
compprefix = ztrdup(tmp);
*ss = sav; *ss = sav;
untokenize(ss);
compsuffix = ztrdup(ss); compsuffix = ztrdup(ss);
} }
zsfree(compiprefix); zsfree(compiprefix);
@ -5315,7 +5356,7 @@ makecomplist(char *s, int incmd, int lst)
char *p, *os = s; char *p, *os = s;
/* Inside $... ? */ /* Inside $... ? */
if ((p = check_param(s, 0))) if (compfunc && (p = check_param(s, 0)))
os = s = p; os = s = p;
/* We build a copy of the list of matchers to use to make sure that this /* We build a copy of the list of matchers to use to make sure that this
@ -5415,6 +5456,32 @@ makecomplist(char *s, int incmd, int lst)
/* This should probably be moved into tokenize(). */ /* This should probably be moved into tokenize(). */
/**/
static char *
ctokenize(char *p)
{
char *r = p;
int bslash = 0;
tokenize(p);
for (p = r; *p; p++) {
if (*p == '\\')
bslash = 1;
else {
if (*p == '$' || *p == '{' || *p == '}') {
if (bslash)
p[-1] = Bnull;
else
*p = (*p == '$' ? String :
(*p == '{' ? Inbrace : Outbrace));
}
bslash = 0;
}
}
return r;
}
/**/ /**/
char * char *
comp_str(int *ipl, int *pl, int untok) comp_str(int *ipl, int *pl, int untok)
@ -5426,11 +5493,11 @@ comp_str(int *ipl, int *pl, int untok)
int lp, ls, lip; int lp, ls, lip;
if (!untok) { if (!untok) {
tokenize(p); ctokenize(p);
remnulargs(p); remnulargs(p);
tokenize(s); ctokenize(s);
remnulargs(s); remnulargs(s);
tokenize(ip); ctokenize(ip);
remnulargs(ip); remnulargs(ip);
} }
ls = strlen(s); ls = strlen(s);
@ -5964,8 +6031,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
if (cc->explain) { if (cc->explain) {
expl = (Cexpl) zhalloc(sizeof(struct cexpl)); expl = (Cexpl) zhalloc(sizeof(struct cexpl));
expl->count = expl->fcount = 0; expl->count = expl->fcount = 0;
} } else
else
expl = NULL; expl = NULL;
/* compadd is the number of characters we have to ignore at the * /* compadd is the number of characters we have to ignore at the *
* beginning of the word. */ * beginning of the word. */
@ -5980,8 +6046,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
uremnode(ccstack, firstnode(ccstack)); uremnode(ccstack, firstnode(ccstack));
return; return;
} }
} } else
else
ipre = NULL; ipre = NULL;
if (cc->matcher) { if (cc->matcher) {
@ -6159,12 +6224,14 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
if ((p = strrchr(lppre, '/'))) { if ((p = strrchr(lppre, '/'))) {
p[1] = '\0'; p[1] = '\0';
lppl = strlen(lppre); lppl = strlen(lppre);
} else { } else if (!sf1) {
lppre = NULL; lppre = NULL;
lppl = 0; lppl = 0;
} else {
lppre = ppre;
lppl = strlen(lppre);
} }
} } else {
else {
lppre = NULL; lppre = NULL;
lppl = 0; lppl = 0;
} }
@ -6179,10 +6246,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
strcpy(p, p + strlen(brend)); strcpy(p, p + strlen(brend));
} }
lpsuf = strchr(lpsuf, '/'); if (!(lpsuf = strchr(lpsuf, '/')) && sf2)
lpsuf = psuf;
lpsl = (lpsuf ? strlen(lpsuf) : 0); lpsl = (lpsuf ? strlen(lpsuf) : 0);
} } else {
else {
lpsuf = NULL; lpsuf = NULL;
lpsl = 0; lpsl = 0;
} }
@ -6244,7 +6311,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
opts[NULLGLOB] = 1; opts[NULLGLOB] = 1;
addwhat = 0; addwhat = 0;
p = (char *)ncalloc(lpl + lsl + 3); p = (char *)zhalloc(lpl + lsl + 3);
strcpy(p, lpre); strcpy(p, lpre);
if (*lsuf != '*' && *lpre && lpre[lpl - 1] != '*') if (*lsuf != '*' && *lpre && lpre[lpl - 1] != '*')
strcat(p, "*"); strcat(p, "*");
@ -6696,8 +6763,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
sprintf(p, "%s%s%s", m->ppre, m->str, m->psuf); sprintf(p, "%s%s%s", m->ppre, m->str, m->psuf);
addlinknode(args, dupstring(p)); addlinknode(args, dupstring(p));
} } else
else
addlinknode(args, dupstring(m->str)); addlinknode(args, dupstring(m->str));
} }
@ -6725,8 +6791,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
else else
endcmgroup(NULL); endcmgroup(NULL);
begcmgroup("default", 0); begcmgroup("default", 0);
} } else if ((tt = cc->explain)) {
else if ((tt = cc->explain)) {
tt = dupstring(tt); tt = dupstring(tt);
if ((cc->mask & CC_EXPANDEXPL) && !parsestr(tt)) { if ((cc->mask & CC_EXPANDEXPL) && !parsestr(tt)) {
singsub(&tt); singsub(&tt);
@ -6949,8 +7014,7 @@ makearray(LinkList l, int s, int *np, int *nlp)
ap = bp; ap = bp;
} }
*cp = NULL; *cp = NULL;
} } else if (s) {
else if (s) {
/* Now sort the array (it contains matches). */ /* Now sort the array (it contains matches). */
qsort((void *) rp, n, sizeof(Cmatch), qsort((void *) rp, n, sizeof(Cmatch),
(int (*) _((const void *, const void *)))matchcmp); (int (*) _((const void *, const void *)))matchcmp);
@ -7153,8 +7217,7 @@ permmatches(void)
e->str = ztrdup(o->str); e->str = ztrdup(o->str);
} }
*ep = NULL; *ep = NULL;
} } else
else
n->expls = NULL; n->expls = NULL;
if ((n->ccount = g->ccount)) { if ((n->ccount = g->ccount)) {
@ -7163,8 +7226,7 @@ permmatches(void)
for (cq = g->ccs; *cq; cq++, cp++) for (cq = g->ccs; *cq; cq++, cp++)
*cp = *cq; *cp = *cq;
*cp = NULL; *cp = NULL;
} } else
else
n->ccs = NULL; n->ccs = NULL;
g = g->next; g = g->next;
} }
@ -7306,8 +7368,11 @@ do_ambiguous(void)
ls = ainfo->csl; ls = ainfo->csl;
} }
if (lc) { if (lc) {
if (!ps)
ps = "";
if (lp) { if (lp) {
if (ls) { if (ls) {
DPUTS(!ainfo->firstm, "BUG: merge without firtsm");
if (ainfo->firstm->psuf) if (ainfo->firstm->psuf)
merge_cline(lc, ps, lp, merge_cline(lc, ps, lp,
dyncat(ainfo->firstm->str, dyncat(ainfo->firstm->str,
@ -7329,11 +7394,13 @@ do_ambiguous(void)
ocs += l; ocs += l;
cs = ocs; cs = ocs;
} }
if(ainfo->suflen && !atend) if(ainfo->suflen && !atend) {
DPUTS(!ainfo->firstm, "BUG: suffix without firstm");
inststrlen(ainfo->firstm->str + inststrlen(ainfo->firstm->str +
strlen(ainfo->firstm->str) - ainfo->suflen, 1, strlen(ainfo->firstm->str) - ainfo->suflen, 1,
ainfo->suflen); ainfo->suflen);
if (ainfo->firstm->psuf) }
if (ainfo->firstm && ainfo->firstm->psuf)
inststrlen(ainfo->firstm->psuf, 0, -1); inststrlen(ainfo->firstm->psuf, 0, -1);
if (brend && *brend) { if (brend && *brend) {
cs -= brsl; cs -= brsl;
@ -7374,7 +7441,8 @@ do_ambiguous(void)
* if it is needed. */ * if it is needed. */
if (isset(LISTBEEP)) if (isset(LISTBEEP))
feep(); feep();
if (uselist && usemenu != 2 && !showinglist && smatches >= 2) if (uselist && usemenu != 2 && !showinglist &&
(smatches >= 2 || (compforcelist && *compforcelist)))
showinglist = -2; showinglist = -2;
} }
@ -7484,13 +7552,11 @@ do_single(Cmatch m)
sprintf(p, "%s%s%s", m->ripre, str, psuf); sprintf(p, "%s%s%s", m->ripre, str, psuf);
if (pl && p[pl-1] == Inbrace) if (pl && p[pl-1] == Inbrace)
strcpy(p+pl-1, p+pl); strcpy(p+pl-1, p+pl);
} } else if (ic) {
else if (ic) {
p = (char *) ncalloc(strlen(ppre) + strlen(str) + p = (char *) ncalloc(strlen(ppre) + strlen(str) +
strlen(psuf) + 2); strlen(psuf) + 2);
sprintf(p, "%c%s%s%s", ic, ppre, str, psuf); sprintf(p, "%c%s%s%s", ic, ppre, str, psuf);
} } else {
else {
p = (char *) ncalloc(strlen(ppre) + strlen(str) + p = (char *) ncalloc(strlen(ppre) + strlen(str) +
strlen(psuf) + 1); strlen(psuf) + 1);
sprintf(p, "%s%s%s", ppre, str, psuf); sprintf(p, "%s%s%s", ppre, str, psuf);
@ -7744,8 +7810,7 @@ listmatches(void)
pp++; pp++;
} }
nlines--; nlines--;
} } else {
else {
while (*pp) { while (*pp) {
if ((l = strlen(*pp)) > longest) if ((l = strlen(*pp)) > longest)
longest = l; longest = l;
@ -7753,8 +7818,7 @@ listmatches(void)
pp++; pp++;
} }
} }
} } else {
else {
for (p = g->matches; (m = *p); p++) { for (p = g->matches; (m = *p); p++) {
if (!(m->flags & CMF_NOLIST)) { if (!(m->flags & CMF_NOLIST)) {
if ((l = niceztrlen(m->str)) > longest) if ((l = niceztrlen(m->str)) > longest)
@ -7851,8 +7915,7 @@ listmatches(void)
if (*++pp) if (*++pp)
putc('\n', shout); putc('\n', shout);
} }
} } else {
else {
int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, a; int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, a;
char **pq; char **pq;
@ -7876,8 +7939,7 @@ listmatches(void)
pp++; pp++;
} }
} }
} } else if (g->lcount) {
else if (g->lcount) {
int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, j, a = 0; int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, j, a = 0;
Cmatch *q; Cmatch *q;
@ -7938,8 +8000,7 @@ listmatches(void)
showinglist = -1; showinglist = -1;
} else } else
clearflag = 0, putc('\n', shout); clearflag = 0, putc('\n', shout);
} } else
else
putc('\n', shout); putc('\n', shout);
} }

View file

@ -2304,26 +2304,25 @@ getmatch(char **sp, char *pat, int fl, int n, char *replstr)
case SUB_LONG: case SUB_LONG:
/* /*
* Largest/smallest possible match at head of string. * Largest/smallest possible match at head of string.
* First get the longest match. * First get the longest match...
*/ */
if (dolongestmatch(s, c, 0)) { if (dolongestmatch(s, c, 0)) {
char *mpos = pptr; char *mpos = pptr;
while (!(fl & SUB_LONG) && pptr > s) { if (!(fl & SUB_LONG)) {
/* /*
* If we want the shortest, keep backing up to the * ... now we know whether it's worth looking for the
* previous character and find the longest up to there. * shortest, which we do by brute force.
* That way we can usually reach the shortest in only */
* a few attempts. for (t = s; t < mpos; METAINC(t)) {
*/
t = (pptr > s + 1 && pptr[-2] == Meta) ? pptr - 2 : pptr -1;
sav = *t; sav = *t;
*t = '\0'; *t = '\0';
if (!dolongestmatch(s, c, 0)) { if (dolongestmatch(s, c, 0)) {
*t = sav; mpos = pptr;
break; *t = sav;
break;
} }
mpos = pptr;
*t = sav; *t = sav;
}
} }
*sp = get_match_ret(*sp, 0, mpos-s, fl, replstr); *sp = get_match_ret(*sp, 0, mpos-s, fl, replstr);
return 1; return 1;

View file

@ -735,6 +735,8 @@ hend(void)
int flag, save = 1; int flag, save = 1;
DPUTS(!chline, "BUG: chline is NULL in hend()"); DPUTS(!chline, "BUG: chline is NULL in hend()");
if (histdone & HISTFLAG_SETTY)
settyinfo(&shttyinfo);
if (histactive & (HA_NOSTORE|HA_NOINC)) { if (histactive & (HA_NOSTORE|HA_NOINC)) {
zfree(chline, hlinesz); zfree(chline, hlinesz);
zfree(chwords, chwordlen*sizeof(short)); zfree(chwords, chwordlen*sizeof(short));

View file

@ -792,7 +792,11 @@ run_init_scripts(void)
void void
init_misc(void) init_misc(void)
{ {
#ifndef RESTRICTED_R
if ( restricted )
#else
if (*zsh_name == 'r' || restricted) if (*zsh_name == 'r' || restricted)
#endif
dosetopt(RESTRICTED, 1, 0); dosetopt(RESTRICTED, 1, 0);
if (cmd) { if (cmd) {
if (SHIN >= 10) if (SHIN >= 10)

View file

@ -249,8 +249,21 @@ inputline(void)
free(pptbuf); free(pptbuf);
} }
ingetcline = shingetline(); ingetcline = shingetline();
} else } else {
ingetcline = (char *)zleread(ingetcpmptl, ingetcpmptr, 1); /*
* Since we may have to read multiple lines before getting
* a complete piece of input, we tell zle not to restore the
* original tty settings after reading each chunk. Instead,
* this is done when the history mechanism for the current input
* terminates, which is not until we have the whole input.
* This is supposed to minimise problems on systems that clobber
* typeahead when the terminal settings are altered.
* pws 1998/03/12
*/
ingetcline = (char *)zleread(ingetcpmptl, ingetcpmptr,
ZLRF_HISTORY|ZLRF_NOSETTY);
histdone |= HISTFLAG_SETTY;
}
if (!ingetcline) { if (!ingetcline) {
return lexstop = 1; return lexstop = 1;
} }

View file

@ -522,11 +522,20 @@ bin_setopt(char *nam, char **args, char *ops, int isun)
/* Globbing option (-m) set. */ /* Globbing option (-m) set. */
while (*args) { while (*args) {
Comp com; Comp com;
char *s, *t;
t = s = dupstring(*args);
while (*t)
if (*t == '_')
chuck(t);
else {
*t = tulower(*t);
t++;
}
/* Expand the current arg. */ /* Expand the current arg. */
tokenize(*args); tokenize(s);
if (!(com = parsereg(*args))) { if (!(com = parsereg(s))) {
untokenize(*args);
zwarnnam(nam, "bad pattern: %s", *args, 0); zwarnnam(nam, "bad pattern: %s", *args, 0);
continue; continue;
} }

View file

@ -6,7 +6,7 @@
# NB: On SunOS 4.1.3 - user-functions don't work properly, also \" problems # NB: On SunOS 4.1.3 - user-functions don't work properly, also \" problems
# Without 0 + hacks some nawks compare numbers as strings # Without 0 + hacks some nawks compare numbers as strings
# #
/^XXNAMES XXSIG[A-Z][A-Z0-9]* [1-9][0-9]*/ { /^XXNAMES XXSIG[A-Z][A-Z0-9]*[\t ][\t ]*[1-9][0-9]*/ {
sigindex = index($0, "SIG") sigindex = index($0, "SIG")
sigtail = substr($0, sigindex, 80) sigtail = substr($0, sigindex, 80)
split(sigtail, tmp) split(sigtail, tmp)

View file

@ -263,7 +263,7 @@ multsub(char **s, char ***a, int *isarr, char *sep)
*isarr = 0; *isarr = 0;
return 0; return 0;
} }
if ((l = countlinknodes(foo)) > 1) { if ((l = countlinknodes(foo)) > 1 || a) {
p = r = ncalloc((l + 1) * sizeof(char*)); p = r = ncalloc((l + 1) * sizeof(char*));
while (nonempty(foo)) while (nonempty(foo))
*p++ = (char *)ugetnode(foo); *p++ = (char *)ugetnode(foo);
@ -976,7 +976,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
skipparens(*s, *s == Inpar ? Outpar : Outbrace, &s); skipparens(*s, *s == Inpar ? Outpar : Outbrace, &s);
sav = *s; sav = *s;
*s = 0; *s = 0;
if (multsub(&val, (aspar ? NULL : &aval), &isarr, NULL) && quoted) { if (multsub(&val, (((quoted || aspar) && !nojoin) ? NULL : &aval),
&isarr, NULL) &&
quoted) {
isarr = -1; isarr = -1;
aval = alloc(sizeof(char *)); aval = alloc(sizeof(char *));
aspar = 0; aspar = 0;

View file

@ -1013,7 +1013,7 @@ struct histent {
#define HISTFLAG_DONE 1 #define HISTFLAG_DONE 1
#define HISTFLAG_NOEXEC 2 #define HISTFLAG_NOEXEC 2
#define HISTFLAG_RECALL 4 #define HISTFLAG_RECALL 4
#define HISTFLAG_SETTY 8
/******************************************/ /******************************************/
/* Definitions for programable completion */ /* Definitions for programable completion */
@ -1403,6 +1403,13 @@ struct heap {
#define ZSIG_IGNORED (1<<1) #define ZSIG_IGNORED (1<<1)
#define ZSIG_FUNC (1<<2) #define ZSIG_FUNC (1<<2)
/**********************************/
/* Flags to third argument of zle */
/**********************************/
#define ZLRF_HISTORY 0x01
#define ZLRF_NOSETTY 0x02
/****************/ /****************/
/* Entry points */ /* Entry points */
/****************/ /****************/

View file

@ -158,6 +158,11 @@
* hash tables. This turns on the `hashinfo' builtin. */ * hash tables. This turns on the `hashinfo' builtin. */
#undef ZSH_HASH_DEBUG #undef ZSH_HASH_DEBUG
/* Undefine this if you don't want to get a restricted shell *
* when zsh is exec'd with basename that starts with r. *
* By default this is defined. */
#undef RESTRICTED_R
/* Define to 1 if your termcap library has the ospeed variable */ /* Define to 1 if your termcap library has the ospeed variable */
#undef HAVE_OSPEED #undef HAVE_OSPEED
/* Define to 1 if you have ospeed, but it is not defined in termcap.h */ /* Define to 1 if you have ospeed, but it is not defined in termcap.h */

368
config.guess vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Attempt to guess a canonical system name. # Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. # Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
# #
# This file is free software; you can redistribute it and/or modify it # This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
@ -52,11 +52,53 @@ trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
alpha:OSF1:*:*) alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
# A Vn.n version is a released version. # A Vn.n version is a released version.
# A Tn.n version is a released field test version. # A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel. # A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r. # 1.2 uses "1.2" for uname -r.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` cat <<EOF >dummy.s
.globl main
.ent main
main:
.frame \$30,0,\$26,0
.prologue 0
.long 0x47e03d80 # implver $0
lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.end main
EOF
${CC-cc} dummy.s -o dummy 2>/dev/null
if test "$?" = 0 ; then
./dummy
case "$?" in
7)
UNAME_MACHINE="alpha"
;;
15)
UNAME_MACHINE="alphaev5"
;;
14)
UNAME_MACHINE="alphaev56"
;;
10)
UNAME_MACHINE="alphapca56"
;;
16)
UNAME_MACHINE="alphaev6"
;;
esac
fi
rm -f dummy.s dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
exit 0 ;; exit 0 ;;
21064:Windows_NT:50:3) 21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5 echo alpha-dec-winnt3.5
@ -68,15 +110,39 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo m68k-cbm-netbsd${UNAME_RELEASE} echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
amiga:OpenBSD:*:*) amiga:OpenBSD:*:*)
echo m68k-cbm-openbsd${UNAME_RELEASE} echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
sa110:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) *:[Aa]miga[Oo][Ss]:*:*)
echo arm-unknown-linux echo ${UNAME_MACHINE}-unknown-amigaos
exit 0;; exit 0 ;;
arc64:OpenBSD:*:*)
echo mips64el-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hkmips:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE} echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;; exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) arm32:NetBSD:*:*)
echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
SR2?01:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3 echo pyramid-pyramid-sysv3
@ -87,6 +153,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
NILE:*:*:dcosx) NILE:*:*:dcosx)
echo pyramid-pyramid-svr4 echo pyramid-pyramid-svr4
exit 0 ;; exit 0 ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;; exit 0 ;;
@ -111,6 +180,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun3*:SunOS:*:*) sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE} echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit 0 ;;
aushp:SunOS:*:*) aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE} echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
@ -118,23 +199,32 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo m68k-atari-netbsd${UNAME_RELEASE} echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
atari*:OpenBSD:*:*) atari*:OpenBSD:*:*)
echo m68k-atari-openbsd${UNAME_RELEASE} echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
sun3*:NetBSD:*:*) sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE} echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
sun3*:OpenBSD:*:*) sun3*:OpenBSD:*:*)
echo m68k-sun-openbsd${UNAME_RELEASE} echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
mac68k:NetBSD:*:*) mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE} echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
mac68k:OpenBSD:*:*) mac68k:OpenBSD:*:*)
echo m68k-apple-openbsd${UNAME_RELEASE} echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
powerpc:machten:*:*) powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE} echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
macppc:NetBSD:*:*)
echo powerpc-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
RISC*:Mach:*:*) RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3 echo mips-dec-mach_bsd4.3
exit 0 ;; exit 0 ;;
@ -144,6 +234,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
VAX*:ULTRIX*:*:*) VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE} echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
2020:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos) mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF >dummy.c sed 's/^ //' << EOF >dummy.c
int main (argc, argv) int argc; char **argv; { int main (argc, argv) int argc; char **argv; {
@ -237,7 +330,8 @@ EOF
fi fi
exit 0 ;; exit 0 ;;
*:AIX:*:4) *:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000 IBM_ARCH=rs6000
else else
IBM_ARCH=powerpc IBM_ARCH=powerpc
@ -270,12 +364,44 @@ EOF
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4 echo m68k-hp-bsd4.4
exit 0 ;; exit 0 ;;
9000/[3478]??:HP-UX:*:*) 9000/[34678]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;; 9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;; 9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; 9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
9000/8?? ) HP_ARCH=hppa1.0 ;; sed 's/^ //' << EOF >dummy.c
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy`
rm -f dummy.c dummy
esac esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV} echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@ -378,8 +504,11 @@ EOF
hp3[0-9][05]:NetBSD:*:*) hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE} echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
hp3[0-9][05]:OpenBSD:*:*) hp300:OpenBSD:*:*)
echo m68k-hp-openbsd${UNAME_RELEASE} echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
i?86:BSD/386:*:* | *:BSD/OS:*:*) i?86:BSD/386:*:* | *:BSD/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@ -394,54 +523,146 @@ EOF
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;; exit 0 ;;
i*:CYGWIN*:*) i*:CYGWIN*:*)
echo i386-pc-cygwin32 echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;; exit 0 ;;
p*:CYGWIN*:*) p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32 echo powerpcle-unknown-cygwin
exit 0 ;; exit 0 ;;
prep*:SunOS:5.*:*) prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;; exit 0 ;;
*:GNU:*:*) *:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;; exit 0 ;;
*:Linux:*:*) *:Linux:*:*)
# uname on the ARM produces all sorts of strangeness, and we need to
# filter it out.
case "$UNAME_MACHINE" in
arm* | sa110*) UNAME_MACHINE="arm" ;;
esac
# The BFD linker knows what the default object file format is, so # The BFD linker knows what the default object file format is, so
# first see if it will tell us. # first see if it will tell us.
ld_help_string=`ld --help 2>&1` ld_help_string=`ld --help 2>&1`
if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then ld_supported_emulations=`echo $ld_help_string \
echo "${UNAME_MACHINE}-pc-linux" ; exit 0 | sed -ne '/supported emulations:/!d
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32arm"; then s/[ ][ ]*/ /g
echo "arm-unknown-linux" ; exit 0 s/.*supported emulations: *//
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then s/ .*//
echo "${UNAME_MACHINE}-pc-linuxaout" ; exit 0 p'`
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then case "$ld_supported_emulations" in
echo "${UNAME_MACHINE}-pc-linuxcoff" ; exit 0 i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0 m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;;
echo "powerpc-unknown-linux" ; exit 0 esac
elif test "${UNAME_MACHINE}" = "alpha" ; then
echo alpha-unknown-linux ; exit 0 if test "${UNAME_MACHINE}" = "alpha" ; then
elif test "${UNAME_MACHINE}" = "sparc" ; then sed 's/^ //' <<EOF >dummy.s
echo sparc-unknown-linux ; exit 0 .globl main
else .ent main
# Either a pre-BFD a.out linker (linuxoldld) or one that does not give us main:
# useful --help. Gcc wants to distinguish between linuxoldld and linuxaout. .frame \$30,0,\$26,0
test ! -d /usr/lib/ldscripts/. \ .prologue 0
&& echo "${UNAME_MACHINE}-pc-linuxoldld" && exit 0 .long 0x47e03d80 # implver $0
# Determine whether the default compiler is a.out or elf lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.end main
EOF
LIBC=""
${CC-cc} dummy.s -o dummy 2>/dev/null
if test "$?" = 0 ; then
./dummy
case "$?" in
7)
UNAME_MACHINE="alpha"
;;
15)
UNAME_MACHINE="alphaev5"
;;
14)
UNAME_MACHINE="alphaev56"
;;
10)
UNAME_MACHINE="alphapca56"
;;
16)
UNAME_MACHINE="alphaev6"
;;
esac
objdump --private-headers dummy | \
grep ld.so.1 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f dummy.s dummy
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
elif test "${UNAME_MACHINE}" = "mips" ; then
cat >dummy.c <<EOF cat >dummy.c <<EOF
main(argc, argv) main(argc, argv)
int argc; int argc;
char *argv[]; char *argv[];
{
#ifdef __MIPSEB__
printf ("%s-unknown-linux-gnu\n", argv[1]);
#endif
#ifdef __MIPSEL__
printf ("%sel-unknown-linux-gnu\n", argv[1]);
#endif
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
else
# Either a pre-BFD a.out linker (linux-gnuoldld)
# or one that does not give us useful --help.
# GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
# If ld does not provide *any* "supported emulations:"
# that means it is gnuoldld.
echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
case "${UNAME_MACHINE}" in
i?86)
VENDOR=pc;
;;
*)
VENDOR=unknown;
;;
esac
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
#include <features.h>
main(argc, argv)
int argc;
char *argv[];
{ {
#ifdef __ELF__ #ifdef __ELF__
printf ("%s-pc-linux\n", argv[1]); # ifdef __GLIBC__
# if __GLIBC__ >= 2
printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
# else
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
# endif
# else
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
# endif
#else #else
printf ("%s-pc-linuxaout\n", argv[1]); printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
#endif #endif
return 0; return 0;
} }
@ -454,6 +675,14 @@ EOF
i?86:DYNIX/ptx:4*:*) i?86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4 echo i386-sequent-sysv4
exit 0 ;; exit 0 ;;
i?86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
@ -475,6 +704,18 @@ EOF
echo ${UNAME_MACHINE}-pc-sysv32 echo ${UNAME_MACHINE}-pc-sysv32
fi fi
exit 0 ;; exit 0 ;;
i?86:UnixWare:*:*)
if /bin/uname -X 2>/dev/null >/dev/null ; then
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
fi
echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION}
exit 0 ;;
pc:*:*:*)
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit 0 ;;
Intel:Mach:3*:*) Intel:Mach:3*:*)
echo i386-pc-mach3 echo i386-pc-mach3
exit 0 ;; exit 0 ;;
@ -526,9 +767,6 @@ EOF
RM*:SINIX-*:*:*) RM*:SINIX-*:*:*)
echo mips-sni-sysv4 echo mips-sni-sysv4
exit 0 ;; exit 0 ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*) *:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null` UNAME_MACHINE=`(uname -p) 2>/dev/null`
@ -537,6 +775,10 @@ EOF
echo ns32k-sni-sysv echo ns32k-sni-sysv
fi fi
exit 0 ;; exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*) *:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>. # From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm # How about differentiating between stratus architectures? -djm
@ -549,23 +791,25 @@ EOF
mc68*:A/UX:*:*) mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE} echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) news*:NEWS-OS:*:6*)
echo mips-sony-newsos6
exit 0 ;;
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE} echo mips-nec-sysv${UNAME_RELEASE}
else else
echo mips-unknown-sysv${UNAME_RELEASE} echo mips-unknown-sysv${UNAME_RELEASE}
fi fi
exit 0 ;; exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
# says <Richard.M.Bartel@ccMail.Census.GOV> echo powerpc-be-beos
echo i586-unisys-sysv4 exit 0 ;;
exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
Power*:Rhapsody:*:*) echo powerpc-apple-beos
echo powerpc-apple-rhapsody${UNAME_RELEASE} exit 0 ;;
exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
*:Rhapsody:*:*) echo i586-pc-beos
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit 0 ;;
exit 0 ;;
esac esac
#echo '(No uname command or uname output not recognized.)' 1>&2 #echo '(No uname command or uname output not recognized.)' 1>&2

View file

@ -185,6 +185,16 @@ AC_ARG_ENABLE(ansi2knr,
[ --enable-ansi2knr translate source to K&R C before compiling], [ --enable-ansi2knr translate source to K&R C before compiling],
[ansi2knr="$enableval"], [ansi2knr=default]) [ansi2knr="$enableval"], [ansi2knr=default])
dnl Do you want to disable restricted on r* commands
undefine([resticted-r])dnl
AC_ARG_ENABLE(resticted-r,
[ --disable-resticted-r turn off restricted shell if the invoked command is r*],
[if test x$enableval = xyes; then
AC_DEFINE(RESTRICTED_R)
fi],
AC_DEFINE(RESTRICTED_R)
)
dnl ------------------ dnl ------------------
dnl CHECK THE COMPILER dnl CHECK THE COMPILER
dnl ------------------ dnl ------------------
@ -766,7 +776,7 @@ if test $zsh_cv_rlim_t_is_longer = yes; then
#include <sys/resource.h> #include <sys/resource.h>
main() { main() {
struct rlimit r; struct rlimit r;
char buf[[20]]; char buf[20];
r.rlim_cur = 0; r.rlim_cur = 0;
sprintf(buf, "%qd", r.rlim_cur); sprintf(buf, "%qd", r.rlim_cur);
exit(strcmp(buf, "0")); exit(strcmp(buf, "0"));
@ -774,7 +784,7 @@ main() {
zsh_cv_rlim_t_is_quad_t=yes, zsh_cv_rlim_t_is_quad_t=yes,
zsh_cv_rlim_t_is_quad_t=no, zsh_cv_rlim_t_is_quad_t=no,
zsh_cv_rlim_t_is_quad_t=no)]) zsh_cv_rlim_t_is_quad_t=no)])
if test $zsh_cv_tlim_t_is_quad_t = yes; then if test $zsh_cv_rlim_t_is_quad_t = yes; then
AC_DEFINE(RLIM_T_IS_QUAD_T) AC_DEFINE(RLIM_T_IS_QUAD_T)
DEFAULT_RLIM_T=quad_t DEFAULT_RLIM_T=quad_t
else else

View file

@ -556,6 +556,8 @@ Sven: 5544: another completion cleanup
pws: 5545: silly set -x mistake pws: 5545: silly set -x mistake
Sven: 5547: group handling -J/-V in compadd
Sven: 5548: _path_files, _comp_parts Sven: 5548: _path_files, _comp_parts
Matt: 5553: under _WIN32, .exe suffix is optional for commands Matt: 5553: under _WIN32, .exe suffix is optional for commands
@ -571,6 +573,8 @@ for four days.
Larry P. Schrof: 5550: last -> previous in history documentation Larry P. Schrof: 5550: last -> previous in history documentation
pws: 5559: cd /.. doesn't show .. (except if RFS was detected).
Sven: 5560: subscripting fixes in params.c: flags for scalars and Sven: 5560: subscripting fixes in params.c: flags for scalars and
converting integer AA element to string converting integer AA element to string
@ -644,10 +648,14 @@ Sven: 5629: approximate correction patches
Sven: 5631: compilation warnings Sven: 5631: compilation warnings
Sven: 5634: return values for compgen and compadd
Sven: 5637: mustuseheap check in complistflags Sven: 5637: mustuseheap check in complistflags
Sven: 5640: _multi_parts, _path_files, _tar Sven: 5640: _multi_parts, _path_files, _tar
Sven: 5647: _multi_parts doesn't replace so many *'s
Andrej: 5650: more tricks with _configure Andrej: 5650: more tricks with _configure
Sven: 5651: widespread completion fixes Sven: 5651: widespread completion fixes
@ -663,3 +671,98 @@ Sven: 5665: return values from completion functions
Sven: 5666: calling inststrlen() with a null string Sven: 5666: calling inststrlen() with a null string
pws: from autoconf 2.13: new config.sub pws: from autoconf 2.13: new config.sub
pws-12
Sven: 5670: parameter completion fix
Sven: 5671: another small parameter fix for multiple braces
Sven: 5675: tidying up for zle_tricky.c
pws: from autoconf 2.13: new config.guess, too.
Sven: 5676: all Completion example functions return a status
Sven: 5677, 5679: Completion/User/_long_options and consequent upgrades for
Completion/User files which use long GNU-style options.
Sven: 5682: bindkey fix
Sven: 5692: remove compstate[matcher] test from _long_options
Sven: 5696, 5697: "${${path}[1]}" indexes on characters again
Sven: 5698: array indexing in _long_options and _multi_parts
Sven: 5699: matching prefixes of various sorts
Sven: 5701: _main_complete, _multi_parts, _path_files, a few cosmetic
changes.
Sven: 5704: _long_options
Sven: 5707: tokenization changes
Sven: 5708: completion manual, -M anchors must be matched explicitly
Sven: 5710: zle_tricky.c, completion inside words
Sven: 5712: _path_files, noglobcomplete fix
Sven: 5713: zle_tricky.c, interesting code specimen made extinct
Sven: 5714: _path_files: failed completions get left alone more often
Sven: 5716: zle.h, zle_misc.c, zle_tricky.c: iremovesuffix() can be told
whether to keep a list of matches
Andrej: 5719: _bindkey can use - as anchor for wildcard matching
Will Day: 5724 (+postprocessing, 5741): signames2.awk: match extra spaces
if produced by CPP.
Sven: 5726: zle_tricky.c: ctokenize() fix and parameter completion
pws: 5729: _bindkey doc
Sven: 5732: _a2ps, _long_options
Sven: 5736: completion before = in assignment
pws: 5737: ${foo#* } is more efficient in ordinary cases
Sven: zsh-users/2211 (+ p -> s): setopt -m handles underscores and case
sensitivity
Lehti Rami: 5754: --disable-restricted-r stops the shell becoming
restricted when its name starts with r
Sven: 5756: compstate[force_list]
Sven: 5757: compconfig
Sven: 5758: _path_files accepts -q, -r and -R options
pws: www archive: updated Etc/FAQ finally, keep forgetting
Sven: 5759: math environment fixes
Sven: 5761: remove unnecessary compiler warnings in compctl.c
Sven: 5766: _path_files closer to compctl/compgen behaviour
Sven: 5770: _path_files again
Sven: 5775: correcting completion will not ignore everything the user has
typed; prefix quote fix
pws: 5776: untested patch for typeahead problems when reading multiple
lines of input
pws: unposted archive changes: .distfiles in Completion hierarchy, dunno
what these do but it looks better; _comp_parts is now _sep_parts; moved
_long_options into Base and mentioned it in Completion/README.
Geoff: 5779: correct mistakes some bozo (guess who) made testing rlim_t for
long long.