mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-12-06 17:51:18 +01:00
zsh-workers/9635
This commit is contained in:
parent
06cd60e1cf
commit
74ccd8d5a3
8 changed files with 378 additions and 242 deletions
|
|
@ -1,14 +1,11 @@
|
||||||
#autoload
|
#autoload
|
||||||
|
|
||||||
local name gropt format gname hidden hide match ign
|
local name gropt=-J format gname hidden hide match opts
|
||||||
|
|
||||||
gropt=(-J)
|
opts=()
|
||||||
hide=()
|
|
||||||
match=()
|
|
||||||
ign=()
|
|
||||||
|
|
||||||
if [[ "$1" = -([12]|)[VJ] ]]; then
|
if [[ "$1" = -([12]|)[VJ] ]]; then
|
||||||
gropt=("$1")
|
gropt="$1"
|
||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -24,14 +21,14 @@ zstyle -s ":completion:${curcontext}:$1" format format ||
|
||||||
zstyle -s ":completion:${curcontext}:$1" hidden hidden
|
zstyle -s ":completion:${curcontext}:$1" hidden hidden
|
||||||
if [[ "$hidden" = (all|yes|true|1|on) ]]; then
|
if [[ "$hidden" = (all|yes|true|1|on) ]]; then
|
||||||
[[ "$hidden" = all ]] && format=''
|
[[ "$hidden" = all ]] && format=''
|
||||||
hide=(-n)
|
opts=(-n)
|
||||||
fi
|
fi
|
||||||
zstyle -s ":completion:${curcontext}:$1" group-name gname &&
|
zstyle -s ":completion:${curcontext}:$1" group-name gname &&
|
||||||
[[ -z "$gname" ]] && gname="$1"
|
[[ -z "$gname" ]] && gname="$1"
|
||||||
zstyle -s ":completion:${curcontext}:$1" matcher match &&
|
zstyle -s ":completion:${curcontext}:$1" matcher match &&
|
||||||
match=(-M "${(q)match}")
|
opts=($opts -M "${(q)match}")
|
||||||
if zstyle -a ":completion:${curcontext}:$1" ignored-patterns _comp_ignore; then
|
if zstyle -a ":completion:${curcontext}:$1" ignored-patterns _comp_ignore; then
|
||||||
ign=(-F _comp_ignore)
|
opts=( $opts -F _comp_ignore)
|
||||||
else
|
else
|
||||||
_comp_ignore=()
|
_comp_ignore=()
|
||||||
fi
|
fi
|
||||||
|
|
@ -41,15 +38,15 @@ shift 2
|
||||||
|
|
||||||
if [[ -n "$gname" ]]; then
|
if [[ -n "$gname" ]]; then
|
||||||
if [[ -n "$format" ]]; then
|
if [[ -n "$format" ]]; then
|
||||||
eval "${name}=($hide $match $ign $gropt ${(q)gname} -X \"${format}\")"
|
eval "${name}=($opts $gropt ${(q)gname} -X \"${format}\")"
|
||||||
else
|
else
|
||||||
eval "${name}=($hide $match $ign $gropt ${(q)gname})"
|
eval "${name}=($opts $gropt ${(q)gname})"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [[ -n "$format" ]]; then
|
if [[ -n "$format" ]]; then
|
||||||
eval "${name}=($hide $match $ign $gropt -default- -X \"${format}\")"
|
eval "${name}=($opts $gropt -default- -X \"${format}\")"
|
||||||
else
|
else
|
||||||
eval "${name}=($hide $match $ign $gropt -default-)"
|
eval "${name}=($opts $gropt -default-)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,21 @@
|
||||||
local opts opt type=file glob group gopts dopts aopts tmp _file_pat_checked=yes
|
local opts opt type=file glob group gopts dopts aopts tmp _file_pat_checked=yes
|
||||||
local hasign ign
|
local hasign ign
|
||||||
|
|
||||||
opts=()
|
zparseopts \
|
||||||
group=()
|
/tmp ftmp g+tmp \
|
||||||
gopts=()
|
qopts nopts 1opts 2opts P:opts S:opts r:opts R:opts W:opts X:opts M:opts \
|
||||||
dopts=(-/)
|
F:opts J:group V:group
|
||||||
aopts=(-f)
|
|
||||||
ign=()
|
|
||||||
while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:12n" opt; do
|
|
||||||
case "$opt" in
|
|
||||||
/) type="${type}dir" ;;
|
|
||||||
g) type="${type}glob"; gopts=(-g "$OPTARG") ;;
|
|
||||||
[qn12]) opts=("$opts[@]" "-$opt" ) ;;
|
|
||||||
[JV]) group=( "-$opt" "$OPTARG") ;;
|
|
||||||
F) opts=("$opts[@]" "-$opt" "$OPTARG"); hasign=yes ;;
|
|
||||||
[^f]) opts=("$opts[@]" "-$opt" "$OPTARG") ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ "$group[2]" = files ]]; then
|
type="${(@j::M)${(@)tmp#-}#?}"
|
||||||
|
[[ -n "$type" ]] || type=f
|
||||||
|
if (( $tmp[(I)-g*] )); then
|
||||||
|
gopts=( -g ${(j: :)${(M)tmp:#-g*}#-g} )
|
||||||
|
else
|
||||||
|
gopts=()
|
||||||
|
fi
|
||||||
|
(( $opts[(I)-F*] )) && hasign=yes
|
||||||
|
|
||||||
|
if [[ "$group[1]" = -?files ]]; then
|
||||||
opts=("$opts[@]" "$group[@]")
|
opts=("$opts[@]" "$group[@]")
|
||||||
group=()
|
group=()
|
||||||
fi
|
fi
|
||||||
|
|
@ -32,36 +29,36 @@ fi
|
||||||
if zstyle -s ":completion:${curcontext}:directories" file-patterns tmp &&
|
if zstyle -s ":completion:${curcontext}:directories" file-patterns tmp &&
|
||||||
[[ -n "$tmp" ]]; then
|
[[ -n "$tmp" ]]; then
|
||||||
dopts=(-g "$tmp")
|
dopts=(-g "$tmp")
|
||||||
if [[ "$type" = (*dir*glob*|*glob*dir*) ]]; then
|
if [[ "$type" = (*/*g*|*g*/*) ]]; then
|
||||||
type=glob
|
type=g
|
||||||
elif [[ "$type" != *(dir|glob)* ]]; then
|
elif [[ "$type" != *[/g]* ]]; then
|
||||||
type="${type}dir"
|
type="${type}/"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if zstyle -s ":completion:${curcontext}:globbed-files" file-patterns tmp &&
|
if zstyle -s ":completion:${curcontext}:globbed-files" file-patterns tmp &&
|
||||||
[[ -n "$tmp" ]]; then
|
[[ -n "$tmp" ]]; then
|
||||||
gopts=(-g "$tmp")
|
gopts=(-g "$tmp")
|
||||||
if [[ "$type" != (*dir*glob*|*glob*dir*) ]]; then
|
if [[ "$type" != (*/*g*|*g*/*) ]]; then
|
||||||
if [[ "$type" = *(dir|glob)* ]]; then
|
if [[ "$type" = *[g/]* ]]; then
|
||||||
type=glob
|
type=g
|
||||||
else
|
else
|
||||||
type=globall
|
type=ga
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case "$type" in
|
case "$type" in
|
||||||
*dir*glob*|*glob*dir*) _tags globbed-files all-files ;;
|
*/*g*|*g*/*) _tags globbed-files all-files ;;
|
||||||
*all*glob*|*glob*all*) _tags globbed-files all-files ;;
|
*a*g*|*g*a*) _tags globbed-files all-files ;;
|
||||||
*glob*) _tags globbed-files directories all-files ;;
|
*g*) _tags globbed-files directories all-files ;;
|
||||||
*dir*) _tags directories all-files ;;
|
*/*) _tags directories all-files ;;
|
||||||
*) _tags all-files ;;
|
*) _tags all-files ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
while _tags; do
|
while _tags; do
|
||||||
if _requested all-files; then
|
if _requested all-files; then
|
||||||
if (( $#group )); then
|
if (( $#group )); then
|
||||||
group[2]=all-files
|
group[1]="${group[1][1,2]}all-files"
|
||||||
_setup all-files
|
_setup all-files
|
||||||
[[ -z "$hasign" ]] &&
|
[[ -z "$hasign" ]] &&
|
||||||
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
||||||
|
|
@ -72,7 +69,7 @@ while _tags; do
|
||||||
elif _requested directories; then
|
elif _requested directories; then
|
||||||
if _requested globbed-files; then
|
if _requested globbed-files; then
|
||||||
if (( $#group )); then
|
if (( $#group )); then
|
||||||
group[2]=globbed-files
|
group[1]="${group[1][1,2]}globbed-files"
|
||||||
_setup globbed-files
|
_setup globbed-files
|
||||||
[[ -z "$hasign" ]] &&
|
[[ -z "$hasign" ]] &&
|
||||||
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
||||||
|
|
@ -81,7 +78,7 @@ while _tags; do
|
||||||
_path_files "$opts[@]" "$ign[@]" "$dopts[@]" "$gopts[@]" && return 0
|
_path_files "$opts[@]" "$ign[@]" "$dopts[@]" "$gopts[@]" && return 0
|
||||||
else
|
else
|
||||||
if (( $#group )); then
|
if (( $#group )); then
|
||||||
group[2]=directories
|
group[1]="${group[1][1,2]}directories"
|
||||||
_setup directories
|
_setup directories
|
||||||
[[ -z "$hasign" ]] &&
|
[[ -z "$hasign" ]] &&
|
||||||
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
||||||
|
|
@ -91,13 +88,13 @@ while _tags; do
|
||||||
fi
|
fi
|
||||||
elif _requested globbed-files; then
|
elif _requested globbed-files; then
|
||||||
if (( $#group )); then
|
if (( $#group )); then
|
||||||
group[2]=globbed-files
|
group[1]="${group[1][1,2]}globbed-files"
|
||||||
_setup globbed-files
|
_setup globbed-files
|
||||||
[[ -z "$hasign" ]] &&
|
[[ -z "$hasign" ]] &&
|
||||||
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
zstyle -a ":completion:${curcontext}:all-files" ignored-patterns _comp_ignore &&
|
||||||
ign=(-F _comp_ignore)
|
ign=(-F _comp_ignore)
|
||||||
fi
|
fi
|
||||||
if [[ "$type" = (*dir*glob*|*glob*dir*) ]]; then
|
if [[ "$type" = (*/*g*|*g*/*) ]]; then
|
||||||
_path_files "$opts[@]" "$ign[@]" "$dopts[@]" "$gopts[@]" && return 0
|
_path_files "$opts[@]" "$ign[@]" "$dopts[@]" "$gopts[@]" && return 0
|
||||||
else
|
else
|
||||||
_path_files "$opts[@]" "$ign[@]" "$gopts[@]" && return 0
|
_path_files "$opts[@]" "$ign[@]" "$gopts[@]" && return 0
|
||||||
|
|
|
||||||
|
|
@ -13,22 +13,18 @@ typeset -U tmp2
|
||||||
|
|
||||||
# Get the options.
|
# Get the options.
|
||||||
|
|
||||||
group=()
|
zparseopts -D \
|
||||||
expl=()
|
J:group V:group X:expl \
|
||||||
opts=()
|
P:opts F:opts \
|
||||||
sopts=()
|
S:sopts r:sopts R:sopts qsopts 1sopts 2sopts nsopts \
|
||||||
while getopts "J:V:X:P:F:S:r:R:qM:12n" opt; do
|
M:match
|
||||||
case "$opt" in
|
|
||||||
[JV]) group=("-$opt" "$OPTARG");;
|
sopts=( "$sopts[@]" "$opts[@]" )
|
||||||
X) expl=(-X "$OPTARG");;
|
if (( $#match )); then
|
||||||
[PF]) opts=( "$opts[@]" "-$opt" "$OPTARG")
|
match="${match[1][3,-1]}"
|
||||||
sopts=( "$sopts[@]" "-$opt" "$OPTARG");;
|
else
|
||||||
[SrR]) sopts=( "$sopts[@]" -P "$OPTARG");;
|
match=''
|
||||||
[q12n]) sopts=( "$sopts[@]" "-$opt");;
|
fi
|
||||||
M) match="$OPTARG";;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift OPTIND-1
|
|
||||||
|
|
||||||
# Get the arguments, first the separator, then the array. The array is
|
# Get the arguments, first the separator, then the array. The array is
|
||||||
# stored in `matches'. Further on this array will always contain those
|
# stored in `matches'. Further on this array will always contain those
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
# Utility function for in-path completion. This allows `/u/l/b<TAB>'
|
# Utility function for in-path completion. This allows `/u/l/b<TAB>'
|
||||||
# to complete to `/usr/local/bin'.
|
# to complete to `/usr/local/bin'.
|
||||||
|
|
||||||
local linepath realpath donepath prepath testpath exppath skips
|
local linepath realpath donepath prepath testpath exppath skips skipped
|
||||||
local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre
|
local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre
|
||||||
local pats haspats=no ignore group expl addpfx addsfx remsfx rem remt
|
local pats haspats=no ignore pfxsfx rem remt sopt gopt opt
|
||||||
local nm=$compstate[nmatches] menu mspec matcher mopts atmp sort match
|
local nm=$compstate[nmatches] menu mspec matcher mopts atmp sort match
|
||||||
|
|
||||||
typeset -U prepaths exppaths
|
typeset -U prepaths exppaths
|
||||||
|
|
@ -13,73 +13,50 @@ typeset -U prepaths exppaths
|
||||||
setopt localoptions nullglob rcexpandparam
|
setopt localoptions nullglob rcexpandparam
|
||||||
unsetopt markdirs globsubst shwordsplit nounset
|
unsetopt markdirs globsubst shwordsplit nounset
|
||||||
|
|
||||||
local sopt='-' gopt='' opt
|
|
||||||
exppaths=()
|
exppaths=()
|
||||||
prepaths=('')
|
|
||||||
ignore=()
|
|
||||||
group=()
|
|
||||||
pats=()
|
|
||||||
addpfx=()
|
|
||||||
addsfx=()
|
|
||||||
remsfx=()
|
|
||||||
expl=()
|
|
||||||
matcher=()
|
|
||||||
mopts=()
|
|
||||||
|
|
||||||
# Get the options.
|
# Get the options.
|
||||||
|
|
||||||
while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:12n" opt; do
|
zparseopts \
|
||||||
case "$opt" in
|
P:pfxsfx S:pfxsfx qpfxsfx r:pfxsfx R:pfxsfx \
|
||||||
[12n]) mopts=( "$mopts[@]" "-$opt" )
|
W:prepaths F:ignore M+matcher \
|
||||||
;;
|
J:mopts V:mopts X:mopts 1:mopts 2:mopts n:mopts \
|
||||||
P) addpfx=(-P "$OPTARG")
|
ftmp1 /tmp1 g+tmp1
|
||||||
;;
|
|
||||||
S) addsfx=(-S "$OPTARG")
|
sopt="-${(@j::M)${(@)tmp1#-}#?}"
|
||||||
;;
|
(( $tmp1[(I)-[/g]*] )) && haspats=yes
|
||||||
q) tmp1=yes
|
(( $tmp1[(I)-g*] )) && gopt=yes
|
||||||
;;
|
if (( $tmp1[(I)-/] )); then
|
||||||
[rR]) remsfx=("-$opt" "$OPTARG")
|
pats=( '*(-/)' ${=${(M)tmp1:#-g*}#-g} )
|
||||||
;;
|
else
|
||||||
W) tmp1="$OPTARG"
|
pats=( "${(@)=${(@M)tmp1:#-g*}#-g}" )
|
||||||
if [[ "$tmp1[1]" = '(' ]]; then
|
fi
|
||||||
prepaths=( ${^=tmp1[2,-2]%/}/ )
|
|
||||||
elif [[ "$tmp1[1]" = '/' ]]; then
|
if (( $#prepaths )); then
|
||||||
prepaths=( "$tmp1/" )
|
tmp1="${prepaths[1][3,-1]}"
|
||||||
else
|
if [[ "$tmp1[1]" = '(' ]]; then
|
||||||
# In this case the variable should be an array, so
|
prepaths=( ${^=tmp1[2,-2]%/}/ )
|
||||||
# don't use an extra ${=...}.
|
elif [[ "$tmp1[1]" = '/' ]]; then
|
||||||
prepaths=( ${(P)^tmp1%/}/ )
|
prepaths=( "$tmp1/" )
|
||||||
(( ! $#prepaths )) && prepaths=( ${tmp1%/}/ )
|
else
|
||||||
fi
|
prepaths=( ${(P)^tmp1%/}/ )
|
||||||
(( ! $#prepaths )) && prepaths=( '' )
|
(( ! $#prepaths )) && prepaths=( ${tmp1%/}/ )
|
||||||
;;
|
fi
|
||||||
F) tmp1="$OPTARG"
|
(( ! $#prepaths )) && prepaths=( '' )
|
||||||
if [[ "$tmp1[1]" = '(' ]]; then
|
else
|
||||||
ignore=( ${=tmp1[2,-2]} )
|
prepaths=( '' )
|
||||||
else
|
fi
|
||||||
ignore=( ${(P)tmp1} )
|
|
||||||
fi
|
if (( $#ignore )); then
|
||||||
;;
|
tmp1="${ignore[1][3,-1]}"
|
||||||
[JV]) group=("-$opt" "$OPTARG")
|
if [[ "$tmp1[1]" = '(' ]]; then
|
||||||
;;
|
ignore=( ${=tmp1[2,-2]} )
|
||||||
X) expl=(-X "$OPTARG")
|
else
|
||||||
;;
|
ignore=( ${(P)tmp1} )
|
||||||
f) sopt="${sopt}f"
|
fi
|
||||||
pats=("$pats[@]" '*')
|
fi
|
||||||
;;
|
|
||||||
/) sopt="${sopt}/"
|
(( $#matcher )) && mspec="${matcher[1][3,-1]}"
|
||||||
pats=("$pats[@]" '*(-/)')
|
|
||||||
haspats=yes
|
|
||||||
;;
|
|
||||||
g) gopt='-g'
|
|
||||||
pats=("$pats[@]" ${=OPTARG})
|
|
||||||
haspats=yes
|
|
||||||
;;
|
|
||||||
M) mspec="$OPTARG"
|
|
||||||
matcher=(-M "$OPTARG")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -z "$_file_pat_checked" ]] &&
|
if [[ -z "$_file_pat_checked" ]] &&
|
||||||
zstyle -s ":completion:${curcontext}:files" file-patterns tmp1 &&
|
zstyle -s ":completion:${curcontext}:files" file-patterns tmp1 &&
|
||||||
|
|
@ -88,20 +65,34 @@ if [[ -z "$_file_pat_checked" ]] &&
|
||||||
gopt=''
|
gopt=''
|
||||||
sopt=-/
|
sopt=-/
|
||||||
else
|
else
|
||||||
gopt='-g'
|
gopt=yes
|
||||||
sopt=-
|
sopt=-
|
||||||
fi
|
fi
|
||||||
pats=( $=tmp1 )
|
pats=( $=tmp1 )
|
||||||
haspats=yes
|
haspats=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if (( ! ( $#group + $#expl ) )); then
|
# If we were given no file selection option, we behave as if we were given
|
||||||
|
# a `-f'.
|
||||||
|
|
||||||
|
if [[ "$sopt" = -(f|) ]]; then
|
||||||
|
if [[ -z "$gopt" ]]; then
|
||||||
|
sopt='-f'
|
||||||
|
pats=('*')
|
||||||
|
else
|
||||||
|
unset sopt
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( ! $mopts[(I)-[JVX]*] )); then
|
||||||
|
local expl
|
||||||
|
|
||||||
if [[ -z "$gopt" && "$sopt" = -/ ]]; then
|
if [[ -z "$gopt" && "$sopt" = -/ ]]; then
|
||||||
_description directories expl directory
|
_description directories expl directory
|
||||||
else
|
else
|
||||||
_description files expl file
|
_description files expl file
|
||||||
fi
|
fi
|
||||||
tmp1=$expl[(I)-M]
|
tmp1=$expl[(I)-M*]
|
||||||
if (( tmp1 )); then
|
if (( tmp1 )); then
|
||||||
mspec="$mspec $expl[1+tmp1]"
|
mspec="$mspec $expl[1+tmp1]"
|
||||||
if (( $#matcher )); then
|
if (( $#matcher )); then
|
||||||
|
|
@ -110,20 +101,7 @@ if (( ! ( $#group + $#expl ) )); then
|
||||||
matcher=(-M "$expl[1+tmp1]")
|
matcher=(-M "$expl[1+tmp1]")
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
mopts=( "$mopts[@]" "$expl[@]" )
|
||||||
|
|
||||||
[[ -n "$tmp1" && $#addsfx -ne 0 ]] && addsfx[1]=-qS
|
|
||||||
|
|
||||||
# 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
|
fi
|
||||||
|
|
||||||
if zstyle -s ":completion:${curcontext}:files" sort tmp1; then
|
if zstyle -s ":completion:${curcontext}:files" sort tmp1; then
|
||||||
|
|
@ -140,8 +118,7 @@ if zstyle -s ":completion:${curcontext}:files" sort tmp1; then
|
||||||
if [[ "$sort" = on ]]; then
|
if [[ "$sort" = on ]]; then
|
||||||
sort=''
|
sort=''
|
||||||
else
|
else
|
||||||
group=( "${(@)group/#-J/-V}" )
|
mopts=( "${(@)mopts/#-J/-V}" )
|
||||||
expl=( "${(@)expl/#-J/-V}" )
|
|
||||||
|
|
||||||
tmp2=()
|
tmp2=()
|
||||||
for tmp1 in "$pats[@]"; do
|
for tmp1 in "$pats[@]"; do
|
||||||
|
|
@ -157,9 +134,15 @@ if zstyle -s ":completion:${curcontext}:files" sort tmp1; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Skip over sequences of slashes.
|
# Check if we have to skip over sequences of slashes. The value of $skips
|
||||||
|
# is used below to match the pathname components we always have to accept
|
||||||
|
# immediatly.
|
||||||
|
|
||||||
zstyle -t ":completion:${curcontext}:paths" squeeze-slashes && skips=yes
|
if zstyle -t ":completion:${curcontext}:paths" squeeze-slashes; then
|
||||||
|
skips='((.|..|)/)##'
|
||||||
|
else
|
||||||
|
skips='((.|..)/)##'
|
||||||
|
fi
|
||||||
|
|
||||||
# We get the prefix and the suffix from the line and save the whole
|
# We get the prefix and the suffix from the line and save the whole
|
||||||
# original string. Then we see if we will do menucompletion.
|
# original string. Then we see if we will do menucompletion.
|
||||||
|
|
@ -182,7 +165,7 @@ eorig="$orig"
|
||||||
|
|
||||||
if (( $#ignore )); then
|
if (( $#ignore )); then
|
||||||
_comp_ignore=( "$_comp_ignore[@]" "$ignore[@]" )
|
_comp_ignore=( "$_comp_ignore[@]" "$ignore[@]" )
|
||||||
(( $expl[(I)-F] )) || expl=( "$expl[@]" -F _comp_ignore )
|
(( $mopts[(I)-F*] )) || mopts=( "$mopts[@]" -F _comp_ignore )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Now let's have a closer look at the string to complete.
|
# Now let's have a closer look at the string to complete.
|
||||||
|
|
@ -256,26 +239,13 @@ for prepath in "$prepaths[@]"; do
|
||||||
tsuf="$suf"
|
tsuf="$suf"
|
||||||
testpath="$donepath"
|
testpath="$donepath"
|
||||||
|
|
||||||
tmp1=( "$prepath$realpath$donepath" )
|
tmp2="${(M)tpre##${~skips}}"
|
||||||
|
tpre="${tpre#$tmp2}"
|
||||||
|
|
||||||
|
tmp1=( "$prepath$realpath$donepath$tmp2" )
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
|
|
||||||
# Skip over `./' and `../'.
|
|
||||||
|
|
||||||
if [[ "$tpre" = (.|..)/* ]]; then
|
|
||||||
tmp1=( ${^tmp1}${tpre%%/*}/ )
|
|
||||||
tpre="${tpre#*/}"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Skip over multiple slashes?
|
|
||||||
|
|
||||||
if [[ -n "$skips" && "$tpre" = /* ]]; then
|
|
||||||
tmp1=( ${^tmp1}/ )
|
|
||||||
tpre="${tpre#/}"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the prefix and suffix for matching.
|
# Get the prefix and suffix for matching.
|
||||||
|
|
||||||
if [[ "$tpre" = */* ]]; then
|
if [[ "$tpre" = */* ]]; then
|
||||||
|
|
@ -289,45 +259,24 @@ for prepath in "$prepaths[@]"; do
|
||||||
# Get the matching files by globbing.
|
# Get the matching files by globbing.
|
||||||
|
|
||||||
if [[ "$tpre$tsuf" = */* ]]; then
|
if [[ "$tpre$tsuf" = */* ]]; then
|
||||||
tmp2=( ${^tmp1}*(-/) )
|
if [[ ! -o globdots && "$PREFIX" = .* ]]; then
|
||||||
[[ ! -o globdots && "$PREFIX" = .* ]] &&
|
tmp1=( ${^tmp1}${skipped}*(-/) ${^tmp1}${slash}.*(-/) )
|
||||||
tmp2=( "$tmp2[@]" ${^tmp1}.*(-/) )
|
else
|
||||||
|
tmp1=( ${^tmp1}${skipped}*(-/) )
|
||||||
|
fi
|
||||||
if [[ -o globdots || "$PREFIX" = .* ]] &&
|
if [[ -o globdots || "$PREFIX" = .* ]] &&
|
||||||
zstyle -s ":completion:${curcontext}:paths" special-dirs atmp; then
|
zstyle -s ":completion:${curcontext}:paths" special-dirs atmp; then
|
||||||
if [[ "$atmp" = (yes|true|1|on) ]]; then
|
if [[ "$atmp" = (yes|true|1|on) ]]; then
|
||||||
tmp2=( "$tmp2[@]" . .. )
|
tmp1=( "$tmp1[@]" . .. )
|
||||||
elif [[ "$atmp" = .. ]]; then
|
elif [[ "$atmp" = .. ]]; then
|
||||||
tmp2=( "$tmp2[@]" .. )
|
tmp1=( "$tmp1[@]" .. )
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
tmp2=( ${^tmp1}${^~pats} )
|
if [[ ! -o globdots && "$PREFIX" = .* ]]; then
|
||||||
[[ ! -o globdots && "$PREFIX" = .* ]] &&
|
tmp1=( ${^tmp1}${skipped}${^~pats} ${^tmp1}${slash}.${^~pats} )
|
||||||
tmp2=( "$tmp2[@]" ${^tmp1}.${^~pats} )
|
else
|
||||||
if (( $#tmp2 )) &&
|
tmp1=( ${^tmp1}${skipped}${^~pats} )
|
||||||
zstyle -s ":completion:${curcontext}:files" ignore-parents rem &&
|
|
||||||
[[ ( "$rem" != *dir* || "$pats" = '*(-/)' ) &&
|
|
||||||
( "$rem" != *..* || "$tmp1" = *../* ) ]]; then
|
|
||||||
if [[ "$rem" = *parent* ]]; then
|
|
||||||
for i in "$tmp2[@]"; do
|
|
||||||
if [[ -d "$i" && "$i" = */* ]]; then
|
|
||||||
remt="${i%/*}"
|
|
||||||
while [[ "$remt" = */* ]]; do
|
|
||||||
[[ "$remt" -ef "$i" ]] && break
|
|
||||||
remt="${remt%/*}"
|
|
||||||
done
|
|
||||||
[[ "$remt" = */* || "$remt" -ef "$i" ]] &&
|
|
||||||
_comp_ignore=( "$_comp_ignore[@]" "${(q)i}" )
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
if [[ "$rem" = *pwd* ]]; then
|
|
||||||
for i in "$tmp2[@]"; do
|
|
||||||
[[ "$i" -ef "$PWD" ]] && _comp_ignore=( "$_comp_ignore[@]" "${(q)i}" )
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
(( $#_comp_ignore )) && (( $expl[(I)-F] )) ||
|
|
||||||
expl=( "$expl[@]" -F _comp_ignore )
|
|
||||||
fi
|
fi
|
||||||
if [[ "$sopt" = *[/f]* && ( -o globdots || "$PREFIX" = .* ) ]] &&
|
if [[ "$sopt" = *[/f]* && ( -o globdots || "$PREFIX" = .* ) ]] &&
|
||||||
zstyle -s ":completion:${curcontext}:paths" special-dirs atmp; then
|
zstyle -s ":completion:${curcontext}:paths" special-dirs atmp; then
|
||||||
|
|
@ -338,22 +287,28 @@ for prepath in "$prepaths[@]"; do
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
tmp1=( "$tmp2[@]" )
|
|
||||||
|
|
||||||
if [[ -n "$PREFIX$SUFFIX" ]]; then
|
if [[ -n "$PREFIX$SUFFIX" ]]; then
|
||||||
# See which of them match what's on the line.
|
# See which of them match what's on the line.
|
||||||
|
|
||||||
builtin compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
|
if [[ -n "$_comp_correct" ]]; then
|
||||||
|
tmp2=( "$tmp1[@]" )
|
||||||
|
builtin compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
|
||||||
|
|
||||||
if [[ $#tmp1 -eq 0 && -n "$_comp_correct" ]]; then
|
if [[ $#tmp1 -eq 0 && -n "$_comp_correct" ]]; then
|
||||||
tmp1=( "$tmp2[@]" )
|
tmp1=( "$tmp2[@]" )
|
||||||
compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp2:t}"
|
compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp2:t}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
[[ "$tmp1[1]" = */* ]] && tmp2=( "$tmp1[@]" )
|
||||||
|
|
||||||
|
builtin compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If no file matches, save the expanded path and continue with
|
# If no file matches, save the expanded path and continue with
|
||||||
# the outer loop.
|
# the outer loop.
|
||||||
|
|
||||||
if [[ $#tmp1 -eq 0 ]]; then
|
if (( ! $#tmp1 )); then
|
||||||
if [[ "$tmp2[1]" = */* ]]; then
|
if [[ "$tmp2[1]" = */* ]]; then
|
||||||
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
|
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
|
||||||
if [[ "$tmp2[1]" = */* ]]; then
|
if [[ "$tmp2[1]" = */* ]]; then
|
||||||
|
|
@ -384,8 +339,7 @@ for prepath in "$prepaths[@]"; do
|
||||||
|
|
||||||
if [[ -z "$tpre$tsuf" && -n "$pre$suf" ]]; then
|
if [[ -z "$tpre$tsuf" && -n "$pre$suf" ]]; then
|
||||||
tmp1=( "$tmp2[@]" )
|
tmp1=( "$tmp2[@]" )
|
||||||
addsfx=(-S '')
|
pfxsfx=(-S '' "$pfxsfx[@]")
|
||||||
remsfx=()
|
|
||||||
break;
|
break;
|
||||||
elif [[ "$haspats" = no && -z "$tpre$tsuf" &&
|
elif [[ "$haspats" = no && -z "$tpre$tsuf" &&
|
||||||
"$pre" = */ && -z "$suf" ]]; then
|
"$pre" = */ && -z "$suf" ]]; then
|
||||||
|
|
@ -397,6 +351,29 @@ for prepath in "$prepaths[@]"; do
|
||||||
continue 2
|
continue 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$tpre$tsuf" != */* && $#tmp1 -ne 0 ]] &&
|
||||||
|
zstyle -s ":completion:${curcontext}:files" ignore-parents rem &&
|
||||||
|
[[ ( "$rem" != *dir* || "$pats" = '*(-/)' ) &&
|
||||||
|
( "$rem" != *..* || "$tmp1" = *../* ) ]]; then
|
||||||
|
if [[ "$rem" = *parent* ]]; then
|
||||||
|
for i in ${(M)^tmp1:#*/*}(-/); do
|
||||||
|
remt="${${i#$prepath$realpath$donepath}%/*}"
|
||||||
|
while [[ "$remt" = */* ]]; do
|
||||||
|
[[ "$prepath$realpath$donepath$remt" -ef "$i" ]] && break
|
||||||
|
remt="${remt%/*}"
|
||||||
|
done
|
||||||
|
[[ "$remt" = */* || "$remt" -ef "$i" ]] &&
|
||||||
|
_comp_ignore=( "$_comp_ignore[@]" "${(q)i}" )
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "$rem" = *pwd* ]]; then
|
||||||
|
for i in ${^tmp1}(-/); do
|
||||||
|
[[ "$i" -ef "$PWD" ]] && _comp_ignore=( "$_comp_ignore[@]" "${(q)i}" )
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
(( $#_comp_ignore && $mopts[(I)-F*] )) || mopts=( "$mopts[@]" -F _comp_ignore )
|
||||||
|
fi
|
||||||
|
|
||||||
# Step over to the next component, if any.
|
# Step over to the next component, if any.
|
||||||
|
|
||||||
if [[ "$tpre" = */* ]]; then
|
if [[ "$tpre" = */* ]]; then
|
||||||
|
|
@ -408,10 +385,16 @@ for prepath in "$prepaths[@]"; do
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# There are more components, so add a slash to the files we are
|
# There are more components, so skip over the next components and make a
|
||||||
# collecting.
|
# slash be added.
|
||||||
|
|
||||||
tmp1=( ${^tmp1}/ )
|
tmp2="${(M)tpre##((.|..|)/)##}" ###
|
||||||
|
if [[ -n "$tmp2" ]]; then
|
||||||
|
skipped="/$tmp2"
|
||||||
|
tpre="${tpre#$tmp2}"
|
||||||
|
else
|
||||||
|
skipped=/
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# The next loop searches the first ambiguous component.
|
# The next loop searches the first ambiguous component.
|
||||||
|
|
@ -471,30 +454,30 @@ for prepath in "$prepaths[@]"; do
|
||||||
if [[ "$tmp3" = */* ]]; then
|
if [[ "$tmp3" = */* ]]; then
|
||||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" -s "/${tmp3#*/}" \
|
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" -s "/${tmp3#*/}" \
|
||||||
-W "$prepath$realpath$testpath" \
|
-W "$prepath$realpath$testpath" \
|
||||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
"$pfxsfx[@]" \
|
||||||
-M "r:|/=* r:|=* $mspec" "$group[@]" "$expl[@]" \
|
-M "r:|/=* r:|=* $mspec" \
|
||||||
- "${(@)tmp1%%/*}"
|
- "${(@)tmp1%%/*}"
|
||||||
else
|
else
|
||||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||||
-W "$prepath$realpath$testpath" \
|
-W "$prepath$realpath$testpath" \
|
||||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
"$pfxsfx[@]" \
|
||||||
-M "r:|/=* r:|=* $mspec" "$group[@]" "$expl[@]" \
|
-M "r:|/=* r:|=* $mspec" \
|
||||||
- "$tmp1[@]"
|
- "$tmp1[@]"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [[ "$tmp3" = */* ]]; then
|
if [[ "$tmp3" = */* ]]; then
|
||||||
atmp=( -Qf "$mopts[@]" -p "$linepath$tmp2"
|
atmp=( -Qf "$mopts[@]" -p "$linepath$tmp2"
|
||||||
-W "$prepath$realpath$testpath"
|
-W "$prepath$realpath$testpath"
|
||||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]"
|
"$pfxsfx[@]" \
|
||||||
-M "r:|/=* r:|=* $mspec" "$group[@]" "$expl[@]" )
|
-M "r:|/=* r:|=* $mspec" )
|
||||||
for i in "$tmp1[@]"; do
|
for i in "$tmp1[@]"; do
|
||||||
compadd "$atmp[@]" -s "/${i#*/}" - "${i%%/*}"
|
compadd "$atmp[@]" -s "/${i#*/}" - "${i%%/*}"
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||||
-W "$prepath$realpath$testpath" \
|
-W "$prepath$realpath$testpath" \
|
||||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
"$pfxsfx[@]" \
|
||||||
-M "r:|/=* r:|=* $mspec" "$group[@]" "$expl[@]" \
|
-M "r:|/=* r:|=* $mspec" \
|
||||||
- "$tmp1[@]"
|
- "$tmp1[@]"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
@ -543,8 +526,8 @@ for prepath in "$prepaths[@]"; do
|
||||||
compquote tmp4 tmp1
|
compquote tmp4 tmp1
|
||||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp4" \
|
compadd -Qf "$mopts[@]" -p "$linepath$tmp4" \
|
||||||
-W "$prepath$realpath$testpath" \
|
-W "$prepath$realpath$testpath" \
|
||||||
"$addpfx[@]" "$addsfx[@]" "$remsfx[@]" \
|
"$pfxsfx[@]" \
|
||||||
-M "r:|/=* r:|=* $mspec" "$group[@]" "$expl[@]" \
|
-M "r:|/=* r:|=* $mspec" \
|
||||||
- "$tmp1[@]"
|
- "$tmp1[@]"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
@ -553,14 +536,17 @@ done
|
||||||
# expanded paths that are different from the string on the line, we add
|
# expanded paths that are different from the string on the line, we add
|
||||||
# them as possible matches.
|
# them as possible matches.
|
||||||
|
|
||||||
exppaths=( "${(@)exppaths:#$eorig}" )
|
|
||||||
|
|
||||||
if zstyle -t ":completion:${curcontext}:paths" expand prefix &&
|
if zstyle -t ":completion:${curcontext}:paths" expand prefix &&
|
||||||
[[ $#exppaths -gt 0 && nm -eq compstate[nmatches] ]]; then
|
[[ nm -eq compstate[nmatches] ]]; then
|
||||||
PREFIX="${opre}"
|
|
||||||
SUFFIX="${osuf}"
|
exppaths=( "${(@)exppaths:#$eorig}" )
|
||||||
compadd -Q "$mopts[@]" -S '' "$group[@]" "$expl[@]" \
|
|
||||||
-M "r:|/=* r:|=* $mspec" -p "$linepath" - "$exppaths[@]"
|
if (( $#exppaths )); then
|
||||||
|
PREFIX="${opre}"
|
||||||
|
SUFFIX="${osuf}"
|
||||||
|
compadd -Q "$mopts[@]" -S '' \
|
||||||
|
-M "r:|/=* r:|=* $mspec" -p "$linepath" - "$exppaths[@]"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ nm -ne compstate[nmatches] ]]
|
[[ nm -ne compstate[nmatches] ]]
|
||||||
|
|
|
||||||
|
|
@ -22,19 +22,16 @@ local matchflags opt group expl nm=$compstate[nmatches] opre osuf opts match
|
||||||
|
|
||||||
# Get the options.
|
# Get the options.
|
||||||
|
|
||||||
group=()
|
zparseopts -D \
|
||||||
expl=()
|
J:group V:group \
|
||||||
opts=()
|
P:opts F:opts S:opts r:opts R:opts qopts 1opts 2opts nopts \
|
||||||
while getopts "J:V:X:P:F:S:r:R:qM:12n" opt; do
|
X:expl M:match
|
||||||
case "$opt" in
|
|
||||||
[JV]) group=("-$opt" "$OPTARG");;
|
if (( $#match )); then
|
||||||
X) expl=(-X "$OPTARG");;
|
match="${match[1][3,-1]}"
|
||||||
[q12n]) opts=( "$opts[@]" "-$opt" );;
|
else
|
||||||
M) match="$OPTARG";;
|
match=''
|
||||||
*) opts=( "$opts[@]" "-$opt" "$OPTARG" );;
|
fi
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift OPTIND-1
|
|
||||||
|
|
||||||
# Get the string from the line.
|
# Get the string from the line.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,4 +111,28 @@ The resulting strings are stored in the var(array).
|
||||||
item(tt(zregexparse))(
|
item(tt(zregexparse))(
|
||||||
This implements the internals of the `tt(_regex_arguments)'.
|
This implements the internals of the `tt(_regex_arguments)'.
|
||||||
)
|
)
|
||||||
|
item(tt(zparseopts) [ tt(-D) ] var(specs))(
|
||||||
|
This builtin can be used to parse the positional arguments and put
|
||||||
|
options found in them into separate arrays. Each var(spec) describes
|
||||||
|
one option which is given as its first character. If the second
|
||||||
|
character is either `tt(:)' or `tt(+)', the option takes an argument
|
||||||
|
(either directly following the option in the same word or in the next
|
||||||
|
word). After the option character or the `tt(:)' or `tt(+)' follows
|
||||||
|
the name of the array in which the option should be stored. The only
|
||||||
|
difference between the form with a `t(:)' and the one with a `tt(+)'
|
||||||
|
is that in the first case the option and its argument will be put in
|
||||||
|
the array only once (later occurrences overwriting earlier ones),
|
||||||
|
whereas with `tt(+)' all occurrences are moved to the array.
|
||||||
|
|
||||||
|
If the tt(-D) option is given, all options found are removed from the
|
||||||
|
positional parameters leaving only those strings that did not match
|
||||||
|
any of the var(specs).
|
||||||
|
|
||||||
|
For example, calling `tt(zparseopts afoo b:bar c+bar)' with the
|
||||||
|
strings `tt(-a)', `tt(-bx)', `tt(-c)', `tt(y)', `tt(-cz)', `tt(baz)'
|
||||||
|
and `tt(-cend)' as positional arguments will set the array tt(foo) to
|
||||||
|
contain the element `tt(-a)' and the array tt(bar) to the strings
|
||||||
|
`tt(-bx)', `tt(-cy)' and `tt(-cz)'. The `tt(baz)' and any strings
|
||||||
|
after it will not be used.
|
||||||
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
|
||||||
|
|
@ -1155,10 +1155,149 @@ bin_zregexparse(char *nam, char **args, char *ops, int func)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct zoptdesc *Zoptdesc;
|
||||||
|
typedef struct zoptarr *Zoptarr;
|
||||||
|
typedef struct zoptval *Zoptval;
|
||||||
|
|
||||||
|
struct zoptdesc {
|
||||||
|
int arg;
|
||||||
|
Zoptarr arr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct zoptarr {
|
||||||
|
char *name;
|
||||||
|
Zoptval vals, last;
|
||||||
|
Zoptarr next;
|
||||||
|
int num;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ZOF_ARG 1
|
||||||
|
#define ZOF_ADD 2
|
||||||
|
|
||||||
|
struct zoptval {
|
||||||
|
char *str;
|
||||||
|
Zoptval next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Zoptarr opt_arrs;
|
||||||
|
|
||||||
|
static Zoptarr
|
||||||
|
get_opt_arr(char *name)
|
||||||
|
{
|
||||||
|
Zoptarr p;
|
||||||
|
|
||||||
|
for (p = opt_arrs; p; p = p->next)
|
||||||
|
if (!strcmp(name, p->name))
|
||||||
|
return p;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bin_zparseopts(char *nam, char **args, char *ops, int func)
|
||||||
|
{
|
||||||
|
char *o, *n, **pp, *str, **aval;
|
||||||
|
Zoptdesc opts[256], d;
|
||||||
|
Zoptarr a;
|
||||||
|
Zoptval v;
|
||||||
|
|
||||||
|
memset(opts, 0, 256 * sizeof(Zoptdesc));
|
||||||
|
opt_arrs = NULL;
|
||||||
|
|
||||||
|
while ((o = *args++)) {
|
||||||
|
if (opts[STOUC(*o)]) {
|
||||||
|
zerrnam(nam, "option described more than once: %s", o, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
d = (Zoptdesc) zhalloc(sizeof(*d));
|
||||||
|
d->arg = (o[1] == ':' ? ZOF_ARG : (o[1] == '+' ? ZOF_ADD : 0));
|
||||||
|
if (!(a = get_opt_arr((n = o + (d->arg ? 2 : 1))))) {
|
||||||
|
a = (Zoptarr) zhalloc(sizeof(*a));
|
||||||
|
a->name = n;
|
||||||
|
a->num = 0;
|
||||||
|
a->vals = a->last = NULL;
|
||||||
|
a->next = opt_arrs;
|
||||||
|
opt_arrs = a;
|
||||||
|
}
|
||||||
|
d->arr = a;
|
||||||
|
opts[STOUC(*o)] = d;
|
||||||
|
}
|
||||||
|
for (pp = pparams; (o = *pp); pp++) {
|
||||||
|
if (*o != '-')
|
||||||
|
break;
|
||||||
|
while (*++o) {
|
||||||
|
if (!(d = opts[STOUC(*o)]))
|
||||||
|
break;
|
||||||
|
if (d->arg) {
|
||||||
|
if (o[1]) {
|
||||||
|
str = (char *) zhalloc(strlen(o) + 2);
|
||||||
|
str[0] = '-';
|
||||||
|
strcpy(str + 1, o);
|
||||||
|
} else if (!pp[1]) {
|
||||||
|
zerrnam(nam, "missing argument for option: -%c", NULL, *o);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
str = (char *) zhalloc(strlen(pp[1]) + 3);
|
||||||
|
str[0] = '-';
|
||||||
|
str[1] = *o;
|
||||||
|
strcpy(str + 2, pp[1]);
|
||||||
|
pp++;
|
||||||
|
}
|
||||||
|
o = "" - 1;
|
||||||
|
} else {
|
||||||
|
str = (char *) zhalloc(3);
|
||||||
|
str[0] = '-';
|
||||||
|
str[1] = *o;
|
||||||
|
str[2] = '\0';
|
||||||
|
}
|
||||||
|
if (d->arg != ZOF_ADD) {
|
||||||
|
for (v = d->arr->vals; v; v = v->next) {
|
||||||
|
if (str[1] == v->str[1]) {
|
||||||
|
v->str = str;
|
||||||
|
str = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (str) {
|
||||||
|
v = (Zoptval) zhalloc(sizeof(*v));
|
||||||
|
v->str = str;
|
||||||
|
v->next = NULL;
|
||||||
|
|
||||||
|
if (d->arr->last)
|
||||||
|
d->arr->last->next = v;
|
||||||
|
else
|
||||||
|
d->arr->vals = v;
|
||||||
|
d->arr->last = v;
|
||||||
|
d->arr->num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*o)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ops['D']) {
|
||||||
|
PERMALLOC {
|
||||||
|
pp = arrdup(pp);
|
||||||
|
} LASTALLOC;
|
||||||
|
|
||||||
|
freearray(pparams);
|
||||||
|
pparams = pp;
|
||||||
|
}
|
||||||
|
for (a = opt_arrs; a; a = a->next) {
|
||||||
|
aval = (char **) zalloc((a->num + 1) * sizeof(char *));
|
||||||
|
for (pp = aval, v = a->vals; v; pp++, v = v->next)
|
||||||
|
*pp = ztrdup(v->str);
|
||||||
|
*pp = NULL;
|
||||||
|
setaparam(a->name, aval);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct builtin bintab[] = {
|
static struct builtin bintab[] = {
|
||||||
BUILTIN("zstyle", 0, bin_zstyle, 0, -1, 0, NULL, NULL),
|
BUILTIN("zstyle", 0, bin_zstyle, 0, -1, 0, NULL, NULL),
|
||||||
BUILTIN("zformat", 0, bin_zformat, 3, -1, 0, NULL, NULL),
|
BUILTIN("zformat", 0, bin_zformat, 3, -1, 0, NULL, NULL),
|
||||||
BUILTIN("zregexparse", 0, bin_zregexparse, 3, -1, 0, "c", NULL),
|
BUILTIN("zregexparse", 0, bin_zregexparse, 3, -1, 0, "c", NULL),
|
||||||
|
BUILTIN("zparseopts", 0, bin_zparseopts, 1, -1, 0, "D", NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,4 @@ moddeps="zsh/complete"
|
||||||
|
|
||||||
objects="zutil.o"
|
objects="zutil.o"
|
||||||
|
|
||||||
autobins="zformat zstyle"
|
autobins="zformat zstyle zregexparse zparseopts"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue