mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-23 16:40:24 +02:00
Initial revision
This commit is contained in:
parent
4a198fed6e
commit
c4b0e2f297
3 changed files with 560 additions and 0 deletions
367
Completion/Base/_values
Normal file
367
Completion/Base/_values
Normal file
|
@ -0,0 +1,367 @@
|
|||
#autoload
|
||||
|
||||
setopt localoptions extendedglob
|
||||
|
||||
local name arg def descr xor str tmp ret=1 expl nm="$compstate[nmatches]"
|
||||
local snames odescr gdescr sep
|
||||
typeset -A names onames xors _values
|
||||
|
||||
# Probably fill our cache.
|
||||
|
||||
if [[ "$*" != "$_vals_cache_args" ]]; then
|
||||
_vals_cache_args="$*"
|
||||
|
||||
unset _vals_cache_{sep,descr,names,onames,snames,xors,odescr}
|
||||
|
||||
typeset -gA _vals_cache_{names,onames,xors}
|
||||
_vals_cache_snames=()
|
||||
_vals_cache_odescr=()
|
||||
|
||||
# Get the separator, if any.
|
||||
|
||||
if [[ "$1" = -s ]]; then
|
||||
_vals_cache_sep="$2"
|
||||
shift 2
|
||||
fi
|
||||
|
||||
# This is the description string for the values.
|
||||
|
||||
_vals_cache_descr="$1"
|
||||
shift
|
||||
|
||||
# Now parse the descriptions.
|
||||
|
||||
while (( $# )); do
|
||||
|
||||
# Get the `name', anything before an unquoted colon.
|
||||
|
||||
if [[ "$1" = *[^\\]:* ]]; then
|
||||
name="${${${(M)1#*[^\\]:}[1,-2]}//\\\\:/:}"
|
||||
else
|
||||
name="$1"
|
||||
fi
|
||||
|
||||
descr=''
|
||||
xor=''
|
||||
|
||||
# Get a description, if any.
|
||||
|
||||
if [[ "$name" = *\[*\] ]]; then
|
||||
descr="${${name#*\[}[1,-2]}"
|
||||
name="${name%%\[*}"
|
||||
fi
|
||||
|
||||
# Get the names of other values that are mutually exclusive with
|
||||
# this one.
|
||||
|
||||
if [[ "$name" = \(*\)* ]]; then
|
||||
xor="${${name[2,-1]}%%\)*}"
|
||||
name="${name#*\)}"
|
||||
fi
|
||||
|
||||
# Finally see if this value may appear more than once.
|
||||
|
||||
if [[ "$name" = \** ]]; then
|
||||
name="$name[2,-1]"
|
||||
else
|
||||
xor="$xor $name"
|
||||
fi
|
||||
|
||||
# Store the information in the cache.
|
||||
|
||||
_vals_cache_odescr=( "$_vals_cache_odescr[@]" "${name}:$descr" )
|
||||
[[ -n "$xor" ]] && _vals_cache_xors[$name]="${${xor##[ ]#}%%[ ]#}"
|
||||
|
||||
# Get the description and store that.
|
||||
|
||||
if [[ "$1" = *[^\\]:* ]]; then
|
||||
descr=":${1#*[^\\]:}"
|
||||
else
|
||||
descr=''
|
||||
fi
|
||||
|
||||
if [[ "$descr" = ::* ]]; then
|
||||
|
||||
# Optional argument.
|
||||
|
||||
_vals_cache_onames[$name]="$descr[3,-1]"
|
||||
elif [[ "$descr" = :* ]]; then
|
||||
|
||||
# Mandatory argument.
|
||||
|
||||
_vals_cache_names[$name]="$descr[2,-1]"
|
||||
else
|
||||
|
||||
# No argument.
|
||||
|
||||
_vals_cache_snames=( "$_vals_cache_snames[@]" "$name" )
|
||||
fi
|
||||
shift
|
||||
done
|
||||
fi
|
||||
|
||||
snames=( "$_vals_cache_snames[@]" )
|
||||
names=( "${(@kv)_vals_cache_names}" )
|
||||
onames=( "${(@kv)_vals_cache_onames}" )
|
||||
xors=( "${(@kv)_vals_cache_xors}" )
|
||||
odescr=( "$_vals_cache_odescr[@]" )
|
||||
gdescr="$_vals_cache_descr"
|
||||
sep="$_vals_cache_sep"
|
||||
|
||||
if [[ -n "$sep" ]]; then
|
||||
|
||||
# We have a separator character. We parse the PREFIX and SUFFIX to
|
||||
# see if any of the values that must not appear more than once are
|
||||
# already on the line.
|
||||
|
||||
while [[ "$PREFIX" = *${sep}* ]]; do
|
||||
|
||||
# Get one part, remove it from PREFIX and put it into IPREFIX.
|
||||
|
||||
tmp="${PREFIX%%${sep}*}"
|
||||
PREFIX="${PREFIX#*${sep}}"
|
||||
IPREFIX="${IPREFIX}${tmp}${sep}"
|
||||
|
||||
# Get the value `name'.
|
||||
|
||||
name="${tmp%%\=*}"
|
||||
|
||||
if [[ "$tmp" = *\=* ]]; then
|
||||
_values[$name]="${tmp#*\=}"
|
||||
else
|
||||
_values[$name]=''
|
||||
fi
|
||||
|
||||
# And remove the descriptions for the values this one makes
|
||||
# superfluous.
|
||||
|
||||
if [[ -n "$xors[$name]" ]]; then
|
||||
snames=( "${(@)snames:#(${(j:|:)~${=xors[$name]}})}" )
|
||||
odescr=( "${(@)odescr:#(${(j:|:)~${=xors[$name]}}):*}" )
|
||||
unset {names,onames,xors}\[${^=tmp}\]
|
||||
fi
|
||||
done
|
||||
if [[ "$SUFFIX" = *${sep}* ]]; then
|
||||
|
||||
# The same for the suffix.
|
||||
|
||||
str="${SUFFIX%%${sep}*}"
|
||||
SUFFIX="${SUFFIX#*${sep}}"
|
||||
while [[ -n "$SUFFIX" ]]; do
|
||||
tmp="${PREFIX%%${sep}*}"
|
||||
if [[ "$SUFFIX" = *${sep}* ]]; then
|
||||
SUFFIX="${SUFFIX#*${sep}}"
|
||||
else
|
||||
SUFFIX=''
|
||||
fi
|
||||
PREFIX="${PREFIX#*${sep}}"
|
||||
IPREFIX="${IPREFIX}${tmp}${sep}"
|
||||
|
||||
name="${tmp%%\=*}"
|
||||
|
||||
if [[ "$tmp" = *\=* ]]; then
|
||||
_values[$name]="${tmp#*\=}"
|
||||
else
|
||||
_values[$name]=''
|
||||
fi
|
||||
|
||||
if [[ -n "$xors[$name]" ]]; then
|
||||
snames=( "${(@)snames:#(${(j:|:)~${=xors[$name]}})}" )
|
||||
odescr=( "${(@)odescr:#(${(j:|:)~${=xors[$name]}}):*}" )
|
||||
unset {names,onames,xors}\[${^=tmp}\]
|
||||
fi
|
||||
done
|
||||
SUFFIX="$str"
|
||||
fi
|
||||
fi
|
||||
|
||||
descr=''
|
||||
str="$PREFIX$SUFFIX"
|
||||
|
||||
if [[ "$str" = *\=* ]]; then
|
||||
|
||||
# The string from the line contains a `=', so we get the stuff before
|
||||
# it and after it and see what we can do here...
|
||||
|
||||
name="${str%%\=*}"
|
||||
arg="${str#*\=}"
|
||||
|
||||
if (( $snames[(I)${name}] )); then
|
||||
|
||||
# According to our information, the value doesn't get an argument,
|
||||
# so give up.
|
||||
|
||||
_message "\`${name}' gets no value"
|
||||
return 1
|
||||
elif (( $+names[$name] )); then
|
||||
|
||||
# It has to get an argument, we skip over the name and complete
|
||||
# the argument (below).
|
||||
|
||||
def="$names[$name]"
|
||||
if ! compset -P '*\='; then
|
||||
IPREFIX="${IPREFIX}${name}="
|
||||
PREFIX="$arg"
|
||||
SUFFIX=''
|
||||
fi
|
||||
elif (( $+onames[$name] )); then
|
||||
|
||||
# Gets an optional argument, same as previous case.
|
||||
|
||||
def="$onames[$name]"
|
||||
if ! compset -P '*\='; then
|
||||
IPREFIX="${IPREFIX}${name}="
|
||||
PREFIX="$arg"
|
||||
SUFFIX=''
|
||||
fi
|
||||
else
|
||||
local pre="$PREFIX" suf="$SUFFIX"
|
||||
|
||||
# The part before the `=' isn't a known value name, so we see if
|
||||
# it matches only one of the known names.
|
||||
|
||||
if [[ "$PREFIX" = *\=* ]]; then
|
||||
PREFIX="${PREFIX%%\=*}"
|
||||
pre="${pre#*\=}"
|
||||
SUFFIX=''
|
||||
else
|
||||
SUFFIX="${SUFFIX%%\=*}"
|
||||
pre="${suf#*\=}"
|
||||
suf=''
|
||||
fi
|
||||
|
||||
tmp=( "${(@k)names}" "${(@k)onames}" )
|
||||
compadd -M 'r:|[-_]=* r:|=*' -D tmp - "$tmp[@]"
|
||||
|
||||
if [[ $#tmp -eq 1 ]]; then
|
||||
|
||||
# It does, so we use that name and immediatly start completing
|
||||
# the argument for it.
|
||||
|
||||
IPREFIX="${IPREFIX}${tmp[1]}="
|
||||
PREFIX="$pre"
|
||||
SUFFIX="$suf"
|
||||
|
||||
def="$names[$tmp[1]]"
|
||||
[[ -z "$def" ]] && def="$onames[$tmp[1]]"
|
||||
elif (( $#tmp )); then
|
||||
_message "ambiguous option \`${PREFIX}${SUFFIX}'"
|
||||
return 1
|
||||
else
|
||||
_message "unknown option \`${PREFIX}${SUFFIX}'"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
|
||||
# No `=', just complete value names.
|
||||
|
||||
_description expl "$gdescr"
|
||||
|
||||
[[ -n "$sep" && ${#snames}+${#names}+${#onames} -ne 1 ]] &&
|
||||
expl=( "-qS$sep" "$expl[@]" )
|
||||
|
||||
tmp=''
|
||||
if [[ -n "$compconfig[describe_values]" &&
|
||||
"$compconfig[describe_values]" != *\!${words[1]}* ]]; then
|
||||
if _display tmp odescr -M 'r:|[_-]=* r:|=*'; then
|
||||
if (( $#snames )); then
|
||||
compadd "$expl[@]" -y tmp -M 'r:|[_-]=* r:|=*' - \
|
||||
"$snames[@]" && ret=0
|
||||
compadd -n -S= -J "_$gdescr" -M 'r:|[_-]=* r:|=*' - \
|
||||
"${(@k)names}" && ret=0
|
||||
compadd -n -qS= -J "_$gdescr" -M 'r:|[_-]=* r:|=*' - \
|
||||
"${(@k)onames}" && ret=0
|
||||
elif (( $#names )); then
|
||||
compadd -n -S= "$expl[@]" -y tmp -M 'r:|[_-]=* r:|=*' - \
|
||||
"${(@k)names}" && ret=0
|
||||
compadd -n -qS= -J "_$gdescr" -M 'r:|[_-]=* r:|=*' - \
|
||||
"${(@k)onames}" && ret=0
|
||||
else
|
||||
compadd -n -qS= "$expl[@]" -y tmp -M 'r:|[_-]=* r:|=*' - \
|
||||
"${(@k)onames}" && ret=0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [[ -z "$tmp" ]]; then
|
||||
compadd "$expl[@]" -M 'r:|[_-]=* r:|=*' - "$snames[@]" && ret=0
|
||||
compadd -S= "$expl[@]" -M 'r:|[_-]=* r:|=*' - "${(@k)names}" && ret=0
|
||||
compadd -qS= "$expl[@]" -M 'r:|[_-]=* r:|=*' - "${(@k)onames}" && ret=0
|
||||
fi
|
||||
return ret
|
||||
fi
|
||||
|
||||
if [[ -z "$def" ]]; then
|
||||
_message 'no value'
|
||||
return 1
|
||||
else
|
||||
local action
|
||||
|
||||
descr="${${${(M)def#*[^\\]:}[1,-2]}//\\\\:/:}"
|
||||
action="${${def#*[^\\]:}//\\\\:/:}"
|
||||
|
||||
_description expl "$descr"
|
||||
|
||||
# We add the separator character as a autoremovable suffix unless
|
||||
# we have only one possible value left.
|
||||
|
||||
[[ -n "$sep" && ${#snames}+${#names}+${#onames} -ne 1 ]] &&
|
||||
expl=( "-qS$sep" "$expl[@]" )
|
||||
|
||||
if [[ "$action" = -\>* ]]; then
|
||||
values=( "${(@kv)_values}" )
|
||||
state="${${action[3,-1]##[ ]#}%%[ ]#}"
|
||||
compstate[restore]=''
|
||||
return 1
|
||||
else
|
||||
typeset -A values
|
||||
|
||||
values=( "${(@kv)_values}" )
|
||||
|
||||
if [[ "$action" = \ # ]]; then
|
||||
|
||||
# An empty action means that we should just display a message.
|
||||
|
||||
_message "$descr"
|
||||
return 1
|
||||
|
||||
elif [[ "$action" = \(\(*\)\) ]]; then
|
||||
local ws
|
||||
|
||||
# ((...)) contains literal strings with descriptions.
|
||||
|
||||
eval ws\=\( "${action[3,-3]}" \)
|
||||
|
||||
if _display tmp ws; then
|
||||
compadd "$expl[@]" -y tmp - "${(@)ws%%:*}"
|
||||
else
|
||||
_message "$descr"
|
||||
return 1
|
||||
fi
|
||||
elif [[ "$action" = \(*\) ]]; then
|
||||
|
||||
# Anything inside `(...)' is added directly.
|
||||
|
||||
compadd "$expl[@]" - ${=action[2,-2]}
|
||||
elif [[ "$action" = \{*\} ]]; then
|
||||
|
||||
# A string in braces is evaluated.
|
||||
|
||||
eval "$action[2,-2]"
|
||||
|
||||
elif [[ "$action" = \ * ]]; then
|
||||
|
||||
# If the action starts with a space, we just call it.
|
||||
|
||||
${(e)=~action}
|
||||
else
|
||||
|
||||
# Otherwise we call it with the description-arguments built above.
|
||||
|
||||
action=( $=action )
|
||||
${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ nm -ne "$compstate[nmatches]" ]]
|
159
Completion/User/_nslookup
Normal file
159
Completion/User/_nslookup
Normal file
|
@ -0,0 +1,159 @@
|
|||
#compdef nslookup
|
||||
|
||||
# This may also be called from the `nslookup' wrapper function during
|
||||
# `vared'iting a line.
|
||||
# In this case this function tries to call other user-defined functions
|
||||
# for certain contexts before adding completion. If these functions are
|
||||
# defined, they are called and the default completions from this function
|
||||
# are not added. The functions called are named `_nslookup_<state>', with
|
||||
# `<state>' being any of:
|
||||
#
|
||||
# command
|
||||
# When completing the first word on the line.
|
||||
# redirect
|
||||
# When completing after a redirection operator.
|
||||
#
|
||||
# Also, when completing after the first word, if the first word contains
|
||||
# only lower case letters, we try to call the function `_nslookup_<word>',
|
||||
# where `<word>' is the first word from the line. If the first word contains
|
||||
# other characters than lower case letters, we try to call the function
|
||||
# `_nslookup_host'.
|
||||
|
||||
setopt localoptions extendedglob
|
||||
|
||||
local state expl ret=1 setopts
|
||||
|
||||
setopts=(
|
||||
'all[print current values]' \
|
||||
'(nodebug)debug[simple debugging information]' \
|
||||
'(debug)nodebug[no simple debugging information]' \
|
||||
'(nod2)d2[extra debugging information]' \
|
||||
'(d2)nod2[no extra debugging information]' \
|
||||
'(nodefname)defname[append default domain name]' \
|
||||
'(defname)nodefname[don'"'"'t append default domain name]' \
|
||||
'(nosearch)search[append search list]' \
|
||||
'(search)nosearch[don'"'"'t append search list]' \
|
||||
'(norecurse)recurse[name server may query other servers]' \
|
||||
'(recurse)norecurse[name server may not query other servers]' \
|
||||
'(novc)vc[use virtual circuit]' \
|
||||
'(vc)novc[don'"'"'t use virtual circuit]' \
|
||||
'(noignoretc)ignoretc[ignore packet truncation errors]' \
|
||||
'(ignoretc)noignoretc[don'"'"'t ignore packet truncation errors]' \
|
||||
'class[change query class]:query class:((in\:Internet\ class chaos\:CHAOS\ class hesiod\:MIT\ Athena\ Hesiod\ class any\:wildcard\ \(any\ of\ the\ above\)))'
|
||||
'domain[change default domain]:default domain:_hosts'
|
||||
'srchlist[change default domain and search list]: :->srchlist'
|
||||
'port[change name server port]:name server port:'
|
||||
{query,}type'[change type of information query]:query information type:((a\:internet\ address cname\:canonical\ name\ for\ alias hinfo\:CPU\ and\ operating\ system\ type minfo\:mailbox\ or\ mail\ list\ information mx\:mail\ exchanger ns\:name\ server\ for\ zone ptr\:host\ name\ or\ other\ information soa\:domain\'"'"'s\ \`start-of-authority\'"'"'\ information txt\:text\ information uinfo\:user\ information wks\:supported\ well-known\ services))'
|
||||
'retry[change number of retries]:number of retries:'
|
||||
'root[change name of root server]:root server:_hosts'
|
||||
'timeout[change initial timeout interval]:timeout (seconds):'
|
||||
)
|
||||
|
||||
if [[ -n "$compcontext" ]]; then
|
||||
if [[ CURRENT -eq 1 ]]; then
|
||||
|
||||
funcall ret _nslookup_command && return ret
|
||||
|
||||
_description expl 'command'
|
||||
compadd "$expl[@]" - server lserver root finger ls view help set && ret=0
|
||||
_hosts && ret=0
|
||||
return ret
|
||||
elif [[ "$compstate[context]" = redirect ]]; then
|
||||
|
||||
funcall ret _nslookup_redirect && return ret
|
||||
|
||||
if [[ "$words[1]" != (finger|ls) ]]; then
|
||||
_message "redirection not allowed for command \`$words[1]'"
|
||||
return 1
|
||||
elif [[ "$compstate[redirect]" = '>' ]]; then
|
||||
_description expl 'write to file'
|
||||
elif [[ "$compstate[redirect]" = '>>' ]]; then
|
||||
_description expl 'append to file'
|
||||
else
|
||||
_message "unknown redirection operator \`$compstate[redirect]'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_files "$expl[@]"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$words[1]" = [a-z]## ]]; then
|
||||
funcall ret _nslookup_$words[1] && return ret
|
||||
else
|
||||
funcall ret _nslookup_host && return ret
|
||||
fi
|
||||
|
||||
case "$words[1]" in
|
||||
(|l)server)
|
||||
_description expl 'new default server'
|
||||
_hosts "$expl[@]"
|
||||
return
|
||||
;;
|
||||
root|exit|help|\?)
|
||||
return 1
|
||||
;;
|
||||
finger)
|
||||
_message 'finger name'
|
||||
return 1
|
||||
;;
|
||||
ls)
|
||||
_arguments -s \
|
||||
'-t[records of given type]:query information type:((a\:internet\ address cname\:canonical\ name\ for\ alias hinfo\:CPU\ and\ operating\ system\ type minfo\:mailbox\ or\ mail\ list\ information mx\:mail\ exchanger ns\:name\ server\ for\ zone ptr\:host\ name\ or\ other\ information soa\:domain\'"'"'s\ \`start-of-authority\'"'"'\ information txt\:text\ information uinfo\:user\ information wks\:supported\ well-known\ services))' \
|
||||
'-a[aliases of hosts in domain]' \
|
||||
'-d[all records]' \
|
||||
'-h[CPU and operating system information]' \
|
||||
'-s[well-known services]' \
|
||||
':domain:_hosts'
|
||||
return
|
||||
;;
|
||||
view)
|
||||
_description expl 'view file'
|
||||
_files "$expl[@]"
|
||||
return
|
||||
;;
|
||||
set)
|
||||
typeset -A values
|
||||
|
||||
_values 'state information' "$setopts[@]" && ret=0
|
||||
|
||||
[[ -z "$state" ]] && return ret
|
||||
;;
|
||||
*)
|
||||
_description expl 'server'
|
||||
_hosts "$expl[@]"
|
||||
return
|
||||
esac
|
||||
fi
|
||||
|
||||
# Now comes the command line option completion part.
|
||||
|
||||
if [[ -z "$state" ]]; then
|
||||
local line
|
||||
typeset -A options
|
||||
|
||||
_arguments \
|
||||
"-${(@)^${(@M)setopts:#*\]:*}/\[/=[}" \
|
||||
"-${(@)^setopts:#(\(|*\]:)*}" \
|
||||
"${(@)^${(@)${(@M)setopts:#\(*}/\)/)-}/\(/(-}" \
|
||||
':host to find:_hosts' \
|
||||
':server:_hosts' && ret=0
|
||||
fi
|
||||
|
||||
# This is completion after `srchlist' for both types.
|
||||
|
||||
if [[ -n "$state" ]]; then
|
||||
if compset -P '*/'; then
|
||||
_description expl 'search list entry'
|
||||
else
|
||||
_description expl 'default domain name and first search list entry'
|
||||
fi
|
||||
if [[ -n "$_vals_cache_multi" ]]; then
|
||||
_hosts "$expl[@]" -qS/ -r "/\\- \\t\\n$_vals_cache_multi"
|
||||
else
|
||||
_hosts "$expl[@]" -qS/
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
return ret
|
34
Functions/Misc/nslookup
Normal file
34
Functions/Misc/nslookup
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Simple wrapper function for `nslookup'. With completion if you are using
|
||||
# the function based completion system.
|
||||
|
||||
setopt localoptions completealiases
|
||||
|
||||
local char line compcontext=nslookup pid
|
||||
|
||||
trap 'print -p exit;return' INT
|
||||
|
||||
coproc command nslookup
|
||||
pid=$!
|
||||
|
||||
while read -pk1 char; do
|
||||
line="$line$char"
|
||||
[[ "$line" = *'
|
||||
> ' ]] && break
|
||||
done
|
||||
print -nr - "$line"
|
||||
|
||||
line=''
|
||||
while vared -p '> ' line; do
|
||||
print -p "$line"
|
||||
line=''
|
||||
while read -pk1 char; do
|
||||
line="$line$char"
|
||||
[[ "$line" = *'
|
||||
> ' ]] && break
|
||||
done
|
||||
print -nr - "$line"
|
||||
line=''
|
||||
done
|
||||
|
||||
print -p exit
|
||||
wait $pid
|
Loading…
Add table
Add a link
Reference in a new issue