mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-16 08:48:06 +02:00
zsh-3.1.6-test-2
This commit is contained in:
parent
1f6786ef7a
commit
d6d4a3abfc
50 changed files with 821 additions and 295 deletions
ChangeLog
Completion
Config
Doc
Etc
Functions
INSTALLMisc
Src
configure.in
141
ChangeLog
141
ChangeLog
|
@ -1,5 +1,146 @@
|
|||
1999-07-19 Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
|
||||
* pws: version 3.1.6-test-2
|
||||
|
||||
* pws: 7192: Src/glob.c: bug with null in pattern if at end of
|
||||
test string (matched as if a real character).
|
||||
|
||||
1999-07-18 Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
|
||||
* pws: 7185: Src/glob.c: don't use strcoll() for character
|
||||
ranges [...] because it can have side effects.
|
||||
|
||||
* pws: 7184: Src/lex.c: histactive didn't get get zeroed before
|
||||
non-interactive history use, hence interactive lines with
|
||||
remhist() were junked more than once.
|
||||
|
||||
* Wayne: 7181: Doc/Zsh/options.y, Doc/Zsh/params.yo: history docs.
|
||||
|
||||
* Wayne: 7180: Src/Zle/complist.c, Src/utils.c: warnings.
|
||||
|
||||
1999-07-16 Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
|
||||
* pws: 7172: Doc/Zsh/options.yo, Src/builtin.c, Src/exec.c,
|
||||
Src/options.c, Src/utils.c, Src/zsh.h: minor bugs with
|
||||
7164 fixed; CHASE_DOTS resolves ..'s to physical path;
|
||||
CHASE_LINKS doesn't do logical path rationalization;
|
||||
xsymlink() and xsymlinks() simplified and option-dependence
|
||||
removed.
|
||||
|
||||
* Sven: 7171: Src/builtin.c: alternate form of Digital/gcc
|
||||
bug workaround.
|
||||
|
||||
1999-07-15 Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
|
||||
* pws: 7164: Src/builtin.c, Src/exec.c: AUTOCD now allows
|
||||
paths with symlinks (as real cd always did); simplify code
|
||||
for testing for existing directory on foo/.. before removing
|
||||
foo/..; as a side effect, relative cd's from directory which
|
||||
has been deleted don't work.
|
||||
|
||||
* Sven: 7161: Src/Zle/comp.h, Src/Zle/complist.c,
|
||||
Src/Zle/zle_tricky.c, Completion/Base/_brace_parameter:
|
||||
be more careful with quote-prefix/suffix and path-prefix/suffix
|
||||
especially with accept-and-menu-complete.
|
||||
|
||||
* pws: 7155: Functions/Zftp/zfgoto, Functions/Zftp/zfinit:
|
||||
zfgoto can cd without needing to re-login; zfinit uses
|
||||
zmodload -e to check for zftp.
|
||||
|
||||
* Sven: 7154: Src/Zle/complist.c, Src/Zle/zle_refresh.c,
|
||||
Src/Zle/zle_tricky.c, Doc/Zsh/mod_complist.yo: don't
|
||||
list too many times on ambiguous completion; don't do
|
||||
menu-selection if no alwayslastprompt behaviour.
|
||||
|
||||
1999-07-14 Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
|
||||
* pws: 7148: INSTALL: User subdirectory
|
||||
|
||||
* Thomas Köhler: 7146: Completion/User/_make: didn't work.
|
||||
|
||||
* pws: 7145: Completion/User/_sh: use compset -q for completing
|
||||
after -c option
|
||||
|
||||
* Sven: 7143: Src/Zle/complist.c, Src/Zle/zle_tricky.c:
|
||||
listing got confused with only hidden matches.
|
||||
|
||||
* Sven: 7141: Completion/Core/_path_files: if there are
|
||||
no completions in a valid directory when we have a path ending
|
||||
in /, use the directory as a completion, to avoid
|
||||
correction/approximation of the existing directory.
|
||||
|
||||
* pws: 7139: Src/builtin.c: not particularly pleasant fix
|
||||
to problem that `cd nonexistent/..' silently did nothing, while
|
||||
making `cd ..' work even if current directory has gone.
|
||||
|
||||
* Sven: 7138: Completion/User/_hosts, Completion/User/_x_options:
|
||||
_hosts passes arguments as options to compadd.
|
||||
|
||||
* Oliver: 7136: Completion/User/_rlogin,
|
||||
Completion/User/_x_options: use _hosts.
|
||||
|
||||
* Sven: 7135: Src/Zle/zle_tricky.c, Completion/Core/_path_files:
|
||||
change quoting of files again.
|
||||
|
||||
* Sven: 7133: Doc/Zsh/expn.yo, Doc/Zsh/mod_complist.yo:
|
||||
ZLS_COLOURS not required for complist to work.
|
||||
|
||||
* pws: 7127: configure.in: help now shows --disable-dynamic
|
||||
and --disable-lfs.
|
||||
|
||||
* Sven: 7126: Src/Zle/comp.h, Src/Zle/comp1.c, Src/Zle/compctl.c,
|
||||
Src/Zle/zle_tricky.c, Doc/Zsh/compwid.yo,
|
||||
Functions/Zle/incremental-complete-word: compstate key
|
||||
normal_nmatches; more i-c-w prompt escapes
|
||||
|
||||
* Sven: 7123: Src/Zle/zle_tricky.c: clear list on expansion
|
||||
failure.
|
||||
|
||||
1999-07-13 Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
|
||||
* pws: 7119: Src/Zle/zle_tricky.c: status from expansion
|
||||
functions.
|
||||
|
||||
* Sven: 7116: Doc/Zsh/compwid.yo, Doc/Zsh/expn.yo: minor
|
||||
changes.
|
||||
|
||||
* pws: 7114: Src/parse.c, Src/utils.c: line numbers again:
|
||||
flushing line in a script made lineno appear one too large;
|
||||
introduce zwarn() function.
|
||||
|
||||
* Sven/pws: 7112: Src/Zle/zle_params.c, Doc/Zsh/zle.yo: change
|
||||
array keys to scalar KEYS, works more like read -k;
|
||||
documentation.
|
||||
|
||||
* Sven: 7110: Src/Modules/zftp.c, Doc/Zsh/compsys.yo,
|
||||
Etc/MACHINES: signed char warnings in zftp; document
|
||||
_long_options options; Digital UNIX problem.
|
||||
|
||||
* Sven: 2432: Src/builtin.c: workaround Digital UNIX 4.0 +
|
||||
gcc 2.8.1 bug.
|
||||
|
||||
* Sven: zsh-users/2430: Etc/NEWS: mention chmod-like mode glob
|
||||
qualifier.
|
||||
|
||||
* Sven: 7108: Misc/job-control-tests: more tests
|
||||
|
||||
* Bart: 7107: configure.in: too many x's in lfs handling.
|
||||
|
||||
* Sven: 7106: Functions/Zle/incremental-complete-word: prompting
|
||||
changes.
|
||||
|
||||
* pws: unposted: update .distfiles and .cvsignore: _sh, _su
|
||||
zshcompsys.yo, zshcompwid.yo, zshzftp.yo, zshcompsys.1,
|
||||
zshcompwid.1, zshzftp.1 were missing from the distribution.
|
||||
|
||||
* Sven: 7105: Src/Zle/Zle_tricky.c: restore the command line
|
||||
in more places.
|
||||
|
||||
1999-07-12 Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
|
||||
* Sven: 7103: Src/Zle/zle_tricky.c, Doc/Zsh/compwid.yo: update
|
||||
CURRENT with compset -q; modify test for quoted delimiters.
|
||||
|
||||
* pws: version 3.1.6-test-1
|
||||
|
||||
* Sven: 7099: Completion/Core/_main_complete, Doc/Zsh/compsys.yo:
|
||||
|
|
1
Completion/.cvsignore
Normal file
1
Completion/.cvsignore
Normal file
|
@ -0,0 +1 @@
|
|||
Makefile
|
|
@ -1,3 +1,3 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles README Makefile.in
|
||||
.cvsignore .distfiles README Makefile.in
|
||||
'
|
||||
|
|
|
@ -18,4 +18,4 @@ q=${(M)lp%%\"#}
|
|||
|
||||
[[ n -gt 0 ]] && suf=''
|
||||
|
||||
_parameters -s "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/'
|
||||
_parameters -Qs "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/'
|
||||
|
|
|
@ -244,7 +244,7 @@ for prepath in "$prepaths[@]"; do
|
|||
if [[ "$tmp2[1]" = */* ]]; then
|
||||
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
|
||||
if [[ "$tmp2[1]" = */* ]]; then
|
||||
exppaths=( "$exppaths[@]" ${^tmp2:h}/${tpre}${tsuf} )
|
||||
exppaths=( "$exppaths[@]" ${^tmp2:h:q}/${tpre}${tsuf} )
|
||||
else
|
||||
exppaths=( "$exppaths[@]" ${tpre}${tsuf} )
|
||||
fi
|
||||
|
@ -252,6 +252,18 @@ for prepath in "$prepaths[@]"; do
|
|||
continue 2
|
||||
fi
|
||||
elif (( ! $#tmp1 )); then
|
||||
# A little extra hack: if we were completing `foo/<TAB>' and `foo'
|
||||
# contains no files, this will normally produce no matches and other
|
||||
# completers might think that's it's their time now. But if the next
|
||||
# completer is _correct or something like that, this will result in
|
||||
# an attempt to correct a valid directory name. So we just add the
|
||||
# original string in such a case so that the command line doesn't
|
||||
# change but other completers still think there are matches.
|
||||
|
||||
if [[ -z "$tpre$tsuf" && "$pre" = */ && -z "$suf" ]]; then
|
||||
compadd -nQS '' - "$linepath$donepath$orig"
|
||||
tmp4=-
|
||||
fi
|
||||
continue 2
|
||||
fi
|
||||
|
||||
|
@ -310,33 +322,33 @@ for prepath in "$prepaths[@]"; do
|
|||
if [[ -n $menu ]]; then
|
||||
[[ -n "$compconfig[path_cursor]" ]] && compstate[to_end]=''
|
||||
if [[ "$tmp3" = */* ]]; then
|
||||
compadd -Uf -p "$linepath$testpath" -s "/${tmp3#*/}" \
|
||||
compadd -QUf -p "$linepath${testpath:q}" -s "/${tmp3#*/}" \
|
||||
-W "$prepath$realpath$testpath" "$ignore[@]" \
|
||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" -M 'r:|/=* r:|=*' \
|
||||
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
- "${(@)tmp1%%/*}"
|
||||
- "${(@)${(@)tmp1%%/*}:q}"
|
||||
else
|
||||
compadd -Uf -p "$linepath$testpath" \
|
||||
compadd -QUf -p "$linepath${testpath:q}" \
|
||||
-W "$prepath$realpath$testpath" "$ignore[@]" \
|
||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
||||
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
- "$tmp1[@]"
|
||||
- "${(@)tmp1:q}"
|
||||
fi
|
||||
else
|
||||
if [[ "$tmp3" = */* ]]; then
|
||||
for i in "$tmp1[@]"; do
|
||||
compadd -Uf -p "$linepath$testpath" -s "/${i#*/}" \
|
||||
compadd -QUf -p "$linepath${testpath:q}" -s "/${${i#*/}:q}" \
|
||||
-W "$prepath$realpath$testpath" "$ignore[@]" \
|
||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" -M 'r:|/=* r:|=*' \
|
||||
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
- "${i%%/*}"
|
||||
- "${${i%%/*}:q}"
|
||||
done
|
||||
else
|
||||
compadd -Uf -p "$linepath$testpath" \
|
||||
compadd -QUf -p "$linepath${testpath:q}" \
|
||||
-W "$prepath$realpath$testpath" "$ignore[@]" \
|
||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
||||
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
- "$tmp1[@]"
|
||||
- "${(@)tmp1:q}"
|
||||
fi
|
||||
fi
|
||||
tmp4=-
|
||||
|
@ -361,11 +373,11 @@ for prepath in "$prepaths[@]"; do
|
|||
done
|
||||
|
||||
if [[ -z "$tmp4" ]]; then
|
||||
compadd -Uf -p "$linepath$testpath" \
|
||||
compadd -QUf -p "$linepath${testpath:q}" \
|
||||
-W "$prepath$realpath$testpath" "$ignore[@]" \
|
||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
||||
"$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
- "$tmp1[@]"
|
||||
- "${(@)tmp1:q}"
|
||||
fi
|
||||
done
|
||||
|
||||
|
@ -376,9 +388,9 @@ done
|
|||
exppaths=( "${(@)exppaths:#$orig}" )
|
||||
|
||||
if [[ -n "$compconfig[path_expand]" &&
|
||||
$#exppaths -eq 1 && nm -eq compstate[nmatches] ]]; then
|
||||
$#exppaths -gt 0 && nm -eq compstate[nmatches] ]]; then
|
||||
compadd -QU -S '' "$group[@]" "$expl[@]" -i "$IPREFIX" -I "$ISUFFIX" \
|
||||
-M 'r:|/=* r:|=*' -p "$linepath" - "${(@)exppaths}"
|
||||
-M 'r:|/=* r:|=*' -p "$linepath" - "$exppaths[@]"
|
||||
fi
|
||||
|
||||
[[ nm -ne compstate[nmatches] ]]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles
|
||||
_a2ps _chown _compress _configure _dd _dvi _find _groups _gunzip _gzip
|
||||
_hosts _use_lo _make _man _mh _pdf _ps _rcs _rlogin _strip _stty
|
||||
_a2ps _chown _compress _configure _dd _dvi _find
|
||||
_gdb _groups _gunzip _gzip
|
||||
_hosts _use_lo _make _man _mh _pdf _ps
|
||||
_rcs _rlogin _sh _strip _stty _su
|
||||
_tar _tar_archive _tex _uncompress _x_options _xfig
|
||||
'
|
||||
|
|
50
Completion/User/_gdb
Normal file
50
Completion/User/_gdb
Normal file
|
@ -0,0 +1,50 @@
|
|||
#compdef gdb
|
||||
|
||||
# This uses the configuration keys `ps_args' and `ps_listargs'
|
||||
# described in the `_wait' function.
|
||||
|
||||
local cur="$words[CURRENT]" prev w list ret=1
|
||||
|
||||
_long_options -t '*=(CORE|SYM)FILE' '_files' \
|
||||
'*=EXECFILE' '_files *(*)' \
|
||||
'*=TTY' 'compadd /dev/tty*' && return 0
|
||||
|
||||
if compset -P '-(cd|directory)='; then
|
||||
_files -/
|
||||
elif compset -P '-tty='; then
|
||||
compadd - /dev/tty*
|
||||
elif compset -P '-(exec|se)='; then
|
||||
_files -/g '*(*)'
|
||||
elif compset -P '-(symbols|core|command)='; then
|
||||
_files
|
||||
elif compset -P -; then
|
||||
compadd -QS '' - symbols\= exec\= se\= core\= command\= directory\= \
|
||||
cd\= tty\=
|
||||
compadd - help h s e c x d nx n quiet q batch fullname f b
|
||||
else
|
||||
prev="$words[CURRENT-1]"
|
||||
|
||||
case "$prev" in
|
||||
(-d) _files -/ && return 0 ;;
|
||||
(-e) _files -/g '*(*)' && return 0 ;;
|
||||
(-[csx]) _files && return 0 ;;
|
||||
(-b) compadd -V baud 0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 \
|
||||
9600 19200 38400 57600 115200 230400 && return 0 ;;
|
||||
esac
|
||||
w=( "${(@)words[2,-1]}" )
|
||||
while [[ "$w[1]" = -* ]]; do
|
||||
[[ "$w[1]" = -[decsxb] ]] && shift 1 w
|
||||
shift 1 w
|
||||
done
|
||||
|
||||
if [[ $#w -gt 1 ]]; then
|
||||
_files && ret=0
|
||||
list=("${(F)${(@Mr:COLUMNS-1:)${(f)$(ps ${compconfig[ps_listargs]:-$compconfig[ps_args]} 2>/dev/null)}[2,-1]:#[ ]#${PREFIX}[0-9]#${SUFFIX}[ ]*${w[1]:t}}}
|
||||
")
|
||||
compadd -y list - ${${${(M)${(f)"$(ps $compconfig[ps_args] 2>/dev/null)"}:#*${w[1]:t}*}## #}%% *} && ret=0
|
||||
|
||||
return ret
|
||||
else
|
||||
_files -/g '*(*)'
|
||||
fi
|
||||
fi
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
: ${(A)hosts:=${(s: :)${(ps:\t:)${${(f)"$(</etc/hosts)"}%%\#*}##[:blank:]#[^[:blank:]]#}}}
|
||||
|
||||
compgen -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' -k hosts
|
||||
compadd -M 'm:{a-zA-Z}={A-Za-z} r:|.=* r:|=*' "$@" - "$hosts[@]"
|
||||
|
|
|
@ -19,6 +19,6 @@ else
|
|||
fi
|
||||
|
||||
[[ -n "$file" ]] &&
|
||||
compadd - $(awk '/^[a-zA-Z0-9][^/ ]+:/ {print $1}' FS=: $file) && ret=0
|
||||
compadd - $(awk '/^[a-zA-Z0-9][^\/ ]+:/ {print $1}' FS=: $file) && ret=0
|
||||
(( ret )) && _files
|
||||
fi
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#compdef rlogin rsh ssh
|
||||
|
||||
if [[ CURRENT -eq 2 ]]; then
|
||||
compgen -k hosts
|
||||
_hosts
|
||||
elif [[ CURRENT -eq 3 ]]; then
|
||||
compadd - -l
|
||||
else
|
||||
|
|
8
Completion/User/_sh
Normal file
8
Completion/User/_sh
Normal file
|
@ -0,0 +1,8 @@
|
|||
#compdef sh ksh bash zsh csh tcsh rc
|
||||
|
||||
if (( CURRENT == ${words[(i)-c]} + 1 )); then
|
||||
compset -q
|
||||
_normal
|
||||
else
|
||||
_default
|
||||
fi
|
22
Completion/User/_su
Normal file
22
Completion/User/_su
Normal file
|
@ -0,0 +1,22 @@
|
|||
#compdef su
|
||||
|
||||
local shell comp name usr base
|
||||
|
||||
[[ $words[2] != - ]]
|
||||
(( base=$?+2 ))
|
||||
|
||||
if [[ CURRENT -eq base ]]; then
|
||||
compgen -u && return
|
||||
usr=root
|
||||
elif [[ CURRENT -ge base+1 ]]; then
|
||||
usr=$words[base]
|
||||
else
|
||||
return
|
||||
fi
|
||||
|
||||
shell=${"$(egrep "^$usr:" </etc/passwd)"##*:}
|
||||
compset -n $base
|
||||
for name in $shell $shell:t -default-; do
|
||||
comp="$_comps[$name]"
|
||||
[[ ! -z "$comp" ]] && "$comp" && return
|
||||
done
|
|
@ -3,7 +3,8 @@
|
|||
# A simple pattern completion, just as an example.
|
||||
|
||||
if [ "$words[CURRENT-1]" = "-display" ]; then
|
||||
compgen -k hosts -S':0'
|
||||
_compskip=''
|
||||
_hosts -S :0
|
||||
else
|
||||
compadd -J options - -display -name -xrm
|
||||
compadd -P- -J options - display name xrm
|
||||
fi
|
||||
|
|
|
@ -27,5 +27,5 @@
|
|||
# This must also serve as a shell script, so do not add spaces around the
|
||||
# `=' signs.
|
||||
|
||||
VERSION=3.1.6-test-1
|
||||
VERSION_DATE='July 9, 1999'
|
||||
VERSION=3.1.6-test-2
|
||||
VERSION_DATE='July 19, 1999'
|
||||
|
|
|
@ -2,11 +2,13 @@ DISTFILES_SRC='
|
|||
.cvsignore .distfiles Makefile.in
|
||||
META-FAQ.yo intro.ms
|
||||
version.yo zmacros.yo zman.yo ztexi.yo
|
||||
zsh.yo zshbuiltins.yo zshcompctl.yo zshexpn.yo zshmisc.yo
|
||||
zshmodules.yo zshoptions.yo zshparam.yo zshzle.yo
|
||||
zsh.yo zshbuiltins.yo zshcompctl.yo zshcompsys.yo zshcompwid.yo
|
||||
zshexpn.yo zshmisc.yo zshmodules.yo zshoptions.yo zshparam.yo
|
||||
zshzftpsys.yo zshzle.yo
|
||||
zsh.texi
|
||||
zsh.1 zshbuiltins.1 zshcompctl.1 zshexpn.1 zshmisc.1 zshmodules.1
|
||||
zshoptions.1 zshparam.1 zshzle.1 zshall.1
|
||||
zsh.1 zshbuiltins.1 zshcompctl.1 zshcompsys.1 zshcompwid.1 zshexpn.1
|
||||
zshmisc.1 zshmodules.1 zshoptions.1 zshparam.1 zshzle.1 zshall.1
|
||||
zshzftpsys.1
|
||||
'
|
||||
|
||||
DISTFILES_DOC='
|
||||
|
|
|
@ -31,7 +31,7 @@ next section.
|
|||
|
||||
Usually, tt(compinstall) will insert code into tt(.zshrc), although if
|
||||
that is not writable it will save it in another file and tell you that
|
||||
file's locations. Note that it is up to you to make sure that the lines
|
||||
file's location. Note that it is up to you to make sure that the lines
|
||||
added to tt(.zshrc) are actually run; you may, for example, need to move
|
||||
them to an earlier place in the file if tt(.zshrc) usually returns early.
|
||||
So long as you keep them all together (including the comment lines at the
|
||||
|
@ -92,7 +92,7 @@ will only need to run this yourself if you change the configuration
|
|||
(e.g. using tt(compdef)) and then want to dump the new one. The name of
|
||||
the old dumped file will be remembered for this purpose.
|
||||
|
||||
If the parameter tt(_compdir) is set, tt(compinit) uses it has a directory
|
||||
If the parameter tt(_compdir) is set, tt(compinit) uses it as a directory
|
||||
where completion functions can be found; this is only necessary if they are
|
||||
not already in the function search path.
|
||||
|
||||
|
@ -489,7 +489,7 @@ non-empty string it should be an expression usable inside a `tt($((...)))'
|
|||
arithmetical expression. In this case, expansion of substitutions will
|
||||
be done if the expression evaluates to `tt(1)'. For example, with
|
||||
|
||||
example(compconf expand_substitute='NUMERIC != 1')
|
||||
example(compconf expand_substitute='${NUMERIC:-1} != 1')
|
||||
|
||||
substitution will be performed only if given an explicit numeric
|
||||
argument other than `tt(1)', as by typing `tt(ESC 2 TAB)'.
|
||||
|
@ -720,8 +720,8 @@ is used.
|
|||
)
|
||||
item(tt(_parameters))(
|
||||
This should be used to complete parameter names if you need some of the
|
||||
extra options of tt(compadd). It first tries to complete only non-local
|
||||
parameters. All arguments are passed unchanged to the tt(compadd) builtin.
|
||||
extra options of tt(compadd). All arguments are passed unchanged to
|
||||
the tt(compadd) builtin.
|
||||
)
|
||||
item(tt(_options))(
|
||||
This can be used to complete option names. The difference to the
|
||||
|
@ -780,9 +780,19 @@ descriptions that contain `tt(=DIR)' or `tt(=PATH)'. These builtin
|
|||
patterns can be overridden by patterns given as arguments, however.
|
||||
|
||||
This function also accepts the `tt(-X)', `tt(-J)', and `tt(-V)'
|
||||
options which are passed unchanged to `tt(compadd)'. Finally, it
|
||||
accepts the option `tt(-t)'; if this is given, completion is only done
|
||||
on words starting with two hyphens.
|
||||
options which are passed unchanged to `tt(compadd)'. If the
|
||||
option `tt(-t)' is given, completion is only done on words starting
|
||||
with two hyphens. The option `tt(-i) var(patterns)' can be used to
|
||||
give patterns for options which should not be completed. The patterns
|
||||
can be given as the name of an array parameter or as a literal list in
|
||||
parentheses. E.g. `tt(-i "(--(en|dis)able-FEATURE*)")' will ignore the
|
||||
options `tt(--enable-FEATURE)' and `tt(--diable-FEATURE)'. Finally,
|
||||
the option `tt(-s) var(pairs)' can be used to describe options
|
||||
aliases. Each var(pair) consists of a pattern and a
|
||||
replacement. E.g. some tt(configure)-scripts describe options only as
|
||||
`tt(--enable-foo)', but also accept `tt(disable-foo)'. To allow
|
||||
completion of the second form, one would use
|
||||
`tt(-s "(#--enable- --disable-)")'.
|
||||
)
|
||||
enditem()
|
||||
|
||||
|
|
|
@ -175,6 +175,12 @@ is unset.
|
|||
item(tt(nmatches))(
|
||||
The number of matches generated and accepted by the completion code so far.
|
||||
)
|
||||
item(tt(normal_nmatches))(
|
||||
Like tt(nmatches), but counts only matches in the normal set. I.e. file
|
||||
names with one of the suffixes from the tt(fignore) array and matches
|
||||
put into the alternate set using the tt(-a) option of the tt(compadd)
|
||||
builtin command (see below) are not counted.
|
||||
)
|
||||
item(tt(matcher))(
|
||||
When completion is performed with a global match specification as defined
|
||||
by
|
||||
|
@ -410,7 +416,7 @@ item(tt(-I) var(ignored-suffix))(
|
|||
Like tt(-i), but gives an ignored suffix.
|
||||
)
|
||||
item(tt(-y) var(array))(
|
||||
This gives a number of string to display instead of the matches. This
|
||||
This gives a number of strings to display instead of the matches. This
|
||||
is like the tt(-y) option of the tt(compctl) builtin command but the
|
||||
var(array) argument may only be the name of an array parameter or a
|
||||
literal array in parentheses containing the strings to display.
|
||||
|
@ -483,7 +489,7 @@ from the first set are stored. Normally only the matches in the first
|
|||
set are used, but if this set is empty, the words from the alternate
|
||||
set are used.
|
||||
|
||||
The tt(compadd) builtin does not use tt(fignore) parameter and
|
||||
The tt(compadd) builtin does not use the tt(fignore) parameter and
|
||||
normally stores all words in the first set. With the tt(-a)-flag
|
||||
given, however, the given var(words) are stored in the alternate set unless
|
||||
this flag is overridden by the tt(-F) option.
|
||||
|
@ -518,7 +524,7 @@ will be done by the completion code. Normally this is used in
|
|||
functions that do the matching themselves.
|
||||
|
||||
Note that with tt(compadd) this option does not automatically turn on
|
||||
menu completion if tt(AUTO_LIST), unlike the corresponding option of
|
||||
menu completion if tt(AUTO_LIST) is set, unlike the corresponding option of
|
||||
tt(compctl) and tt(compgen) commands.
|
||||
)
|
||||
item(tt(-O) var(array))(
|
||||
|
@ -622,9 +628,9 @@ testing and modification is performed as if it were not given.
|
|||
item(tt(-q))(
|
||||
The word
|
||||
currently being completed is split in separate words at the spaces. The
|
||||
resulting words are stored in the tt(words) array, and tt(PREFIX),
|
||||
tt(SUFFIX), tt(QIPREFIX), and tt(QISUFFIX) are modified to reflect the
|
||||
word part that is completed.
|
||||
resulting words are stored in the tt(words) array, and tt(CURRENT),
|
||||
tt(PREFIX), tt(SUFFIX), tt(QIPREFIX), and tt(QISUFFIX) are modified to
|
||||
reflect the word part that is completed.
|
||||
)
|
||||
enditem()
|
||||
|
||||
|
|
|
@ -1192,7 +1192,7 @@ 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
|
||||
strings of length two, 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
|
||||
|
@ -1351,7 +1351,7 @@ bit.
|
|||
|
||||
Thus, `tt(*(f70?))' gives the files for which the owner has read,
|
||||
write, and execute permission, and for which other group members have
|
||||
no rights, independent of the permissions for other user. The pattern
|
||||
no rights, independent of the permissions for other users. The pattern
|
||||
`tt(*(f-100))' gives all files for which the owner does not have
|
||||
execute permission, and `tt(*(f:gu+w,o-rx))' gives the files for which
|
||||
the owner and the other members of the group have at least write
|
||||
|
@ -1455,7 +1455,7 @@ returned list. The syntax is the same as for array
|
|||
subscripts. var(beg) and the optional var(end) may be mathematical
|
||||
expressions. As in parameter subscripting they may be negative to make
|
||||
them count from the last match backward. E.g.: `tt(*(-OL[1,3]))'
|
||||
gives a list of the names of three biggest files.
|
||||
gives a list of the names of the three largest files.
|
||||
)
|
||||
enditem()
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ not automatically be loaded if it is not linked in: on systems with
|
|||
dynamic loading, `tt(zmodload complist)' is required.
|
||||
|
||||
subsect(Parameters)
|
||||
For both extensions one of the parameters tt(ZLS_COLORS) or tt(ZLS_COLOURS)
|
||||
must be set, even if the value is empty (which uses all the default values
|
||||
given below). These describe how matches are highlighted. The format of the
|
||||
The parameters tt(ZLS_COLORS) and tt(ZLS_COLOURS) describe how matches
|
||||
are highlighted. To turn on highlighting an empty value suffices, in
|
||||
which case all the default values given below will be used. The format of the
|
||||
value of these parameters is the same as used by the GNU version of the
|
||||
tt(ls) command: a colon-separated list of specifications of the form
|
||||
`var(name)=var(value)'. The var(name) may be one of the following strings,
|
||||
|
@ -79,7 +79,12 @@ the default values will have no visual effect.
|
|||
|
||||
subsect(Menu selection)
|
||||
The tt(complist) module also offers an alternative style of selecting
|
||||
matches from a list, called menu-selection. It can be invoked directly by
|
||||
matches from a list, called menu-selection, which can be used if the
|
||||
shell is set up to return to the last prompt after showing a
|
||||
completion list (see the tt(ALWAYS_LAST_PROMPT) option in
|
||||
ifzman(zmanref(zshoptions))\
|
||||
ifnzman(noderef(Options))\
|
||||
). It can be invoked directly by
|
||||
the widget tt(menu-select) defined by the module. Alternatively,
|
||||
the parameter tt(SELECTMIN) can be set to an integer, which give the
|
||||
minimum number of matches that must be present before menu selection is
|
||||
|
|
|
@ -205,11 +205,30 @@ tt(AUTO_CD) option set) is not a directory, and does not begin with a
|
|||
slash, try to expand the expression as if it were preceded by a `tt(~)' (see
|
||||
noderef(Filename Expansion)).
|
||||
)
|
||||
pindex(CHASE_DOTS)
|
||||
cindex(cd, with .. in argument)
|
||||
item(tt(CHASE_DOTS))(
|
||||
When changing to a directory containing a path segment `tt(..)' which would
|
||||
otherwise be treated as cancelling the previous segment in the path (in
|
||||
other words, `tt(foo/..)' would be removed from the path, or if `tt(..)' is
|
||||
the first part of the path, the last part of tt($PWD) would be deleted),
|
||||
instead resolve the path to the physical directory. This option is
|
||||
overridden by tt(CHASE_LINKS).
|
||||
|
||||
For example, suppose tt(/foo/bar) is a link to the directory tt(/alt/rod).
|
||||
Without this option set, `tt(cd /foo/bar/..)' changes to tt(/foo); with it
|
||||
set, it changes to tt(/alt). The same applies if the current directory
|
||||
is tt(/foo/bar) and `tt(cd ..)' is used. Note that all other symbolic
|
||||
links in the path will also be resolved.
|
||||
)
|
||||
pindex(CHASE_LINKS)
|
||||
cindex(links, symbolic)
|
||||
cindex(symbolic links)
|
||||
item(tt(CHASE_LINKS) (tt(-w)))(
|
||||
Resolve symbolic links to their true values when changing directory.
|
||||
This also has the effect of tt(CHASE_DOTS), i.e. a `tt(..)' path segment
|
||||
will be treated as referring to the physical parent, even if the preceeding
|
||||
path segment is a symbolic link.
|
||||
)
|
||||
pindex(CLOBBER)
|
||||
cindex(clobbering, of files)
|
||||
|
@ -416,9 +435,13 @@ isn't there.
|
|||
pindex(HIST_EXPIRE_DUPS_FIRST)
|
||||
cindex(history, expiring duplicates)
|
||||
item(tt(HIST_EXPIRE_DUPS_FIRST))(
|
||||
If the internal history needs to be trimmed to add a new line,
|
||||
setting this option will cause the oldest duplicate history line to
|
||||
be lost before losing a unique line from the list.
|
||||
If the internal history needs to be trimmed to add the current command line,
|
||||
setting this option will cause the oldest history event that has a duplicate
|
||||
to be lost before losing a unique event from the list.
|
||||
You should be sure to set the value of tt(HISTSIZE) to a larger number
|
||||
than tt(SAVEHIST) in order to give you some room for the duplicated
|
||||
events, otherwise this option will behave just like
|
||||
tt(HIST_IGNORE_ALL_DUPS) once the history fills up with unique events.
|
||||
)
|
||||
pindex(HIST_IGNORE_ALL_DUPS)
|
||||
cindex(history, ignoring all duplicates)
|
||||
|
|
|
@ -507,7 +507,10 @@ If unset, the history is not saved.
|
|||
)
|
||||
vindex(HISTSIZE)
|
||||
item(tt(HISTSIZE) <S>)(
|
||||
The maximum size of the history list.
|
||||
The maximum number of events stored in the internal history list.
|
||||
If you use the tt(HIST_EXPIRE_DUPS_FIRST) option, setting this value
|
||||
larger than the tt(SAVEHIST) size will give you the difference as a
|
||||
cushion for saving duplicated history events.
|
||||
)
|
||||
vindex(HOME)
|
||||
item(tt(HOME) <S>)(
|
||||
|
|
|
@ -154,12 +154,9 @@ vindex(LASTWIDGET)
|
|||
item(tt(LASTWIDGET) (scalar))(
|
||||
The name of the last widget that was executed.
|
||||
)
|
||||
vindex(keys)
|
||||
item(tt(keys) (array))(
|
||||
The keys typed to invoke this widget, one element per
|
||||
key. Control-keys are reported with a leading `tt(^)', as in `tt(^A)',
|
||||
and meta-keys are reported with a leading `tt(M-)', as in `tt(M-a)' and
|
||||
`tt(M-^A)'.
|
||||
vindex(KEYS)
|
||||
item(tt(KEYS) (scalar))(
|
||||
The keys typed to invoke this widget, as a literal string.
|
||||
)
|
||||
vindex(NUMERIC)
|
||||
item(tt(NUMERIC) (integer))(
|
||||
|
|
13
Etc/MACHINES
13
Etc/MACHINES
|
@ -39,15 +39,21 @@ DEC: OSF/1 1.2, 1.3, 2.0, 3.*, DEC Unix 4.* (Alpha)
|
|||
remove the bogus strip and use /bin/strip instead.
|
||||
|
||||
On Digital UNIX 4.0, compilation with gcc and with --enable-dynamic
|
||||
apparently needs configuring with explicit flags:
|
||||
apparently needs configuring with explicit flags when compiling
|
||||
with debugging enabled:
|
||||
DLLD=gcc LDFLAGS='-g -rpath <path-to-.so-files>' ./configure ...
|
||||
|
||||
FreeBSD: FreeBSD 2.2.7 [3.1.4]
|
||||
Should build `out-of-the-box'.
|
||||
|
||||
HP: HP-UX 9, 10.20
|
||||
HP: HP-UX 9, 10.20, 11.0
|
||||
Should build `out-of-the-box'.
|
||||
|
||||
Problems with dynamic loading have been reported under 11, but
|
||||
this should compile using the standard dlopen() function set
|
||||
(rather than the 10.20 shl_load() function set). More details of
|
||||
any difficulties would be appreciated.
|
||||
|
||||
IBM: AIX
|
||||
Should build `out-of-the-box'. On AIX 3.x (at least),
|
||||
--enable-zsh-mem will not work.
|
||||
|
@ -87,9 +93,6 @@ SGI: IRIX 5.1.1.1, 5.2, 5.3, 6.2, 6.3, 6.5
|
|||
full optimization (cc -O3 -OPT:Olimit=0) causes problems.
|
||||
|
||||
Sun: SunOS 4.1.*
|
||||
Dynamic loading does not work under SunOS 4.1. Sometimes,
|
||||
you may need to turn it off explicitly with --disable-dynamic.
|
||||
|
||||
Under 4.1.3 if yellow pages is used, username completion may cause
|
||||
segmentation violation. This is a bug in the shared library not
|
||||
in zsh. Some libc.so.1.9.* has this bug (it fails in yp_all).
|
||||
|
|
1
Etc/NEWS
1
Etc/NEWS
|
@ -34,6 +34,7 @@ Globbing changes:
|
|||
- Case-insensitive and approximate globbing.
|
||||
- Ordering and indexing of globbing matches, e.g. *(om[1]) picks
|
||||
most recently modified file.
|
||||
- General file mode qualifier with chmod(1)-like syntax, e.g. *(f:u+wx:)
|
||||
|
||||
New loadable modules:
|
||||
- zftp, plus associated function suite, for turning your zsh session
|
||||
|
|
1
Functions/.cvsignore
Normal file
1
Functions/.cvsignore
Normal file
|
@ -0,0 +1 @@
|
|||
Makefile
|
|
@ -1,3 +1,3 @@
|
|||
DISTFILES_SRC='
|
||||
.distfiles Makefile.in README.zftp
|
||||
.cvsignore .distfiles Makefile.in README.zftp
|
||||
'
|
||||
|
|
|
@ -67,7 +67,10 @@ line=${line#*@}
|
|||
host=${line%%:*}
|
||||
dir=${line#*:}
|
||||
|
||||
if [[ $user = ftp || $user = anonymous ]]; then
|
||||
if [[ $ZFTP_USER = $user && $ZFTP_HOST = $host ]]; then
|
||||
# We're already there, just change directory
|
||||
zfcd ${dir:-~}
|
||||
elif [[ $user = ftp || $user = anonymous ]]; then
|
||||
# Anonymous ftp, so we don't need password etc.
|
||||
zfanon $host && [[ -n $dir ]] && zfcd $dir
|
||||
elif [[ $zflastsession = ${host}:* && $user = $zflastuser ]]; then
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
emulate -L zsh
|
||||
|
||||
[[ $1 = -n ]] || zmodload -ia zftp
|
||||
[[ $1 = -n ]] || zmodload -e zftp || zmodload -ia zftp
|
||||
|
||||
alias zfcd='noglob zfcd'
|
||||
alias zfget='noglob zfget'
|
||||
|
|
|
@ -4,32 +4,55 @@
|
|||
# to a key.
|
||||
|
||||
# This allows incremental completion of a word. After starting this
|
||||
# command, a list of completion choices is shown after every character you
|
||||
# type, which you can delete with ^h or DEL. RET will accept the
|
||||
# completion so far. You can hit TAB to do normal completion and ^g to
|
||||
# abort back to the state when you started.
|
||||
# command, a list of completion choices can be shown after every character
|
||||
# you type, which you can delete with ^h or DEL. RET will accept the
|
||||
# completion so far. You can hit TAB to do normal completion, ^g to
|
||||
# abort back to the state when you started, and ^d to list the matches.
|
||||
#
|
||||
# Completion keys:
|
||||
# incremental_prompt Prompt to show in status line during icompletion;
|
||||
# the sequence `%u' is replaced by the unambiguous
|
||||
# part of all matches if there is any and it is
|
||||
# different from the word on the line
|
||||
# incremental_stop Pattern matching keys which will cause icompletion
|
||||
# to stop and the key to be re-executed
|
||||
# incremental_break Pattern matching keys which will cause icompletion
|
||||
# to stop and the key to be discarded
|
||||
# incremental_completer Set of completers, like the `completer' key
|
||||
# incremental_list If set to a non-empty string, the matches will be
|
||||
# listed on every key-press
|
||||
# This works best with the new function based completion system.
|
||||
#
|
||||
# Configuration keys:
|
||||
#
|
||||
# incremental_prompt
|
||||
# Prompt to show in status line during icompletion. The sequence `%u'
|
||||
# is replaced by the unambiguous part of all matches if there is any
|
||||
# and it is different from the word on the line. A `%s' is replaced
|
||||
# with `-no match-', `-no prefix-', or an empty string if there is
|
||||
# no completion matching the word on the line, if the matches have
|
||||
# no common prefix different from the word on the line or if there is
|
||||
# such a common prefix, respectively. The sequence `%c' is replaced
|
||||
# by the name of the completer function that generated the matches
|
||||
# (without the leading underscore). Finally, `%n' is replaced by the
|
||||
# number of matches generated and `%a' is replaced by an empty string
|
||||
# if the matches are in the normal set (i.e. the one without file names
|
||||
# with one of the suffixes from `fignore') and with ` -alt-' if the
|
||||
# matches are in the alternate set.
|
||||
#
|
||||
# incremental_stop
|
||||
# Pattern matching keys which will cause icompletion to stop and the
|
||||
# key to be re-executed.
|
||||
#
|
||||
# incremental_break
|
||||
# Pattern matching keys which will cause icompletion to stop and the
|
||||
# key to be discarded.
|
||||
#
|
||||
# incremental_completer
|
||||
# Set of completers, like the `completer' key for normal completion.
|
||||
#
|
||||
# incremental_list
|
||||
# If set to a non-empty string, the matches will be listed on every
|
||||
# key-press.
|
||||
|
||||
|
||||
emulate -L zsh
|
||||
unsetopt autolist menucomplete automenu # doesn't work well
|
||||
|
||||
local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word lastl lastr wid twid
|
||||
local key lbuf="$LBUFFER" rbuf="$RBUFFER" pmpt word
|
||||
local lastl lastr wid twid num alt
|
||||
|
||||
[[ -n "$compconfig[incremental_completer]" ]] &&
|
||||
set ${(s.:.)compconfig[incremental_completer]}
|
||||
pmpt="${compconfig[incremental_prompt]-incremental completion...}"
|
||||
set ${(s.:.)compconfig[incremental_completer]}
|
||||
pmpt="${compconfig[incremental_prompt]-incremental (%c): %u%s}"
|
||||
|
||||
if [[ -n "$compconfig[incremental_list]" ]]; then
|
||||
wid=list-choices
|
||||
|
@ -40,12 +63,22 @@ fi
|
|||
zle $wid "$@"
|
||||
LBUFFER="$lbuf"
|
||||
RBUFFER="$rbuf"
|
||||
if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
|
||||
if (( ! _lastcomp[nmatches] )); then
|
||||
word=''
|
||||
state='-no match-'
|
||||
elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
|
||||
word=''
|
||||
state='-no prefix-'
|
||||
else
|
||||
word="${_lastcomp[unambiguous]}"
|
||||
state=''
|
||||
fi
|
||||
zle -R "${pmpt//\\%u/$word}"
|
||||
num=$_lastcomp[normal_nmatches]
|
||||
if (( ! num )); then
|
||||
num="${_lastcomp[nmatches]}"
|
||||
alt=' -alt-'
|
||||
fi
|
||||
zle -R "${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}"
|
||||
read -k key
|
||||
|
||||
while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
|
||||
|
@ -72,12 +105,24 @@ while [[ '#key' -ne '#\\r' && '#key' -ne '#\\n' &&
|
|||
zle $twid "$@"
|
||||
LBUFFER="$lastl"
|
||||
RBUFFER="$lastr"
|
||||
if [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
|
||||
if (( ! _lastcomp[nmatches] )); then
|
||||
word=''
|
||||
state='-no match-'
|
||||
elif [[ "${LBUFFER}${RBUFFER}" = *${_lastcomp[unambiguous]}* ]]; then
|
||||
word=''
|
||||
state='-no prefix-'
|
||||
else
|
||||
word="${_lastcomp[unambiguous]}"
|
||||
state=''
|
||||
fi
|
||||
zle -R "${pmpt//\\%u/$word}"
|
||||
num=$_lastcomp[normal_nmatches]
|
||||
if (( ! num )); then
|
||||
num="${_lastcomp[nmatches]}"
|
||||
alt=' -alt-'
|
||||
else
|
||||
alt=''
|
||||
fi
|
||||
zle -R "${${${${${pmpt//\\%u/$word}//\\%s/$state}//\\%c/${_lastcomp[completer][2,-1]}}//\\%n/$num}//\\%a/$alt}"
|
||||
read -k key
|
||||
done
|
||||
|
||||
|
|
9
INSTALL
9
INSTALL
|
@ -246,9 +246,12 @@ plus those provide functions for the line editor, i.e.
|
|||
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* Zle/*'
|
||||
and if the --enable-dynamic option was given, the functions in
|
||||
Functions/Zftp, which require the zftp module to be available (see the
|
||||
zshzftpsys manual page), will be included as well. There are also some
|
||||
miscellaneous functions with documentation in comments; the complete set
|
||||
of functions can be installed with
|
||||
zshzftpsys manual page), will be included as well. Note, however, that
|
||||
some of the functions in the User subdirectory are version- and
|
||||
system-specific.
|
||||
|
||||
There are also some miscellaneous functions with documentation in comments;
|
||||
the complete set of functions can be installed with
|
||||
FUNCTIONS_INSTALL='Core/* Base/* Builtins/* User/* Commands/* \
|
||||
Misc/* Zftp/* Zle/*'
|
||||
Note you should set this by hand to include `Zftp/*' if you have zftp
|
||||
|
|
|
@ -29,3 +29,48 @@ while true; do sed -e 's/foo/bar/' Src/builtin.c >/dev/null; done
|
|||
# ignoring the error messages from sed.
|
||||
# ^Z is more of a problem since you have to catch the sed.
|
||||
while true; do sed -e 's/foo/bar/' non-existent-file >/dev/null; done
|
||||
|
||||
# Try
|
||||
# ^Z
|
||||
# fg
|
||||
# ^Z
|
||||
# fg
|
||||
fn() {
|
||||
local a
|
||||
while read a; do :; done
|
||||
less "$@"
|
||||
}
|
||||
cat foo | fn bar
|
||||
|
||||
# Try
|
||||
# ^Z
|
||||
# fg
|
||||
fn() {
|
||||
cat builtin.c
|
||||
}
|
||||
fn | while read a; do :; done
|
||||
|
||||
# Try
|
||||
# ^Z
|
||||
# fg
|
||||
# q
|
||||
# ^Z
|
||||
# fg
|
||||
# q
|
||||
fn() {
|
||||
less builtin.c
|
||||
echo done
|
||||
}
|
||||
x=2; while (( x-- )); do f; done
|
||||
|
||||
# Try
|
||||
# ^C
|
||||
# This won't work because zcat doesn't tell us that it received a signal.
|
||||
# But
|
||||
# ^Z
|
||||
# fg
|
||||
# ^C (probably a second ^C is needed: if the continued zcat is still running)
|
||||
# works.
|
||||
# (See also the file Etc/BUGS)
|
||||
while true; do zcat foo.gz > /dev/null; done
|
||||
|
||||
|
|
|
@ -2261,7 +2261,7 @@ zftp_type(char *name, char **args, int flags)
|
|||
fflush(stdout);
|
||||
return 0;
|
||||
} else {
|
||||
nt = toupper(*str);
|
||||
nt = toupper(STOUC(*str));
|
||||
/*
|
||||
* RFC959 specifies other types, but these are the only
|
||||
* ones we know what to do with.
|
||||
|
@ -2294,7 +2294,7 @@ zftp_mode(char *name, char **args, int flags)
|
|||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
nt = str[0] = toupper(*str);
|
||||
nt = str[0] = toupper(STOUC(*str));
|
||||
if (str[1] || (nt != 'S' && nt != 'B')) {
|
||||
zwarnnam(name, "transfer mode %s not recognised", str, 0);
|
||||
return 1;
|
||||
|
@ -2651,7 +2651,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
|
|||
if ((prefs = getsparam("ZFTP_PREFS"))) {
|
||||
zfprefs = 0;
|
||||
for (ptr = prefs; *ptr; ptr++) {
|
||||
switch (toupper(*ptr)) {
|
||||
switch (toupper(STOUC(*ptr))) {
|
||||
case 'S':
|
||||
/* sendport */
|
||||
zfprefs |= ZFPF_SNDP;
|
||||
|
|
|
@ -218,6 +218,8 @@ struct cmatch {
|
|||
int brsl; /* ...and the suffix */
|
||||
char *rems; /* when to remove the suffix */
|
||||
char *remf; /* shell function to call for suffix-removal */
|
||||
int qipl; /* length of quote-prefix */
|
||||
int qisl; /* length of quote-suffix */
|
||||
int rnum; /* group relative number */
|
||||
int gnum; /* global number */
|
||||
};
|
||||
|
@ -349,25 +351,25 @@ struct chdata {
|
|||
|
||||
|
||||
#define CPN_NMATCHES 0
|
||||
#define CP_NMATCHES (1 << CPN_NMATCHES)
|
||||
#define CP_NMATCHES (1 << CPN_NMATCHES)
|
||||
#define CPN_MATCHER 1
|
||||
#define CP_MATCHER (1 << CPN_MATCHER)
|
||||
#define CP_MATCHER (1 << CPN_MATCHER)
|
||||
#define CPN_MATCHERSTR 2
|
||||
#define CP_MATCHERSTR (1 << CPN_MATCHERSTR)
|
||||
#define CP_MATCHERSTR (1 << CPN_MATCHERSTR)
|
||||
#define CPN_MATCHERTOT 3
|
||||
#define CP_MATCHERTOT (1 << CPN_MATCHERTOT)
|
||||
#define CP_MATCHERTOT (1 << CPN_MATCHERTOT)
|
||||
#define CPN_CONTEXT 4
|
||||
#define CP_CONTEXT (1 << CPN_CONTEXT)
|
||||
#define CP_CONTEXT (1 << CPN_CONTEXT)
|
||||
#define CPN_PARAMETER 5
|
||||
#define CP_PARAMETER (1 << CPN_PARAMETER)
|
||||
#define CP_PARAMETER (1 << CPN_PARAMETER)
|
||||
#define CPN_REDIRECT 6
|
||||
#define CP_REDIRECT (1 << CPN_REDIRECT)
|
||||
#define CP_REDIRECT (1 << CPN_REDIRECT)
|
||||
#define CPN_QUOTE 7
|
||||
#define CP_QUOTE (1 << CPN_QUOTE)
|
||||
#define CP_QUOTE (1 << CPN_QUOTE)
|
||||
#define CPN_QUOTING 8
|
||||
#define CP_QUOTING (1 << CPN_QUOTING)
|
||||
#define CP_QUOTING (1 << CPN_QUOTING)
|
||||
#define CPN_RESTORE 9
|
||||
#define CP_RESTORE (1 << CPN_RESTORE)
|
||||
#define CP_RESTORE (1 << CPN_RESTORE)
|
||||
#define CPN_LIST 10
|
||||
#define CP_LIST (1 << CPN_LIST)
|
||||
#define CPN_FORCELIST 11
|
||||
|
@ -398,6 +400,8 @@ struct chdata {
|
|||
#define CP_OLDINS (1 << CPN_OLDINS)
|
||||
#define CPN_VARED 24
|
||||
#define CP_VARED (1 << CPN_VARED)
|
||||
#define CPN_NNMATCHES 25
|
||||
#define CP_NNMATCHES (1 << CPN_NNMATCHES)
|
||||
|
||||
#define CP_KEYPARAMS 25
|
||||
#define CP_KEYPARAMS 26
|
||||
#define CP_ALLKEYS ((unsigned int) 0xffffff)
|
||||
|
|
|
@ -105,6 +105,7 @@ int incompfunc;
|
|||
/**/
|
||||
zlong compcurrent,
|
||||
compnmatches,
|
||||
compnnmatches,
|
||||
compmatcher,
|
||||
compmatchertot,
|
||||
complistmax;
|
||||
|
|
|
@ -27,6 +27,7 @@ compmatcher
|
|||
compmatcherstr
|
||||
compmatchertot
|
||||
compnmatches
|
||||
compnnmatches
|
||||
compoldlist
|
||||
compoldins
|
||||
compparameter
|
||||
|
|
|
@ -2210,6 +2210,7 @@ static struct compparam compkparams[] = {
|
|||
{ "old_list", PM_SCALAR, VAL(compoldlist), NULL, NULL },
|
||||
{ "old_insert", PM_SCALAR, VAL(compoldins), NULL, NULL },
|
||||
{ "vared", PM_SCALAR, VAL(compvared), NULL, NULL },
|
||||
{ "normal_nmatches", PM_INTEGER, VAL(compnnmatches), NULL, NULL },
|
||||
{ NULL, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -308,8 +308,8 @@ complistmatches(Hookdef dummy, Chdata dat)
|
|||
Cmatch *p, m;
|
||||
Cexpl *e;
|
||||
int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0, opl = 0;
|
||||
int of = isset(LISTTYPES);
|
||||
int mc, ml = 0, cc, hasm = 0, cl;
|
||||
int of = isset(LISTTYPES), cf;
|
||||
int mc, ml = 0, cc, hasm = 0, cl = -1;
|
||||
struct listcols col;
|
||||
|
||||
if (minfo.asked == 2) {
|
||||
|
@ -318,15 +318,6 @@ complistmatches(Hookdef dummy, Chdata dat)
|
|||
}
|
||||
getcols(&col);
|
||||
|
||||
/* Set the cursor below the prompt. */
|
||||
if (inselect)
|
||||
clearflag = 0;
|
||||
trashzle();
|
||||
showinglist = listshown = 0;
|
||||
|
||||
clearflag = (isset(USEZLE) && !termflags &&
|
||||
complastprompt && *complastprompt);
|
||||
|
||||
for (g = amatches; g; g = g->next) {
|
||||
char **pp = g->ylist;
|
||||
int nl = 0, l;
|
||||
|
@ -403,6 +394,19 @@ complistmatches(Hookdef dummy, Chdata dat)
|
|||
nlines += 1 + ((1 + niceztrlen(m->str)) / columns);
|
||||
}
|
||||
}
|
||||
cf = (isset(USEZLE) && !termflags && complastprompt && *complastprompt);
|
||||
if (!nlines || (mselect >= 0 && (!cf || (nlines + nlnct - 1) >= lines))) {
|
||||
showinglist = listshown = 0;
|
||||
noselect = 1;
|
||||
return 1;
|
||||
}
|
||||
/* Set the cursor below the prompt. */
|
||||
if (inselect)
|
||||
clearflag = 0;
|
||||
trashzle();
|
||||
showinglist = listshown = 0;
|
||||
|
||||
clearflag = cf;
|
||||
|
||||
/* Maybe we have to ask if the user wants to see the list. */
|
||||
if ((!minfo.cur || !minfo.asked) &&
|
||||
|
@ -654,20 +658,20 @@ complistmatches(Hookdef dummy, Chdata dat)
|
|||
pnl = 1;
|
||||
g = g->next;
|
||||
}
|
||||
|
||||
if (clearflag) {
|
||||
/* Move the cursor up to the prompt, if always_last_prompt *
|
||||
* is set and all that... */
|
||||
if ((nlines += nlnct - 1) < lines) {
|
||||
tcmultout(TCUP, TCMULTUP, nlines);
|
||||
showinglist = -1;
|
||||
listshown = 1;
|
||||
} else
|
||||
clearflag = 0, putc('\n', shout);
|
||||
} else
|
||||
putc('\n', shout);
|
||||
listshown = (clearflag ? 1 : -1);
|
||||
if (!hasm || nlines >= lines)
|
||||
noselect = 1;
|
||||
|
||||
return noselect;
|
||||
}
|
||||
|
||||
|
@ -676,7 +680,7 @@ typedef struct menustack *Menustack;
|
|||
struct menustack {
|
||||
Menustack prev;
|
||||
char *line;
|
||||
int cs;
|
||||
int cs, acc;
|
||||
struct menuinfo info;
|
||||
Cmgroup amatches, pmatches, lmatches;
|
||||
};
|
||||
|
@ -742,19 +746,19 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
s->amatches = amatches;
|
||||
s->pmatches = pmatches;
|
||||
s->lmatches = lmatches;
|
||||
menucmp = 0;
|
||||
s->acc = menuacc;
|
||||
menucmp = menuacc = 0;
|
||||
fixsuffix();
|
||||
validlist = 0;
|
||||
pmatches = NULL;
|
||||
invalidatelist();
|
||||
menucomplete(zlenoargs);
|
||||
if (dat->num < 2 || !minfo.cur || !*(minfo.cur)) {
|
||||
noselect = 1;
|
||||
clearlist = 1;
|
||||
noselect = clearlist = listshown = 1;
|
||||
zrefresh();
|
||||
break;
|
||||
}
|
||||
clearlist = 1;
|
||||
clearlist = listshown = 1;
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
continue;
|
||||
} else if (cmd == Th(z_acceptandhold) ||
|
||||
|
@ -767,6 +771,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
s->cs = cs;
|
||||
memcpy(&(s->info), &minfo, sizeof(struct menuinfo));
|
||||
s->amatches = s->pmatches = s->lmatches = NULL;
|
||||
s->acc = menuacc;
|
||||
acceptlast();
|
||||
do_menucmp(0);
|
||||
mselect = (*(minfo.cur))->gnum;
|
||||
|
@ -782,6 +787,7 @@ domenuselect(Hookdef dummy, Chdata dat)
|
|||
spaceinline(l = strlen(u->line));
|
||||
strncpy((char *) line, u->line, l);
|
||||
cs = u->cs;
|
||||
menuacc = u->acc;
|
||||
memcpy(&minfo, &(u->info), sizeof(struct menuinfo));
|
||||
p = &(minfo.cur);
|
||||
if (u->pmatches && pmatches != u->pmatches) {
|
||||
|
|
|
@ -24,6 +24,7 @@ lastambig
|
|||
linkkeymap
|
||||
listshown
|
||||
lmatches
|
||||
menuacc
|
||||
menucmp
|
||||
menucomplete
|
||||
menucur
|
||||
|
|
|
@ -67,7 +67,7 @@ static struct zleparam {
|
|||
zleunsetfn, NULL },
|
||||
{ "LASTWIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_lwidget),
|
||||
zleunsetfn, NULL },
|
||||
{ "keys", PM_ARRAY | PM_READONLY, NULL, FN(get_keys),
|
||||
{ "KEYS", PM_SCALAR | PM_READONLY, NULL, FN(get_keys),
|
||||
zleunsetfn, NULL },
|
||||
{ "NUMERIC", PM_INTEGER | PM_UNSET, FN(set_numeric), FN(get_numeric),
|
||||
unset_numeric, NULL },
|
||||
|
@ -247,29 +247,10 @@ get_lwidget(Param pm)
|
|||
}
|
||||
|
||||
/**/
|
||||
static char **
|
||||
static char *
|
||||
get_keys(Param pm)
|
||||
{
|
||||
char **r, **q, *p, *k, c;
|
||||
|
||||
r = (char **) zhalloc((strlen(keybuf) + 1) * sizeof(char *));
|
||||
for (q = r, p = keybuf; (c = *p); q++, p++) {
|
||||
k = *q = (char *) zhalloc(5);
|
||||
if (c & 0x80) {
|
||||
*k++ = 'M';
|
||||
*k++ = '-';
|
||||
c &= 0x7f;
|
||||
}
|
||||
if (c < 32 || c == 0x7f) {
|
||||
*k++ = '^';
|
||||
c ^= 64;
|
||||
}
|
||||
*k++ = c;
|
||||
*k = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
|
||||
return r;
|
||||
return keybuf;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
|
@ -53,7 +53,8 @@ int nlnct;
|
|||
/**/
|
||||
int showinglist;
|
||||
|
||||
/* Non-zero if a completion list was displayed. */
|
||||
/* > 0 if a completion list is displayed below the prompt,
|
||||
* < 0 if a list is displayed above the prompt. */
|
||||
|
||||
/**/
|
||||
int listshown;
|
||||
|
@ -265,7 +266,7 @@ zrefresh(void)
|
|||
if (inlist)
|
||||
return;
|
||||
|
||||
if (clearlist && listshown) {
|
||||
if (clearlist && listshown > 0) {
|
||||
if (tccan(TCCLEAREOD)) {
|
||||
int ovln = vln, ovcs = vcs;
|
||||
char *nb = nbuf[vln];
|
||||
|
@ -331,7 +332,8 @@ zrefresh(void)
|
|||
tcout(TCCLEAREOD);
|
||||
else
|
||||
cleareol = 1; /* request: clear to end of line */
|
||||
listshown = 0;
|
||||
if (listshown > 0)
|
||||
listshown = 0;
|
||||
}
|
||||
if (t0 > -1)
|
||||
olnct = t0;
|
||||
|
|
|
@ -106,10 +106,11 @@ static int insmnum, insgnum, insgroup, insspace;
|
|||
|
||||
static int movetoend;
|
||||
|
||||
/* != 0 if we are in the middle of a menu completion */
|
||||
/* != 0 if we are in the middle of a menu completion and number of matches
|
||||
* accepted with accept-and-menu-complete */
|
||||
|
||||
/**/
|
||||
int menucmp;
|
||||
int menucmp, menuacc;
|
||||
|
||||
/* Information about menucompletion. */
|
||||
|
||||
|
@ -192,6 +193,10 @@ static char *qipre, *qisuf, autoq;
|
|||
static int lpl, lsl, rpl, rsl, fpl, fsl, lppl, lpsl;
|
||||
static int noreal;
|
||||
|
||||
/* A parameter expansion prefix (like ${). */
|
||||
|
||||
static char *parpre;
|
||||
|
||||
/* This is either zero or equal to the special character the word we are *
|
||||
* trying to complete starts with (e.g. Tilde or Equals). */
|
||||
|
||||
|
@ -209,9 +214,9 @@ static char *qword;
|
|||
|
||||
static Cmgroup mgroup;
|
||||
|
||||
/* A match counter. */
|
||||
/* Match counters: all matches, normal matches (not alternate set). */
|
||||
|
||||
static int mnum;
|
||||
static int mnum, nmnum;
|
||||
|
||||
/* The match counter when unambig_data() was called. */
|
||||
|
||||
|
@ -540,6 +545,8 @@ reversemenucomplete(char **args)
|
|||
void
|
||||
acceptlast(void)
|
||||
{
|
||||
menuacc++;
|
||||
|
||||
if (brbeg && *brbeg) {
|
||||
int l;
|
||||
|
||||
|
@ -553,10 +560,16 @@ acceptlast(void)
|
|||
brbeg[l] = ',';
|
||||
brbeg[l + 1] = '\0';
|
||||
} else {
|
||||
int l;
|
||||
|
||||
cs = minfo.pos + minfo.len + minfo.insc;
|
||||
iremovesuffix(' ', 1);
|
||||
|
||||
l = cs;
|
||||
cs = minfo.pos + minfo.len - (*(minfo.cur))->qisl;
|
||||
foredel(l - cs);
|
||||
inststrlen(" ", 1, 1);
|
||||
if (parpre)
|
||||
inststr(parpre);
|
||||
minfo.insc = minfo.len = 0;
|
||||
minfo.pos = cs;
|
||||
minfo.we = 1;
|
||||
|
@ -694,6 +707,9 @@ check_param(char *s, int set, int test)
|
|||
{
|
||||
char *p;
|
||||
|
||||
zsfree(parpre);
|
||||
parpre = NULL;
|
||||
|
||||
if (!test)
|
||||
ispar = parq = eparq = 0;
|
||||
/* Try to find a `$'. */
|
||||
|
@ -755,6 +771,8 @@ check_param(char *s, int set, int test)
|
|||
|
||||
/* Now make sure that the cursor is inside the name. */
|
||||
if (offs <= e - s && offs >= b - s && n <= 0) {
|
||||
char sav;
|
||||
|
||||
if (br) {
|
||||
p = e;
|
||||
while (*p == (test ? Dnull : '"'))
|
||||
|
@ -782,6 +800,12 @@ check_param(char *s, int set, int test)
|
|||
else
|
||||
parq = eparq = 0;
|
||||
|
||||
/* Save the prefix. */
|
||||
sav = *b;
|
||||
*b = '\0';
|
||||
untokenize(parpre = ztrdup(s));
|
||||
*b = sav;
|
||||
|
||||
/* And adjust wb, we, and offs again. */
|
||||
offs -= b - s;
|
||||
wb = cs - offs;
|
||||
|
@ -1017,7 +1041,7 @@ docomplete(int lst)
|
|||
int ocs = cs, ne = noerrs;
|
||||
|
||||
noerrs = 1;
|
||||
doexpansion(s, lst, olst, lincmd);
|
||||
ret = doexpansion(s, lst, olst, lincmd);
|
||||
lastambig = 0;
|
||||
noerrs = ne;
|
||||
|
||||
|
@ -1043,8 +1067,8 @@ docomplete(int lst)
|
|||
}
|
||||
}
|
||||
ret = docompletion(s, lst, lincmd);
|
||||
} else
|
||||
ret = !strcmp(ol, (char *) line);
|
||||
} else if (ret)
|
||||
clearlist = 1;
|
||||
} else
|
||||
/* Just do completion. */
|
||||
ret = docompletion(s, lst, lincmd);
|
||||
|
@ -1064,7 +1088,7 @@ docomplete(int lst)
|
|||
dat.num = nmatches;
|
||||
dat.cur = NULL;
|
||||
if (runhookdef(MENUSTARTHOOK, (void *) &dat))
|
||||
menucmp = 0;
|
||||
menucmp = menuacc = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1736,9 +1760,10 @@ get_comp_string(void)
|
|||
/* Expand the current word. */
|
||||
|
||||
/**/
|
||||
static void
|
||||
static int
|
||||
doexpansion(char *s, int lst, int olst, int explincmd)
|
||||
{
|
||||
int ret = 1;
|
||||
LinkList vl;
|
||||
char *ss;
|
||||
|
||||
|
@ -1775,7 +1800,7 @@ doexpansion(char *s, int lst, int olst, int explincmd)
|
|||
}
|
||||
if (lst == COMP_LIST_EXPAND) {
|
||||
/* Only the list of expansions was requested. */
|
||||
listlist(vl);
|
||||
ret = listlist(vl);
|
||||
showinglist = 0;
|
||||
goto end;
|
||||
}
|
||||
|
@ -1783,6 +1808,7 @@ doexpansion(char *s, int lst, int olst, int explincmd)
|
|||
cs = wb;
|
||||
foredel(we - wb);
|
||||
while ((ss = (char *)ugetnode(vl))) {
|
||||
ret = 0;
|
||||
untokenize(ss);
|
||||
ss = quotename(ss, NULL);
|
||||
inststr(ss);
|
||||
|
@ -1801,6 +1827,8 @@ doexpansion(char *s, int lst, int olst, int explincmd)
|
|||
end:
|
||||
popheap();
|
||||
} LASTALLOC;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This is called from the lexer to give us word positions. */
|
||||
|
@ -3547,6 +3575,8 @@ add_match_data(int alt, char *str, Cline line,
|
|||
ai->line = join_clines(ai->line, line);
|
||||
|
||||
mnum++;
|
||||
if (!alt)
|
||||
nmnum++;
|
||||
ai->count++;
|
||||
|
||||
/* Allocate and fill the match structure. */
|
||||
|
@ -3569,6 +3599,8 @@ add_match_data(int alt, char *str, Cline line,
|
|||
cm->flags = flags;
|
||||
cm->brpl = bpl;
|
||||
cm->brsl = bsl;
|
||||
cm->qipl = qipl;
|
||||
cm->qisl = qisl;
|
||||
cm->autoq = (autoq ? autoq : (inbackt ? '`' : '\0'));
|
||||
cm->rems = cm->remf = NULL;
|
||||
addlinknode((alt ? fmatches : matches), cm);
|
||||
|
@ -3896,6 +3928,7 @@ addmatches(Cadata dat, char **argv)
|
|||
}
|
||||
}
|
||||
compnmatches = mnum;
|
||||
compnnmatches = nmnum;
|
||||
if (dat->exp)
|
||||
addexpl();
|
||||
if (dat->apar)
|
||||
|
@ -4380,10 +4413,14 @@ docompletion(char *s, int lst, int incmd)
|
|||
}
|
||||
if (comppatmatch && *comppatmatch && comppatmatch != opm)
|
||||
haspattern = 1;
|
||||
if (!useline && uselist)
|
||||
if (!useline && uselist) {
|
||||
/* All this and the guy only wants to see the list, sigh. */
|
||||
cs = 0;
|
||||
foredel(ll);
|
||||
inststr(origline);
|
||||
cs = origcs;
|
||||
showinglist = -2;
|
||||
else if (useline) {
|
||||
} else if (useline) {
|
||||
/* We have matches. */
|
||||
if (nmatches > 1) {
|
||||
/* There is more than one match. */
|
||||
|
@ -4399,9 +4436,13 @@ docompletion(char *s, int lst, int incmd)
|
|||
do_single(m->matches[0]);
|
||||
invalidatelist();
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
invalidatelist();
|
||||
|
||||
cs = 0;
|
||||
foredel(ll);
|
||||
inststr(origline);
|
||||
cs = origcs;
|
||||
}
|
||||
/* Print the explanation strings if needed. */
|
||||
if (!showinglist && validlist && usemenu != 2 && nmatches != 1) {
|
||||
Cmgroup g = amatches;
|
||||
|
@ -4582,22 +4623,22 @@ callcompfunc(char *s, char *fn)
|
|||
zsfree(compprefix);
|
||||
zsfree(compsuffix);
|
||||
if (unset(COMPLETEINWORD)) {
|
||||
/* Maybe we'll have to do quoting here some time. */
|
||||
tmp = dupstring(s);
|
||||
tmp = quotename(s, NULL);
|
||||
untokenize(tmp);
|
||||
compprefix = ztrdup(tmp);
|
||||
compsuffix = ztrdup("");
|
||||
} else {
|
||||
char *ss, sav;
|
||||
|
||||
tmp = dupstring(s);
|
||||
ss = tmp + offs;
|
||||
ss = s + offs;
|
||||
|
||||
sav = *ss;
|
||||
*ss = '\0';
|
||||
tmp = quotename(s, NULL);
|
||||
untokenize(tmp);
|
||||
compprefix = ztrdup(tmp);
|
||||
*ss = sav;
|
||||
ss = quotename(ss, NULL);
|
||||
untokenize(ss);
|
||||
compsuffix = ztrdup(ss);
|
||||
}
|
||||
|
@ -4611,6 +4652,7 @@ callcompfunc(char *s, char *fn)
|
|||
compqisuffix = ztrdup(qisuf ? qisuf : "");
|
||||
compcurrent = (usea ? (clwpos + 1 - aadd) : 0);
|
||||
compnmatches = mnum;
|
||||
compnnmatches = nmnum;
|
||||
|
||||
zsfree(complist);
|
||||
switch (uselist) {
|
||||
|
@ -4825,13 +4867,13 @@ makecomplist(char *s, int incmd, int lst)
|
|||
if (!validlist)
|
||||
lastambig = 0;
|
||||
amatches = NULL;
|
||||
mnum = 0;
|
||||
mnum = nmnum = 0;
|
||||
unambig_mnum = -1;
|
||||
isuf = NULL;
|
||||
insmnum = insgnum = 1;
|
||||
insgroup = oldlist = oldins = 0;
|
||||
begcmgroup("default", 0);
|
||||
menucmp = 0;
|
||||
menucmp = menuacc = 0;
|
||||
|
||||
ccused = newlinklist();
|
||||
ccstack = newlinklist();
|
||||
|
@ -4984,6 +5026,8 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
|||
memcpy(tmp + sl + 1, s, noffs);
|
||||
tmp[(scs = cs = sl + 1 + noffs)] = 'x';
|
||||
strcpy(tmp + sl + 2 + noffs, s + noffs);
|
||||
if (incompfunc)
|
||||
tmp = rembslash(tmp);
|
||||
inpush(dupstrspace(tmp), 0, NULL);
|
||||
line = (unsigned char *) tmp;
|
||||
ll = tl - 1;
|
||||
|
@ -5013,6 +5057,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
|||
p = NULL;
|
||||
if (!got && !zleparse) {
|
||||
DPUTS(!p, "no current word in substr");
|
||||
got = 1;
|
||||
cur = i;
|
||||
swb = wb - 1;
|
||||
swe = we - 1;
|
||||
|
@ -5077,7 +5122,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
|||
}
|
||||
sav = s[(i = swb - sl - 1)];
|
||||
s[i] = '\0';
|
||||
qp = tricat(qipre, s, "");
|
||||
qp = tricat(qipre, (incompfunc ? rembslash(s) : s), "");
|
||||
s[i] = sav;
|
||||
if (swe < swb)
|
||||
swe = swb;
|
||||
|
@ -5085,7 +5130,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
|||
sl = strlen(s);
|
||||
if (swe > sl)
|
||||
swe = sl, ns[swe - swb + 1] = '\0';
|
||||
qs = tricat(s + swe, qisuf, "");
|
||||
qs = tricat((incompfunc ? rembslash(s + swe) : s + swe), qisuf, "");
|
||||
sl = strlen(ns);
|
||||
if (soffs > sl)
|
||||
soffs = sl;
|
||||
|
@ -5172,7 +5217,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
|||
compisuffix = ztrdup("");
|
||||
zsfree(compqiprefix);
|
||||
zsfree(compqisuffix);
|
||||
if (instring) {
|
||||
if (ois) {
|
||||
compqiprefix = qp;
|
||||
compqisuffix = qs;
|
||||
} else {
|
||||
|
@ -5188,6 +5233,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec)
|
|||
p = compwords[i] = (char *) getdata(n);
|
||||
untokenize(p);
|
||||
}
|
||||
compcurrent = cur + 1;
|
||||
compwords[i] = NULL;
|
||||
}
|
||||
autoq = oaq;
|
||||
|
@ -5242,6 +5288,7 @@ makecomplistcall(Compctl cc)
|
|||
inbackt = oib;
|
||||
autoq = oaq;
|
||||
compnmatches = mnum;
|
||||
compnnmatches = nmnum;
|
||||
} LASTALLOC;
|
||||
} SWITCHBACKHEAPS;
|
||||
|
||||
|
@ -5317,6 +5364,7 @@ makecomplistctl(int flags)
|
|||
autoq = oaq;
|
||||
offs = ooffs;
|
||||
compnmatches = mnum;
|
||||
compnnmatches = nmnum;
|
||||
zsfree(cmdstr);
|
||||
freearray(clwords);
|
||||
cmdstr = os;
|
||||
|
@ -5979,7 +6027,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
|||
char save = line[cs];
|
||||
|
||||
line[cs] = 0;
|
||||
lppre = dupstring((char *) (line + wb));
|
||||
lppre = dupstring((char *) line + wb +
|
||||
(qipre && *qipre ?
|
||||
(strlen(qipre) -
|
||||
(*qipre == '\'' || *qipre == '\"')) : 0));
|
||||
line[cs] = save;
|
||||
if (brbeg && *brbeg)
|
||||
strcpy(lppre + qbrpl, lppre + qbrpl + strlen(brbeg));
|
||||
|
@ -5998,11 +6049,17 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
|||
lppl = 0;
|
||||
}
|
||||
if (cs != we) {
|
||||
char save = line[we];
|
||||
int end = we;
|
||||
char save = line[end];
|
||||
|
||||
line[we] = 0;
|
||||
if (qisuf && *qisuf) {
|
||||
int ql = strlen(qisuf);
|
||||
|
||||
end -= ql - (qisuf[ql-1] == '\'' || qisuf[ql-1] == '"');
|
||||
}
|
||||
line[end] = 0;
|
||||
lpsuf = dupstring((char *) (line + cs));
|
||||
line[we] = save;
|
||||
line[end] = save;
|
||||
if (brend && *brend) {
|
||||
char *p = lpsuf + qbrsl - (cs - wb);
|
||||
|
||||
|
@ -6640,7 +6697,8 @@ invalidatelist(void)
|
|||
listmatches();
|
||||
if (validlist)
|
||||
freematches();
|
||||
lastambig = menucmp = validlist = showinglist = fromcomp = 0;
|
||||
lastambig = menucmp = menuacc = validlist = showinglist =
|
||||
fromcomp = listshown = 0;
|
||||
minfo.cur = NULL;
|
||||
minfo.asked = 0;
|
||||
compwidget = NULL;
|
||||
|
@ -6917,6 +6975,8 @@ dupmatch(Cmatch m)
|
|||
r->rems = ztrdup(m->rems);
|
||||
r->remf = ztrdup(m->remf);
|
||||
r->autoq = m->autoq;
|
||||
r->qipl = m->qipl;
|
||||
r->qisl = m->qisl;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -7346,7 +7406,9 @@ instmatch(Cmatch m, int *scs)
|
|||
|
||||
/* Ignored prefix. */
|
||||
if (m->ipre) {
|
||||
inststrlen(m->ipre, 1, (l = strlen(m->ipre)));
|
||||
char *p = m->ipre + (menuacc ? m->qipl : 0);
|
||||
|
||||
inststrlen(p, 1, (l = strlen(p)));
|
||||
r += l;
|
||||
}
|
||||
/* -P prefix. */
|
||||
|
@ -7413,7 +7475,8 @@ static int
|
|||
do_ambiguous(void)
|
||||
{
|
||||
int ret = 0;
|
||||
menucmp = 0;
|
||||
|
||||
menucmp = menuacc = 0;
|
||||
|
||||
/* If we have to insert the first match, call do_single(). This is *
|
||||
* how REC_EXACT takes effect. We effectively turn the ambiguous *
|
||||
|
@ -7501,11 +7564,13 @@ do_ambiguous(void)
|
|||
* if it is needed. */
|
||||
if (isset(LISTBEEP))
|
||||
ret = 1;
|
||||
if (uselist && (usemenu != 2 || (!showinglist && !oldlist)) &&
|
||||
|
||||
if (uselist && (usemenu != 2 || (!listshown && !oldlist)) &&
|
||||
((!showinglist && (!listshown || !oldlist)) ||
|
||||
(usemenu == 3 && !oldlist)) &&
|
||||
(smatches >= 2 || (compforcelist && *compforcelist)))
|
||||
showinglist = -2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -7649,7 +7714,7 @@ do_single(Cmatch m)
|
|||
}
|
||||
}
|
||||
if (!minfo.insc)
|
||||
cs = minfo.pos + minfo.len;
|
||||
cs = minfo.pos + minfo.len - m->qisl;
|
||||
}
|
||||
/* If completing in a brace expansion... */
|
||||
if (brbeg) {
|
||||
|
@ -7688,8 +7753,11 @@ do_single(Cmatch m)
|
|||
if (minfo.we && m->ripre && isset(AUTOPARAMKEYS))
|
||||
makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq);
|
||||
|
||||
if ((menucmp && !minfo.we) || !movetoend)
|
||||
if ((menucmp && !minfo.we) || !movetoend) {
|
||||
cs = minfo.end;
|
||||
if (cs + m->qisl == lastend)
|
||||
cs += minfo.insc;
|
||||
}
|
||||
{
|
||||
Cmatch *om = minfo.cur;
|
||||
struct chdata dat;
|
||||
|
@ -7732,6 +7800,7 @@ do_ambig_menu(void)
|
|||
|
||||
if (usemenu != 3) {
|
||||
menucmp = 1;
|
||||
menuacc = 0;
|
||||
minfo.cur = NULL;
|
||||
} else {
|
||||
if (oldlist) {
|
||||
|
@ -7931,13 +8000,6 @@ ilistmatches(Hookdef dummy, Chdata dat)
|
|||
int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0;
|
||||
int of = isset(LISTTYPES), opl = 0;
|
||||
|
||||
/* Set the cursor below the prompt. */
|
||||
trashzle();
|
||||
showinglist = listshown = 0;
|
||||
|
||||
clearflag = (isset(USEZLE) && !termflags &&
|
||||
complastprompt && *complastprompt);
|
||||
|
||||
for (g = amatches; g; g = g->next) {
|
||||
char **pp = g->ylist;
|
||||
int nl = 0, l;
|
||||
|
@ -8013,6 +8075,16 @@ ilistmatches(Hookdef dummy, Chdata dat)
|
|||
nlines += 1 + ((1 + niceztrlen(m->str)) / columns);
|
||||
}
|
||||
}
|
||||
if (!nlines) {
|
||||
showinglist = listshown = 0;
|
||||
return 1;
|
||||
}
|
||||
/* Set the cursor below the prompt. */
|
||||
trashzle();
|
||||
showinglist = listshown = 0;
|
||||
|
||||
clearflag = (isset(USEZLE) && !termflags &&
|
||||
complastprompt && *complastprompt);
|
||||
|
||||
/* Maybe we have to ask if the user wants to see the list. */
|
||||
if ((!minfo.cur || !minfo.asked) &&
|
||||
|
@ -8152,25 +8224,25 @@ ilistmatches(Hookdef dummy, Chdata dat)
|
|||
pnl = 1;
|
||||
g = g->next;
|
||||
}
|
||||
|
||||
if (clearflag) {
|
||||
/* Move the cursor up to the prompt, if always_last_prompt *
|
||||
* is set and all that... */
|
||||
if ((nlines += nlnct - 1) < lines) {
|
||||
tcmultout(TCUP, TCMULTUP, nlines);
|
||||
showinglist = -1;
|
||||
listshown = 1;
|
||||
} else
|
||||
clearflag = 0, putc('\n', shout);
|
||||
} else
|
||||
putc('\n', shout);
|
||||
listshown = (clearflag ? 1 : -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is used to print expansions. */
|
||||
|
||||
/**/
|
||||
void
|
||||
int
|
||||
listlist(LinkList l)
|
||||
{
|
||||
struct cmgroup dg;
|
||||
|
@ -8193,6 +8265,8 @@ listlist(LinkList l)
|
|||
validlist = vl;
|
||||
smatches = sm;
|
||||
complastprompt = oclp;
|
||||
|
||||
return !dg.lcount;
|
||||
}
|
||||
|
||||
/* Expand the history references. */
|
||||
|
|
112
Src/builtin.c
112
Src/builtin.c
|
@ -658,6 +658,9 @@ set_pwd_env(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* set if we are resolving links to their true paths */
|
||||
static int chasinglinks;
|
||||
|
||||
/* The main pwd changing function. The real work is done by other *
|
||||
* functions. cd_get_dest() does the initial argument processing; *
|
||||
* cd_do_chdir() actually changes directory, if possible; cd_new_pwd() *
|
||||
|
@ -670,7 +673,6 @@ bin_cd(char *nam, char **argv, char *ops, int func)
|
|||
{
|
||||
LinkNode dir;
|
||||
struct stat st1, st2;
|
||||
int chaselinks;
|
||||
|
||||
if (isset(RESTRICTED)) {
|
||||
zwarnnam(nam, "restricted", NULL, 0);
|
||||
|
@ -694,7 +696,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
|
|||
for (s = *argv; *++s; ops[STOUC(*s)] = 1);
|
||||
}
|
||||
brk:
|
||||
chaselinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
|
||||
chasinglinks = ops['P'] || (isset(CHASELINKS) && !ops['L']);
|
||||
PERMALLOC {
|
||||
pushnode(dirstack, ztrdup(pwd));
|
||||
if (!(dir = cd_get_dest(nam, argv, ops, func))) {
|
||||
|
@ -702,7 +704,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
|
|||
LASTALLOC_RETURN 1;
|
||||
}
|
||||
} LASTALLOC;
|
||||
cd_new_pwd(func, dir, chaselinks);
|
||||
cd_new_pwd(func, dir);
|
||||
|
||||
if (stat(unmeta(pwd), &st1) < 0) {
|
||||
zsfree(pwd);
|
||||
|
@ -710,7 +712,7 @@ bin_cd(char *nam, char **argv, char *ops, int func)
|
|||
} else if (stat(".", &st2) < 0)
|
||||
chdir(unmeta(pwd));
|
||||
else if (st1.st_ino != st2.st_ino || st1.st_dev != st2.st_dev) {
|
||||
if (chaselinks) {
|
||||
if (chasinglinks) {
|
||||
zsfree(pwd);
|
||||
pwd = metafy(zgetcwd(), -1, META_DUP);
|
||||
} else {
|
||||
|
@ -915,40 +917,49 @@ static char *
|
|||
cd_try_chdir(char *pfix, char *dest, int hard)
|
||||
{
|
||||
char *buf;
|
||||
int dlen, dochaselinks = 0;
|
||||
|
||||
/* handle directory prefix */
|
||||
if (pfix && *pfix) {
|
||||
if (*pfix == '/')
|
||||
buf = tricat(pfix, "/", dest);
|
||||
else {
|
||||
int pwl = strlen(pwd);
|
||||
int pfl = strlen(pfix);
|
||||
dlen = strlen(pwd);
|
||||
|
||||
buf = zalloc(pwl + pfl + strlen(dest) + 3);
|
||||
buf = zalloc(dlen + pfl + strlen(dest) + 3);
|
||||
strcpy(buf, pwd);
|
||||
buf[pwl] = '/';
|
||||
strcpy(buf + pwl + 1, pfix);
|
||||
buf[pwl + 1 + pfl] = '/';
|
||||
strcpy(buf + pwl + pfl + 2, dest);
|
||||
buf[dlen] = '/';
|
||||
strcpy(buf + dlen + 1, pfix);
|
||||
buf[dlen + 1 + pfl] = '/';
|
||||
strcpy(buf + dlen + pfl + 2, dest);
|
||||
}
|
||||
} else if (*dest == '/')
|
||||
buf = ztrdup(dest);
|
||||
else {
|
||||
int pwl = strlen(pwd);
|
||||
dlen = strlen(pwd);
|
||||
|
||||
buf = zalloc(pwl + strlen(dest) + 2);
|
||||
buf = zalloc(dlen + strlen(dest) + 2);
|
||||
strcpy(buf, pwd);
|
||||
buf[pwl] = '/';
|
||||
strcpy(buf + pwl + 1, dest);
|
||||
buf[dlen] = '/';
|
||||
strcpy(buf + dlen + 1, dest);
|
||||
}
|
||||
|
||||
/* Normalise path. See the definition of fixdir() for what this means. */
|
||||
fixdir(buf);
|
||||
/* Normalise path. See the definition of fixdir() for what this means.
|
||||
* We do not do this if we are chasing links.
|
||||
*/
|
||||
if (!chasinglinks)
|
||||
dochaselinks = fixdir(buf);
|
||||
else
|
||||
unmetafy(buf, &dlen);
|
||||
|
||||
if (lchdir(buf, NULL, hard)) {
|
||||
zsfree(buf);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
/* the chdir succeeded, so decide if we should force links to be chased */
|
||||
if (dochaselinks)
|
||||
chasinglinks = 1;
|
||||
return metafy(buf, -1, META_NOALLOC);
|
||||
}
|
||||
|
||||
|
@ -956,7 +967,7 @@ cd_try_chdir(char *pfix, char *dest, int hard)
|
|||
|
||||
/**/
|
||||
static void
|
||||
cd_new_pwd(int func, LinkNode dir, int chaselinks)
|
||||
cd_new_pwd(int func, LinkNode dir)
|
||||
{
|
||||
List l;
|
||||
char *new_pwd, *s;
|
||||
|
@ -972,7 +983,7 @@ cd_new_pwd(int func, LinkNode dir, int chaselinks)
|
|||
} else if (func == BIN_CD && unset(AUTOPUSHD))
|
||||
zsfree(getlinknode(dirstack));
|
||||
|
||||
if (chaselinks) {
|
||||
if (chasinglinks) {
|
||||
s = new_pwd;
|
||||
new_pwd = findpwd(s);
|
||||
zsfree(s);
|
||||
|
@ -1039,17 +1050,20 @@ printdirstack(void)
|
|||
}
|
||||
|
||||
/* Normalise a path. Segments consisting of ., and foo/.. *
|
||||
* combinations, are removed and the path is unmetafied. */
|
||||
* combinations, are removed and the path is unmetafied.
|
||||
* Returns 1 if we found a ../ path which should force links to
|
||||
* be chased, 0 otherwise.
|
||||
*/
|
||||
|
||||
/**/
|
||||
static void
|
||||
int
|
||||
fixdir(char *src)
|
||||
{
|
||||
char *dest = src;
|
||||
char *d0 = dest;
|
||||
#ifdef __CYGWIN__
|
||||
char *dest = src, *d0 = dest;
|
||||
#ifdef __CYGWIN
|
||||
char *s0 = src;
|
||||
#endif
|
||||
int ret = 0;
|
||||
|
||||
/*** if have RFS superroot directory ***/
|
||||
#ifdef HAVE_SUPERROOT
|
||||
|
@ -1081,19 +1095,40 @@ fixdir(char *src)
|
|||
while (dest > d0 + 1 && dest[-1] == '/')
|
||||
dest--;
|
||||
*dest = '\0';
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
if (src[0] == '.' && src[1] == '.' &&
|
||||
(src[2] == '\0' || src[2] == '/')) {
|
||||
if (dest > d0 + 1) {
|
||||
/* remove a foo/.. combination */
|
||||
for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
|
||||
if (dest[-1] != '/')
|
||||
dest--;
|
||||
(src[2] == '\0' || src[2] == '/')) {
|
||||
if (isset(CHASEDOTS)) {
|
||||
ret = 1;
|
||||
/* and treat as normal path segment */
|
||||
} else {
|
||||
if (dest > d0 + 1) {
|
||||
/*
|
||||
* remove a foo/.. combination:
|
||||
* first check foo exists, else return.
|
||||
*/
|
||||
struct stat st;
|
||||
*dest = '\0';
|
||||
if (stat(d0, &st) < 0 || !S_ISDIR(st.st_mode)) {
|
||||
char *ptrd, *ptrs;
|
||||
if (dest == src)
|
||||
*dest = '.';
|
||||
for (ptrs = src, ptrd = dest; *ptrs; ptrs++, ptrd++)
|
||||
*ptrd = (*ptrs == Meta) ? (*++ptrs ^ 32) : *ptrs;
|
||||
*ptrd = '\0';
|
||||
return 1;
|
||||
}
|
||||
for (dest--; dest > d0 + 1 && dest[-1] != '/'; dest--);
|
||||
if (dest[-1] != '/')
|
||||
dest--;
|
||||
}
|
||||
src++;
|
||||
while (*++src == '/');
|
||||
continue;
|
||||
}
|
||||
src++;
|
||||
while (*++src == '/');
|
||||
} else if (src[0] == '.' && (src[1] == '/' || src[1] == '\0')) {
|
||||
}
|
||||
if (src[0] == '.' && (src[1] == '/' || src[1] == '\0')) {
|
||||
/* skip a . section */
|
||||
while (*++src == '/');
|
||||
} else {
|
||||
|
@ -3249,12 +3284,11 @@ bin_read(char *name, char **args, char *ops, int func)
|
|||
nchars = 1;
|
||||
args++;
|
||||
}
|
||||
|
||||
firstarg = *args;
|
||||
if (*args && **args == '?')
|
||||
args++;
|
||||
/* default result parameter */
|
||||
/* This `*args++ : *args' looks a bit weird, but it works around a bug
|
||||
* in gcc-2.8.1 under DU 4.0. */
|
||||
firstarg = (*args && **args == '?' ? *args++ : *args);
|
||||
reply = *args ? *args++ : ops['A'] ? "reply" : "REPLY";
|
||||
|
||||
if (ops['A'] && *args) {
|
||||
zwarnnam(name, "only one array argument allowed", NULL, 0);
|
||||
return 1;
|
||||
|
|
17
Src/exec.c
17
Src/exec.c
|
@ -3144,9 +3144,24 @@ static int
|
|||
cancd2(char *s)
|
||||
{
|
||||
struct stat buf;
|
||||
char *us = unmeta(s);
|
||||
char *us, *us2 = NULL;
|
||||
|
||||
/*
|
||||
* If CHASEDOTS and CHASELINKS are not set, we want to rationalize the
|
||||
* path by removing foo/.. combinations in the logical rather than
|
||||
* the physical path. If either is set, we test the physical path.
|
||||
*/
|
||||
if (!isset(CHASEDOTS) && !isset(CHASELINKS)) {
|
||||
if (*s != '/')
|
||||
us = tricat(pwd[1] ? pwd : "", "/", s);
|
||||
else
|
||||
us = ztrdup(s);
|
||||
fixdir(us2 = us);
|
||||
} else
|
||||
us = unmeta(s);
|
||||
return !(access(us, X_OK) || stat(us, &buf) || !S_ISDIR(buf.st_mode));
|
||||
if (us2)
|
||||
free(us2);
|
||||
}
|
||||
|
||||
/**/
|
||||
|
|
10
Src/glob.c
10
Src/glob.c
|
@ -2724,6 +2724,9 @@ charmatch(Comp c, char *x, char *y)
|
|||
* Here we bypass tulower() and tuupper() for speed.
|
||||
*/
|
||||
int xi = (STOUC(UNMETA(x)) & 0xff), yi = (STOUC(UNMETA(y)) & 0xff);
|
||||
/* A NULL is a real null, since a \000 would be metafied. */
|
||||
if (!*x || !*y)
|
||||
return 0;
|
||||
return xi == yi ||
|
||||
(((c->stat & C_IGNCASE) ?
|
||||
((isupper(xi) ? tolower(xi) : xi) ==
|
||||
|
@ -2926,7 +2929,10 @@ rangematch(char **patptr, int ch, int rchar)
|
|||
* and optional ^ have already been skipped. */
|
||||
|
||||
char *pat = *patptr;
|
||||
#ifdef HAVE_STRCOLL
|
||||
/* We don't use strcoll() for ranges, since it can have side
|
||||
* effects. It's less necessary now we have [:posix:] ranges.
|
||||
*/
|
||||
#if 0
|
||||
char l_buf[2], r_buf[2], ch_buf[2];
|
||||
|
||||
ch_buf[0] = ch;
|
||||
|
@ -2944,7 +2950,7 @@ rangematch(char **patptr, int ch, int rchar)
|
|||
break;
|
||||
} else if (*pat == '-' && pat[-1] != rchar &&
|
||||
pat[1] != Outbrack) {
|
||||
#ifdef HAVE_STRCOLL
|
||||
#if 0
|
||||
l_buf[0] = PPAT(-1);
|
||||
r_buf[0] = PAT(1);
|
||||
if (strcoll(l_buf, ch_buf) <= 0 &&
|
||||
|
|
|
@ -241,6 +241,7 @@ lexsave(void)
|
|||
cmdsp = 0;
|
||||
inredir = 0;
|
||||
hdocs = NULL;
|
||||
histactive = 0;
|
||||
|
||||
ls->next = lstack;
|
||||
lstack = ls;
|
||||
|
|
|
@ -91,6 +91,7 @@ static struct optname optns[] = {
|
|||
{NULL, "braceccl", 0, BRACECCL},
|
||||
{NULL, "bsdecho", OPT_EMULATE|OPT_SH, BSDECHO},
|
||||
{NULL, "cdablevars", 0, CDABLEVARS},
|
||||
{NULL, "chasedots", 0, CHASEDOTS},
|
||||
{NULL, "chaselinks", 0, CHASELINKS},
|
||||
{NULL, "clobber", OPT_ALL, CLOBBER},
|
||||
{NULL, "completealiases", 0, COMPLETEALIASES},
|
||||
|
|
26
Src/parse.c
26
Src/parse.c
|
@ -72,7 +72,13 @@ struct list dummy_list;
|
|||
|
||||
#define YYERROR { tok = LEXERR; return NULL; }
|
||||
#define YYERRORV { tok = LEXERR; return; }
|
||||
#define COND_ERROR(X,Y) do{herrflush();zerr(X,Y,0);YYERROR}while(0)
|
||||
#define COND_ERROR(X,Y) do { \
|
||||
zwarn(X,Y,0); \
|
||||
herrflush(); \
|
||||
if (noerrs != 2) \
|
||||
errflag = 1; \
|
||||
YYERROR \
|
||||
} while(0)
|
||||
|
||||
#define make_list() allocnode(N_LIST)
|
||||
#define make_sublist() allocnode(N_SUBLIST)
|
||||
|
@ -140,11 +146,13 @@ par_event(void)
|
|||
}
|
||||
if (!l) {
|
||||
if (errflag) {
|
||||
yyerror();
|
||||
yyerror(0);
|
||||
return NULL;
|
||||
}
|
||||
yyerror(1);
|
||||
herrflush();
|
||||
yyerror();
|
||||
if (noerrs != 2)
|
||||
errflag = 1;
|
||||
return NULL;
|
||||
} else {
|
||||
l->right = par_event();
|
||||
|
@ -163,7 +171,7 @@ parse_list(void)
|
|||
yylex();
|
||||
ret = par_list();
|
||||
if (tok == LEXERR) {
|
||||
yyerror();
|
||||
yyerror(0);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
|
@ -1480,7 +1488,7 @@ par_cond_multi(char *a, LinkList l)
|
|||
|
||||
/**/
|
||||
static void
|
||||
yyerror(void)
|
||||
yyerror(int noerr)
|
||||
{
|
||||
int t0;
|
||||
|
||||
|
@ -1488,9 +1496,11 @@ yyerror(void)
|
|||
if (!yytext || !yytext[t0] || yytext[t0] == '\n')
|
||||
break;
|
||||
if (t0 == 20)
|
||||
zerr("parse error near `%l...'", yytext, 20);
|
||||
zwarn("parse error near `%l...'", yytext, 20);
|
||||
else if (t0)
|
||||
zerr("parse error near `%l'", yytext, t0);
|
||||
zwarn("parse error near `%l'", yytext, t0);
|
||||
else
|
||||
zerr("parse error", NULL, 0);
|
||||
zwarn("parse error", NULL, 0);
|
||||
if (!noerr && noerrs != 2)
|
||||
errflag = 1;
|
||||
}
|
||||
|
|
99
Src/utils.c
99
Src/utils.c
|
@ -30,23 +30,12 @@
|
|||
#include "zsh.mdh"
|
||||
#include "utils.pro"
|
||||
|
||||
/* Print an error */
|
||||
|
||||
/**/
|
||||
void
|
||||
zwarnnam(const char *cmd, const char *fmt, const char *str, int num)
|
||||
{
|
||||
int waserr;
|
||||
|
||||
waserr = errflag;
|
||||
zerrnam(cmd, fmt, str, num);
|
||||
errflag = waserr;
|
||||
}
|
||||
|
||||
/* name of script being sourced */
|
||||
|
||||
/**/
|
||||
char *scriptname;
|
||||
|
||||
/* Print an error */
|
||||
|
||||
/**/
|
||||
void
|
||||
|
@ -57,7 +46,27 @@ zerr(const char *fmt, const char *str, int num)
|
|||
errflag = 1;
|
||||
return;
|
||||
}
|
||||
zwarn(fmt, str, num);
|
||||
errflag = 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
zerrnam(const char *cmd, const char *fmt, const char *str, int num)
|
||||
{
|
||||
if (errflag || noerrs)
|
||||
return;
|
||||
|
||||
zwarnnam(cmd, fmt, str, num);
|
||||
errflag = 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
zwarn(const char *fmt, const char *str, int num)
|
||||
{
|
||||
if (errflag || noerrs)
|
||||
return;
|
||||
trashzle();
|
||||
/*
|
||||
* scriptname is set when sourcing scripts, so that we get the
|
||||
|
@ -68,25 +77,29 @@ zerr(const char *fmt, const char *str, int num)
|
|||
nicezputs((isset(SHINSTDIN) && !locallevel) ? "zsh" :
|
||||
scriptname ? scriptname : argzero, stderr);
|
||||
fputs(": ", stderr);
|
||||
zerrnam(NULL, fmt, str, num);
|
||||
zerrmsg(fmt, str, num);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
zerrnam(const char *cmd, const char *fmt, const char *str, int num)
|
||||
zwarnnam(const char *cmd, const char *fmt, const char *str, int num)
|
||||
{
|
||||
if (cmd) {
|
||||
if (errflag || noerrs)
|
||||
return;
|
||||
errflag = 1;
|
||||
trashzle();
|
||||
if (unset(SHINSTDIN) || locallevel) {
|
||||
nicezputs(scriptname ? scriptname : argzero, stderr);
|
||||
fputs(": ", stderr);
|
||||
}
|
||||
nicezputs(cmd, stderr);
|
||||
if (errflag || noerrs)
|
||||
return;
|
||||
trashzle();
|
||||
if (unset(SHINSTDIN) || locallevel) {
|
||||
nicezputs(scriptname ? scriptname : argzero, stderr);
|
||||
fputs(": ", stderr);
|
||||
}
|
||||
nicezputs(cmd, stderr);
|
||||
fputs(": ", stderr);
|
||||
zerrmsg(fmt, str, num);
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
zerrmsg(const char *fmt, const char *str, int num)
|
||||
{
|
||||
while (*fmt)
|
||||
if (*fmt == '%') {
|
||||
fmt++;
|
||||
|
@ -302,7 +315,7 @@ slashsplit(char *s)
|
|||
|
||||
/**/
|
||||
static int
|
||||
xsymlinks(char *s, int flag)
|
||||
xsymlinks(char *s)
|
||||
{
|
||||
char **pp, **opp;
|
||||
char xbuf2[PATH_MAX*2], xbuf3[PATH_MAX*2];
|
||||
|
@ -325,15 +338,9 @@ xsymlinks(char *s, int flag)
|
|||
*p = '\0';
|
||||
continue;
|
||||
}
|
||||
if (unset(CHASELINKS)) {
|
||||
strcat(xbuf, "/");
|
||||
strcat(xbuf, *pp);
|
||||
zsfree(*pp);
|
||||
continue;
|
||||
}
|
||||
sprintf(xbuf2, "%s/%s", xbuf, *pp);
|
||||
t0 = readlink(unmeta(xbuf2), xbuf3, PATH_MAX);
|
||||
if (t0 == -1 || !flag) {
|
||||
if (t0 == -1) {
|
||||
strcat(xbuf, "/");
|
||||
strcat(xbuf, *pp);
|
||||
zsfree(*pp);
|
||||
|
@ -342,9 +349,9 @@ xsymlinks(char *s, int flag)
|
|||
metafy(xbuf3, t0, META_NOALLOC);
|
||||
if (*xbuf3 == '/') {
|
||||
strcpy(xbuf, "");
|
||||
xsymlinks(xbuf3 + 1, flag);
|
||||
xsymlinks(xbuf3 + 1);
|
||||
} else
|
||||
xsymlinks(xbuf3, flag);
|
||||
xsymlinks(xbuf3);
|
||||
zsfree(*pp);
|
||||
}
|
||||
}
|
||||
|
@ -352,19 +359,19 @@ xsymlinks(char *s, int flag)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* expand symlinks in s, and remove other weird things */
|
||||
/*
|
||||
* expand symlinks in s, and remove other weird things:
|
||||
* note that this always expands symlinks.
|
||||
*/
|
||||
|
||||
/**/
|
||||
char *
|
||||
xsymlink(char *s)
|
||||
{
|
||||
if (unset(CHASELINKS))
|
||||
return ztrdup(s);
|
||||
if (*s != '/')
|
||||
return NULL;
|
||||
*xbuf = '\0';
|
||||
if (!xsymlinks(s + 1, 1))
|
||||
return ztrdup(s);
|
||||
xsymlinks(s + 1);
|
||||
if (!*xbuf)
|
||||
return ztrdup("/");
|
||||
return ztrdup(xbuf);
|
||||
|
@ -374,15 +381,10 @@ xsymlink(char *s)
|
|||
void
|
||||
print_if_link(char *s)
|
||||
{
|
||||
int chase;
|
||||
|
||||
if (*s == '/') {
|
||||
chase = opts[CHASELINKS];
|
||||
opts[CHASELINKS] = 1;
|
||||
*xbuf = '\0';
|
||||
if (xsymlinks(s + 1, 1))
|
||||
if (xsymlinks(s + 1))
|
||||
printf(" -> "), zputs(*xbuf ? xbuf : "/", stdout);
|
||||
opts[CHASELINKS] = chase;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -573,7 +575,8 @@ getnameddir(char *name)
|
|||
/* Retrieve an entry from the password table/database for this user. */
|
||||
struct passwd *pw;
|
||||
if ((pw = getpwnam(name))) {
|
||||
char *dir = xsymlink(pw->pw_dir);
|
||||
char *dir = isset(CHASELINKS) ? xsymlink(pw->pw_dir)
|
||||
: ztrdup(pw->pw_dir);
|
||||
adduserdir(name, dir, ND_USERNAME, 1);
|
||||
str = dupstring(dir);
|
||||
zsfree(dir);
|
||||
|
@ -3202,7 +3205,7 @@ getkeystring(char *s, int *len, int fromwhere, int *misc)
|
|||
int meta = 0, control = 0;
|
||||
|
||||
if (fromwhere == 6)
|
||||
t = tmp;
|
||||
t = buf = tmp;
|
||||
else if (fromwhere != 4)
|
||||
t = buf = zhalloc(strlen(s) + 1);
|
||||
else {
|
||||
|
|
|
@ -1171,6 +1171,7 @@ enum {
|
|||
BRACECCL,
|
||||
BSDECHO,
|
||||
CDABLEVARS,
|
||||
CHASEDOTS,
|
||||
CHASELINKS,
|
||||
CLOBBER,
|
||||
COMPLETEALIASES,
|
||||
|
|
|
@ -100,7 +100,7 @@ fi])
|
|||
dnl Do you want large file support, if available?
|
||||
undefine([lfs])dnl
|
||||
AC_ARG_ENABLE(lfs,
|
||||
[ --enable-lfs turn on support for large files],
|
||||
[ --disable-lfs turn off support for large files],
|
||||
[lfs="$enableval"], [lfs=yes])
|
||||
|
||||
dnl Pathnames for global zsh scripts
|
||||
|
@ -183,7 +183,7 @@ AC_SUBST(zlogout)dnl
|
|||
dnl Do you want dynamically loaded binary modules.
|
||||
undefine([dynamic])dnl
|
||||
AC_ARG_ENABLE(dynamic,
|
||||
[ --enable-dynamic allow dynamically loaded binary modules],
|
||||
[ --disable-dynamic turn off dynamically loaded binary modules],
|
||||
[dynamic="$enableval"], [dynamic=yes])
|
||||
|
||||
dnl Do you want to compile as K&R C.
|
||||
|
@ -599,7 +599,7 @@ main() { return sizeof(ino_t) < 8; }
|
|||
if test $lfs != no -o $zsh_cv_off_t_is_64_bit = yes \
|
||||
-o $zsh_cv_ino_t_is_64_bit = yes; then
|
||||
AC_CACHE_CHECK(if compiler has a 64 bit type, zsh_cv_64_bit_type,
|
||||
[if test $lfs != xyes -a $lfs != xno; then
|
||||
[if test $lfs != yes -a $lfs != no; then
|
||||
zsh_64_BIT_TYPE(${lfs}, zsh_cv_64_bit_type, force)
|
||||
else
|
||||
zsh_64_BIT_TYPE(long long, zsh_cv_64_bit_type)
|
||||
|
|
Loading…
Reference in a new issue