mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-16 20:58:05 +02:00
zsh-3.1.5-pws-10
This commit is contained in:
parent
b4a5b9db8b
commit
904b939cbd
97 changed files with 2943 additions and 541 deletions
Completion
Base
Builtins
_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
Commands
Core
READMEUser
Config
Doc/Zsh
Misc
Src
acconfig.hconfigure.inpatchlist.txt
3
Completion/Base/_command_names
Normal file
3
Completion/Base/_command_names
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp -command-
|
||||
|
||||
complist -c
|
10
Completion/Base/_condition
Normal file
10
Completion/Base/_condition
Normal file
|
@ -0,0 +1,10 @@
|
|||
#defcomp -condition-
|
||||
|
||||
if [[ -current -1 -o ]]; then
|
||||
complist -o -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}'
|
||||
elif [[ -current -1 -nt || -current -1 -ot || -current -1 -ef ]]; then
|
||||
_files
|
||||
else
|
||||
_files
|
||||
complist -v
|
||||
fi
|
13
Completion/Base/_default
Normal file
13
Completion/Base/_default
Normal file
|
@ -0,0 +1,13 @@
|
|||
#defcomp -default-
|
||||
|
||||
# We first try the `compctl's. This is without first (-T) and default (-D)
|
||||
# completion. If you want them add `-T' and/or `-D' to this command.
|
||||
# If there is a `compctl' for the command we are working on, we return
|
||||
# immediatly. If you want to use new style completion anyway, remove the
|
||||
# `|| return'. Also, you may want to use new style completion if the
|
||||
# `compctl' didn't produce any matches. In that case remove the `|| return'
|
||||
# and at the line `[[ -nmatches 0 ]] || return' after `compcall'.
|
||||
|
||||
compcall || return
|
||||
|
||||
_files
|
31
Completion/Base/_match_pattern
Normal file
31
Completion/Base/_match_pattern
Normal file
|
@ -0,0 +1,31 @@
|
|||
#autoload
|
||||
|
||||
# This function is called from functions that do matching whenever they
|
||||
# need to build a pattern that is used to match possible completions.
|
||||
# It gets the name of the calling function and two names of parameters
|
||||
# as arguments. The first one is used in the calling function to build
|
||||
# the pattern used for matching possible completions. The content of this
|
||||
# parameter on entry to this function is the string taken from the line.
|
||||
# Here it parameter should be changed to a pattern that matches words as
|
||||
# the match specs currently in use do.
|
||||
# In the calling function this pattern may be changed again or used only
|
||||
# in parts. The second parameter whose name is given as the third argument
|
||||
# allows to give pattern flags liek `(#l)' that are to be used whenever
|
||||
# matching is done.
|
||||
#
|
||||
# As an example, if you have global match specifications like:
|
||||
#
|
||||
# compctl -M 'm:{a-z}={A-Z}' 'm:{a-z}={A-Z} r:|[.-]=* r:|=*'
|
||||
#
|
||||
# This function would look like:
|
||||
#
|
||||
# eval "${3}='(#l)'"
|
||||
# [[ MATCHER -eq 2 ]] && eval "$1='${(P)2:gs/./*./:gs/-/*-/}'"
|
||||
#
|
||||
# The first line makes sure that matching is done case-insensitive as
|
||||
# specified by `m:{a-z}={A-Z}'. The second line replaces dots and hyphens
|
||||
# in the given string by patterns matching any characters before them,
|
||||
# like the `r:|[.-]=* r:|=*'. To make this work, the function `_match_test'
|
||||
# would have to be changed to `(( MATCHERS <= 2 ))'
|
||||
#
|
||||
# The default implementation of this function is empty.
|
15
Completion/Base/_match_test
Normal file
15
Completion/Base/_match_test
Normal file
|
@ -0,0 +1,15 @@
|
|||
#autoload
|
||||
|
||||
# This function is called at the beginning of functions that do matching in
|
||||
# shell code. It should test the value of the `MATCHER' special parameter
|
||||
# and return non-zero if the calling function should try to generate matches
|
||||
# for the global match specification in use.
|
||||
#
|
||||
# This function gets one argument, the name of the function calling it.
|
||||
#
|
||||
# If you have a global match specification with more than one set of patterns
|
||||
# you may want to modify this function to return non-zero for all of your
|
||||
# match specifications and modify the function `_match_pattern' to build the
|
||||
# pattern to use in the calling function.
|
||||
|
||||
(( MATCHER == 1 ))
|
5
Completion/Base/_precommand
Normal file
5
Completion/Base/_precommand
Normal file
|
@ -0,0 +1,5 @@
|
|||
#defcomp - nohup nice eval time rusage noglob nocorrect exec
|
||||
|
||||
[[ -position 1 -1 ]]
|
||||
|
||||
_normal "$@"
|
3
Completion/Base/_redirect
Normal file
3
Completion/Base/_redirect
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp -redirect-
|
||||
|
||||
_files
|
4
Completion/Base/_subscript
Normal file
4
Completion/Base/_subscript
Normal file
|
@ -0,0 +1,4 @@
|
|||
#defcomp -subscript-
|
||||
|
||||
_compalso -math- "$@"
|
||||
[[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )"
|
3
Completion/Base/_vars
Normal file
3
Completion/Base/_vars
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp -math- getopts read unset vared
|
||||
|
||||
complist -v
|
3
Completion/Builtins/_aliases
Normal file
3
Completion/Builtins/_aliases
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp unalias
|
||||
|
||||
complist -a
|
3
Completion/Builtins/_arrays
Normal file
3
Completion/Builtins/_arrays
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp shift
|
||||
|
||||
complist -A
|
3
Completion/Builtins/_autoload
Normal file
3
Completion/Builtins/_autoload
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp autoload
|
||||
|
||||
complist -s '${^fpath}/*(N:t)'
|
3
Completion/Builtins/_bg_jobs
Normal file
3
Completion/Builtins/_bg_jobs
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp bg
|
||||
|
||||
complist -z -P '%'
|
7
Completion/Builtins/_bindkey
Normal file
7
Completion/Builtins/_bindkey
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp bindkey
|
||||
|
||||
if [[ -mword 1 -*[DAN]* || -mcurrent -1 -*M ]]; then
|
||||
complist -s '$(bindkey -l)'
|
||||
else
|
||||
complist -b
|
||||
fi
|
7
Completion/Builtins/_builtin
Normal file
7
Completion/Builtins/_builtin
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp builtin
|
||||
|
||||
if [[ -position 2 -1 ]]; then
|
||||
_normal "$@"
|
||||
else
|
||||
complist -eB
|
||||
fi
|
3
Completion/Builtins/_cd
Normal file
3
Completion/Builtins/_cd
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp cd
|
||||
|
||||
_files -W cdpath -g '*(-/)'
|
7
Completion/Builtins/_command
Normal file
7
Completion/Builtins/_command
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp command
|
||||
|
||||
if [[ -position 2 -1 ]]; then
|
||||
_normal "$@"
|
||||
else
|
||||
complist -em
|
||||
fi
|
3
Completion/Builtins/_dirs
Normal file
3
Completion/Builtins/_dirs
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp rmdir df du dircmp
|
||||
|
||||
_files -/
|
6
Completion/Builtins/_disable
Normal file
6
Completion/Builtins/_disable
Normal file
|
@ -0,0 +1,6 @@
|
|||
#defcomp disable
|
||||
|
||||
[[ -mcurrent -1 -*a* ]] && complist -ea
|
||||
[[ -mcurrent -1 -*f* ]] && complist -eF
|
||||
[[ -mcurrent -1 -*r* ]] && complist -ew
|
||||
[[ ! -mcurrent -1 -* ]] && complist -eB
|
3
Completion/Builtins/_echotc
Normal file
3
Completion/Builtins/_echotc
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp echotc
|
||||
|
||||
complist -k '(al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up)'
|
6
Completion/Builtins/_enable
Normal file
6
Completion/Builtins/_enable
Normal file
|
@ -0,0 +1,6 @@
|
|||
#defcomp enable
|
||||
|
||||
[[ -mcurrent -1 -*a* ]] && complist -da
|
||||
[[ -mcurrent -1 -*f* ]] && complist -dF
|
||||
[[ -mcurrent -1 -*r* ]] && complist -dw
|
||||
[[ ! -mcurrent -1 -* ]] && complist -dB
|
7
Completion/Builtins/_fc
Normal file
7
Completion/Builtins/_fc
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp fc
|
||||
|
||||
if [[ -mcurrent -1 -*e ]]; then
|
||||
complist -c
|
||||
elif [[ -mcurrent -1 -[ARWI]## ]]; then
|
||||
_files
|
||||
fi
|
3
Completion/Builtins/_functions
Normal file
3
Completion/Builtins/_functions
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp unfunction
|
||||
|
||||
complist -F
|
13
Completion/Builtins/_hash
Normal file
13
Completion/Builtins/_hash
Normal file
|
@ -0,0 +1,13 @@
|
|||
#defcomp hash
|
||||
|
||||
if [[ -mword 1 -*d* ]]; then
|
||||
if [[ -string 1 '=' ]]; then
|
||||
_path_files -g '*(-/)'
|
||||
else
|
||||
complist -n -q -S '='
|
||||
fi
|
||||
elif [[ -string 1 '=' ]]; then
|
||||
_files -/g '*(*)'
|
||||
else
|
||||
complist -m -q -S '='
|
||||
fi
|
3
Completion/Builtins/_jobs
Normal file
3
Completion/Builtins/_jobs
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp fg jobs
|
||||
|
||||
complist -j -P '%'
|
11
Completion/Builtins/_kill
Normal file
11
Completion/Builtins/_kill
Normal file
|
@ -0,0 +1,11 @@
|
|||
#defcomp kill
|
||||
|
||||
local list
|
||||
|
||||
if [[ -iprefix '-' ]]; then
|
||||
complist -k "($signals[1,-3])"
|
||||
else
|
||||
complist -P '%' -j
|
||||
list=("$(ps 2>/dev/null)")
|
||||
complist -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`'
|
||||
fi
|
3
Completion/Builtins/_limits
Normal file
3
Completion/Builtins/_limits
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp limit unlimit
|
||||
|
||||
complist -k "(${(j: :)${(f)$(limit)}%% *})"
|
3
Completion/Builtins/_sched
Normal file
3
Completion/Builtins/_sched
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp sched
|
||||
|
||||
[[ -position 2 -1 ]] && _normal "$@"
|
7
Completion/Builtins/_set
Normal file
7
Completion/Builtins/_set
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp set
|
||||
|
||||
if [[ -mcurrent -1 [-+]o ]]; then
|
||||
complist -o
|
||||
elif [[ -current -1 -A ]]; then
|
||||
complist -A
|
||||
fi
|
7
Completion/Builtins/_setopt
Normal file
7
Completion/Builtins/_setopt
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp setopt
|
||||
|
||||
local nm=$NMATCHES
|
||||
|
||||
complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
|
||||
-s '$({ unsetopt kshoptionprint; unsetopt } 2>/dev/null)'
|
||||
[[ -nmatches nm ]] && complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o
|
7
Completion/Builtins/_source
Normal file
7
Completion/Builtins/_source
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp source
|
||||
|
||||
if [[ -position 2 -1 ]]; then
|
||||
_normal "$@"
|
||||
else
|
||||
_files
|
||||
fi
|
7
Completion/Builtins/_trap
Normal file
7
Completion/Builtins/_trap
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp trap
|
||||
|
||||
if [[ -position 1 ]]; then
|
||||
complist -c
|
||||
else
|
||||
complist -k signals
|
||||
fi
|
6
Completion/Builtins/_unhash
Normal file
6
Completion/Builtins/_unhash
Normal file
|
@ -0,0 +1,6 @@
|
|||
#defcomp unhash
|
||||
|
||||
[[ -mword 1 -*d* ]] && complist -n
|
||||
[[ -mword 1 -*a* ]] && complist -a
|
||||
[[ -mword 1 -*f* ]] && complist -F
|
||||
[[ ! -mword 1 -* ]] && complist -m
|
7
Completion/Builtins/_unsetopt
Normal file
7
Completion/Builtins/_unsetopt
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp unsetopt
|
||||
|
||||
local nm=$NMATCHES
|
||||
|
||||
complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
|
||||
-s '$({ unsetopt kshoptionprint; setopt } 2>/dev/null)'
|
||||
[[ -nmatches nm ]] && complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o
|
3
Completion/Builtins/_vars_eq
Normal file
3
Completion/Builtins/_vars_eq
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp declare export integer local readonly typeset
|
||||
|
||||
complist -v -q -S '='
|
7
Completion/Builtins/_wait
Normal file
7
Completion/Builtins/_wait
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp wait
|
||||
|
||||
local list
|
||||
|
||||
complist -P '%' -j
|
||||
list=("$(ps 2>/dev/null)")
|
||||
complist -y '$list' -s '`ps 2>/dev/null | tail +2 | cut -c1-5`'
|
3
Completion/Builtins/_which
Normal file
3
Completion/Builtins/_which
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp which whence where type
|
||||
|
||||
complist -caF
|
50
Completion/Builtins/_zftp
Normal file
50
Completion/Builtins/_zftp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#defpatcomp zf*
|
||||
|
||||
# Don't try any more completion after this.
|
||||
_compskip=1
|
||||
|
||||
# Completion for zftp builtin and zf* functions. The functions
|
||||
# zfcd_match and zfget_match (used for old-style completion)
|
||||
# need to be installed for remote file and directory completion to work.
|
||||
|
||||
local subcom
|
||||
|
||||
if [[ $COMMAND = zftp ]]; then
|
||||
if [[ $CURRENT -eq 1 ]]; then
|
||||
compadd -m open params user login type ascii binary mode put \
|
||||
putat get getat append appendat ls dir local remote mkdir rmdir
|
||||
return
|
||||
fi
|
||||
subcom=$1
|
||||
else
|
||||
subcom=$COMMAND
|
||||
fi
|
||||
|
||||
case $subcom in
|
||||
*(cd|ls|dir))
|
||||
# complete remote directories; we could be smarter about hiding prefixes
|
||||
zfcd_match $PREFIX $SUFFIX
|
||||
(( $#reply )) && compadd -m -S/ -q $reply
|
||||
;;
|
||||
|
||||
*(get(|at)|gcp|delete|remote))
|
||||
# complete remote files
|
||||
zfget_match $PREFIX $SUFFIX
|
||||
(( $#reply )) && compadd -F fignore -m $reply
|
||||
;;
|
||||
|
||||
*(put(|at)|pcp))
|
||||
# complete local files
|
||||
_files
|
||||
;;
|
||||
|
||||
*(open|anon|params))
|
||||
# complete hosts: should do cleverer stuff with user names
|
||||
complist -k hosts
|
||||
;;
|
||||
|
||||
*)
|
||||
# dunno... try ordinary completion after all.
|
||||
unset _compskip
|
||||
;;
|
||||
esac
|
7
Completion/Builtins/_zle
Normal file
7
Completion/Builtins/_zle
Normal file
|
@ -0,0 +1,7 @@
|
|||
#defcomp zle
|
||||
|
||||
if [[ -word 1 -N && -position 3 ]]; then
|
||||
complist -F
|
||||
else
|
||||
complist -b
|
||||
fi
|
9
Completion/Builtins/_zmodload
Normal file
9
Completion/Builtins/_zmodload
Normal file
|
@ -0,0 +1,9 @@
|
|||
#defcomp zmodload
|
||||
|
||||
if [[ -mword 1 -*(a*u|u*a)* || -mword 1 -*a* && -position 3 -1 ]]; then
|
||||
complist -B
|
||||
elif [[ -mword 1 -*u* ]]; then
|
||||
complist -s '$(zmodload)'
|
||||
else
|
||||
complist -s '${^module_path}/*(N:t:r)'
|
||||
fi
|
37
Completion/Commands/_correct_filename
Normal file
37
Completion/Commands/_correct_filename
Normal file
|
@ -0,0 +1,37 @@
|
|||
#defkeycomp complete-word \C-xc
|
||||
|
||||
# Function to correct a filename. Can be used as a completion widget,
|
||||
# or as a function in its own right, in which case it will print the
|
||||
# corrected filename to standard output.
|
||||
#
|
||||
# You can adapt max_approx to the maximum number of mistakes
|
||||
# which are allowed in total.
|
||||
|
||||
emulate -LR zsh
|
||||
setopt extendedglob
|
||||
|
||||
local file="$PREFIX$SUFFIX" trylist
|
||||
integer approx max_approx=6
|
||||
|
||||
[[ -z $WIDGET ]] && file=$1
|
||||
|
||||
if [[ -e "$file" ]]; then
|
||||
if [[ -n $WIDGET ]]; then
|
||||
compadd "$file"
|
||||
else
|
||||
print "$file"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
for (( approx = 1; approx <= max_approx; approx++ )); do
|
||||
trylist=( (#a$approx)"$file"(N) )
|
||||
(( $#trylist )) && break
|
||||
done
|
||||
(( $#trylist )) || return 1
|
||||
|
||||
if [[ -n $WIDGET ]]; then
|
||||
compadd -U "${trylist[@]}"
|
||||
else
|
||||
print "${trylist[@]}"
|
||||
fi
|
4
Completion/Commands/_most_recent_file
Normal file
4
Completion/Commands/_most_recent_file
Normal file
|
@ -0,0 +1,4 @@
|
|||
#defkeycomp complete-word \C-xm
|
||||
local file
|
||||
file=($~PREFIX*$~SUFFIX(om[1]N))
|
||||
(( $#file )) && compadd -f $file
|
147
Completion/Core/_comp_parts
Normal file
147
Completion/Core/_comp_parts
Normal file
|
@ -0,0 +1,147 @@
|
|||
#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.:
|
||||
#
|
||||
# _comp_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
|
||||
|
||||
# Test if we should use this function for the global matcher in use.
|
||||
|
||||
_match_test _comp_parts || return
|
||||
|
||||
# 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"
|
||||
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}*}"
|
||||
matchflags=""
|
||||
_match_pattern _comp_parts test matchflags
|
||||
test="${matchflags}${test}"
|
||||
testarr=( "${(@M)${(@P)arr}:#${~test}*}" )
|
||||
|
||||
# If there are no matches we give up. If there is more than one
|
||||
# match, this is the part we will complete.
|
||||
(( $#testarr )) || return
|
||||
[[ $#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.
|
||||
matchflags=""
|
||||
test="$str"
|
||||
_match_pattern _comp_parts test matchflags
|
||||
test="${matchflags}${test}"
|
||||
testarr=( "${(@M)${(@P)arr}:#${~test}*}" )
|
||||
fi
|
||||
|
||||
[[ $#testarr -eq 0 || ${#testarr[1]} -eq 0 ]] && return
|
||||
|
||||
# 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
|
||||
matchflags=""
|
||||
_match_pattern _comp_parts test matchflags
|
||||
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
|
||||
suffixes=("${^suffixes[@]}${1}${(@M)^${(@P)arr}:#${~test}*}")
|
||||
|
||||
# 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}=*")
|
||||
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 "$group[@]" "$expl[@]" "$matchers[@]" "$autosuffix[@]" -p "$prefix" -s "$i" - "$testarr[@]"
|
||||
done
|
13
Completion/Core/_compalso
Normal file
13
Completion/Core/_compalso
Normal file
|
@ -0,0 +1,13 @@
|
|||
#autoload
|
||||
|
||||
# This searches $1 in the array for normal completions and calls the result.
|
||||
# It is used to include completions for another command or special context
|
||||
# into the list generated by the calling function.
|
||||
# For example the function for `-subscript-' could call this as in
|
||||
# `_compalso -math- "$@"' to get the completions that would be generated
|
||||
# for a mathematical context.
|
||||
|
||||
local tmp
|
||||
|
||||
tmp="$_comps[$1]"
|
||||
[[ -z "$tmp" ]] || "$tmp" "$@"
|
26
Completion/Core/_files
Normal file
26
Completion/Core/_files
Normal file
|
@ -0,0 +1,26 @@
|
|||
#autoload
|
||||
|
||||
# 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().
|
||||
|
||||
local nm=$NMATCHES
|
||||
|
||||
_path_files "$@"
|
||||
|
||||
if [[ $# -ne 0 && -nmatches nm ]]; then
|
||||
local opt opts
|
||||
|
||||
# We didn't get any matches for those types of files described by
|
||||
# the `-g' or `-/' option. Now we try it again accepting all files.
|
||||
# First we get those options that we have to use even if then. If
|
||||
# we find out that the `-f' option was given, we already accepted
|
||||
# all files and give up immediatly.
|
||||
|
||||
opts=()
|
||||
while getopts "P:S:W:F:J:V:X:f/g:" opt; do
|
||||
[[ "$opt" = f ]] && return
|
||||
[[ "$opt" = [PSWFJVX] ]] && opts=("$opts[@]" "-$opt" "$OPTARG")
|
||||
done
|
||||
|
||||
_path_files "$opts[@]"
|
||||
fi
|
48
Completion/Core/_main_complete
Normal file
48
Completion/Core/_main_complete
Normal file
|
@ -0,0 +1,48 @@
|
|||
#autoload
|
||||
|
||||
# The main loop of the completion code. This is what is called when
|
||||
# completion is attempted from the command line.
|
||||
# The completion code gives us the special variables and the arguments
|
||||
# from the command line are given as positional parameters.
|
||||
|
||||
local comp name
|
||||
|
||||
setopt localoptions nullglob rcexpandparam globdots
|
||||
unsetopt markdirs globsubst shwordsplit nounset
|
||||
|
||||
# An entry for `-first-' is the replacement for `compctl -T'
|
||||
# Completion functions may set `_compskip' to any value to make the
|
||||
# main loops stop calling other completion functions.
|
||||
|
||||
comp="$_comps[-first-]"
|
||||
if [[ ! -z "$comp" ]]; then
|
||||
"$comp" "$@"
|
||||
if (( $+_compskip )); then
|
||||
unset _compskip
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# For arguments we use the `_normal function.
|
||||
|
||||
if [[ $CONTEXT == argument || $CONTEXT == command ]]; then
|
||||
_normal "$@"
|
||||
else
|
||||
# Let's see if we have a special completion definition for the other
|
||||
# possible contexts.
|
||||
|
||||
comp=''
|
||||
|
||||
case $CONTEXT in
|
||||
redirect) comp="$_comps[-redirect-]";;
|
||||
math) comp="$_comps[-math-]";;
|
||||
subscript) comp="$_comps[-subscript-]";;
|
||||
value) comp="$_comps[-value-]";;
|
||||
condition) comp="$_comps[-condition-]";;
|
||||
esac
|
||||
|
||||
# If not, we use default completion, if any.
|
||||
|
||||
[[ -z "$comp" ]] && comp="$_comps[-default-]"
|
||||
[[ -z "$comp" ]] || "$comp" "$@"
|
||||
fi
|
54
Completion/Core/_normal
Normal file
54
Completion/Core/_normal
Normal file
|
@ -0,0 +1,54 @@
|
|||
#autoload
|
||||
|
||||
local comp cmd1 cmd2 pat val name
|
||||
|
||||
# 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.
|
||||
# a path and the last path name component).
|
||||
|
||||
if [[ $CONTEXT == command ]]; then
|
||||
comp="$_comps[-command-]"
|
||||
[[ -z "$comp" ]] || "$comp" "$@"
|
||||
return
|
||||
elif [[ "$COMMAND[1]" == '=' ]]; then
|
||||
eval cmd1\=$COMMAND
|
||||
cmd2="$COMMAND[2,-1]"
|
||||
elif [[ "$COMMAND" == */* ]]; then
|
||||
cmd1="$COMMAND"
|
||||
cmd2="${COMMAND:t}"
|
||||
else
|
||||
cmd1="$COMMAND"
|
||||
eval cmd2=$(whence -p $COMMAND)
|
||||
fi
|
||||
|
||||
# See if there are any matching pattern completions.
|
||||
|
||||
for i in "$_patcomps[@]"; do
|
||||
pat="${i% *}"
|
||||
val="${i#* }"
|
||||
if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then
|
||||
"$val" "$@"
|
||||
if (( $+_compskip )); then
|
||||
unset _compskip
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Now look up the two names in the normal completion array.
|
||||
|
||||
name="$cmd1"
|
||||
comp="$_comps[$cmd1]"
|
||||
|
||||
if [[ -z "$comp" ]]; then
|
||||
name="$cmd2"
|
||||
comp="$_comps[$cmd2]"
|
||||
fi
|
||||
|
||||
# And generate the matches, probably using default completion.
|
||||
|
||||
if [[ -z "$comp" ]]; then
|
||||
name=-default-
|
||||
comp="$_comps[-default-]"
|
||||
fi
|
||||
[[ -z "$comp" ]] || "$comp" "$@"
|
311
Completion/Core/_path_files
Normal file
311
Completion/Core/_path_files
Normal file
|
@ -0,0 +1,311 @@
|
|||
#autoload
|
||||
|
||||
# Utility function for in-path completion.
|
||||
# Supported arguments are: `-f', `-/', `-g <patterns>', `-J <group>',
|
||||
# `-V <group>', `-W paths', `-X explanation', and `-F <ignore>'. All but
|
||||
# the last have the same syntax and meaning as for `complist'. The
|
||||
# `-F <ignore>' option may be used to give a list of suffixes either by
|
||||
# giving the name of an array or literally by giving them in a string
|
||||
# surrounded by 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'.
|
||||
|
||||
# First see if we should generate matches for the global matcher in use.
|
||||
|
||||
_match_test _path_files || return
|
||||
|
||||
# Yes, so...
|
||||
|
||||
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 addpfx addsfx expl
|
||||
|
||||
setopt localoptions nullglob rcexpandparam globdots extendedglob
|
||||
unsetopt markdirs globsubst shwordsplit nounset
|
||||
|
||||
prepaths=('')
|
||||
ignore=()
|
||||
group=()
|
||||
sopt='-'
|
||||
gopt=''
|
||||
pats=()
|
||||
addpfx=()
|
||||
addsfx=()
|
||||
expl=()
|
||||
|
||||
# Get the options.
|
||||
|
||||
while getopts "P:S:W:F:J:V:X:f/g:" opt; do
|
||||
case "$opt" in
|
||||
P) addpfx=(-P "$OPTARG")
|
||||
;;
|
||||
S) addsfx=(-S "$OPTARG")
|
||||
;;
|
||||
W) tmp1="$OPTARG"
|
||||
if [[ "$tmp1[1]" = '(' ]]; then
|
||||
prepaths=( ${^=tmp1[2,-2]}/ )
|
||||
else
|
||||
prepaths=( ${(P)=${tmp1}} )
|
||||
(( ! $#prepaths )) && prepaths=( ${tmp1}/ )
|
||||
fi
|
||||
(( ! $#prepaths )) && prepaths=( '' )
|
||||
;;
|
||||
F) tmp1="$OPTARG"
|
||||
if [[ "$tmp1[1]" = '(' ]]; then
|
||||
ignore=( ${^=tmp1[2,-2]}/ )
|
||||
else
|
||||
ignore=( ${(P)${tmp1}} )
|
||||
fi
|
||||
(( $#ignore )) && ignore=(-F "( $ignore )")
|
||||
;;
|
||||
[JV]) group=("-$opt" "$OPTARG")
|
||||
;;
|
||||
X) expl=(-X "$OPTARG")
|
||||
;;
|
||||
f) sopt="${sopt}f"
|
||||
pats=("$pats[@]" '*')
|
||||
;;
|
||||
/) sopt="${sopt}/"
|
||||
pats=("$pats[@]" '*(-/)')
|
||||
;;
|
||||
g) gopt='-g'
|
||||
pats=("$pats[@]" ${=OPTARG})
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# If we were given no file selection option, we behave as if we were given
|
||||
# a `-f'.
|
||||
|
||||
if [[ "$sopt" = - ]]; then
|
||||
if [[ -z "$gopt" ]]; then
|
||||
sopt='-f'
|
||||
pats=('*')
|
||||
else
|
||||
unset sopt
|
||||
fi
|
||||
fi
|
||||
|
||||
# str holds the whole string from the command line with a `*' between
|
||||
# the prefix and the suffix.
|
||||
|
||||
str="${PREFIX:q}*${SUFFIX:q}"
|
||||
|
||||
# If the string began with a `~', the quoting turned this into `\~',
|
||||
# remove the slash.
|
||||
|
||||
[[ "$str" = \\\~* ]] && str="$str[2,-1]"
|
||||
|
||||
# We will first try normal completion called with `complist', but only if we
|
||||
# weren't given a `-F' option.
|
||||
|
||||
if (( ! $#ignore )); then
|
||||
# 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
|
||||
# is a absolute path or relative to the current directory.
|
||||
|
||||
if [[ -z "$tmp1[1]" || "$str[1]" = [~/] || "$str" = (.|..)/* ]]; then
|
||||
tmp1=()
|
||||
else
|
||||
tmp1=(-W "( $prepaths )")
|
||||
fi
|
||||
|
||||
# Now call complist.
|
||||
|
||||
nm=$NMATCHES
|
||||
if [[ -z "$gopt" ]]; then
|
||||
complist "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" "$tmp1[@]" $sopt
|
||||
else
|
||||
complist "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" "$tmp1[@]" $sopt -g "$pats"
|
||||
fi
|
||||
|
||||
# If this generated any matches, we don't want to do in-path completion.
|
||||
|
||||
[[ -nmatches nm ]] || return
|
||||
|
||||
# No `-F' option, so we want to use `fignore'.
|
||||
|
||||
ignore=(-F fignore)
|
||||
fi
|
||||
|
||||
# Now let's have a closer look at the string to complete.
|
||||
|
||||
if [[ "$str[1]" = \~ ]]; then
|
||||
# It begins with `~', so remember anything before the first slash to be able
|
||||
# to report it to the completion code. Also get an expanded version of it
|
||||
# (in `realpath'), so that we can generate the matches. Then remove that
|
||||
# prefix from the string to complete, set `donepath' to build the correct
|
||||
# paths and make sure that the loop below is run only once with an empty
|
||||
# prefix path by setting `prepaths'.
|
||||
|
||||
linepath="${str%%/*}/"
|
||||
eval realpath\=$linepath
|
||||
str="${str#*/}"
|
||||
donepath=''
|
||||
prepaths=( '' )
|
||||
else
|
||||
# If the string does not start with a `~' we don't remove a prefix from the
|
||||
# string.
|
||||
|
||||
liniepath=''
|
||||
realpath=''
|
||||
|
||||
if [[ "$str[1]" = / ]]; then
|
||||
# If it is a absolut path name, we remove the first slash and put it in
|
||||
# `donepath' meaning that we treat it as the path that was already handled.
|
||||
# Also, we don't use the paths from `-W'.
|
||||
|
||||
str="$str[2,-1]"
|
||||
donepath='/'
|
||||
prepaths=( '' )
|
||||
else
|
||||
# The common case, we just use the string as it is, unless it begins with
|
||||
# `./' or `../' in which case we don't use the paths from `-W'.
|
||||
|
||||
[[ "$str" = (.|..)/* ]] && prepaths=( '' )
|
||||
donepath=''
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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
|
||||
# `lib5'. Pathname components skipped this way are taken from `str' and added
|
||||
# to `donepath'.
|
||||
|
||||
while [[ "$str" = */* ]] do
|
||||
[[ -e "$realpath$donepath${str%%/*}" ]] || break
|
||||
donepath="$donepath${str%%/*}/"
|
||||
str="${str#*/}"
|
||||
done
|
||||
|
||||
# Now build the glob pattern by calling `_match_pattern'.
|
||||
patstr="$str"
|
||||
matchflags=""
|
||||
_match_pattern _path_files patstr matchflags
|
||||
|
||||
# We almost expect the pattern to have changed `..' into `*.*.', `/.' into
|
||||
# `/*.', and probably to contain two or more consecutive `*'s. Since these
|
||||
# have special meaning for globbing, we remove them. But before that, we
|
||||
# add the pattern for matching any characters before a slash.
|
||||
|
||||
patstr="$patstr:gs-/-*/-:gs/*.*.//:gs-/*.-/.-:gs/**/*/"
|
||||
|
||||
# Finally, generate the matches. First we loop over all the paths from `-W'.
|
||||
# Note that in this loop `str' is used as a modifyable version of `patstr'
|
||||
# and `testpath' is a modifyable version of `donepath'.
|
||||
|
||||
for prepath in "$prepaths[@]"; do
|
||||
str="$patstr"
|
||||
testpath="$donepath"
|
||||
|
||||
# The second loop tests the components of the path in `str' to get the
|
||||
# possible matches.
|
||||
|
||||
while [[ "$str" = */* ]] do
|
||||
# `rest' is the pathname after the first slash that is left. In `tmp1'
|
||||
# we get the globbing matches for the pathname component currently
|
||||
# handled.
|
||||
|
||||
rest="${str#*/}"
|
||||
tmp1="${prepath}${realpath}${testpath}${~matchflags}${str%%/*}(-/)"
|
||||
tmp1=( $~tmp1 )
|
||||
|
||||
if [[ $#tmp1 -eq 0 ]]; then
|
||||
# If this didn't produce any matches, we don't need to test this path
|
||||
# any further, so continue with the next `-W' path, if any.
|
||||
|
||||
continue 2
|
||||
elif [[ $#tmp1 -gt 1 ]]; then
|
||||
# If it produced more than one match, we want to remove those which
|
||||
# don't have possible following pathname components matching the
|
||||
# rest of the string we are completing. (The case with only one
|
||||
# match is handled below.)
|
||||
# In `collect' we will collect those of the produced pathnames that
|
||||
# have a matching possible path-suffix. In `suffixes' we build an
|
||||
# array containing strings build from the rest of the string to
|
||||
# complete and the glob patterns we were given as arguments.
|
||||
|
||||
collect=()
|
||||
suffixes=( $rest$^pats )
|
||||
suffixes=( "${(@)suffixes:gs.**.*.}" )
|
||||
|
||||
# In the loop the prefixes from the `tmp1' array produced above and
|
||||
# the suffixes we just built are used to produce possible matches
|
||||
# via globbing.
|
||||
|
||||
for i in $tmp1; do
|
||||
tmp2=( ${~i}/${~matchflags}${~suffixes} )
|
||||
[[ $#tmp2 -ne 0 ]] && collect=( $collect $i )
|
||||
done
|
||||
|
||||
# If this test showed that none of the matches from the glob in `tmp1'
|
||||
# has a possible sub-path matching what's on the line, we give up and
|
||||
# continue with the next `-W' path.
|
||||
|
||||
if [[ $#collect -eq 0 ]]; then
|
||||
continue 2
|
||||
elif [[ $#collect -ne 1 ]]; then
|
||||
# If we have more than one possible match, this means that the
|
||||
# pathname component currently handled is ambiguous, so we give
|
||||
# it to the completion code.
|
||||
# First we build the full path prefix in `tmp1'.
|
||||
|
||||
tmp1="$prepath$realpath$testpath"
|
||||
|
||||
# Now produce all matching pathnames in `collect'.
|
||||
|
||||
collect=( ${~collect}/${~matchflags}${~suffixes} )
|
||||
|
||||
# And then remove the common path prefix from all these matches.
|
||||
|
||||
collect=( ${collect#$tmp1} )
|
||||
|
||||
# Finally, we add all these matches with the common (unexpanded)
|
||||
# pathprefix (the `-p' option), the path-prefix (the `-W' option)
|
||||
# to allow the completion code to test file type, and the path-
|
||||
# suffix (the `-s' option). We also tell the completion code that
|
||||
# these are file names and that `fignore' should be used as usual
|
||||
# (the `-f' and `-F' options).
|
||||
|
||||
for i in $collect; do
|
||||
compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" -p "$linepath$testpath" -W "$tmp1" -s "/${i#*/}" -f "$ignore[@]" - "${i%%/*}"
|
||||
done
|
||||
|
||||
# We have just finished handling all the matches from above, so we
|
||||
# can continue with the next `-W' path.
|
||||
|
||||
continue 2
|
||||
fi
|
||||
# We reach this point if only one of the path prefixes in `tmp1'
|
||||
# has a existing path-suffix matching the string from the line.
|
||||
# In this case we accept this match and continue with the next
|
||||
# path-name component.
|
||||
|
||||
tmp1=( "$collect[1]" )
|
||||
fi
|
||||
# This is also reached if the first globbing produced only one match
|
||||
# in this case we just continue with the next pathname component, too.
|
||||
|
||||
tmp1="$tmp1[1]"
|
||||
testpath="$testpath${tmp1##*/}/"
|
||||
str="$rest"
|
||||
done
|
||||
|
||||
# We are here if all pathname components except the last one (which is still
|
||||
# not tested) are unambiguous. So we add matches with the full path prefix,
|
||||
# no path suffix, the `-W' we are currently handling, all the matches we
|
||||
# can produce in this directory, if any.
|
||||
|
||||
tmp1="$prepath$realpath$testpath"
|
||||
suffixes=( $str$^pats )
|
||||
suffixes=( "${(@)suffixes:gs.**.*.}" )
|
||||
tmp2=( ${~tmp1}${~matchflags}${~suffixes} )
|
||||
if [[ $#tmp2 -eq 0 && "$sopt" = */* ]]; then
|
||||
[[ "$testpath[-1]" = / ]] && testpath="$testpath[1,-2]"
|
||||
compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" -f - "$linepath$testpath"
|
||||
else
|
||||
compadd "$addpfx[@]" "$addsfx[@]" "$group[@]" "$expl[@]" -p "$linepath$testpath" -W "$prepath$realpath$testpath" -f "$ignore[@]" - ${(@)tmp2#$tmp1}
|
||||
fi
|
||||
done
|
89
Completion/Core/compdump
Normal file
89
Completion/Core/compdump
Normal file
|
@ -0,0 +1,89 @@
|
|||
# This is a file to be sourced to dump the definitions for new-style
|
||||
# completion defined by 'compinit' in the same directory. The output
|
||||
# should be directed into the "compinit.dump" in the same directory as
|
||||
# compinit. If you rename init, just stick .dump onto the end of whatever
|
||||
# you have called it and put it in the same directory. This is handled
|
||||
# automatically if you invoke compinit with the option -d.
|
||||
#
|
||||
# You will need to update the dump every time you add a new completion.
|
||||
# To do this, simply remove the .dump file, start a new shell, and
|
||||
# create the .dump file as before. Again, compinit -d handles this
|
||||
# automatically.
|
||||
#
|
||||
# It relies on KSH_ARRAYS not being set.
|
||||
|
||||
# Print the number of files used for completion. This is used in compinit
|
||||
# to see if auto-dump should re-dump the dump-file.
|
||||
|
||||
_d_file=${COMPDUMP-${0:h}/compinit.dump}
|
||||
|
||||
typeset -U _d_files
|
||||
_d_files=( ${^~fpath}/_*~*~(N:t) )
|
||||
|
||||
print "#files: $#_d_files" > $_d_file
|
||||
|
||||
unset _d_files
|
||||
|
||||
# First dump the arrays _comps and _patcomps. The quoting hieroglyphyics
|
||||
# ensure that a single quote inside a variable is itself correctly quoted.
|
||||
|
||||
print "_comps=(" >> $_d_file
|
||||
for _d_f in ${(ok)_comps}; do
|
||||
print -r - "'${_d_f//\'/'\\''}'" "'${_comps[$_d_f]//\'/'\\''}'"
|
||||
done >> $_d_file
|
||||
print ")" >> $_d_file
|
||||
|
||||
print "\n_patcomps=(" >> $_d_file
|
||||
for _d_f in "$_patcomps[@]"; do
|
||||
print -r - "'${_d_f//\'/'\\''}'"
|
||||
done >> $_d_file
|
||||
print ")" >> $_d_file
|
||||
|
||||
print >> $_d_file
|
||||
|
||||
# Now dump the key bindings. We dump all bindings for zle widgets
|
||||
# whose names start with a underscore.
|
||||
# We need both the zle -C's and the bindkey's to recreate.
|
||||
|
||||
_d_bks=()
|
||||
zle -lL |
|
||||
while read -rA _d_line; do
|
||||
if [[ ${_d_line[5]} = _* ]]; then
|
||||
print -r - ${_d_line}
|
||||
_d_bks=($_d_bks ${_d_line[3]})
|
||||
fi
|
||||
done >> $_d_file
|
||||
bindkey |
|
||||
while read -rA _d_line; do
|
||||
if [[ ${_d_line[2]} = (${(j.|.)~_d_bks}) ]]; then
|
||||
print -r "bindkey '${_d_line[1][2,-2]}' ${_d_line[2]}"
|
||||
fi
|
||||
done >> $_d_file
|
||||
|
||||
print >> $_d_file
|
||||
|
||||
|
||||
# Autoloads: whence -w produces "_d_foo: function", so look for
|
||||
# all functions beginning with `_'.
|
||||
|
||||
_d_als=($(whence -wm '_*' | sort |
|
||||
while read -rA _d_line; do
|
||||
[[ ${_d_line[2]} = function ]] && print -r - ${_d_line[1]%:}
|
||||
done))
|
||||
|
||||
# print them out: about five to a line looks neat
|
||||
|
||||
while (( $#_d_als )); do
|
||||
print -n autoload
|
||||
for (( _i = 0; _i < 5; _i++ )); do
|
||||
if (( $#_d_als )); then
|
||||
print -n " $_d_als[1]"
|
||||
shift _d_als
|
||||
fi
|
||||
done
|
||||
print
|
||||
done >> $_d_file
|
||||
|
||||
print >> $_d_file
|
||||
|
||||
unset _d_line _d_zle _d_bks _d_als _d_f _f_file
|
269
Completion/Core/compinit
Normal file
269
Completion/Core/compinit
Normal file
|
@ -0,0 +1,269 @@
|
|||
# Initialisation for new style completion. This mainly contains some helper
|
||||
# function and aliases. Everything else is split into different files in this
|
||||
# directory that will automatically be made autoloaded (see the end of this
|
||||
# file).
|
||||
# The names of the files that will be considered for autoloading have to
|
||||
# start with a underscores (like `_setopt).
|
||||
# The first line of these files will be read and has to say what should be
|
||||
# done with its contents:
|
||||
#
|
||||
# `#defcomp <names ...>'
|
||||
# if the first line looks like this, the file is
|
||||
# autoloaded as a function and that function will
|
||||
# be called to generate the matches when completing
|
||||
# for one of the commands whose <name> is given
|
||||
#
|
||||
# `#defpatcomp <pattern>'
|
||||
# this defines a function that should be called to generate
|
||||
# matches for commands whose name matches <pattern>; note
|
||||
# that only one pattern may be given
|
||||
#
|
||||
# `#defkeycomp <style> [ <key-sequence> ... ]
|
||||
# this is used to bind special completions to all the given
|
||||
# <key-sequence>(s). The <style> is the name of one of the built-in
|
||||
# completion widgets (complete-word, delete-char-or-list,
|
||||
# expand-or-complete, expand-or-complete-prefix, list-choices,
|
||||
# menu-complete, menu-expand-or-complete, or reverse-menu-complete).
|
||||
# This creates a widget behaving like <style> so that the
|
||||
# completions are chosen as given in the the rest of the file,
|
||||
# rather than by the context. The widget has the same name as
|
||||
# the autoload file and can be bound using bindkey in the normal way.
|
||||
#
|
||||
# `#autoload'
|
||||
# this is for helper functions that are not used to
|
||||
# generate matches, but should automatically be loaded
|
||||
# when they are called
|
||||
#
|
||||
# Note that no white space is allowed between the `#' and the rest of
|
||||
# the string.
|
||||
#
|
||||
# See the file `compdump' for how to speed up initialiation.
|
||||
#
|
||||
# If you are using global matching specifications with `compctl -M ...'
|
||||
# have a look at the files `_match_test' and `_match_pattern'. To make
|
||||
# all the example functions use matching as specified with `-M' these
|
||||
# need some editing.
|
||||
#
|
||||
# If we got the `-d'-flag, we will automatically dump the new state (at
|
||||
# the end).
|
||||
|
||||
if [[ "$1" = -d ]]; then
|
||||
_i_autodump=1
|
||||
else
|
||||
_i_autodump=0
|
||||
fi
|
||||
|
||||
# The associative array containing the definitions for the commands.
|
||||
# Definitions for patterns will be stored in the normal array `_patcomps'.
|
||||
|
||||
typeset -A _comps
|
||||
_patcomps=()
|
||||
|
||||
# This function is used to register or delete completion functions. For
|
||||
# registering completion functions, it is invoked with the name of the
|
||||
# function as it's first argument (after the options). The other
|
||||
# arguments depend on what type of completion function is defined. If
|
||||
# none of the `-p' and `-k' options is given a function for a command is
|
||||
# defined. The arguments after the function name are then interpreted as
|
||||
# the names of the command for which the function generates matches.
|
||||
# With the `-p' option a function for a name pattern is defined. This
|
||||
# function will be invoked when completing for a command whose name
|
||||
# matches the pattern given as argument after the function name (in this
|
||||
# case only one argument is accepted).
|
||||
# With the `-k' option a function for a special completion keys is
|
||||
# defined and immediatly bound to those keys. Here, the extra arguments
|
||||
# are the name of one of the builtin completion widgets and any number
|
||||
# of key specifications as accepted by the `bindkey' builtin.
|
||||
# In any case the `-a' option may be given which makes the function
|
||||
# whose name is given as the first argument be autoloaded. When defining
|
||||
# a function for command names the `-n' option may be given and keeps
|
||||
# the definitions from overriding any previous definitions for the
|
||||
# commands.
|
||||
# For deleting definitions, the `-d' option must be given. Without the
|
||||
# `-p' option, this deletes definitions for functions for the commands
|
||||
# whose names are given as arguments. If combined with the `-p' option
|
||||
# it deletes the definitions for the patterns given as argument.
|
||||
# The `-d' option may not be combined with the `-k' option, i.e.
|
||||
# definitions for key function can not be removed.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# compdef -a foo bar baz
|
||||
# make the completion for the commands `bar' and `baz' use the
|
||||
# function `foo' and make this function be autoloaded
|
||||
#
|
||||
# compdef -p foo 'c*'
|
||||
# make completion for all command whose name begins with a `c'
|
||||
# generate matches by calling the function `foo' before generating
|
||||
# matches defined for the command itself
|
||||
#
|
||||
# compdef -k foo list-choices '^X^M' '\C-xm'
|
||||
# make the function `foo' be invoked when typing `Control-X Control-M'
|
||||
# or `Control-X m'; the function should generate matches and will
|
||||
# behave like the `list-choices' builtin widget
|
||||
#
|
||||
# compdef -d bar baz
|
||||
# delete the definitions for the command names `bar' and `baz'
|
||||
|
||||
compdef() {
|
||||
local opt autol type func delete new i
|
||||
|
||||
# Get the options.
|
||||
|
||||
while getopts "anpkd" opt; do
|
||||
case "$opt" in
|
||||
a) autol=yes;;
|
||||
n) new=yes;;
|
||||
[pk]) if [[ -n "$type" ]]; then
|
||||
# Error if both `-p' and `-k' are given (or one of them
|
||||
# twice).
|
||||
echo "$0: type already set to $type"
|
||||
return 1
|
||||
fi
|
||||
if [[ "$opt" = p ]]; then
|
||||
type=pattern
|
||||
else
|
||||
type=key
|
||||
fi
|
||||
;;
|
||||
d) delete=yes;;
|
||||
esac
|
||||
done
|
||||
shift OPTIND-1
|
||||
|
||||
if [[ -z "$delete" ]]; then
|
||||
# Adding definitions, first get the name of the function name
|
||||
# and probably do autoloading.
|
||||
|
||||
func="$1"
|
||||
[[ -n "$autol" ]] && autoload "$func"
|
||||
shift
|
||||
|
||||
case "$type" in
|
||||
pattern)
|
||||
if [[ $# -gt 1 ]]; then
|
||||
echo "$0: only one pattern allowed"
|
||||
return 1
|
||||
fi
|
||||
# Patterns are stored in strings like `c* foo', with a space
|
||||
# between the pattern and the function name.
|
||||
|
||||
_patcomps=("$_patcomps[@]" "$1 $func")
|
||||
;;
|
||||
key)
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "$0: missing keys"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Define the widget.
|
||||
zle -C "$func" "$1" "$func"
|
||||
shift
|
||||
|
||||
# And bind the keys...
|
||||
for i; do
|
||||
bindkey "$i" "$func"
|
||||
done
|
||||
;;
|
||||
*)
|
||||
# For commands store the function name in the `_comps'
|
||||
# associative array, command names as keys.
|
||||
for i; do
|
||||
[[ -z "$new" || "${+_comps[$i]}" -eq 0 ]] && _comps[$i]="$func"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
else
|
||||
# Handle the `-d' option, deleting.
|
||||
case "$type" in
|
||||
pattern)
|
||||
# Note the space.
|
||||
for i; do
|
||||
_patcomps=("${(@)patcomps:#$i *}")
|
||||
done
|
||||
;;
|
||||
key)
|
||||
# Oops, cannot do that yet.
|
||||
|
||||
echo "$0: cannot restore key bindings"
|
||||
return 1
|
||||
;;
|
||||
*)
|
||||
# Deleting definitons for command is even simpler.
|
||||
for i; do
|
||||
unset "_comps[$i]"
|
||||
done
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
# 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
|
||||
_i_noextglob=yes
|
||||
setopt extendedglob
|
||||
fi
|
||||
|
||||
typeset -U _i_files
|
||||
_i_files=( ${^~fpath}/_*~*~(N:t) )
|
||||
_i_initname=$0
|
||||
_i_done=''
|
||||
|
||||
# If we have a dump file, load it.
|
||||
|
||||
if [[ -f "$COMPDUMP" ]]; then
|
||||
read -rA _i_line < "$COMPDUMP"
|
||||
if [[ _i_autodump -eq 1 && $_i_line[2] -eq $#_i_files ]]; then
|
||||
builtin . "$COMPDUMP"
|
||||
_i_done=yes
|
||||
fi
|
||||
unset _i_line
|
||||
fi
|
||||
if [[ -z "$_i_done" ]]; then
|
||||
for _i_dir in $fpath; do
|
||||
[[ $_i_dir = . ]] && continue
|
||||
for _i_file in $_i_dir/_*~*~(N); do
|
||||
read -rA _i_line < $_i_file
|
||||
_i_tag=$_i_line[1]
|
||||
shift _i_line
|
||||
if [[ $_i_tag = '#defcomp' ]]; then
|
||||
compdef -na "${_i_file:t}" "${_i_line[@]}"
|
||||
elif [[ $_i_tag = '#defpatcomp' ]]; then
|
||||
compdef -pa "${_i_file:t}" "${_i_line[@]}"
|
||||
elif [[ $_i_tag = '#defkeycomp' ]]; then
|
||||
compdef -ka "${_i_file:t}" "${_i_line[@]}"
|
||||
elif [[ $_i_tag = '#autoload' ]]; then
|
||||
autoload ${_i_file:t}
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
bindkey |
|
||||
while read -rA _i_line; do
|
||||
if [[ "$_i_line[2]" = complete-word ||
|
||||
"$_i_line[2]" = delete-char-or-list ||
|
||||
"$_i_line[2]" = expand-or-complete ||
|
||||
"$_i_line[2]" = expand-or-complete-prefix ||
|
||||
"$_i_line[2]" = list-choices ||
|
||||
"$_i_line[2]" = menu-complete ||
|
||||
"$_i_line[2]" = menu-expand-or-complete ||
|
||||
"$_i_line[2]" = reverse-menu-complete ]]; then
|
||||
zle -C _complete_$_i_line[2] $_i_line[2] _main_complete
|
||||
bindkey "${_i_line[1][2,-2]}" _complete_$_i_line[2]
|
||||
fi
|
||||
done
|
||||
|
||||
unset _i_dir _i_line _i_file _i_tag
|
||||
|
||||
# If autodumping was requested, do it now.
|
||||
|
||||
(( _i_autodump )) && builtin . ${_i_initname:h}/compdump
|
||||
fi
|
||||
|
||||
[[ -z "$_i_noextglob" ]] || unsetopt extendedglob
|
||||
|
||||
unset _i_files _i_initname _i_done _i_autodump _i_noextglob
|
107
Completion/README
Normal file
107
Completion/README
Normal file
|
@ -0,0 +1,107 @@
|
|||
The subdirectories contain code for the new function-based completion
|
||||
system. Broadly speaking, this uses shell functions defined for each
|
||||
command to determine how the arguments of a command should be completed.
|
||||
|
||||
You should copy all the files you need or want to a directory of your own,
|
||||
which should be included in your autoload path as defined by $fpath. Then
|
||||
in your .zshrc you should source the file which appears here in
|
||||
Core/compinit. It is recommnded that you use the -d option, which outputs
|
||||
a file containing the necessary variables, bindkeys etc., making later
|
||||
loading much faster. For example,
|
||||
[[ -f ~/completion/compinit ]] && . ~/completion/compinit -d
|
||||
This will rebind any keys which do completion to use the new system.
|
||||
For more detailed instructions, including how to add new completions, see
|
||||
the top of Core/compinit .
|
||||
|
||||
The subdirectories contain:
|
||||
|
||||
Core:
|
||||
The basic functions and files to be sourced. You will certainly need
|
||||
these, and will most likely not feel like altering them (or, in some
|
||||
cases, even reading them, unless you are a shell wizard). The files are:
|
||||
compinit
|
||||
As already described, this is not a function, but is sourced once
|
||||
(with the `source' or `.' commands) to set up the completion system.
|
||||
compdump
|
||||
This dumps the completions status for faster initialisation. The
|
||||
easiest way of doing this is to use the -d option to compinit rather
|
||||
than calling compdump directly.
|
||||
_comp_parts
|
||||
Utility used for completing words with multiple separate parts, such as
|
||||
`<user>@<host>'
|
||||
_compalso
|
||||
Utility for calling a function to add additional completions to an
|
||||
already existing set.
|
||||
_files
|
||||
A frontend to _path_files which will default to any old file if the
|
||||
specified file was not found.
|
||||
_main_complete
|
||||
The main entry point called by the key bindings which compinit sets
|
||||
up (the main `completion widget' in zsh jargon).
|
||||
_normal
|
||||
The function called by _main_complete to handle the most common
|
||||
cases, such as completing a command name or its arguments. This
|
||||
function dispatches to the various other functions for individual
|
||||
commands. (Actually, the system is fairly context-sensitive, so
|
||||
it is wider than just command+argument.)
|
||||
_path_files
|
||||
The function usually called to complete filenames and directories. It
|
||||
replaces the standard -f and -/ options for the basic completion
|
||||
commands: it can do various extra tricks, such as expanding a whole
|
||||
path at once, e.g. F/C/C/_p<TAB> -> Functions/Completion/Core/_path_files
|
||||
Base:
|
||||
You will almost certainly want these files, too, which handle standard
|
||||
tasks like completing files. However, you may want to edit them for
|
||||
your own particular setup. Files are:
|
||||
_command_names
|
||||
This handles completion of the command word, i.e. the first thing
|
||||
on the command line. You may want to alter this, for example,
|
||||
to complete parameters to assign to.
|
||||
_condition
|
||||
This handles completing inside [[ ... ]] .
|
||||
_default
|
||||
This handles completion of command arguments when no special function
|
||||
exists. Usually this means completing files, but you can modify this
|
||||
as you wish.
|
||||
_match_pattern
|
||||
_match_test
|
||||
These are used by Base/_path_files (and hence also Base/_files) for
|
||||
file completion with control over matching (whether to complete
|
||||
case-insensitively, or to allow insertion before `.', etc.) See
|
||||
_match_test for instructions. Note _path_files expects these files
|
||||
to be present.
|
||||
_precommand
|
||||
Allows completion when the first word on the line has to be ignored,
|
||||
for example `noglob ...' should ignore the noglob and just complete
|
||||
as if it wasn't there. Add other such commands to the top line.
|
||||
_redirect
|
||||
Completes after `<' or `<': this version calls _files.
|
||||
_subscript
|
||||
For completion in subscripts of parameters, e.g $foo[...].
|
||||
_vars
|
||||
Completion for commands which need variables (so this could also be in
|
||||
the Builtins directory), but also in math environments such as ((...)).
|
||||
Builtins:
|
||||
Define completions for various shell builtins. The top line of each file
|
||||
says which builtins they apply to; in many cases you can guess from the
|
||||
name. Note in particular that _zftp defines completions for all commands
|
||||
beginning `zf', not just for the module command zftp. This is only
|
||||
really useful if you use zftp with the zf* function suite (zfopen, zfget,
|
||||
...).
|
||||
User:
|
||||
This contains a pot pourri of completions for various external commands.
|
||||
Not all will work unmodified on your system.
|
||||
Commands:
|
||||
These functions define separate completion commands which do not use
|
||||
the usual context information, and hence have to be bound separately
|
||||
to keys. As they appear, they have bindings which you can change or
|
||||
delete by altering the top line of the file. To bind a function
|
||||
(strictly speaking, the corresponding completion widget) yourself
|
||||
after completion is loaded, use `bindkey '<key-string>' <_function_name>'.
|
||||
The files are:
|
||||
_correct_filename, bound to \C-xc
|
||||
Correct the word under the cursor as a filename. This is significantly
|
||||
more powerful than the standard \e$ (spell-word) binding.
|
||||
_most_recent_file, bound to \C-xm
|
||||
Insert the name of the most recent file matching the pattern
|
||||
so far on the command line.
|
22
Completion/User/_a2ps
Normal file
22
Completion/User/_a2ps
Normal file
|
@ -0,0 +1,22 @@
|
|||
#defcomp a2ps
|
||||
|
||||
if [[ -prefix -- ]]; then
|
||||
_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)'
|
||||
|
||||
complist -S= -k '(--medium --columns --rows --line-numbers
|
||||
--font-size --lines-per-page --chars-per-line
|
||||
--tabsize --non-printable-format --encoding
|
||||
--title --stdin --prologue --highlight-level
|
||||
--strip-level --output --version-control --suffix
|
||||
--printer --copies --sides --page-prefeed
|
||||
--no-page-prefeed)'
|
||||
complist -qS= -k '(--margin --header --underlay --left-title
|
||||
--right-title --left-footer --footer --right-footer
|
||||
--pages --pretty-print)'
|
||||
complist -k '(--landscape --portrait --catman --no-header)'
|
||||
else
|
||||
_files -F fignore -g "*~*.ps"
|
||||
fi
|
3
Completion/User/_compress
Normal file
3
Completion/User/_compress
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp compress
|
||||
|
||||
_files -g '*~*.Z'
|
12
Completion/User/_configure
Normal file
12
Completion/User/_configure
Normal file
|
@ -0,0 +1,12 @@
|
|||
#defcomp configure
|
||||
|
||||
if [[ $PREFIX = *=* ]]; then
|
||||
# Complete filenames after e.g. --prefix=
|
||||
IPREFIX=${PREFIX%%=*}=
|
||||
PREFIX=${PREFIX#*=}
|
||||
complist -f
|
||||
else
|
||||
# Generate a list of options from configure --help
|
||||
complist -s '$($COMMAND --help |
|
||||
sed -n -e '\''s/^ *\(--[-a-z0-9]*\)[ =,].*$/\1/p'\'')'
|
||||
fi
|
13
Completion/User/_dd
Normal file
13
Completion/User/_dd
Normal file
|
@ -0,0 +1,13 @@
|
|||
#defcomp dd
|
||||
|
||||
if [[ -iprefix conv= ]]; then
|
||||
# If there's a comma present, ignore up to the last one. The
|
||||
# test alone will have that effect.
|
||||
[[ -string , ]]
|
||||
complist -S, -q \
|
||||
-k '(ascii ebcdic ibm block unblock lcase ucase swab noerror sync)'
|
||||
elif [[ -iprefix 'if=' || -iprefix 'of=' ]]; then
|
||||
_files
|
||||
else
|
||||
complist -S '=' -k '(if of ibs obs bs cbs skip files seek count conv)'
|
||||
fi
|
3
Completion/User/_dvi
Normal file
3
Completion/User/_dvi
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp xdvi dvips dvibook dviconcat dvicopy dvidvi dviselect dvitodvi dvitype
|
||||
|
||||
_files -g '*.(dvi|DVI)'
|
21
Completion/User/_find
Normal file
21
Completion/User/_find
Normal file
|
@ -0,0 +1,21 @@
|
|||
#defcomp find
|
||||
|
||||
if [[ -mbetween -(ok|exec) \\\; ]]; then
|
||||
_normal "$@"
|
||||
elif [[ -iprefix - ]]; then
|
||||
complist -s 'daystart {max,min,}depth follow noleaf version xdev \
|
||||
{a,c,}newer {a,c,m}{min,time} empty false {fs,x,}type gid inum links \
|
||||
{i,}{l,}name {no,}{user,group} path perm regex size true uid used \
|
||||
exec {f,}print{f,0,} ok prune ls'
|
||||
elif [[ -position 1 ]]; then
|
||||
complist -g '. ..'
|
||||
_files -g '(-/)'
|
||||
elif [[ -mcurrent -1 -((a|c|)newer|fprint(|0|f)) ]]; then
|
||||
_files
|
||||
elif [[ -current -1 -fstype ]]; then
|
||||
complist -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)'
|
||||
elif [[ -current -1 -group ]]; then
|
||||
complist -k groups
|
||||
elif [[ -current -1 -user ]]; then
|
||||
complist -u
|
||||
fi
|
3
Completion/User/_gunzip
Normal file
3
Completion/User/_gunzip
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp gunzip zcat
|
||||
|
||||
_files -g '*.[gG][z]'
|
3
Completion/User/_gzip
Normal file
3
Completion/User/_gzip
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp gzip
|
||||
|
||||
_files -g '*~*.[gG][zZ]'
|
3
Completion/User/_hosts
Normal file
3
Completion/User/_hosts
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp ftp ncftp ping rwho rup xping traceroute nslookup
|
||||
|
||||
complist -k hosts
|
3
Completion/User/_make
Normal file
3
Completion/User/_make
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp make gmake pmake
|
||||
|
||||
complist -s "\$(awk '/^[a-zA-Z0-9][^/ ]+:/ {print \$1}' FS=: [mM]akefile)"
|
11
Completion/User/_man
Normal file
11
Completion/User/_man
Normal file
|
@ -0,0 +1,11 @@
|
|||
#defcomp man
|
||||
setopt localoptions rcexpandparam
|
||||
|
||||
local rep
|
||||
if [[ $2 = (<->*|ln) ]]; then
|
||||
rep=( $manpath/(man|cat)$2/$PREFIX*$SUFFIX.<->*(N:t:r) )
|
||||
else
|
||||
rep=( $manpath/(man|cat)*/$PREFIX*$SUFFIX.<->*(N:t:r) )
|
||||
fi
|
||||
|
||||
(( $#rep )) && compadd -m $rep
|
70
Completion/User/_mh
Normal file
70
Completion/User/_mh
Normal file
|
@ -0,0 +1,70 @@
|
|||
#defcomp folder comp inc mark refile repl scan show next prev rmm pick whom mhn mhpath mhpatch
|
||||
|
||||
# Completion for all possible MH commands.
|
||||
# Alter the following two to your own mh directory and the directory
|
||||
# where standard mh library files live. (It works anyway, but this
|
||||
# will save a little time.)
|
||||
local mymhdir=~/Mail
|
||||
local mhlib=/usr/lib/mh
|
||||
|
||||
# To be on the safe side, check this exists and if not, get it anyway.
|
||||
[[ -d $mymhdir ]] || mymhdir=$(mhpath +)
|
||||
|
||||
if [[ -iprefix - ]]; then
|
||||
# get list of options, which MH commands can generate themselves
|
||||
# awk is just too icky to use for this, sorry. send me one if
|
||||
# you come up with it.
|
||||
compadd -m $($COMMAND -help | perl -ne 'if (/^\s*-\(?(\S+)/) {
|
||||
$n = $1;
|
||||
$n =~ s/\)//g;
|
||||
print $n =~ s/^\[([a-z]+)\]// ? "$n\n$1$n\n" : "$n\n";
|
||||
}')
|
||||
return
|
||||
elif [[ -iprefix '+' || -iprefix '@' || -current -1 -draftfolder ]]; then
|
||||
# Complete folder names.
|
||||
local mhpath
|
||||
if [[ $IPREFIX != '@' ]]; then
|
||||
[[ $IPREFIX = '+' ]] || IPREFIX=+
|
||||
mhpath=$mymhdir
|
||||
else
|
||||
mhpath=$(mhpath)
|
||||
fi
|
||||
|
||||
# painless, or what?
|
||||
complist -W mhpath -/
|
||||
elif [[ -mcurrent -1 -(editor|(whatnow|rmm|show|more)proc) ]]; then
|
||||
complist -c
|
||||
elif [[ -current -1 -file ]]; then
|
||||
complist -f
|
||||
elif [[ -mcurrent -1 -(form|audit|filter) ]]; then
|
||||
# Need some MH template file, which may be in our own MH directory
|
||||
# or with the standard library.
|
||||
local mhfpath
|
||||
# This is the only place we need mhlib, so leave the test till here.
|
||||
[[ -d $mhlib ]] || { mhlib=$(mhparam mhlproc); mhlib=$mhlib:h; }
|
||||
mhfpath=($mymhdir $mhlib)
|
||||
|
||||
complist -W mhfpath -g '*(.)'
|
||||
elif [[ -mcurrent -1 -(no|)cc ]]; then
|
||||
compadd -m all to cc me
|
||||
elif [[ -mcurrent -1 -[rw]cache ]]; then
|
||||
compadd -m public private never ask
|
||||
else
|
||||
# Generate sequences.
|
||||
local foldnam folddir f
|
||||
for f in $argv; do
|
||||
[[ $f = [@+]* ]] && foldnam=$f
|
||||
done
|
||||
if [[ $foldnam = '+'* ]]; then
|
||||
folddir=$mymhdir/${foldnam#+}
|
||||
elif [[ $foldnam = '@'* ]]; then
|
||||
folddir=$(mhpath)/${foldnam#@}
|
||||
else
|
||||
folddir=$(mhpath)
|
||||
# leaving foldnam empty works here
|
||||
fi
|
||||
|
||||
complist -s '$(mark $foldnam | awk -F: '\''{ print $1 }'\'')'
|
||||
compadd -m reply next cur prev first last all unseen
|
||||
complist -W folddir -g '<->'
|
||||
fi
|
3
Completion/User/_pdf
Normal file
3
Completion/User/_pdf
Normal file
|
@ -0,0 +1,3 @@
|
|||
function acroread
|
||||
|
||||
_files -g '*.(pdf|PDF)'
|
3
Completion/User/_ps
Normal file
3
Completion/User/_ps
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp gs ghostview gview psnup psselect pswrap pstops pstruct lpr
|
||||
|
||||
_files -g '*([pP][sS]|eps)'
|
9
Completion/User/_rcs
Normal file
9
Completion/User/_rcs
Normal file
|
@ -0,0 +1,9 @@
|
|||
#defcomp co ci rcs
|
||||
|
||||
[[ $COMMAND = ci || $COMMAND = rcs ]] && _files
|
||||
|
||||
if [[ $NMATCHES -eq 0 && -d RCS && $COMMAND != ci ]]; then
|
||||
local rep
|
||||
rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//))
|
||||
(( $#rep )) && compadd -m $rep
|
||||
fi
|
9
Completion/User/_rlogin
Normal file
9
Completion/User/_rlogin
Normal file
|
@ -0,0 +1,9 @@
|
|||
#defcomp rlogin rsh ssh
|
||||
|
||||
if [[ -position 1 ]]; then
|
||||
complist -k hosts
|
||||
elif [[ -position 2 ]]; then
|
||||
complist -k '(-l)'
|
||||
else
|
||||
complist -u
|
||||
fi
|
2
Completion/User/_strip
Normal file
2
Completion/User/_strip
Normal file
|
@ -0,0 +1,2 @@
|
|||
#defcomp strip
|
||||
_files -g '*(*)'
|
16
Completion/User/_stty
Normal file
16
Completion/User/_stty
Normal file
|
@ -0,0 +1,16 @@
|
|||
#defcomp stty
|
||||
|
||||
if [[ -mcurrent -1 \
|
||||
(*erase|discard|status|dsusp|intr|kill|lnext|quit|reprint|start|s*p) ]]
|
||||
then
|
||||
compadd -m -Q '^-' '^h' '^?' '^c' '^u'
|
||||
else
|
||||
[[ -string '-' || -string '+' ]]
|
||||
compadd -m rows columns intr quit erase kill eof eol \
|
||||
eol2 start stop susp dsusp reprint discard werase lnext \
|
||||
parenb parodd cs8 cstopb hupcl cread clocal parext \
|
||||
ignbrk brkint ignpar parmrk inpck istrip inlcr igncr icrnl iuclc \
|
||||
ixon ixany ixoff imaxbel isig icanon xcase echo echoe echok \
|
||||
echonl noflsh tostop echoctl echoprt echoke flusho pending iexten \
|
||||
opost olcuc onlcr ocrnl onocr onlret ofill ofdel
|
||||
fi
|
11
Completion/User/_tar
Normal file
11
Completion/User/_tar
Normal file
|
@ -0,0 +1,11 @@
|
|||
#defcomp tar
|
||||
|
||||
local nm=$NMATCHES tf="$2"
|
||||
|
||||
if [[ ( -mword 1 *t*f* || -mword 1 *x*f* ) && -position 3 100000 ]]; then
|
||||
complist -k "( $(tar tf $tf) )"
|
||||
elif [[ -mword 1 *c*f* && -position 3 100000 ]]; then
|
||||
_files
|
||||
elif [[ -mcurrent -1 *f* && -position 2 ]]; then
|
||||
_files -g '*.(tar|TAR)'
|
||||
fi
|
3
Completion/User/_tex
Normal file
3
Completion/User/_tex
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp tex latex slitex
|
||||
|
||||
_files -g '*.(tex|TEX|texinfo|texi)'
|
3
Completion/User/_uncompress
Normal file
3
Completion/User/_uncompress
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp uncompress zmore
|
||||
|
||||
_files -g '*.Z'
|
5
Completion/User/_x_options
Normal file
5
Completion/User/_x_options
Normal file
|
@ -0,0 +1,5 @@
|
|||
#defpatcomp */X11/*
|
||||
|
||||
# A simple pattern completion, just as an example.
|
||||
|
||||
complist -J options -k '(-display -name -xrm)'
|
3
Completion/User/_xfig
Normal file
3
Completion/User/_xfig
Normal file
|
@ -0,0 +1,3 @@
|
|||
#defcomp xfig
|
||||
|
||||
_files -g '*.fig'
|
|
@ -27,5 +27,5 @@
|
|||
# This must also serve as a shell script, so do not add spaces around the
|
||||
# `=' signs.
|
||||
|
||||
VERSION=3.1.5-pws-9
|
||||
VERSION_DATE='February 18, 1999'
|
||||
VERSION=3.1.5-pws-10
|
||||
VERSION_DATE='February 26, 1999'
|
||||
|
|
|
@ -162,7 +162,7 @@ xitem(tt(compadd) [ tt(-qQfnUam) ] [ tt(-F) var(array) ])
|
|||
xitem([ tt(-P) var(prefix) ] [ tt(-S) var(suffix) ])
|
||||
xitem([ tt(-p) var(hidden-prefix) ] [ tt(-s) var(hidden-suffix) ])
|
||||
xitem([ tt(-i) var(ignored-prefix) ] [ tt(-W) var(file-prefix) ])
|
||||
xitem([ tt(-J) var(name) ] [ tt(-V) var(name) ])
|
||||
xitem([ tt(-J) var(name) ] [ tt(-V) var(name) ] [ tt(-X) var(explanation) ])
|
||||
xitem([ tt(-r) var(remove-chars) ] [ tt(-R) var(remove-func) ])
|
||||
item([ tt(-M) var(match-spec) ] [ tt(--) ] [ var(words) ... ])(
|
||||
|
||||
|
@ -182,14 +182,17 @@ item(tt(-S) var(suffix))(
|
|||
Like tt(-P) but gives a string that has to be inserted after the match.
|
||||
)
|
||||
item(tt(-p) var(hidden-prefix))(
|
||||
This gives a string that should be
|
||||
...
|
||||
This gives a string that should be inserted in the line before the
|
||||
match but that should not appear in the list of matches.
|
||||
)
|
||||
item(tt(-s) var(hidden-suffix))(
|
||||
...
|
||||
Like `tt(-p)', but gives a string to insert after the match.
|
||||
)
|
||||
item(tt(-i) var(ignored-prefix))(
|
||||
...
|
||||
This gives a string to insert into the command line just before any
|
||||
string given with the `tt(-P)' option. Without `tt(-P)' the string is
|
||||
inserted before the string given with `tt(-p)' or directly before the
|
||||
match.
|
||||
)
|
||||
item(tt(-J) var(name))(
|
||||
As for tt(compctl) and tt(complist) this gives the name of the group
|
||||
|
@ -198,6 +201,10 @@ of matches the words should be stored in.
|
|||
item(tt(-V) var(name))(
|
||||
Like tt(-J) but naming a unsorted group.
|
||||
)
|
||||
item(tt(-X) var(explanation))(
|
||||
The var(explanation) string will be printed with the list of matches,
|
||||
as for tt(compctl -X).
|
||||
)
|
||||
item(tt(-q))(
|
||||
This flag has the same meaning as for tt(compctl) and tt(complist),
|
||||
too. It makes the suffix given with tt(-S) be automatically removed if
|
||||
|
@ -382,15 +389,19 @@ given, it is true if the number of words is equal to or greater than
|
|||
var(min) and equal to or less than var(max)
|
||||
)
|
||||
item(tt(-after) var(string))(
|
||||
true if the cursor is after a word that is equal to var(string)
|
||||
true if the cursor is after a word that is equal to var(string); this
|
||||
removes all words up to and including the matched word from the
|
||||
positional parameters
|
||||
)
|
||||
item(tt(-mafter) var(pattern))(
|
||||
like tt(-after) but using pattern matching
|
||||
)
|
||||
item(tt(-between) var(string1) var(string2))(
|
||||
true if the cursor is after a word that is equal to var(string1), if
|
||||
there is also a word that is equal to va(string2), this is true only
|
||||
if the cursor is before it
|
||||
there is also a word that is equal to var(string2), this is true only
|
||||
if the cursor is before it; as a side effect, all words before
|
||||
var(string1) and after var(string2) (both inclusive) are removed from
|
||||
the positional parameters
|
||||
)
|
||||
item(tt(-mbetween) var(pattern1) var(pattern2))(
|
||||
like tt(-between) but using pattern matching
|
||||
|
|
|
@ -869,7 +869,7 @@ can be specified by separating two characters by a `tt(-)'.
|
|||
A `tt(-)' or `tt(])' may be matched by including it as the
|
||||
first character in the list.
|
||||
There are also several named classes of characters, in the form
|
||||
`tt([:)var(name)(tt:])' with the following meanings: `tt([:alnum:])'
|
||||
`tt([:)var(name)tt(:])' with the following meanings: `tt([:alnum:])'
|
||||
alphanumeric, `tt([:alpha:])' alphabetic,
|
||||
`tt([:blank:])' space or tab,
|
||||
`tt([:cntrl:])' control character, `tt([:digit:])' decimal
|
||||
|
@ -988,12 +988,18 @@ item(I)(
|
|||
Case sensitive: locally negates the effect of tt(i) or tt(l) from
|
||||
that point on.
|
||||
)
|
||||
item(tt(a)var(num))(
|
||||
Approximate matching: var(num) errors are allowed in the string matched by
|
||||
the pattern. The rules for this are described in the next subsection.
|
||||
)
|
||||
enditem()
|
||||
|
||||
For example, the test string tt(fooxx) can be matched by the pattern
|
||||
tt(LPAR()#i)tt(RPAR()FOOXX), but not by tt(LPAR()#l)tt(RPAR()FOOXX),
|
||||
tt(LPAR()#i)tt(RPAR()FOO)tt(LPAR()#I)tt(RPAR()XX) or
|
||||
tt(LPAR()LPAR()#i)tt(RPAR()FOOX)tt(RPAR()X).
|
||||
tt(LPAR()LPAR()#i)tt(RPAR()FOOX)tt(RPAR()X). The string
|
||||
tt(LPAR()#ia2)tt(RPAR()readme) specifies case-insensitive matching of
|
||||
tt(readme) with up to two errors.
|
||||
|
||||
When using the ksh syntax for grouping both tt(KSH_GLOB) and
|
||||
tt(EXTENDED_GLOB) must be set and the left parenthesis should be
|
||||
|
@ -1004,6 +1010,61 @@ examining whole paths case-insensitively every directory must be
|
|||
searched for all files which match, so that a pattern of the form
|
||||
tt(LPAR()#i)tt(RPAR()/foo/bar/...) is potentially slow.
|
||||
|
||||
subsect(Approximate Matching)
|
||||
When matching approximately, the shell keeps a count of the errors found,
|
||||
which cannot exceed the number specified in the
|
||||
tt(LPAR()#a)var(num)tt(RPAR()) flags. Four types of error are recognised:
|
||||
|
||||
startitem()
|
||||
item(1.)(
|
||||
Different characters, as in tt(fooxbar) and tt(fooybar).
|
||||
)
|
||||
item(2.)(
|
||||
Transposition of characters, as in tt(banana) and tt(abnana).
|
||||
)
|
||||
item(3.)(
|
||||
A character missing in the target string, as with the pattern tt(road) and
|
||||
target string tt(rod).
|
||||
)
|
||||
item(4.)(
|
||||
An extra character appearing in the target string, as with tt(stove)
|
||||
and tt(strove).
|
||||
)
|
||||
enditem()
|
||||
|
||||
Thus, the pattern tt(LPAR()#a3)tt(RPAR()abcd) matches tt(dcba), with the
|
||||
errors occurring by using the first rule twice and the second once,
|
||||
grouping the string as tt([d][cb][a]) and tt([a][bc][d]).
|
||||
|
||||
Non-literal parts of the pattern must match exactly, including characters
|
||||
in character ranges: hence tt(LPAR()#a1)tt(RPAR()???) matches strings of
|
||||
length four, by applying rule 4 to an empty part of the pattern, but not
|
||||
strings of length three, since all the tt(?) must match. Other characters
|
||||
which must match exactly are initial dots in filenames (unless the
|
||||
tt(GLOB_DOTS) option is set), and all slashes in file names, so that
|
||||
tt(a/bc) is two errors from tt(ab/c) (the slash cannot be transposed with
|
||||
another character). Similarly, errors are counted separately for
|
||||
non-contiguous strings in the pattern, so that tt(LPAR()ab|cd)tt(RPAR()ef)
|
||||
is two errors from tt(aebf).
|
||||
|
||||
When using exclusion via the tt(~) operator, approximate matching is
|
||||
treated entirely separately for the excluded part and must be activated
|
||||
separately. Thus, tt(LPAR()#a1)tt(RPAR()README~READ_ME) matches
|
||||
tt(READ.ME) but not tt(READ_ME), as the trailing tt(READ_ME) is matched
|
||||
without approximation. However,
|
||||
tt(LPAR()#a1)tt(RPAR()README~LPAR()#a1)tt(RPAR()READ_ME)
|
||||
does not match any pattern of the form tt(READ)var(?)tt(ME) as all
|
||||
such forms are now excluded.
|
||||
|
||||
Apart from exclusions, there is only one overall error count; however, the
|
||||
maximum errors allowed may be altered locally, and this can be delimited by
|
||||
grouping. For example,
|
||||
tt(LPAR()#a1)tt(RPAR()cat)tt(LPAR()LPAR()#a0)tt(RPAR()dog)tt(RPAR()fox)
|
||||
allows one error in total, which may not occur in the tt(dog) section, and
|
||||
the pattern
|
||||
tt(LPAR()#a1)tt(RPAR()cat)tt(LPAR()#a0)tt(RPAR()dog)tt(LPAR()#a1)tt(RPAR()fox)
|
||||
is equivalent.
|
||||
|
||||
subsect(Recursive Globbing)
|
||||
A pathname component of the form `tt(LPAR())var(foo)tt(/RPAR()#)'
|
||||
matches a path consisting of zero or more directories
|
||||
|
|
|
@ -144,8 +144,8 @@ then be processed with bf(dvips) and optionally bf(gs) (Ghostscript) to
|
|||
produce a nicely formatted printed guide.
|
||||
)
|
||||
item(The HTML guide)(
|
||||
Mark Borges, tt(<mdb@cdc.noaa.gov), maintains an HTML version of this
|
||||
guide at tt(http://www.peak.org/zsh/Doc/zsh_toc.html).
|
||||
An HTML version of this guide is available at the Zsh web site via
|
||||
tt(http://sunsite.auc.dk/zsh/Doc/index.html).
|
||||
(The HTML version is produced with bf(texi2html), which may be obtained
|
||||
from tt(http://wwwcn.cern.ch/dci/texi2html/). The command is
|
||||
`tt(texi2html -split_chapter -expandinfo zsh.texi)'.)
|
||||
|
|
|
@ -103,6 +103,7 @@ t :] [:]]#
|
|||
t [ [[]
|
||||
t ] []]
|
||||
t [] [^]]]
|
||||
# Case insensitive matching
|
||||
t fooxx (#i)FOOXX
|
||||
f fooxx (#l)FOOXX
|
||||
t FOOXX (#l)fooxx
|
||||
|
@ -113,5 +114,36 @@ f fooxx ((#i)FOOX)X
|
|||
f BAR (bar|(#i)foo)
|
||||
t FOO (bar|(#i)foo)
|
||||
t Modules (#i)*m*
|
||||
# Approximate matching
|
||||
t READ.ME (#ia1)readme
|
||||
f READ..ME (#ia1)readme
|
||||
t README (#ia1)readm
|
||||
t READM (#ia1)readme
|
||||
t README (#ia1)eadme
|
||||
t EADME (#ia1)readme
|
||||
t READEM (#ia1)readme
|
||||
f ADME (#ia1)readme
|
||||
f README (#ia1)read
|
||||
t bob (#a1)[b][b]
|
||||
f bob (#a1)[b][b]a
|
||||
t bob (#a1)[b]o[b]a
|
||||
f bob (#a1)[c]o[b]
|
||||
t abcd (#a2)XbcX
|
||||
t abcd (#a2)ad
|
||||
t ad (#a2)abcd
|
||||
t abcd (#a2)bd
|
||||
t bd (#a2)abcd
|
||||
t badc (#a2)abcd
|
||||
# This next one is a little tricky: a[d]bc[] = a[]bc[d]
|
||||
t adbc (#a2)abcd
|
||||
f dcba (#a2)abcd
|
||||
# the next one is [d][cb][a] = [a][bc][d] with a transposition
|
||||
t dcba (#a3)abcd
|
||||
t aabaXaaabY (#a1)(a#b)#Y
|
||||
t aabaXaaabY (#a1)(a#b)(a#b)Y
|
||||
t aaXaaaaabY (#a1)(a#b)(a#b)Y
|
||||
f read.me (#ia1)README~READ.ME
|
||||
t read.me (#ia1)README~READ_ME
|
||||
f read.me (#ia1)README~(#a1)READ_ME
|
||||
EOT
|
||||
print "$failed tests failed."
|
||||
|
|
|
@ -19,6 +19,7 @@ zsh
|
|||
libzsh.so*
|
||||
sigcount.h
|
||||
signames.c
|
||||
version.h
|
||||
zshpaths.h
|
||||
zshxmods.h
|
||||
bltinmods.list
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
# include "rlimits.h"
|
||||
|
||||
# if defined(RLIM_T_IS_QUAD_T) || defined(RLIM_T_IS_UNSIGNED)
|
||||
# if defined(RLIM_T_IS_QUAD_T) || defined(RLIM_T_IS_LONG_LONG) || defined(RLIM_T_IS_UNSIGNED)
|
||||
static rlim_t
|
||||
zstrtorlimt(const char *s, char **t, int base)
|
||||
{
|
||||
|
@ -62,9 +62,9 @@ zstrtorlimt(const char *s, char **t, int base)
|
|||
*t = (char *)s;
|
||||
return ret;
|
||||
}
|
||||
# else /* !RLIM_T_IS_QUAD_T && !RLIM_T_IS_UNSIGNED */
|
||||
# else /* !RLIM_T_IS_QUAD_T && !RLIM_T_IS_LONG_LONG && !RLIM_T_IS_UNSIGNED */
|
||||
# define zstrtorlimt(a, b, c) zstrtol((a), (b), (c))
|
||||
# endif /* !RLIM_T_IS_QUAD_T && !RLIM_T_IS_UNSIGNED */
|
||||
# endif /* !RLIM_T_IS_QUAD_T && !RLIM_T_IS_LONG_LONG && !RLIM_T_IS_UNSIGNED */
|
||||
|
||||
/* Display resource limits. hard indicates whether `hard' or `soft' *
|
||||
* limits should be displayed. lim specifies the limit, or may be -1 *
|
||||
|
@ -107,9 +107,15 @@ showlimits(int hard, int lim)
|
|||
else
|
||||
printf("%qdkB\n", val / 1024L);
|
||||
# else
|
||||
# ifdef RLIM_T_IS_LONG_LONG
|
||||
printf("%lldMB\n", val / (1024L * 1024L));
|
||||
else
|
||||
printf("%lldkB\n", val / 1024L);
|
||||
# else
|
||||
printf("%ldMB\n", val / (1024L * 1024L));
|
||||
else
|
||||
printf("%ldkB\n", val / 1024L);
|
||||
# endif /* RLIM_T_IS_LONG_LONG */
|
||||
# endif /* RLIM_T_IS_QUAD_T */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,9 +271,10 @@ struct cline {
|
|||
#define CLF_MISS 4
|
||||
#define CLF_DIFF 8
|
||||
#define CLF_SUF 16
|
||||
#define CLF_NEW 32
|
||||
#define CLF_VAR 64
|
||||
#define CLF_JOIN 128
|
||||
#define CLF_PNEW 32
|
||||
#define CLF_SNEW 64
|
||||
#define CLF_VAR 128
|
||||
#define CLF_JOIN 256
|
||||
|
||||
/* Flags for makecomplist*(). Things not to do. */
|
||||
|
||||
|
|
|
@ -49,10 +49,10 @@ void (*makecompparamsptr) _((void));
|
|||
/* pointers to functions required by compctl and defined by zle */
|
||||
|
||||
/**/
|
||||
void (*addmatchesptr) _((char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, int, int, Cmatcher, char **));
|
||||
void (*addmatchesptr) _((char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, int, int, Cmatcher, char *, char **));
|
||||
|
||||
/**/
|
||||
char *(*comp_strptr) _((int*,int*));
|
||||
char *(*comp_strptr) _((int*, int*, int));
|
||||
|
||||
/**/
|
||||
int (*getcpatptr) _((char *, int, char *, int));
|
||||
|
@ -410,6 +410,7 @@ setup_comp1(Module m)
|
|||
cc_first.mask2 = CC_CCCONT;
|
||||
compcontext = compcommand = compprefix = compsuffix =
|
||||
compiprefix = NULL;
|
||||
makecompparamsptr = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1676,7 +1676,7 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
|||
char *p, **sp, *e;
|
||||
char *ipre = NULL, *ppre = NULL, *psuf = NULL, *prpre = NULL;
|
||||
char *pre = NULL, *suf = NULL, *group = NULL, *m = NULL, *rs = NULL;
|
||||
char *ign = NULL, *rf = NULL;
|
||||
char *ign = NULL, *rf = NULL, *expl = NULL;
|
||||
int f = 0, a = 0, dm;
|
||||
Cmatcher match = NULL;
|
||||
|
||||
|
@ -1757,6 +1757,10 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
|||
e = "matching specification expected after -%c";
|
||||
dm = 1;
|
||||
break;
|
||||
case 'X':
|
||||
sp = &expl;
|
||||
e = "string expected after -%c";
|
||||
break;
|
||||
case 'r':
|
||||
f |= CMF_REMOVE;
|
||||
sp = &rs;
|
||||
|
@ -1802,7 +1806,7 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
|||
|
||||
match = cpcmatcher(match);
|
||||
addmatchesptr(ipre, ppre, psuf, prpre, pre, suf, group,
|
||||
rs, rf, ign, f, a, match, argv);
|
||||
rs, rf, ign, f, a, match, expl, argv);
|
||||
freecmatcher(match);
|
||||
|
||||
return 0;
|
||||
|
@ -2049,8 +2053,8 @@ cond_strcl(char **a, int id)
|
|||
zerr("zle not loaded, zle condition not available", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
i = getcpatptr(comp_strptr(&ipl, NULL), i, s, id);
|
||||
if (i != -1) {
|
||||
i = getcpatptr(comp_strptr(&ipl, NULL, 1), i, s, id);
|
||||
if (i != -1 && i >= ipl) {
|
||||
ignore_prefix(i - ipl);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -478,6 +478,17 @@ bin_zle_complete(char *name, char **args, char *ops, char func)
|
|||
Thingy t;
|
||||
Widget w, cw;
|
||||
|
||||
#ifdef DYNAMIC
|
||||
if (!require_module(name, "compctl", 0, 0)) {
|
||||
zerrnam(name, "can't load compctl module", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
if (!makecompparamsptr) {
|
||||
zerrnam(name, "compctl module not available", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
t = rthingy(args[1]);
|
||||
cw = t->widget;
|
||||
unrefthingy(t);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2558,7 +2558,7 @@ execarith(Cmd cmd)
|
|||
val = matheval(e);
|
||||
}
|
||||
if (isset(XTRACE)) {
|
||||
fprintf(stderr, " ))\n", stderr);
|
||||
fprintf(stderr, " ))\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
errflag = 0;
|
||||
|
|
441
Src/glob.c
441
Src/glob.c
|
@ -71,6 +71,7 @@ struct gmatch {
|
|||
int badcshglob;
|
||||
|
||||
static int mode; /* != 0 if we are parsing glob patterns */
|
||||
static int scanning; /* != 0 if we are scanning file paths */
|
||||
static int pathpos; /* position in pathbuf */
|
||||
static int matchsz; /* size of matchbuf */
|
||||
static int matchct; /* number of matches found */
|
||||
|
@ -134,7 +135,7 @@ struct complist {
|
|||
struct comp {
|
||||
Comp left, right, next, exclude;
|
||||
char *str;
|
||||
int stat;
|
||||
int stat, errsmax;
|
||||
};
|
||||
|
||||
/* Type of Comp: a closure with one or two #'s, the end of a *
|
||||
|
@ -162,6 +163,18 @@ struct comp {
|
|||
#define GF_PATHADD 1 /* file glob, adding path components */
|
||||
#define GF_TOPLEV 2 /* outside (), so ~ ends main match */
|
||||
|
||||
/* Next character after one which may be a Meta (x is any char *) */
|
||||
#define METANEXT(x) (*(x) == Meta ? (x)+2 : (x)+1)
|
||||
/*
|
||||
* Increment pointer which may be on a Meta (x is a pointer variable),
|
||||
* returning the incremented value (i.e. like pre-increment).
|
||||
*/
|
||||
#define METAINC(x) ((x) += (*(x) == Meta) ? 2 : 1)
|
||||
/*
|
||||
* Return unmetafied char from string (x is any char *)
|
||||
*/
|
||||
#define UNMETA(x) (*(x) == Meta ? (x)[1] ^ 32 : *(x))
|
||||
|
||||
static char *pptr; /* current place in string being matched */
|
||||
static Comp tail;
|
||||
static int first; /* are leading dots special? */
|
||||
|
@ -352,6 +365,25 @@ haswilds(char *str)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Flags to apply to current level of grouping */
|
||||
|
||||
static int addflags;
|
||||
|
||||
/*
|
||||
* Approximate matching.
|
||||
*
|
||||
* errsmax is used while parsing to store the current number
|
||||
* of errors allowed. While executing it is usually set to -1,
|
||||
* but can be set to something else to fix a different maximum
|
||||
* no. of errors which acts as a limit on the local value: see
|
||||
* scanner() for why this is necessary.
|
||||
*
|
||||
* errsfound is used while executing a pattern to record the
|
||||
* number of errors found so far.
|
||||
*/
|
||||
|
||||
static int errsmax, errsfound;
|
||||
|
||||
/* Do the globbing: scanner is called recursively *
|
||||
* with successive bits of the path until we've *
|
||||
* tried all of it. */
|
||||
|
@ -363,6 +395,7 @@ scanner(Complist q)
|
|||
Comp c;
|
||||
int closure;
|
||||
int pbcwdsav = pathbufcwd;
|
||||
int errssofar = errsfound;
|
||||
struct dirsav ds;
|
||||
|
||||
ds.ino = ds.dev = 0;
|
||||
|
@ -381,7 +414,7 @@ scanner(Complist q)
|
|||
c = q->comp;
|
||||
/* Now the actual matching for the current path section. */
|
||||
if (!(c->next || c->left) && !haswilds(c->str)
|
||||
&& (!(c->stat & (C_LCMATCHUC|C_IGNCASE))
|
||||
&& (!((c->stat & (C_LCMATCHUC|C_IGNCASE)) || c->errsmax)
|
||||
|| !strcmp(".", c->str) || !strcmp("..", c->str))) {
|
||||
/*
|
||||
* We always need to match . and .. explicitly, even if we're
|
||||
|
@ -433,6 +466,7 @@ scanner(Complist q)
|
|||
((glob_pre && !strpfx(glob_pre, fn))
|
||||
|| (glob_suf && !strsfx(glob_suf, fn))))
|
||||
continue;
|
||||
errsfound = errssofar;
|
||||
if (domatch(fn, c, gf_noglobdots)) {
|
||||
/* if this name matchs the pattern... */
|
||||
if (pbcwdsav == pathbufcwd &&
|
||||
|
@ -453,7 +487,34 @@ scanner(Complist q)
|
|||
if (dirs) {
|
||||
int l;
|
||||
|
||||
/* if not the last component in the path */
|
||||
/*
|
||||
* If not the last component in the path:
|
||||
*
|
||||
* If we made an approximation in the new path segment,
|
||||
* and the pattern includes closures other than a
|
||||
* trailing * (we only test if it is not a string),
|
||||
* then it is possible we made too many errors. For
|
||||
* example, (ab)#(cb)# will match the directory abcb
|
||||
* with one error if allowed to, even though it can
|
||||
* match with none. This will stop later parts of the
|
||||
* path matching, so we need to check by reducing the
|
||||
* maximum number of errors and seeing if the directory
|
||||
* still matches. Luckily, this is not a terribly
|
||||
* common case, since complex patterns typically occur
|
||||
* in the last part of the path which is not affected
|
||||
* by this problem.
|
||||
*/
|
||||
if (errsfound > errssofar && (c->next || c->left)) {
|
||||
errsmax = errsfound - 1;
|
||||
while (errsmax >= errssofar) {
|
||||
errsfound = errssofar;
|
||||
if (!domatch(fn, c, gf_noglobdots))
|
||||
break;
|
||||
errsmax = errsfound - 1;
|
||||
}
|
||||
errsfound = errsmax + 1;
|
||||
errsmax = -1;
|
||||
}
|
||||
if (closure) {
|
||||
/* if matching multiple directories */
|
||||
struct stat buf;
|
||||
|
@ -470,9 +531,14 @@ scanner(Complist q)
|
|||
continue;
|
||||
}
|
||||
l = strlen(fn) + 1;
|
||||
subdirs = hrealloc(subdirs, subdirlen, subdirlen + l);
|
||||
subdirs = hrealloc(subdirs, subdirlen, subdirlen + l
|
||||
+ sizeof(int));
|
||||
strcpy(subdirs + subdirlen, fn);
|
||||
subdirlen += l;
|
||||
/* store the count of errors made so far, too */
|
||||
memcpy(subdirs + subdirlen, (char *)&errsfound,
|
||||
sizeof(int));
|
||||
subdirlen += sizeof(int);
|
||||
} else
|
||||
/* if the last filename component, just add it */
|
||||
insert(fn, 1);
|
||||
|
@ -482,8 +548,11 @@ scanner(Complist q)
|
|||
if (subdirs) {
|
||||
int oppos = pathpos;
|
||||
|
||||
for (fn = subdirs; fn < subdirs+subdirlen; fn += strlen(fn) + 1) {
|
||||
for (fn = subdirs; fn < subdirs+subdirlen; ) {
|
||||
addpath(fn);
|
||||
fn += strlen(fn) + 1;
|
||||
memcpy((char *)&errsfound, fn, sizeof(int));
|
||||
fn += sizeof(int);
|
||||
scanner((q->closure) ? q : q->next); /* scan next level */
|
||||
pathbuf[pathpos = oppos] = '\0';
|
||||
}
|
||||
|
@ -502,16 +571,13 @@ scanner(Complist q)
|
|||
|
||||
/* Parse a series of path components pointed to by pptr */
|
||||
|
||||
/* Flags to apply to current level of grourping */
|
||||
|
||||
static int addflags;
|
||||
|
||||
/**/
|
||||
static Comp
|
||||
compalloc(void)
|
||||
{
|
||||
Comp c = (Comp) alloc(sizeof *c);
|
||||
c->stat |= addflags;
|
||||
c->errsmax = errsmax;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -519,10 +585,19 @@ compalloc(void)
|
|||
static int
|
||||
getglobflags()
|
||||
{
|
||||
char *nptr;
|
||||
/* (#X): assumes we are still positioned on the initial '(' */
|
||||
pptr++;
|
||||
while (*++pptr && *pptr != Outpar) {
|
||||
switch (*pptr) {
|
||||
case 'a':
|
||||
/* Approximate matching, max no. of errors follows */
|
||||
errsmax = zstrtol(++pptr, &nptr, 10);
|
||||
if (pptr == nptr)
|
||||
return 1;
|
||||
pptr = nptr-1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
/* Lowercase in pattern matches lower or upper in target */
|
||||
addflags |= C_LCMATCHUC;
|
||||
|
@ -635,6 +710,7 @@ parsecomp(int gflag)
|
|||
if (eptr == cstr) {
|
||||
/* if no string yet, carry on and get one. */
|
||||
c->stat = addflags;
|
||||
c->errsmax = errsmax;
|
||||
cstr = pptr;
|
||||
continue;
|
||||
}
|
||||
|
@ -817,6 +893,7 @@ parsecompsw(int gflag)
|
|||
{
|
||||
Comp c1, c2, c3, excl = NULL, stail = tail;
|
||||
int oaddflags = addflags;
|
||||
int oerrsmax = errsmax;
|
||||
char *sptr;
|
||||
|
||||
/*
|
||||
|
@ -845,12 +922,14 @@ parsecompsw(int gflag)
|
|||
return NULL;
|
||||
if (isset(EXTENDEDGLOB) && *pptr == Tilde) {
|
||||
/* Matching remainder of pattern excludes the pattern from matching */
|
||||
int oldmode = mode;
|
||||
int oldmode = mode, olderrsmax = errsmax;
|
||||
|
||||
mode = 1;
|
||||
errsmax = 0;
|
||||
pptr++;
|
||||
excl = parsecomp(gflag);
|
||||
mode = oldmode;
|
||||
errsmax = olderrsmax;
|
||||
if (!excl)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -878,8 +957,10 @@ parsecompsw(int gflag)
|
|||
c2->stat |= C_PATHADD;
|
||||
c1 = c2;
|
||||
}
|
||||
if (!(gflag & GF_TOPLEV))
|
||||
if (!(gflag & GF_TOPLEV)) {
|
||||
addflags = oaddflags;
|
||||
errsmax = oerrsmax;
|
||||
}
|
||||
return c1;
|
||||
}
|
||||
|
||||
|
@ -965,6 +1046,7 @@ parsepat(char *str)
|
|||
{
|
||||
mode = 0; /* path components present */
|
||||
addflags = 0;
|
||||
errsmax = 0;
|
||||
pptr = str;
|
||||
tail = NULL;
|
||||
/*
|
||||
|
@ -1102,7 +1184,7 @@ static int
|
|||
gmatchcmp(Gmatch a, Gmatch b)
|
||||
{
|
||||
int i, *s;
|
||||
long r;
|
||||
long r = 0L;
|
||||
|
||||
for (i = gf_nsorts, s = gf_sortlist; i; i--, s++) {
|
||||
switch (*s & ~GS_DESC) {
|
||||
|
@ -1594,10 +1676,14 @@ glob(LinkList list, LinkNode np)
|
|||
matchptr = matchbuf = (Gmatch)zalloc((matchsz = 16) *
|
||||
sizeof(struct gmatch));
|
||||
matchct = 0;
|
||||
errsfound = 0;
|
||||
errsmax = -1;
|
||||
|
||||
/* The actual processing takes place here: matches go into *
|
||||
* matchbuf. This is the only top-level call to scanner(). */
|
||||
scanning = 1;
|
||||
scanner(q);
|
||||
scanning = 0;
|
||||
|
||||
/* Deal with failures to match depending on options */
|
||||
if (matchct)
|
||||
|
@ -2427,6 +2513,14 @@ domatch(char *str, Comp c, int fist)
|
|||
int ret;
|
||||
pptr = str;
|
||||
first = fist;
|
||||
/*
|
||||
* If scanning paths, keep the error count over the whole
|
||||
* filename
|
||||
*/
|
||||
if (!scanning) {
|
||||
errsfound = 0;
|
||||
errsmax = -1;
|
||||
}
|
||||
if (*pptr == Nularg)
|
||||
pptr++;
|
||||
PERMALLOC {
|
||||
|
@ -2444,15 +2538,17 @@ static int
|
|||
excluded(Comp c, char *eptr)
|
||||
{
|
||||
char *saves = pptr;
|
||||
int savei = first, savel = longest, ret;
|
||||
int savei = first, savel = longest, savee = errsfound, ret;
|
||||
|
||||
first = 0;
|
||||
/*
|
||||
* Even if we've been told always to match the longest string,
|
||||
* i.e. not anchored to the end, we want to match the full string
|
||||
* we've already matched when we're trying to exclude it.
|
||||
* Likewise, approximate matching here is treated separately.
|
||||
*/
|
||||
longest = 0;
|
||||
errsfound = 0;
|
||||
if (PATHADDP(c) && pathpos) {
|
||||
VARARR(char, buf, pathpos + strlen(eptr) + 1);
|
||||
|
||||
|
@ -2470,13 +2566,18 @@ excluded(Comp c, char *eptr)
|
|||
pptr = saves;
|
||||
first = savei;
|
||||
longest = savel;
|
||||
errsfound = savee;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure for storing instances of a pattern in a closured.
|
||||
*/
|
||||
struct gclose {
|
||||
char *start;
|
||||
char *end;
|
||||
char *start; /* Start of this instance */
|
||||
char *end; /* End of this instance */
|
||||
int errsfound; /* Errors found up to start of instance */
|
||||
};
|
||||
typedef struct gclose *Gclose;
|
||||
|
||||
|
@ -2488,34 +2589,48 @@ typedef struct gclose *Gclose;
|
|||
* also not bother going any further, since the first time we got to
|
||||
* that position (when it was marked), we must already have failed on
|
||||
* and backtracked over any further closure matches beyond that point.
|
||||
* If we are using approximation, the number in the string is incremented
|
||||
* by the current error count; if we come back to that point with a
|
||||
* lower error count, it is worth trying from that point again, but
|
||||
* we must now mark that point in trystring with the new error.
|
||||
*/
|
||||
|
||||
/**/
|
||||
static void
|
||||
addclosures(Comp c, LinkList closlist, int *pdone, char *trystring)
|
||||
addclosures(Comp c, LinkList closlist, int *pdone, unsigned char *trystring)
|
||||
{
|
||||
Gclose gcnode;
|
||||
char *opptr = pptr;
|
||||
unsigned char *tpos;
|
||||
|
||||
while (*pptr) {
|
||||
if (STARP(c)) {
|
||||
if (trystring[(pptr+1)-opptr])
|
||||
break;
|
||||
if (*(tpos = trystring + ((pptr+1) - opptr))) {
|
||||
if ((unsigned)(errsfound+1) >= *tpos)
|
||||
break;
|
||||
*tpos = (unsigned)(errsfound+1);
|
||||
}
|
||||
gcnode = (Gclose)zalloc(sizeof(struct gclose));
|
||||
gcnode->start = pptr;
|
||||
gcnode->end = ++pptr;
|
||||
gcnode->end = METAINC(pptr);
|
||||
gcnode->errsfound = errsfound;
|
||||
} else {
|
||||
char *saves = pptr;
|
||||
int savee = errsfound;
|
||||
if (OPTIONALP(c) && *pdone >= 1)
|
||||
return;
|
||||
if (!matchonce(c) || saves == pptr ||
|
||||
trystring[pptr-opptr]) {
|
||||
(*(tpos = trystring + (pptr-opptr)) &&
|
||||
(unsigned)(errsfound+1) >= *tpos)) {
|
||||
pptr = saves;
|
||||
break;
|
||||
}
|
||||
if (*tpos)
|
||||
*tpos = (unsigned)(errsfound+1);
|
||||
gcnode = (Gclose)zalloc(sizeof(struct gclose));
|
||||
gcnode->start = saves;
|
||||
gcnode->end = pptr;
|
||||
gcnode->errsfound = savee;
|
||||
}
|
||||
pushnode(closlist, gcnode);
|
||||
(*pdone)++;
|
||||
|
@ -2523,13 +2638,29 @@ addclosures(Comp c, LinkList closlist, int *pdone, char *trystring)
|
|||
}
|
||||
|
||||
/*
|
||||
* Match characters with case-insensitivity.
|
||||
* Note CHARMATCH(x,y) != CHARMATCH(y,x)
|
||||
* Match characters with case-insensitivity. Note charmatch(x,y) !=
|
||||
* charmatch(y,x): the first argument comes from the target string, the
|
||||
* second from the pattern. This used to be a macro, and in principle
|
||||
* could be turned back into one.
|
||||
*/
|
||||
#define CHARMATCH(x, y) \
|
||||
(x == y || (((c->stat & C_IGNCASE) ? (tulower(x) == tulower(y)) : \
|
||||
(c->stat & C_LCMATCHUC) ? (islower(y) && tuupper(y) == x) : 0)))
|
||||
|
||||
/**/
|
||||
static int
|
||||
charmatch(Comp c, char *x, char *y)
|
||||
{
|
||||
/*
|
||||
* This takes care of matching two characters which may be a
|
||||
* two byte sequence, Meta followed by something else.
|
||||
* Here we bypass tulower() and tuupper() for speed.
|
||||
*/
|
||||
int xi = (STOUC(UNMETA(x)) & 0xff), yi = (STOUC(UNMETA(y)) & 0xff);
|
||||
return xi == yi ||
|
||||
(((c->stat & C_IGNCASE) ?
|
||||
((isupper(xi) ? tolower(xi) : xi) ==
|
||||
(isupper(yi) ? tolower(yi) : yi)) :
|
||||
(c->stat & C_LCMATCHUC) ?
|
||||
(islower(yi) && toupper(yi) == xi) : 0));
|
||||
}
|
||||
|
||||
/* see if current string in pptr matches c */
|
||||
|
||||
|
@ -2539,14 +2670,16 @@ doesmatch(Comp c)
|
|||
{
|
||||
if (CLOSUREP(c)) {
|
||||
int done, retflag = 0;
|
||||
char *saves, *trystring, *opptr;
|
||||
char *saves, *opptr;
|
||||
unsigned char *trystring, *tpos;
|
||||
int savee;
|
||||
LinkList closlist;
|
||||
Gclose gcnode;
|
||||
|
||||
if (first && *pptr == '.')
|
||||
return 0;
|
||||
|
||||
if (!inclosure && !c->left) {
|
||||
if (!inclosure && !c->left && !c->errsmax) {
|
||||
/* We are not inside another closure, and the current
|
||||
* pattern is a simple string. We handle this very common
|
||||
* case specially: otherwise, matches like *foo* are
|
||||
|
@ -2561,26 +2694,30 @@ doesmatch(Comp c)
|
|||
!itok(looka)) {
|
||||
/* Another simple optimisation for a very common case:
|
||||
* we are processing a * and there is
|
||||
* an ordinary character match next. We look ahead for
|
||||
* that character, taking care of Meta bytes.
|
||||
* an ordinary character match (which may not be a Metafied
|
||||
* character, just to make it easier) next. We look ahead
|
||||
* for that character, taking care of Meta bytes.
|
||||
*/
|
||||
while (*pptr) {
|
||||
for (; *pptr; pptr++) {
|
||||
if (*pptr == Meta)
|
||||
pptr++;
|
||||
else if (CHARMATCH(STOUC(*pptr), STOUC(looka)))
|
||||
else if (charmatch(c, pptr, &looka))
|
||||
break;
|
||||
}
|
||||
if (!*(saves = pptr))
|
||||
break;
|
||||
savee = errsfound;
|
||||
if (doesmatch(c->next))
|
||||
return 1;
|
||||
pptr = saves+1;
|
||||
errsfound = savee;
|
||||
}
|
||||
} else {
|
||||
/* Standard track-forward code */
|
||||
for (done = 0; ; done++) {
|
||||
saves = pptr;
|
||||
savee = errsfound;
|
||||
if ((done || ONEHASHP(c) || OPTIONALP(c)) &&
|
||||
((!c->next && (!LASTP(c) || !*pptr || longest)) ||
|
||||
(c->next && doesmatch(c->next))))
|
||||
|
@ -2588,6 +2725,7 @@ doesmatch(Comp c)
|
|||
if (done && OPTIONALP(c))
|
||||
return 0;
|
||||
pptr = saves;
|
||||
errsfound = savee;
|
||||
first = 0;
|
||||
if (STARP(c)) {
|
||||
if (!*pptr)
|
||||
|
@ -2602,7 +2740,7 @@ doesmatch(Comp c)
|
|||
/* The full, gory backtracking code is now necessary. */
|
||||
inclosure++;
|
||||
closlist = newlinklist();
|
||||
trystring = zcalloc(strlen(pptr)+1);
|
||||
trystring = (unsigned char *)zcalloc(strlen(pptr)+1);
|
||||
opptr = pptr;
|
||||
|
||||
/* Start by making a list where each match is as long
|
||||
|
@ -2621,7 +2759,7 @@ doesmatch(Comp c)
|
|||
retflag = 1;
|
||||
break;
|
||||
}
|
||||
trystring[saves-opptr] = 1;
|
||||
trystring[saves-opptr] = (unsigned)(errsfound + 1);
|
||||
/*
|
||||
* If we failed, the first thing to try is whether we can
|
||||
* shorten the match using the last pattern in the closure.
|
||||
|
@ -2633,14 +2771,18 @@ doesmatch(Comp c)
|
|||
char savec = *gcnode->end;
|
||||
*gcnode->end = '\0';
|
||||
pptr = gcnode->start;
|
||||
errsfound = gcnode->errsfound;
|
||||
if (matchonce(c) && pptr != gcnode->start
|
||||
&& !trystring[pptr-opptr]) {
|
||||
&& (!*(tpos = trystring + (pptr-opptr)) ||
|
||||
*tpos > (unsigned)(errsfound+1))) {
|
||||
if (*tpos)
|
||||
*tpos = (unsigned)(errsfound+1);
|
||||
*gcnode->end = savec;
|
||||
gcnode->end = pptr;
|
||||
/* Try again to construct a list based on
|
||||
* this new position
|
||||
*/
|
||||
addclosures(c, closlist, &done, trystring+(pptr-opptr));
|
||||
addclosures(c, closlist, &done, tpos);
|
||||
continue;
|
||||
}
|
||||
*gcnode->end = savec;
|
||||
|
@ -2650,6 +2792,7 @@ doesmatch(Comp c)
|
|||
*/
|
||||
if ((gcnode = (Gclose)getlinknode(closlist))) {
|
||||
pptr = gcnode->start;
|
||||
errsfound = gcnode->errsfound;
|
||||
zfree(gcnode, sizeof(struct gclose));
|
||||
done--;
|
||||
} else
|
||||
|
@ -2723,8 +2866,7 @@ rangematch(char **patptr, int ch, int rchar)
|
|||
#define PAT(X) (pat[X] == Meta ? pat[(X)+1] ^ 32 : untok(pat[X]))
|
||||
#define PPAT(X) (pat[(X)-1] == Meta ? pat[X] ^ 32 : untok(pat[X]))
|
||||
|
||||
for (pat++; *pat != Outbrack && *pat;
|
||||
*pat == Meta ? pat += 2 : pat++) {
|
||||
for (pat++; *pat != Outbrack && *pat; METAINC(pat)) {
|
||||
if (*pat == Inbrack) {
|
||||
/* Inbrack can only occur inside a range if we found [:...:]. */
|
||||
pat += 2;
|
||||
|
@ -2748,6 +2890,22 @@ rangematch(char **patptr, int ch, int rchar)
|
|||
*patptr = pat;
|
||||
}
|
||||
|
||||
/*
|
||||
* matchonce() is the core of the pattern matching, handling individual
|
||||
* strings and instances of a pattern in a closure.
|
||||
*
|
||||
* Note on approximate matching: The rule is supposed to be
|
||||
* (1) Take the longest possible match without approximation.
|
||||
* (2) At any failure, make the single approximation that results
|
||||
* in the longest match for the remaining part (which may
|
||||
* include further approximations).
|
||||
* (3) If we match the same distance, take the one with fewer
|
||||
* approximations.
|
||||
* If this is wrong, I haven't yet discovered a counterexample. Email
|
||||
* lines are now open.
|
||||
* pws 1999/02/23
|
||||
*/
|
||||
|
||||
/**/
|
||||
static int
|
||||
matchonce(Comp c)
|
||||
|
@ -2758,7 +2916,7 @@ matchonce(Comp c)
|
|||
if (!pat || !*pat) {
|
||||
/* No current pattern (c->str). */
|
||||
char *saves;
|
||||
int savei;
|
||||
int savee, savei;
|
||||
|
||||
if (errflag)
|
||||
return 0;
|
||||
|
@ -2766,6 +2924,7 @@ matchonce(Comp c)
|
|||
* check for exclusion of pattern or alternatives. */
|
||||
saves = pptr;
|
||||
savei = first;
|
||||
savee = errsfound;
|
||||
/* Loop over alternatives with exclusions: (foo~bar|...). *
|
||||
* Exclusions apply to the pattern in c->left. */
|
||||
if (c->left || c->right) {
|
||||
|
@ -2812,6 +2971,7 @@ matchonce(Comp c)
|
|||
*/
|
||||
exclend--;
|
||||
pptr = saves;
|
||||
errsfound = savee;
|
||||
}
|
||||
inclosure--;
|
||||
if (ret)
|
||||
|
@ -2822,19 +2982,43 @@ matchonce(Comp c)
|
|||
if (c->right && (!ret || inclosure)) {
|
||||
/* If in a closure, we always want the longest match. */
|
||||
char *newpptr = pptr;
|
||||
int newerrsfound = errsfound;
|
||||
pptr = saves;
|
||||
first = savei;
|
||||
errsfound = savee;
|
||||
ret2 = doesmatch(c->right);
|
||||
if (ret && (!ret2 || pptr < newpptr))
|
||||
if (ret && (!ret2 || pptr < newpptr)) {
|
||||
pptr = newpptr;
|
||||
errsfound = newerrsfound;
|
||||
}
|
||||
}
|
||||
if (!ret && !ret2) {
|
||||
pptr = saves;
|
||||
first = savei;
|
||||
errsfound = savee;
|
||||
break;
|
||||
}
|
||||
if (!ret && !ret2)
|
||||
return 0;
|
||||
}
|
||||
if (CLOSUREP(c))
|
||||
return 1;
|
||||
if (!c->next) /* no more patterns left */
|
||||
return (!LASTP(c) || !*pptr || longest);
|
||||
if (!c->next) {
|
||||
/*
|
||||
* No more patterns left, but we may still be in the middle
|
||||
* of a match, in which case alles in Ordnung...
|
||||
*/
|
||||
if (!LASTP(c))
|
||||
return 1;
|
||||
/*
|
||||
* ...else we're at the last pattern, so this is our last
|
||||
* ditch attempt at an approximate match: try to omit the
|
||||
* last few characters.
|
||||
*/
|
||||
for (; *pptr && errsfound < c->errsmax &&
|
||||
(errsmax == -1 || errsfound < errsmax);
|
||||
METAINC(pptr))
|
||||
errsfound++;
|
||||
return !*pptr || longest;
|
||||
}
|
||||
/* optimisation when next pattern is not a closure */
|
||||
if (!CLOSUREP(c->next)) {
|
||||
c = c->next;
|
||||
|
@ -2843,7 +3027,10 @@ matchonce(Comp c)
|
|||
}
|
||||
return doesmatch(c->next);
|
||||
}
|
||||
/* Don't match leading dot if first is set */
|
||||
/*
|
||||
* Don't match leading dot if first is set
|
||||
* (don't even try for an approximate match)
|
||||
*/
|
||||
if (first && *pptr == '.' && *pat != '.')
|
||||
return 0;
|
||||
if (*pat == Star) { /* final * is not expanded to ?#; returns success */
|
||||
|
@ -2852,39 +3039,47 @@ matchonce(Comp c)
|
|||
return 1;
|
||||
}
|
||||
first = 0; /* finished checking start of pattern */
|
||||
if (*pat == Quest && *pptr) {
|
||||
if (*pat == Quest) {
|
||||
/* match exactly one character */
|
||||
if (*pptr == Meta)
|
||||
pptr++;
|
||||
pptr++;
|
||||
if (!*pptr)
|
||||
break;
|
||||
METAINC(pptr);
|
||||
pat++;
|
||||
continue;
|
||||
}
|
||||
if (*pat == Inbrack) {
|
||||
/* Match groups of characters */
|
||||
char ch;
|
||||
char *saves, *savep;
|
||||
|
||||
if (!*pptr)
|
||||
break;
|
||||
ch = *pptr == Meta ? pptr[1] ^ 32 : *pptr;
|
||||
saves = pptr;
|
||||
savep = pat;
|
||||
ch = UNMETA(pptr);
|
||||
if (pat[1] == Hat || pat[1] == '^' || pat[1] == '!') {
|
||||
/* group is negated */
|
||||
*++pat = Hat;
|
||||
rangematch(&pat, ch, Hat);
|
||||
DPUTS(!*pat, "BUG: something is very wrong in doesmatch()");
|
||||
if (*pat != Outbrack)
|
||||
if (*pat != Outbrack) {
|
||||
pptr = saves;
|
||||
pat = savep;
|
||||
break;
|
||||
}
|
||||
pat++;
|
||||
*pptr == Meta ? pptr += 2 : pptr++;
|
||||
METAINC(pptr);
|
||||
continue;
|
||||
} else {
|
||||
/* pattern is not negated (affirmed? asserted?) */
|
||||
rangematch(&pat, ch, Inbrack);
|
||||
DPUTS(!pat || !*pat, "BUG: something is very wrong in doesmatch()");
|
||||
if (*pat == Outbrack)
|
||||
if (*pat == Outbrack) {
|
||||
pptr = saves;
|
||||
pat = savep;
|
||||
break;
|
||||
for (*pptr == Meta ? pptr += 2 : pptr++;
|
||||
*pat != Outbrack; pat++);
|
||||
}
|
||||
for (METAINC(pptr); *pat != Outbrack; pat++);
|
||||
pat++;
|
||||
continue;
|
||||
}
|
||||
|
@ -2892,7 +3087,7 @@ matchonce(Comp c)
|
|||
if (*pat == Inang) {
|
||||
/* Numeric globbing. */
|
||||
unsigned long t1, t2, t3;
|
||||
char *ptr;
|
||||
char *ptr, *saves = pptr, *savep = pat;
|
||||
|
||||
if (!idigit(*pptr))
|
||||
break;
|
||||
|
@ -2933,19 +3128,146 @@ matchonce(Comp c)
|
|||
pptr--;
|
||||
t1 /= 10;
|
||||
}
|
||||
if (t1 < t2 || (!not3 && t1 > t3))
|
||||
if (t1 < t2 || (!not3 && t1 > t3)) {
|
||||
pptr = saves;
|
||||
pat = savep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (CHARMATCH(STOUC(*pptr), STOUC(*pat))) {
|
||||
/* just plain old characters */
|
||||
pptr++;
|
||||
pat++;
|
||||
/* itok(Meta) is zero */
|
||||
DPUTS(itok(*pat), "BUG: matching tokenized character");
|
||||
if (charmatch(c, pptr, pat)) {
|
||||
/* just plain old characters (or maybe unplain new characters) */
|
||||
METAINC(pptr);
|
||||
METAINC(pat);
|
||||
continue;
|
||||
}
|
||||
if (errsfound < c->errsmax &&
|
||||
(errsmax == -1 || errsfound < errsmax)) {
|
||||
/*
|
||||
* We tried to match literal characters and failed. Now it's
|
||||
* time to match approximately. Note this doesn't handle the
|
||||
* case where we *didn't* try to match literal characters,
|
||||
* including the case where we were already at the end of the
|
||||
* pattern, because then we never get here. In that case the
|
||||
* pattern has to be matched exactly, but we could maybe
|
||||
* advance up the target string before trying it, so we have to
|
||||
* handle that case elsewhere.
|
||||
*/
|
||||
char *saves = pptr, *savep = c->str;
|
||||
char *maxpptr = pptr, *patnext = METANEXT(pat);
|
||||
int savee, maxerrs = -1;
|
||||
|
||||
/* First try to advance up the pattern. */
|
||||
c->str = patnext;
|
||||
savee = ++errsfound;
|
||||
if (matchonce(c)) {
|
||||
maxpptr = pptr;
|
||||
maxerrs = errsfound;
|
||||
}
|
||||
errsfound = savee;
|
||||
|
||||
if (*saves) {
|
||||
/*
|
||||
* If we have characters on both strings, we have more
|
||||
* choice.
|
||||
*
|
||||
* Try to edge up the target string.
|
||||
*/
|
||||
char *strnext = METANEXT(saves);
|
||||
pptr = strnext;
|
||||
c->str = pat;
|
||||
if (matchonce(c) &&
|
||||
(maxerrs == -1 || pptr > maxpptr ||
|
||||
(pptr == maxpptr && errsfound <= maxerrs))) {
|
||||
maxpptr = pptr;
|
||||
maxerrs = errsfound;
|
||||
}
|
||||
errsfound = savee;
|
||||
|
||||
/*
|
||||
* Try edging up both of them at once.
|
||||
* Note this takes precedence in the case of equal
|
||||
* length as we get further up the pattern.
|
||||
*/
|
||||
c->str = patnext;
|
||||
pptr = strnext;
|
||||
if (matchonce(c) &&
|
||||
(maxerrs == -1 || pptr > maxpptr ||
|
||||
(pptr == maxpptr && errsfound <= maxerrs))) {
|
||||
maxpptr = pptr;
|
||||
maxerrs = errsfound;
|
||||
}
|
||||
errsfound = savee;
|
||||
|
||||
/*
|
||||
* See if we can transpose: that counts as just one error.
|
||||
*
|
||||
* Note, however, `abanana' and `banana': transposing
|
||||
* is wrong here, as it gets us two errors,
|
||||
* [ab][a]nana vs [ba][]nana, instead of the correct
|
||||
* [a]banana vs []banana, so we still need to try
|
||||
* the other possibilities.
|
||||
*/
|
||||
if (strnext && patnext && !itok(*patnext) &&
|
||||
charmatch(c, strnext, pat) &&
|
||||
charmatch(c, saves, patnext)) {
|
||||
c->str = patnext;
|
||||
METAINC(c->str);
|
||||
|
||||
pptr = strnext;
|
||||
METAINC(pptr);
|
||||
|
||||
if (matchonce(c) &&
|
||||
(maxerrs == -1 || pptr > maxpptr ||
|
||||
(pptr == maxpptr && errsfound <= maxerrs))) {
|
||||
maxpptr = pptr;
|
||||
maxerrs = errsfound;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We don't usually restore state on failure, but we need
|
||||
* to fix up the Comp structure which we altered to
|
||||
* look at the tail of the pattern.
|
||||
*/
|
||||
c->str = savep;
|
||||
/*
|
||||
* If that failed, game over: we don't want to break
|
||||
* and try the other approximate test, because we just did
|
||||
* that.
|
||||
*/
|
||||
if (maxerrs == -1)
|
||||
return 0;
|
||||
pptr = maxpptr;
|
||||
errsfound = maxerrs;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*pptr && errsfound < c->errsmax &&
|
||||
(errsmax == -1 || errsfound < errsmax)) {
|
||||
/*
|
||||
* The pattern failed, but we can try edging up the target string
|
||||
* and rematching with an error. Note we do this from wherever we
|
||||
* got to in the pattern string c->str, not the start. hence the
|
||||
* need to modify c->str.
|
||||
*
|
||||
* At this point, we don't have a literal character in the pattern
|
||||
* (handled above), so we don't try any funny business on the
|
||||
* pattern itself.
|
||||
*/
|
||||
int ret;
|
||||
char *savep = c->str;
|
||||
errsfound++;
|
||||
METAINC(pptr);
|
||||
c->str = pat;
|
||||
ret = matchonce(c);
|
||||
c->str = savep;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2958,6 +3280,7 @@ parsereg(char *str)
|
|||
remnulargs(str);
|
||||
mode = 1; /* no path components */
|
||||
addflags = 0;
|
||||
errsmax = 0;
|
||||
pptr = str;
|
||||
tail = NULL;
|
||||
return parsecompsw(GF_TOPLEV);
|
||||
|
|
|
@ -607,6 +607,9 @@ hashdir(char **dirp)
|
|||
Cmdnam cn;
|
||||
DIR *dir;
|
||||
char *fn;
|
||||
#ifdef _WIN32
|
||||
char *exe;
|
||||
#endif
|
||||
|
||||
if (isrelative(*dirp) || !(dir = opendir(unmeta(*dirp))))
|
||||
return;
|
||||
|
@ -618,6 +621,23 @@ hashdir(char **dirp)
|
|||
cn->u.name = dirp;
|
||||
cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
/* Hash foo.exe as foo, since when no real foo exists, foo.exe
|
||||
will get executed by DOS automatically. This quiets
|
||||
spurious corrections when CORRECT or CORRECT_ALL is set. */
|
||||
if ((exe = strrchr(fn, '.')) &&
|
||||
(exe[1] == 'E' || exe[1] == 'e') &&
|
||||
(exe[2] == 'X' || exe[2] == 'x') &&
|
||||
(exe[3] == 'E' || exe[3] == 'e') && exe[4] == 0) {
|
||||
*exe = 0;
|
||||
if (!cmdnamtab->getnode(cmdnamtab, fn)) {
|
||||
cn = (Cmdnam) zcalloc(sizeof *cn);
|
||||
cn->flags = 0;
|
||||
cn->u.name = dirp;
|
||||
cmdnamtab->addnode(cmdnamtab, ztrdup(fn), cn);
|
||||
}
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
|
49
Src/module.c
49
Src/module.c
|
@ -567,6 +567,37 @@ load_module(char const *name)
|
|||
return m;
|
||||
}
|
||||
|
||||
/* This ensures that the module with the name given as the second argument
|
||||
* is loaded.
|
||||
* The third argument should be non-zero if the function should complain
|
||||
* about trying to load a module with a full path name in restricted mode.
|
||||
* The last argument should be non-zero if this function should signal an
|
||||
* error if the module is already loaded.
|
||||
* The return value is the module of NULL if the module couldn't be loaded. */
|
||||
|
||||
/**/
|
||||
Module
|
||||
require_module(char *nam, char *module, int res, int test)
|
||||
{
|
||||
Module m = NULL;
|
||||
LinkNode node;
|
||||
|
||||
node = find_module(module);
|
||||
if (node && (m = ((Module) getdata(node)))->handle &&
|
||||
!(m->flags & MOD_UNLOAD)) {
|
||||
if (test) {
|
||||
zwarnnam(nam, "module %s already loaded.", module, 0);
|
||||
return NULL;
|
||||
}
|
||||
} else if (res && isset(RESTRICTED) && strchr(module, '/')) {
|
||||
zwarnnam(nam, "%s: restricted", module, 0);
|
||||
return NULL;
|
||||
} else
|
||||
return load_module(module);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
add_dep(char *name, char *from)
|
||||
|
@ -963,22 +994,10 @@ bin_zmodload_load(char *nam, char **args, char *ops)
|
|||
return 0;
|
||||
} else {
|
||||
/* load modules */
|
||||
for (; *args; args++) {
|
||||
Module m;
|
||||
for (; *args; args++)
|
||||
if (!require_module(nam, *args, 1, (!ops['i'])))
|
||||
ret = 1;
|
||||
|
||||
node = find_module(*args);
|
||||
if (node && (m = ((Module) getdata(node)))->handle &&
|
||||
!(m->flags & MOD_UNLOAD)) {
|
||||
if (!ops['i']) {
|
||||
zwarnnam(nam, "module %s already loaded.", *args, 0);
|
||||
ret = 1;
|
||||
}
|
||||
} else if (isset(RESTRICTED) && strchr(*args, '/')) {
|
||||
zwarnnam(nam, "%s: restricted", *args, 0);
|
||||
ret = 1;
|
||||
} else if (!load_module(*args))
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
13
Src/params.c
13
Src/params.c
|
@ -679,11 +679,13 @@ static char **garr;
|
|||
static long
|
||||
getarg(char **str, int *inv, Value v, int a2, long *w)
|
||||
{
|
||||
int num = 1, word = 0, rev = 0, ind = 0, down = 0, l, i;
|
||||
int num = 1, word = 0, rev = 0, ind = 0, down = 0, l, i, ishash;
|
||||
char *s = *str, *sep = NULL, *t, sav, *d, **ta, **p, *tt;
|
||||
long r = 0;
|
||||
Comp c;
|
||||
|
||||
ishash = (v->pm && PM_TYPE(v->pm->flags) == PM_HASHED);
|
||||
|
||||
/* first parse any subscription flags */
|
||||
if (v->pm && (*s == '(' || *s == Inpar)) {
|
||||
int escapes = 0;
|
||||
|
@ -771,12 +773,13 @@ getarg(char **str, int *inv, Value v, int a2, long *w)
|
|||
} else if (rev) {
|
||||
v->isarr |= SCANPM_WANTVALS;
|
||||
}
|
||||
if (!down && v->pm && PM_TYPE(v->pm->flags) == PM_HASHED)
|
||||
if (!down && ishash)
|
||||
v->isarr &= ~SCANPM_MATCHMANY;
|
||||
*inv = ind;
|
||||
}
|
||||
|
||||
for (t=s, i=0; *t && ((*t != ']' && *t != Outbrack && *t != ',') || i); t++)
|
||||
for (t=s, i=0;
|
||||
*t && ((*t != ']' && *t != Outbrack && (ishash || *t != ',')) || i); t++)
|
||||
if (*t == '[' || *t == Inbrack)
|
||||
i++;
|
||||
else if (*t == ']' || *t == Outbrack)
|
||||
|
@ -791,7 +794,7 @@ getarg(char **str, int *inv, Value v, int a2, long *w)
|
|||
singsub(&s);
|
||||
|
||||
if (!rev) {
|
||||
if (v->pm && PM_TYPE(v->pm->flags) == PM_HASHED) {
|
||||
if (ishash) {
|
||||
HashTable ht = v->pm->gets.hfn(v->pm);
|
||||
if (!ht) {
|
||||
ht = newparamtable(17, v->pm->nam);
|
||||
|
@ -867,7 +870,7 @@ getarg(char **str, int *inv, Value v, int a2, long *w)
|
|||
|
||||
if ((c = parsereg(s))) {
|
||||
if (v->isarr) {
|
||||
if (PM_TYPE(v->pm->flags) == PM_HASHED) {
|
||||
if (ishash) {
|
||||
scancomp = c;
|
||||
if (ind)
|
||||
v->isarr |= SCANPM_MATCHKEY;
|
||||
|
|
|
@ -999,11 +999,12 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
|
||||
if (!(v = fetchvalue((subexp ? &ov : &s), (wantt ? -1 :
|
||||
((unset(KSHARRAYS) || inbrace) ? 1 : -1)),
|
||||
hkeys|hvals)))
|
||||
hkeys|hvals)) ||
|
||||
(v->pm && (v->pm->flags & PM_UNSET)))
|
||||
vunset = 1;
|
||||
|
||||
if (wantt) {
|
||||
if (v) {
|
||||
if (v && v->pm && !(v->pm->flags & PM_UNSET)) {
|
||||
int f = v->pm->flags;
|
||||
|
||||
switch (PM_TYPE(f)) {
|
||||
|
|
11
Src/system.h
11
Src/system.h
|
@ -70,8 +70,15 @@ char *alloca _((size_t));
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBC_H /* NeXT */
|
||||
# include <libc.h>
|
||||
/*
|
||||
* libc.h in an optional package for Debian Linux is broken (it
|
||||
* defines dup() as a synonym for dup2(), which has a different
|
||||
* number of arguments), so just include it for next.
|
||||
*/
|
||||
#ifdef __NeXT__
|
||||
# ifdef HAVE_LIBC_H
|
||||
# include <libc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
|
|
|
@ -173,6 +173,7 @@ refreshptr
|
|||
remlpaths
|
||||
remnulargs
|
||||
removehashnode
|
||||
require_module
|
||||
resetneeded
|
||||
restoredir
|
||||
reswdtab
|
||||
|
|
|
@ -196,10 +196,13 @@
|
|||
/* Define to 1 if system has working FIFO's */
|
||||
#undef HAVE_FIFOS
|
||||
|
||||
/* Define to 1 if struct rlimit use quad_t */
|
||||
/* Define to 1 if struct rlimit uses quad_t */
|
||||
#undef RLIM_T_IS_QUAD_T
|
||||
|
||||
/* Define to 1 if rlimit use unsigned */
|
||||
/* Define to 1 if struct rlimit uses long long */
|
||||
#undef RLIM_T_IS_LONG_LONG
|
||||
|
||||
/* Define to 1 if rlimit uses unsigned */
|
||||
#undef RLIM_T_IS_UNSIGNED
|
||||
|
||||
/* Define to the type used in struct rlimit */
|
||||
|
|
54
configure.in
54
configure.in
|
@ -673,7 +673,8 @@ dnl The backslash substitution is to persuade cygwin to cough up
|
|||
dnl slashes rather than doubled backslashes in the path.
|
||||
echo "#include <signal.h>" > nametmp.c
|
||||
sigfile_list="`$CPP nametmp.c |
|
||||
sed -n -e 's/^#[ ].*\"\(.*\)\"/\1/p' -e 's/\\\\\\\\/\//g' |
|
||||
sed -n 's/^#[ ].*\"\(.*\)\"/\1/p' |
|
||||
sed 's/\\\\\\\\/\//g' |
|
||||
$AWK '{ if (\$1 ~ \"sig\") files[[\$1]] = \$1 }
|
||||
END { for (var in files) print var }'`"
|
||||
rm -f nametmp.c
|
||||
|
@ -681,6 +682,7 @@ if test -z "$sigfile_list"; then
|
|||
dnl In case we don't get the stuff from the preprocesor, use the old
|
||||
dnl list of standard places.
|
||||
sigfile_list="/usr/include/bsd/sys/signal.h
|
||||
/usr/include/signum.h
|
||||
/usr/include/asm/signum.h
|
||||
/usr/include/asm/signal.h
|
||||
/usr/include/linux/signal.h
|
||||
|
@ -689,9 +691,13 @@ if test -z "$sigfile_list"; then
|
|||
fi
|
||||
for SIGNAL_H in $sigfile_list
|
||||
do
|
||||
test -f $SIGNAL_H && \
|
||||
grep '#[ ]*define[ ][ ]*SIG[0-9A-Z]*[ ]*[0-9][0-9]*' $SIGNAL_H > /dev/null && \
|
||||
break
|
||||
dnl Try to make sure it doesn't get confused by files that don't
|
||||
dnl have real signal definitions in, but do #define SIG* by counting
|
||||
dnl the number of signals. Maybe we could even check for e.g. SIGHUP?
|
||||
nsigs=`test -f $SIGNAL_H && \
|
||||
grep '#[ ]*define[ ][ ]*SIG[0-9A-Z]*[ ]*[0-9][0-9]*' $SIGNAL_H | \
|
||||
wc -l | sed 's/[ ]//g'`
|
||||
test "x$nsigs" != x && test "$nsigs" -ge 7 && break
|
||||
done
|
||||
zsh_cv_path_signal_h=$SIGNAL_H
|
||||
])
|
||||
|
@ -729,20 +735,43 @@ dnl ------------------
|
|||
dnl rlimit type checks
|
||||
dnl ------------------
|
||||
DEFAULT_RLIM_T=long
|
||||
AC_CACHE_CHECK(if rlim_t is quad_t,
|
||||
zsh_cv_rlim_t_is_quad_t,
|
||||
AC_CACHE_CHECK(if rlim_t is longer than a long,
|
||||
zsh_cv_rlim_t_is_longer,
|
||||
[AC_TRY_RUN([
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/resource.h>
|
||||
main(){struct rlimit r;exit(sizeof(r.rlim_cur) <= sizeof(long));}],
|
||||
zsh_cv_rlim_t_is_quad_t=yes,
|
||||
zsh_cv_rlim_t_is_quad_t=no,
|
||||
zsh_cv_rlim_t_is_quad_t=yes)])
|
||||
if test $zsh_cv_rlim_t_is_quad_t = yes; then
|
||||
AC_DEFINE(RLIM_T_IS_QUAD_T)
|
||||
DEFAULT_RLIM_T=quad_t
|
||||
zsh_cv_rlim_t_is_longer=yes,
|
||||
zsh_cv_rlim_t_is_longer=no,
|
||||
zsh_cv_rlim_t_is_longer=yes)])
|
||||
if test $zsh_cv_rlim_t_is_longer = yes; then
|
||||
AC_CACHE_CHECK(if rlim_t is a quad,
|
||||
zsh_cv_rlim_t_is_quad_t,
|
||||
[AC_TRY_RUN([
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <sys/resource.h>
|
||||
main() {
|
||||
struct rlimit r;
|
||||
char buf[[20]];
|
||||
r.rlim_cur = 0;
|
||||
sprintf(buf, "%qd", r.rlim_cur);
|
||||
exit(strcmp(buf, "0"));
|
||||
}],
|
||||
zsh_cv_rlim_t_is_quad_t=yes,
|
||||
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
|
||||
AC_DEFINE(RLIM_T_IS_QUAD_T)
|
||||
DEFAULT_RLIM_T=quad_t
|
||||
else
|
||||
AC_DEFINE(RLIM_T_IS_LONG_LONG)
|
||||
DEFAULT_RLIM_T='long long'
|
||||
fi
|
||||
else
|
||||
AC_CACHE_CHECK(if the rlim_t is unsigned,
|
||||
zsh_cv_type_rlim_t_is_unsigned,
|
||||
|
@ -1113,7 +1142,6 @@ main()
|
|||
elif test "x$zsh_cv_func_dlsym_needs_underscore" != xno; then
|
||||
dnl Do not cache failed value
|
||||
unset zsh_cv_func_dlsym_needs_underscore
|
||||
dynamic=no
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
117
patchlist.txt
117
patchlist.txt
|
@ -299,7 +299,7 @@ Phil: zless, 5032, simplified by Bart, 5037, also added a `setopt
|
|||
localoptions' after spending an hour wondering why nothing worked any
|
||||
more.
|
||||
|
||||
Me: `make install' does not do `make install.info', 5047
|
||||
pws: `make install' does not do `make install.info', 5047
|
||||
|
||||
Sven: compcall tries old-style completion from new-style function,
|
||||
compctl -K ' func' handles newstyle completion, 5059; avoid recursion,
|
||||
|
@ -309,7 +309,7 @@ Sven: inserting completion inside brace expansion, 5060
|
|||
|
||||
Sven: extra completion context, 5092
|
||||
|
||||
Me: typeset -T MYPATH mypath, 5094, plus fix for MYPATH=(foo),
|
||||
pws: typeset -T MYPATH mypath, 5094, plus fix for MYPATH=(foo),
|
||||
mypath=foo (and also existing PATH=(foo) bug), 5120
|
||||
|
||||
Sven: doc fix for glob qualifiers, 5102
|
||||
|
@ -320,18 +320,18 @@ Drazen Kacar, modified by me: workaround for terminal bug on Solaris,
|
|||
Sven: zle and widget information via variables in new completion
|
||||
functions, 5104
|
||||
|
||||
Me: remove old zle -C, zle -C now does new completion, 5105
|
||||
pws: remove old zle -C, zle -C now does new completion, 5105
|
||||
|
||||
Sven: glob qualifier o for modes, 5107
|
||||
|
||||
Me: fix for unsetting special zle variables, 5111
|
||||
pws: fix for unsetting special zle variables, 5111
|
||||
|
||||
Drazen Kacar, modified by me: unlock terminal device on Solaris, 5118
|
||||
(5117 was wrong)
|
||||
|
||||
pws-7
|
||||
|
||||
Me: patch for zls, 5054 (appeared in pws-6 but not in corresponding
|
||||
pws: patch for zls, 5054 (appeared in pws-6 but not in corresponding
|
||||
patchlist).
|
||||
|
||||
Bart: finally added missing hunk from 4965 which allowed unsetting an
|
||||
|
@ -355,7 +355,7 @@ Sven: fix for command completion and pattern completions, 5178
|
|||
|
||||
Sven: ${(P)...} 5183, 5199, 5200
|
||||
|
||||
Me: compctl documentation tidy-up, 5185, 5198
|
||||
pws: compctl documentation tidy-up, 5185, 5198
|
||||
|
||||
Sven: zle commands which use the minibuffer erase completion listings,
|
||||
5201
|
||||
|
@ -370,13 +370,13 @@ Sven: ${foo:q}, 5208, preliminary
|
|||
|
||||
Sven: use ${foo:q} for quoting prefix and suffix in new completion, 5120
|
||||
|
||||
Me: bashautolist option, 5229; Sven's addition, 5234, and doc 5235; 5269
|
||||
pws: bashautolist option, 5229; Sven's addition, 5234, and doc 5235; 5269
|
||||
|
||||
Me: .zlogout doc, 5233
|
||||
pws: .zlogout doc, 5233
|
||||
|
||||
Me: added note on Linux Alpha with egcs to Etc/MACHINES, not posted
|
||||
pws: added note on Linux Alpha with egcs to Etc/MACHINES, not posted
|
||||
|
||||
Me: typeset -T fix, 5247
|
||||
pws: typeset -T fix, 5247
|
||||
|
||||
Bart: parameter scoping docs, 5258
|
||||
|
||||
|
@ -390,7 +390,7 @@ Sven: rewrite of $foo:q, 5265, +doc, 5284
|
|||
|
||||
Sven: get matcher number in new completion function, 5266
|
||||
|
||||
Me: interrupts in getquery() weren't gracefully handled, 5281
|
||||
pws: interrupts in getquery() weren't gracefully handled, 5281
|
||||
|
||||
pws-8
|
||||
|
||||
|
@ -409,14 +409,14 @@ Sven: compctl matcher to use reference counts, 5316
|
|||
|
||||
Sven: keys available in zle widget functions, 5320
|
||||
|
||||
Me: compctl -LM, 5321
|
||||
pws: compctl -LM, 5321
|
||||
|
||||
Me: revamped signames.c generation, 5326, 5329, plus Matt fix, 5330
|
||||
pws: revamped signames.c generation, 5326, 5329, plus Matt fix, 5330
|
||||
|
||||
Sweth, Bart, Me: Functions/allopt, basically as in 2121 with the odd
|
||||
emulate and local.
|
||||
|
||||
Me: emulate -L, 5332
|
||||
pws: emulate -L, 5332
|
||||
|
||||
Sven: printing of zle condition codes, 5335
|
||||
|
||||
|
@ -425,9 +425,9 @@ Sven: Modularisation of new completion shell code, 5341
|
|||
Sven: ignoring ignored prefix in new conditions, 5342; related fixes,
|
||||
5343
|
||||
|
||||
Me: patch for completion init and __normal, 5344; Sven fix, 5351
|
||||
pws: patch for completion init and __normal, 5344; Sven fix, 5351
|
||||
|
||||
Me: "$foo[@]" didn't remove the argument if $foo wasn't set, 5349;
|
||||
pws: "$foo[@]" didn't remove the argument if $foo wasn't set, 5349;
|
||||
Bart's fix so this works on OSes other than AIX, 5361
|
||||
|
||||
Sven: change fignore handling, 5352
|
||||
|
@ -437,14 +437,14 @@ failed, 5354
|
|||
|
||||
Sven: compadd -R function for suffix removal, 5355
|
||||
|
||||
Me: #key-* completions now allow 0 or more key bindings, 5362
|
||||
pws: #key-* completions now allow 0 or more key bindings, 5362
|
||||
|
||||
Me: Moved Misc/Completion to Functions/Completion; added some of my own
|
||||
pws: Moved Misc/Completion to Functions/Completion; added some of my own
|
||||
new-style completions: not posted
|
||||
|
||||
Me: 5281 now works, 5364
|
||||
pws: 5281 now works, 5364
|
||||
|
||||
Me: make dependencies for main.o, Makemod, zshpaths.h, 5365
|
||||
pws: make dependencies for main.o, Makemod, zshpaths.h, 5365
|
||||
|
||||
pws-9
|
||||
|
||||
|
@ -458,9 +458,9 @@ Andrej: Reliant UNIX configuration, 5377
|
|||
|
||||
Sven: Manual for new completion (so far), 5384, 5397
|
||||
|
||||
Me: dump new completion status for fast initialisation, 5393
|
||||
pws: dump new completion status for fast initialisation, 5393
|
||||
|
||||
Me: bug fixlet for __path_files, 5398
|
||||
pws: bug fixlet for __path_files, 5398
|
||||
|
||||
Sven: overhaul of do_ambiguous with some bug-fixage, 5399, 5407
|
||||
|
||||
|
@ -469,11 +469,11 @@ $COMPDUMP file, 5402
|
|||
|
||||
Sven: files -> __files, 5401
|
||||
|
||||
Me: magicequalsubst now affects all arguments ...=~...:~..., 5403
|
||||
pws: magicequalsubst now affects all arguments ...=~...:~..., 5403
|
||||
|
||||
Me: set -x output for [[ ... ]], 5408
|
||||
pws: set -x output for [[ ... ]], 5408
|
||||
|
||||
Me: IRIX 6.5 problems in Etc/MACHINES (see 5410 from Helmut Jarausch).
|
||||
pws: IRIX 6.5 problems in Etc/MACHINES (see 5410 from Helmut Jarausch).
|
||||
|
||||
Sven: 5412: better matcher control.
|
||||
|
||||
|
@ -483,7 +483,7 @@ Sven: 5417: multiple subscripts with undefined array
|
|||
|
||||
Sven: 5418: small addmatches fixes
|
||||
|
||||
Me: 5421: setting same element of assoc array in full array assignment crashed
|
||||
pws: 5421: setting same element of assoc array in full array assignment crashed
|
||||
|
||||
Sven: 5422: braces in completions were not tokenized; array parameters were
|
||||
used uncopied
|
||||
|
@ -492,14 +492,73 @@ Sven: 5423: compadd accepts either - or -- to end options
|
|||
|
||||
Sven: 5424: addmatches fix when not doing matching
|
||||
|
||||
Me: 5425: fix pattern matching for new completion
|
||||
pws: 5425: fix pattern matching for new completion
|
||||
|
||||
Sven: 5429: $CONTEXT strings
|
||||
|
||||
Sven: 5430: rewrite Functions/Completions with simplified syntax (no #array
|
||||
type completions).
|
||||
|
||||
Me: 5436: set -x for function calls and ((...)).
|
||||
pws: 5436: set -x for function calls and ((...)).
|
||||
|
||||
Me: unposted (but see 5440): zftp changes: more return 6's, functions now
|
||||
pws: unposted (but see 5440): zftp changes: more return 6's, functions now
|
||||
do auto-open and avoid subshells.
|
||||
|
||||
pws-10
|
||||
|
||||
Martin Buchholz: 5448: libc.h can't be included on Debian Linux, so only
|
||||
include it on NeXT where it's necessary.
|
||||
|
||||
Matt: 5330: I've put this back the way it original was. I hate sed almost
|
||||
as much as awk.
|
||||
|
||||
Sven: 5455: keep track of which matcher specification to use
|
||||
|
||||
Sven: 5466: compwid manual for -after and -between
|
||||
|
||||
Sven: 5467: expn manual typo
|
||||
|
||||
Sven: 5469: init fix and Functions/Completion/_comp_parts
|
||||
|
||||
Sven: 5470: new completion conditions didn't handle untokenization
|
||||
consistently.
|
||||
|
||||
Sven: 5471: range code knows not to handle associative arrays
|
||||
|
||||
Sven: 5476: quoting of tildes in Functions/Completion/_path_files
|
||||
|
||||
Sven: 5483: completeinword fixes
|
||||
|
||||
Sven: 5489: control for matching in _path_files and _comp_parts
|
||||
|
||||
Sven: 5490: unset test for AA elements when substituting
|
||||
|
||||
pws: unposted, see 5503: remove dynamic=no from configure.in when
|
||||
underscore is needed.
|
||||
|
||||
pws: 5508: init and dump, globbing and printing.
|
||||
|
||||
Sven: 5511: make sure compctl is available for new completion
|
||||
|
||||
Sven: 5512, 5525: globcomplete fix for new completion
|
||||
|
||||
Sven: 5521: improved option handling for _path_files
|
||||
|
||||
Sven: 5529: cleanup for Functions/Completion
|
||||
|
||||
pws: 5531: small init fix
|
||||
|
||||
pws: 5538: approximate pattern matching, (#a1)readme etc.
|
||||
|
||||
Sven: 5543: compadd -X, zshcompwid manual
|
||||
|
||||
Sven: 5544: another completion cleanup
|
||||
|
||||
pws: 5545: silly set -x mistake
|
||||
|
||||
Sven: 5548: _path_files, _comp_parts
|
||||
|
||||
Matt: 5553: under _WIN32, .exe suffix is optional for commands
|
||||
|
||||
pws: unposted: Functions/Completion moved to Completion; subdirectories
|
||||
Core, Base, Builtins, User, Commands created; Completion/README created.
|
||||
|
|
Loading…
Reference in a new issue