mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-21 10:28:05 +02:00
zsh-3.1.5-pws-17
This commit is contained in:
parent
206237c8ec
commit
53d36e795b
39 changed files with 1103 additions and 221 deletions
Completion
Config
Doc/Zsh
Src
Util
patchlist.txt
10
Completion/Builtins/_stat
Normal file
10
Completion/Builtins/_stat
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#compdef stat
|
||||||
|
|
||||||
|
if [[ "$words[CURRENT-1]" = -[AH] ]]; then
|
||||||
|
compgen -A
|
||||||
|
else
|
||||||
|
[[ "$PREFIX[1]" = + ]] &&
|
||||||
|
compadd - +device +inode +mode +nlink +uid +gid +rdev +size \
|
||||||
|
+atime +mtime +ctime +blksize +block +link
|
||||||
|
_files
|
||||||
|
fi
|
|
@ -1,6 +1,7 @@
|
||||||
DISTFILES_SRC='
|
DISTFILES_SRC='
|
||||||
.distfiles
|
.distfiles
|
||||||
_approximate _compalso _complete _correct _expand _files _list
|
_approximate _closequotes _compalso _complete _correct _expand _files
|
||||||
_main_complete _match _multi_parts _normal _options _parameters
|
_list _main_complete _match _menu _multi_parts _normal _oldlist _options
|
||||||
_path_files _sep_parts _set_options _unset_options compdump compinit
|
_parameters _path_files _sep_parts _set_options _unset_options
|
||||||
|
compdump compinit compinstall
|
||||||
'
|
'
|
||||||
|
|
11
Completion/Core/_closequotes
Normal file
11
Completion/Core/_closequotes
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#autoload
|
||||||
|
|
||||||
|
# If the current completion is in quotes, add the closing quote.
|
||||||
|
# This can clash with some of the more sophisticated forms of completion
|
||||||
|
|
||||||
|
if [[ -n $compstate[quote] && $RBUFFER != *${compstate[quote]}* ]]; then
|
||||||
|
compstate[restore]=''
|
||||||
|
ISUFFIX="$ISUFFIX$compstate[quote]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
21
Completion/Core/_menu
Normal file
21
Completion/Core/_menu
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#autoload
|
||||||
|
|
||||||
|
# This completer is an example showing how menucompletion can be
|
||||||
|
# implemented with the new completion system.
|
||||||
|
# Use this one before the normal _complete completer, as in:
|
||||||
|
#
|
||||||
|
# compconf completer=_menu:_complete
|
||||||
|
|
||||||
|
if [[ -n "$compstate[old_list]" ]]; then
|
||||||
|
|
||||||
|
# We have an old list, keep it and insert the next match.
|
||||||
|
|
||||||
|
compstate[old_list]=keep
|
||||||
|
compstate[insert]=$((compstate[old_insert]+1))
|
||||||
|
else
|
||||||
|
# No old list, make completion insert the first match.
|
||||||
|
|
||||||
|
compstate[insert]=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
|
@ -83,8 +83,7 @@ while true; do
|
||||||
else
|
else
|
||||||
# No exact match, see how many strings match what's on the line.
|
# No exact match, see how many strings match what's on the line.
|
||||||
|
|
||||||
tmp2=( "${(@)matches%%${sep}*}" )
|
compadd -O tmp1 - "${(@)matches%%${sep}*}"
|
||||||
compadd -O tmp1 - "$tmp2[@]"
|
|
||||||
|
|
||||||
if [[ $#tmp1 -eq 1 ]]; then
|
if [[ $#tmp1 -eq 1 ]]; then
|
||||||
|
|
||||||
|
|
29
Completion/Core/_oldlist
Normal file
29
Completion/Core/_oldlist
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#autoload
|
||||||
|
|
||||||
|
# If this is a listing widget and there is already an old list,
|
||||||
|
# and either the compconfig key oldlist_list is `always', or it is not `never'
|
||||||
|
# and the list is not already shown, then use the existing list for listing
|
||||||
|
# (even if it was generated by another widget).
|
||||||
|
if [[ -n $compstate[old_list] && $compconfig[oldlist_list] != never &&
|
||||||
|
$WIDGET = *list* &&
|
||||||
|
( $compconfig[oldlist_list] = always || $compstate[old_list] != shown ) ]]
|
||||||
|
then
|
||||||
|
compstate[old_list]=keep
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If this is a completion widget, and we have a completion inserted already,
|
||||||
|
# and the compconfig key oldlist_menu is not never, then we cycle through the
|
||||||
|
# existing list (even if it was generated by another widget).
|
||||||
|
if [[ -n $compstate[old_insert] && $WIDGET = *complete(|-prefix|-word) &&
|
||||||
|
$compconfig[oldlist_menu] != never ]]; then
|
||||||
|
compstate[old_list]=keep
|
||||||
|
if [[ $WIDGET = *reverse* ]]; then
|
||||||
|
compstate[insert]=$(( compstate[old_insert] - 1 ))
|
||||||
|
else
|
||||||
|
compstate[insert]=$(( compstate[old_insert] + 1 ))
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
|
@ -230,14 +230,15 @@ for prepath in "$prepaths[@]"; do
|
||||||
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.
|
||||||
|
|
||||||
compadd -O tmp2 "$ignore[@]" - "${(@)tmp1##*/}"
|
tmp2=("$tmp1[@]")
|
||||||
|
compadd -D tmp1 "$ignore[@]" - "${(@)tmp1##*/}"
|
||||||
|
|
||||||
# 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 [[ $#tmp2 -eq 0 ]]; then
|
if [[ $#tmp1 -eq 0 ]]; then
|
||||||
if [[ "$tmp1[1]" = */* ]]; then
|
if [[ "$tmp2[1]" = */* ]]; then
|
||||||
tmp2=( "${(@)tmp1#${prepath}${realpath}}" )
|
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
|
||||||
if [[ "$tmp2[1]" = */* ]]; then
|
if [[ "$tmp2[1]" = */* ]]; then
|
||||||
exppaths=( "$exppaths[@]" ${^tmp2%/*}/${tpre}${tsuf} )
|
exppaths=( "$exppaths[@]" ${^tmp2%/*}/${tpre}${tsuf} )
|
||||||
else
|
else
|
||||||
|
@ -246,14 +247,6 @@ for prepath in "$prepaths[@]"; do
|
||||||
fi
|
fi
|
||||||
continue 2
|
continue 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Remove all files that weren't matched.
|
|
||||||
|
|
||||||
if [[ "$tmp1[1]" = */* ]]; then
|
|
||||||
tmp1=( "${(@M)tmp1:#*/(${(j:|:)~${(@)tmp2:q}})}" )
|
|
||||||
else
|
|
||||||
tmp1=( "${(@M)tmp1:#(${(j:|:)~${(@)tmp2:q}})}" )
|
|
||||||
fi
|
|
||||||
elif (( ! $#tmp1 )); then
|
elif (( ! $#tmp1 )); then
|
||||||
continue 2
|
continue 2
|
||||||
fi
|
fi
|
||||||
|
|
216
Completion/Core/compinstall
Normal file
216
Completion/Core/compinstall
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
# This script is to be run by a user to setup the new function based
|
||||||
|
# completion system. The functions themselves are assumed to be already
|
||||||
|
# available in some directory; they should have been installed with the
|
||||||
|
# the shell (except we haven't written that yet).
|
||||||
|
#
|
||||||
|
# Run it as a script under zsh and answer the questions.
|
||||||
|
# You can run it as `zsh compinstall $FPATH' and it will be able to check
|
||||||
|
# your function path for the completion functions.
|
||||||
|
#
|
||||||
|
# Normally, this will alter ~/.zshrc (or wherever ZDOTDIR puts it),
|
||||||
|
# but you can make that unwritable and it will leave the lines in a
|
||||||
|
# temporary file instead.
|
||||||
|
#
|
||||||
|
# You can use this script to modify what compinstall previously
|
||||||
|
# added to ~/.zshrc.
|
||||||
|
#
|
||||||
|
# It is safe to abort with ^C any time you are being prompted for
|
||||||
|
# information; your .zshrc will not be altered.
|
||||||
|
#
|
||||||
|
# To do:
|
||||||
|
# - Maybe this should be sourced, then it can check the user's current
|
||||||
|
# setup better. But then there is a potentially horrendous option
|
||||||
|
# setting/resetting problem. (Maybe we need another way of doing that.)
|
||||||
|
# - Should probably offer to set different options for _approximate than
|
||||||
|
# for _complete if both are used.
|
||||||
|
# - Could add code for setting other completers and options.
|
||||||
|
# - Could add keys for context-sensitive help.
|
||||||
|
# - Probably should allow a set of directories to be added to $fpath,
|
||||||
|
# like Core, Base, etc.
|
||||||
|
|
||||||
|
# In case a startup script changed options
|
||||||
|
emulate zsh
|
||||||
|
|
||||||
|
[[ -n $1 ]] && FPATH=$1
|
||||||
|
|
||||||
|
for f in $fpath; do
|
||||||
|
if [[ $f != . && -f $f/compinit && -f $f/compdump ]]; then
|
||||||
|
fdir=$f
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z $fdir ]]; then
|
||||||
|
print "Trying to find where the completion functions are..."
|
||||||
|
if [[ $0 = */* && -f $0:h/compinit && -f $0:h/compdump ]]; then
|
||||||
|
fdir=$0:h
|
||||||
|
else
|
||||||
|
# more guesses?
|
||||||
|
print \
|
||||||
|
"Please edit the name of the directory where the completion functions are
|
||||||
|
installed. If they are not installed, you will need to find them in the
|
||||||
|
Completion/* directories of the zsh distribution and install them yourself,
|
||||||
|
or insult your system manager for incompetence."
|
||||||
|
vared -c fdir
|
||||||
|
while [[ ! -d ${~fdir} || ! -f ${~fdir}/compinit ||
|
||||||
|
! -f ${~fdir}/compdump ]]; do
|
||||||
|
print "I can't find them in that directory. Try again or abort."
|
||||||
|
vared fdir
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
eval "fpath=($fdir \$fpath)"
|
||||||
|
fdir=${fdir/#$HOME/\~}
|
||||||
|
lines="fpath=($fdir \$fpath)\n"
|
||||||
|
else
|
||||||
|
print "Found completion functions in your fpath, will not alter it."
|
||||||
|
fi
|
||||||
|
|
||||||
|
files=( ${^~fpath:/.}/_(|*[^~])(N:t) )
|
||||||
|
if [[ $#files -lt 20 ]]; then
|
||||||
|
print "
|
||||||
|
Hmmm, completion functions seem a bit thin on the ground. There should
|
||||||
|
be lots of files with names beginning with an underscore (_). You should
|
||||||
|
look and see what's happened to these.
|
||||||
|
[Hit return to continue]"
|
||||||
|
read
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -w ${~fdir} && ( ! -f ${~fdir}/compinit.dump ||
|
||||||
|
-w ${~fdir}/compinit.dump ) ]]
|
||||||
|
then
|
||||||
|
print "
|
||||||
|
Using standard dumpfile
|
||||||
|
${~fdir}/compinit.dump
|
||||||
|
to speed up initialisation.
|
||||||
|
[Hit return to continue]"
|
||||||
|
read
|
||||||
|
else
|
||||||
|
print "
|
||||||
|
I will force completion to dump its status, which will speed up the shell's
|
||||||
|
start-up considerably. However, I can't write the file I'd like to, namely
|
||||||
|
$fdir/compinit.dump. Please edit a replacement."
|
||||||
|
dumpfile='~/.compinit.dump'
|
||||||
|
vared dumpfile
|
||||||
|
while ! touch ${~dumpfile} >& /dev/null; do
|
||||||
|
print "Sorry, I can't write that either. Try again."
|
||||||
|
vared dumpfile
|
||||||
|
done
|
||||||
|
[[ -s $dumpfile ]] || rm -f $dumpfile
|
||||||
|
dumpfile=" $dumpfile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fdir=${fdir/#$HOME/\~}
|
||||||
|
|
||||||
|
lines="${lines}. $fdir/compinit -d$dumpfile\n"
|
||||||
|
|
||||||
|
|
||||||
|
print "
|
||||||
|
In addition to completion, zsh can also perform correction of the
|
||||||
|
current word, or approximate completion, i.e. completion where the part of
|
||||||
|
the word typed so far can be corrected; or it can try correction, then
|
||||||
|
approximate completion if that fails. Would you like:
|
||||||
|
0: Just ordinary completion
|
||||||
|
C: Correction
|
||||||
|
A: Approximate completion
|
||||||
|
B: Both?
|
||||||
|
Please type one of the keys above:"
|
||||||
|
while read -k type; do
|
||||||
|
print
|
||||||
|
case $type in
|
||||||
|
0*) completer=_complete
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[cC]*) completer=_complete:_correct
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[aA]*) completer=_complete:_approximate
|
||||||
|
break;
|
||||||
|
;;
|
||||||
|
[bB]*) completer=_complete:_correct:_approximate
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*) print Try again
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
lines="${lines}compconf completer=$completer"
|
||||||
|
|
||||||
|
|
||||||
|
if [[ $completer = *(correct|approx)* ]]; then
|
||||||
|
print "
|
||||||
|
Correction and approximation will normally allow up to two errors,
|
||||||
|
and you will be able to use a numeric prefix (e.g. <Esc>4) to allow
|
||||||
|
more. The standard prompt is \`correct to:'. Do you want to change
|
||||||
|
any of this? [n]"
|
||||||
|
if read -q; then
|
||||||
|
print "Number of errors to accept normally (0 is OK):"
|
||||||
|
read accept
|
||||||
|
while [[ $accept != <-> ]]; do
|
||||||
|
read accept"?Please enter a number: "
|
||||||
|
done
|
||||||
|
print \
|
||||||
|
"How would you like the numeric prefix to be treated:
|
||||||
|
0: Not used by correction
|
||||||
|
U: Used to given the number of errors
|
||||||
|
I: If present, and not 1, do not perform correction?
|
||||||
|
Please type one of the keys above:"
|
||||||
|
while read -k type; do
|
||||||
|
print
|
||||||
|
case $type in
|
||||||
|
0*) break
|
||||||
|
;;
|
||||||
|
[uU]*) accept="${accept}n"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[Ii]*) accept="${accept}!n"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
*) print Try again
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
lines="$lines \\\\
|
||||||
|
correct_accept='$accept'"
|
||||||
|
print "
|
||||||
|
Instead of the prompt \`correct to:', you can have no prompt, or a
|
||||||
|
prompt of your choosing which can display the number of errors found by
|
||||||
|
containing the string \`%e'. Do you wish to change the correction
|
||||||
|
prompt? [n]"
|
||||||
|
if read -q; then
|
||||||
|
cprompt=''
|
||||||
|
print "Edit a new prompt (may be empty):"
|
||||||
|
vared cprompt
|
||||||
|
lines="$lines \\\\
|
||||||
|
correct_prompt='${cprompt//\'/\'\\\'\'}'"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
lines="$lines\n"
|
||||||
|
|
||||||
|
|
||||||
|
startline='# The following lines were added by compinstall'
|
||||||
|
endline='# End of lines added by compinstall'
|
||||||
|
|
||||||
|
ifile=${ZDOTDIR:-~}/.zshrc
|
||||||
|
[[ -f $ifile ]] || touch $ifile
|
||||||
|
tmpf=${TMPPPREFIX:-/tmp/zsh}compinstall$$
|
||||||
|
|
||||||
|
if [[ ! -w $ifile ]]; then
|
||||||
|
print "\nI can't write to $ifile. I will leave the lines to add in
|
||||||
|
\`$tmpf' and you must add them by hand."
|
||||||
|
print "\n$startline\n$lines\n$endline" >$tmpf
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep $endline $ifile >& /dev/null; then
|
||||||
|
print -- "$startline\n$lines$endline" >$tmpf
|
||||||
|
sed -e "/^$endline/r $tmpf
|
||||||
|
/^$startline/,/^$endline/d" $ifile >${tmpf}2 && mv ${tmpf}2 $ifile &&
|
||||||
|
print "\nSuccesfully modified old compinstall lines in $ifile."
|
||||||
|
rm -f $tmpf ${tmpf}2
|
||||||
|
else
|
||||||
|
print "\n$startline\n$lines\n$endline" >>$ifile &&
|
||||||
|
print "\nSuccessfully appended lines to $ifile."
|
||||||
|
fi
|
|
@ -1,3 +1,3 @@
|
||||||
#compdef make gmake pmake
|
#compdef make gmake pmake
|
||||||
|
|
||||||
compgen -s "\$(awk '/^[a-zA-Z0-9][^\/ ]+:/ {print \$1}' FS=: [mM]akefile /dev/null)"
|
compgen -s "\$(awk '/^[a-zA-Z0-9][^\/ ]+:/ {print \$1}' FS=: [mM]akefile /dev/null)"
|
||||||
|
|
|
@ -27,5 +27,5 @@
|
||||||
# This must also serve as a shell script, so do not add spaces around the
|
# This must also serve as a shell script, so do not add spaces around the
|
||||||
# `=' signs.
|
# `=' signs.
|
||||||
|
|
||||||
VERSION=3.1.5-pws-16
|
VERSION=3.1.5-pws-17
|
||||||
VERSION_DATE='April 25, 1999'
|
VERSION_DATE='April 30, 1999'
|
||||||
|
|
|
@ -1175,9 +1175,12 @@ xitem(tt(zmodload) tt(-d) [ tt(-L) ] [ var(name) [ var(dep) ... ] ])
|
||||||
xitem(tt(zmodload) tt(-du) var(name) [ var(dep) ... ])
|
xitem(tt(zmodload) tt(-du) var(name) [ var(dep) ... ])
|
||||||
xitem(tt(zmodload) tt(-a) [ tt(-iL) ] [ var(name) [ var(builtin) ... ] ])
|
xitem(tt(zmodload) tt(-a) [ tt(-iL) ] [ var(name) [ var(builtin) ... ] ])
|
||||||
xitem(tt(zmodload) tt(-au) [ tt(-i) ] var(builtin) ...)
|
xitem(tt(zmodload) tt(-au) [ tt(-i) ] var(builtin) ...)
|
||||||
xitem(tt(zmodload) tt(-c) [ tt(-iI) ] [ var(name) [ var(cond) ... ] ])
|
xitem(tt(zmodload) tt(-c) [ tt(-iI) ] var(name) [ var(cond) ... ])
|
||||||
xitem(tt(zmodload) tt(-cu) [ tt(-iI) ] var(cond) ...)
|
xitem(tt(zmodload) tt(-cu) [ tt(-iI) ] var(cond) ...)
|
||||||
item(tt(zmodload) tt(-c) [ tt(-IL) ])(
|
xitem(tt(zmodload) tt(-c) [ tt(-IL) ])
|
||||||
|
xitem(tt(zmodload) tt(-p) [ tt(-i) ] var(name) [ var(parameter) ... ])
|
||||||
|
xitem(tt(zmodload) tt(-pu) [ tt(-i) ] var(parameter) ... ])
|
||||||
|
item(tt(zmodload) tt(-p) [ tt(-L) ])(
|
||||||
tt(zmodload) performs operations relating to zsh's loadable modules.
|
tt(zmodload) performs operations relating to zsh's loadable modules.
|
||||||
This feature is not available on all operating systems,
|
This feature is not available on all operating systems,
|
||||||
or on all installations on a particular operating system.
|
or on all installations on a particular operating system.
|
||||||
|
@ -1253,5 +1256,8 @@ names. Without this option prefix condition names are defined.
|
||||||
Together with the tt(-u) option definitions for autoloaded conditions
|
Together with the tt(-u) option definitions for autoloaded conditions
|
||||||
are removed. If given no condition names all defined names are listed
|
are removed. If given no condition names all defined names are listed
|
||||||
(as a series of tt(zmodload) commands if the tt(-L) option is given).
|
(as a series of tt(zmodload) commands if the tt(-L) option is given).
|
||||||
|
|
||||||
|
The tt(-p) option is like the tt(-c) option, but makes tt(zmodload)
|
||||||
|
work on autoloaded parameters instead of condition codes.
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
|
@ -528,6 +528,53 @@ tt(MENU_COMPLETE) option and does not work with the other
|
||||||
menucompletion widgets such as tt(reverse-menu-complete), or
|
menucompletion widgets such as tt(reverse-menu-complete), or
|
||||||
tt(accept-and-menu-complete).
|
tt(accept-and-menu-complete).
|
||||||
)
|
)
|
||||||
|
item(tt(_oldlist))(
|
||||||
|
This completer controls how the standard completion widgets behave when
|
||||||
|
there is an existing list of completions which may have been generated by a
|
||||||
|
special completion (i.e. a separately-bound completion command). It should
|
||||||
|
appear in the list of completers before any of the widgets which generate
|
||||||
|
matches. It understands two configuration keys:
|
||||||
|
|
||||||
|
startitem()
|
||||||
|
item(tt(oldlist_list))(
|
||||||
|
If this is set to tt(always), then standard widgets which perform listing
|
||||||
|
will retain the current list of matches, however they were generated. If
|
||||||
|
it is set to tt(never), this will not be done (the behaviour without the
|
||||||
|
tt(_oldlist) completer). If it is unset, or any other value, then the
|
||||||
|
existing list of completions will be displayed if it is not already;
|
||||||
|
otherwise, the standard completion list will be generated: this is the
|
||||||
|
default behaviour of tt(_oldlist).
|
||||||
|
|
||||||
|
For example, suppose you type tt(^Xc) to use the tt(_correct_word)
|
||||||
|
widget, which generates a list of corrections for the word under the
|
||||||
|
cursor. Usually, typing tt(^D) would generate a standard list of
|
||||||
|
completions for the word on the command line, and show that. With
|
||||||
|
tt(_oldlist), it will instead show the list of corrections already
|
||||||
|
generated.
|
||||||
|
)
|
||||||
|
item(tt(oldlist_menu))(
|
||||||
|
Controls how menu completion behaves when a completion has already been
|
||||||
|
inserted and the user types a standard completion key type as tt(TAB).
|
||||||
|
The default behaviour of tt(_oldlist) is that menu completion always
|
||||||
|
continues with the existing list of completions. If this key is set to
|
||||||
|
tt(never), however, a new completion is started if the old list was
|
||||||
|
generated by a different completion command (the behaviour without the
|
||||||
|
tt(_oldlist) completer).
|
||||||
|
For example, suppose you type tt(^Xc) to generate a list of corrections,
|
||||||
|
and menu completion is started in one of the usual ways. Usually, typing
|
||||||
|
tt(TAB) at this point would start trying to complete the line as it now
|
||||||
|
appears. With tt(_oldlist), it will instead continue to cycle through the
|
||||||
|
list of completions.
|
||||||
|
)
|
||||||
|
enditem()
|
||||||
|
)
|
||||||
|
item(tt(_closequotes))(
|
||||||
|
When a completion starts in quotes, this completer will recognise the fact
|
||||||
|
and insert a matching closing quote if there is not already one later on
|
||||||
|
the line. It should come earlier in the list of completers than any of the
|
||||||
|
completers which generate matches. It can be confused by some of the more
|
||||||
|
sophisticated forms of completion.
|
||||||
|
)
|
||||||
enditem()
|
enditem()
|
||||||
|
|
||||||
texinode(Completion Functions)()(Control Functions)(Completion System)
|
texinode(Completion Functions)()(Control Functions)(Completion System)
|
||||||
|
|
|
@ -140,6 +140,12 @@ with tt(${).
|
||||||
)
|
)
|
||||||
enditem()
|
enditem()
|
||||||
)
|
)
|
||||||
|
item(tt(vared))(
|
||||||
|
If completion is called while editing a line using the tt(vared)
|
||||||
|
builtin, the value of this key is set to the name of the parameter
|
||||||
|
given as argument to tt(vared). If tt(vared) is not currently used,
|
||||||
|
this key is unset.
|
||||||
|
)
|
||||||
item(tt(parameter))(
|
item(tt(parameter))(
|
||||||
The name of the parameter when completing in a subscript or in the
|
The name of the parameter when completing in a subscript or in the
|
||||||
value of a parameter assignment.
|
value of a parameter assignment.
|
||||||
|
@ -340,7 +346,7 @@ xitem([ tt(-W) var(file-prefix) ])
|
||||||
xitem([ tt(-J) var(name) ] [ tt(-V) var(name) ] [ tt(-X) var(explanation) ])
|
xitem([ tt(-J) var(name) ] [ tt(-V) var(name) ] [ tt(-X) var(explanation) ])
|
||||||
xitem([ tt(-r) var(remove-chars) ] [ tt(-R) var(remove-func) ])
|
xitem([ tt(-r) var(remove-chars) ] [ tt(-R) var(remove-func) ])
|
||||||
xitem([ tt(-M) var(match-spec) ] [ tt(-O) var(array) ] [ tt(-A) var(array) ])
|
xitem([ tt(-M) var(match-spec) ] [ tt(-O) var(array) ] [ tt(-A) var(array) ])
|
||||||
item([ tt(--) ] [ var(words) ... ])(
|
item([ tt(-D) var(array) ] [ tt(--) ] [ var(words) ... ])(
|
||||||
|
|
||||||
This builtin command can be used to add matches directly and control
|
This builtin command can be used to add matches directly and control
|
||||||
all the information the completion code stores with each possible
|
all the information the completion code stores with each possible
|
||||||
|
@ -518,6 +524,13 @@ on the command line and the string `tt(foo)' as one of the var(words), this
|
||||||
option stores the string `tt(nofoo)' in the array, whereas the tt(-O)
|
option stores the string `tt(nofoo)' in the array, whereas the tt(-O)
|
||||||
option stores the `tt(foo)' originally given.
|
option stores the `tt(foo)' originally given.
|
||||||
)
|
)
|
||||||
|
item(tt(-D) var(array))(
|
||||||
|
As with tt(-O), the var(words) are not added to the set of possible
|
||||||
|
completions. Instead, the completion code tests every var(word) if
|
||||||
|
it matches what is on the line. If the var(n)'th var(word) does not
|
||||||
|
match, the var(n)'th element of the var(array) is removed. Elements
|
||||||
|
for which the corresponding var(word) is matched are retained.
|
||||||
|
)
|
||||||
item(tt(-), tt(--))(
|
item(tt(-), tt(--))(
|
||||||
This flag ends the list of flags and options. All arguments after it
|
This flag ends the list of flags and options. All arguments after it
|
||||||
will be taken as the words to use as matches even if they begin with
|
will be taken as the words to use as matches even if they begin with
|
||||||
|
|
|
@ -361,6 +361,7 @@ the parameter is then substituted.
|
||||||
item(tt(${)var(name)tt(:?)var(word)tt(}))(
|
item(tt(${)var(name)tt(:?)var(word)tt(}))(
|
||||||
If var(name) is set and is non-null, then substitute
|
If var(name) is set and is non-null, then substitute
|
||||||
its value; otherwise, print var(word) and exit from the shell.
|
its value; otherwise, print var(word) and exit from the shell.
|
||||||
|
Interactive shells do not exit.
|
||||||
If var(word) is omitted, then a standard message is printed.
|
If var(word) is omitted, then a standard message is printed.
|
||||||
)
|
)
|
||||||
item(tt(${)var(name)tt(:PLUS())var(word)tt(}))(
|
item(tt(${)var(name)tt(:PLUS())var(word)tt(}))(
|
||||||
|
@ -596,11 +597,12 @@ Pad the resulting words on the left. Each word will be truncated if
|
||||||
required and placed in a field var(expr) characters wide. The space
|
required and placed in a field var(expr) characters wide. The space
|
||||||
to the left will be filled with var(string1) (concatenated as often
|
to the left will be filled with var(string1) (concatenated as often
|
||||||
as needed) or spaces if var(string1) is not given. If both
|
as needed) or spaces if var(string1) is not given. If both
|
||||||
var(string1) and var(string2) are given, this string will be placed
|
var(string1) and var(string2) are given, this string is inserted
|
||||||
exactly once directly to the left of the resulting word.
|
once directly to the left of each word, before padding.
|
||||||
)
|
)
|
||||||
item(tt(r:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))(
|
item(tt(r:)var(expr)tt(::)var(string1)tt(::)var(string2)tt(:))(
|
||||||
As tt(l), but pad the words on the right.
|
As tt(l), but pad the words on the right and insert var(string2)
|
||||||
|
on the right.
|
||||||
)
|
)
|
||||||
item(tt(j:)var(string)tt(:))(
|
item(tt(j:)var(string)tt(:))(
|
||||||
Join the words of arrays together using var(string) as a separator.
|
Join the words of arrays together using var(string) as a separator.
|
||||||
|
|
|
@ -670,7 +670,7 @@ tt(trap) and
|
||||||
tt(unset).
|
tt(unset).
|
||||||
)
|
)
|
||||||
pindex(PRINT_EIGHT_BIT)
|
pindex(PRINT_EIGHT_BIT)
|
||||||
cindex(exit status, printing)
|
cindex(eight bit characters, printing)
|
||||||
item(tt(PRINT_EIGHT_BIT))(
|
item(tt(PRINT_EIGHT_BIT))(
|
||||||
Print eight bit characters literally in completion lists, etc.
|
Print eight bit characters literally in completion lists, etc.
|
||||||
This option is not necessary if your system correctly returns the
|
This option is not necessary if your system correctly returns the
|
||||||
|
|
|
@ -180,4 +180,4 @@ the command named in the shell variable tt(READNULLCMD) is assumed.
|
||||||
|
|
||||||
nofill(tt(< file))
|
nofill(tt(< file))
|
||||||
|
|
||||||
prints the contents of tt(file).
|
copies the contents of tt(file) to the standard output.
|
||||||
|
|
|
@ -30,22 +30,45 @@
|
||||||
#include "example.mdh"
|
#include "example.mdh"
|
||||||
#include "example.pro"
|
#include "example.pro"
|
||||||
|
|
||||||
|
/* parameters */
|
||||||
|
|
||||||
|
static long intparam;
|
||||||
|
static char *strparam;
|
||||||
|
static char **arrparam;
|
||||||
|
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
bin_example(char *nam, char **args, char *ops, int func)
|
bin_example(char *nam, char **args, char *ops, int func)
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
char **oargs = args, **p = arrparam;
|
||||||
|
long i = 0;
|
||||||
|
|
||||||
printf("Options: ");
|
printf("Options: ");
|
||||||
for (c = 32; ++c < 128;)
|
for (c = 32; ++c < 128;)
|
||||||
if (ops[c])
|
if (ops[c])
|
||||||
putchar(c);
|
putchar(c);
|
||||||
printf("\nArguments:");
|
printf("\nArguments:");
|
||||||
for (; *args; args++) {
|
for (; *args; i++, args++) {
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
fputs(*args, stdout);
|
fputs(*args, stdout);
|
||||||
}
|
}
|
||||||
printf("\nName: %s\n", nam);
|
printf("\nName: %s\n", nam);
|
||||||
|
printf("\nInteger Parameter: %ld\n", intparam);
|
||||||
|
printf("String Parameter: %s\n", strparam ? strparam : "");
|
||||||
|
printf("Array Parameter:");
|
||||||
|
if (p)
|
||||||
|
while (*p) printf(" %s", *p++);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
intparam = i;
|
||||||
|
zsfree(strparam);
|
||||||
|
strparam = ztrdup(*oargs ? *oargs : "");
|
||||||
|
freearray(arrparam);
|
||||||
|
PERMALLOC {
|
||||||
|
arrparam = arrdup(oargs);
|
||||||
|
} LASTALLOC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +126,12 @@ static struct conddef cotab[] = {
|
||||||
CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0),
|
CONDDEF("ex", CONDF_INFIX, cond_i_ex, 0, 0, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct paramdef patab[] = {
|
||||||
|
INTPARAMDEF("exint", &intparam),
|
||||||
|
STRPARAMDEF("exstr", &strparam),
|
||||||
|
ARRPARAMDEF("exarr", &arrparam),
|
||||||
|
};
|
||||||
|
|
||||||
static struct funcwrap wrapper[] = {
|
static struct funcwrap wrapper[] = {
|
||||||
WRAPDEF(ex_wrapper),
|
WRAPDEF(ex_wrapper),
|
||||||
};
|
};
|
||||||
|
@ -120,8 +149,15 @@ setup_example(Module m)
|
||||||
int
|
int
|
||||||
boot_example(Module m)
|
boot_example(Module m)
|
||||||
{
|
{
|
||||||
|
intparam = 42;
|
||||||
|
strparam = ztrdup("example");
|
||||||
|
arrparam = (char **) zalloc(3 * sizeof(char *));
|
||||||
|
arrparam[0] = ztrdup("example");
|
||||||
|
arrparam[1] = ztrdup("array");
|
||||||
|
arrparam[2] = NULL;
|
||||||
return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
|
return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
|
||||||
addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)) |
|
addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)) |
|
||||||
|
addparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab)) |
|
||||||
!addwrapper(m, wrapper));
|
!addwrapper(m, wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +169,7 @@ cleanup_example(Module m)
|
||||||
{
|
{
|
||||||
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
|
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
|
||||||
deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
|
deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
|
||||||
|
deleteparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab));
|
||||||
deletewrapper(m, wrapper);
|
deletewrapper(m, wrapper);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,6 @@ autobins="example"
|
||||||
|
|
||||||
autoinfixconds="ex"
|
autoinfixconds="ex"
|
||||||
autoprefixconds="len"
|
autoprefixconds="len"
|
||||||
|
autoparams="exint exstr exarr"
|
||||||
|
|
||||||
objects="example.o"
|
objects="example.o"
|
||||||
|
|
|
@ -71,6 +71,9 @@
|
||||||
#ifdef HAVE_POLL_H
|
#ifdef HAVE_POLL_H
|
||||||
# include <poll.h>
|
# include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_POLL) && !defined(POLLIN) && !defined(POLLNORM)
|
||||||
|
# undef HAVE_POLL
|
||||||
|
#endif
|
||||||
|
|
||||||
/* pinch the definition from <netinet/in.h> for deficient headers */
|
/* pinch the definition from <netinet/in.h> for deficient headers */
|
||||||
#ifndef INADDR_NONE
|
#ifndef INADDR_NONE
|
||||||
|
|
|
@ -270,6 +270,31 @@ struct cpattern {
|
||||||
#define CAF_ALT 4
|
#define CAF_ALT 4
|
||||||
#define CAF_MATCH 8
|
#define CAF_MATCH 8
|
||||||
|
|
||||||
|
/* Data for compadd and addmatches() */
|
||||||
|
|
||||||
|
typedef struct cadata *Cadata;
|
||||||
|
|
||||||
|
struct cadata {
|
||||||
|
char *ipre; /* ignored prefix (-i) */
|
||||||
|
char *isuf; /* ignored suffix (-I) */
|
||||||
|
char *ppre; /* `path' prefix (-p) */
|
||||||
|
char *psuf; /* `path' suffix (-s) */
|
||||||
|
char *prpre; /* expanded `path' prefix (-W) */
|
||||||
|
char *pre; /* prefix to insert (-P) */
|
||||||
|
char *suf; /* suffix to insert (-S) */
|
||||||
|
char *group; /* name of the group (-[JV]) */
|
||||||
|
char *rems; /* remove suffix on chars... (-r) */
|
||||||
|
char *remf; /* function to remove suffix (-R) */
|
||||||
|
char *ign; /* ignored suffixes (-F) */
|
||||||
|
int flags; /* CMF_* flags (-[fqn]) */
|
||||||
|
int aflags; /* CAF_* flags (-[QUa]) */
|
||||||
|
Cmatcher match; /* match spec (parsed from -M) */
|
||||||
|
char *exp; /* explanation (-X) */
|
||||||
|
char *apar; /* array to store matches in (-A) */
|
||||||
|
char *opar; /* array to store originals in (-O) */
|
||||||
|
char *dpar; /* array to delete non-matches in (-D) */
|
||||||
|
};
|
||||||
|
|
||||||
/* Flags for special parameters. */
|
/* Flags for special parameters. */
|
||||||
|
|
||||||
#define CP_WORDS (1 << 0)
|
#define CP_WORDS (1 << 0)
|
||||||
|
@ -306,7 +331,8 @@ struct cpattern {
|
||||||
#define CP_TOEND (1 << 28)
|
#define CP_TOEND (1 << 28)
|
||||||
#define CP_OLDLIST (1 << 29)
|
#define CP_OLDLIST (1 << 29)
|
||||||
#define CP_OLDINS (1 << 30)
|
#define CP_OLDINS (1 << 30)
|
||||||
|
#define CP_VARED (1 << 31)
|
||||||
|
|
||||||
#define CP_NUM 31
|
#define CP_NUM 32
|
||||||
|
|
||||||
#define CP_ALLMASK ((int) ((((unsigned int) 1) << CP_NUM) - 1))
|
#define CP_ALLMASK ((unsigned int) 0xffffffff)
|
||||||
|
|
|
@ -52,7 +52,7 @@ void (*comp_setunsetptr) _((int, int));
|
||||||
/* pointers to functions required by compctl and defined by zle */
|
/* pointers to functions required by compctl and defined by zle */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int (*addmatchesptr) _((char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, int, int, Cmatcher, char *, char *, char *, char **));
|
int (*addmatchesptr) _((Cadata, char **));
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
char *(*comp_strptr) _((int *, int *, int));
|
char *(*comp_strptr) _((int *, int *, int));
|
||||||
|
@ -129,7 +129,8 @@ char **compwords,
|
||||||
*complastprompt,
|
*complastprompt,
|
||||||
*comptoend,
|
*comptoend,
|
||||||
*compoldlist,
|
*compoldlist,
|
||||||
*compoldins;
|
*compoldins,
|
||||||
|
*compvared;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
Param *comppms;
|
Param *comppms;
|
||||||
|
@ -445,7 +446,7 @@ setup_comp1(Module m)
|
||||||
compquoting = comprestore = complist = compinsert =
|
compquoting = comprestore = complist = compinsert =
|
||||||
compexact = compexactstr = comppatmatch = comppatinsert =
|
compexact = compexactstr = comppatmatch = comppatinsert =
|
||||||
compforcelist = complastprompt = comptoend =
|
compforcelist = complastprompt = comptoend =
|
||||||
compoldlist = compoldins = NULL;
|
compoldlist = compoldins = compvared = NULL;
|
||||||
makecompparamsptr = NULL;
|
makecompparamsptr = NULL;
|
||||||
comp_setunsetptr = NULL;
|
comp_setunsetptr = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -497,6 +498,7 @@ finish_comp1(Module m)
|
||||||
zsfree(comptoend);
|
zsfree(comptoend);
|
||||||
zsfree(compoldlist);
|
zsfree(compoldlist);
|
||||||
zsfree(compoldins);
|
zsfree(compoldins);
|
||||||
|
zsfree(compvared);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ comp_setunsetptr
|
||||||
comp_strptr
|
comp_strptr
|
||||||
compsuffix
|
compsuffix
|
||||||
comptoend
|
comptoend
|
||||||
|
compvared
|
||||||
compwords
|
compwords
|
||||||
freecmatcher
|
freecmatcher
|
||||||
freecmlist
|
freecmlist
|
||||||
|
|
|
@ -1691,17 +1691,22 @@ bin_compgen(char *name, char **argv, char *ops, int func)
|
||||||
static int
|
static int
|
||||||
bin_compadd(char *name, char **argv, char *ops, int func)
|
bin_compadd(char *name, char **argv, char *ops, int func)
|
||||||
{
|
{
|
||||||
char *p, **sp, *e;
|
struct cadata dat;
|
||||||
char *ipre = NULL, *isuf = NULL, *ppre = NULL, *psuf = NULL, *prpre = NULL;
|
char *p, **sp, *e, *m = NULL;
|
||||||
char *pre = NULL, *suf = NULL, *group = NULL, *m = NULL, *rs = NULL;
|
int dm;
|
||||||
char *ign = NULL, *rf = NULL, *expl = NULL, *apar = NULL, *opar = NULL;
|
|
||||||
int f = 0, a = CAF_MATCH, dm;
|
|
||||||
Cmatcher match = NULL;
|
Cmatcher match = NULL;
|
||||||
|
|
||||||
if (incompfunc != 1) {
|
if (incompfunc != 1) {
|
||||||
zerrnam(name, "can only be called from completion function", NULL, 0);
|
zerrnam(name, "can only be called from completion function", NULL, 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre =
|
||||||
|
dat.pre = dat.suf = dat.group = dat.rems = dat.remf =
|
||||||
|
dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL;
|
||||||
|
dat.match = NULL;
|
||||||
|
dat.flags = 0;
|
||||||
|
dat.aflags = CAF_MATCH;
|
||||||
|
|
||||||
for (; *argv && **argv == '-'; argv++) {
|
for (; *argv && **argv == '-'; argv++) {
|
||||||
if (!(*argv)[1]) {
|
if (!(*argv)[1]) {
|
||||||
argv++;
|
argv++;
|
||||||
|
@ -1713,64 +1718,64 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
||||||
dm = 0;
|
dm = 0;
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'q':
|
case 'q':
|
||||||
f |= CMF_REMOVE;
|
dat.flags |= CMF_REMOVE;
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
a |= CAF_QUOTE;
|
dat.aflags |= CAF_QUOTE;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
f |= CMF_FILE;
|
dat.flags |= CMF_FILE;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
sp = &ign;
|
sp = &(dat.ign);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
f |= CMF_NOLIST;
|
dat.flags |= CMF_NOLIST;
|
||||||
break;
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
a &= ~CAF_MATCH;
|
dat.aflags &= ~CAF_MATCH;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
sp = ⪯
|
sp = &(dat.pre);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
sp = &suf;
|
sp = &(dat.suf);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'J':
|
case 'J':
|
||||||
sp = &group;
|
sp = &(dat.group);
|
||||||
e = "group name expected after -%c";
|
e = "group name expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
if (!group)
|
if (!dat.group)
|
||||||
a |= CAF_NOSORT;
|
dat.aflags |= CAF_NOSORT;
|
||||||
sp = &group;
|
sp = &(dat.group);
|
||||||
e = "group name expected after -%c";
|
e = "group name expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
sp = &ipre;
|
sp = &(dat.ipre);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
sp = &isuf;
|
sp = &(dat.isuf);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
sp = &ppre;
|
sp = &(dat.ppre);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
sp = &psuf;
|
sp = &(dat.psuf);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'W':
|
case 'W':
|
||||||
sp = &prpre;
|
sp = &(dat.prpre);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
a |= CAF_ALT;
|
dat.aflags |= CAF_ALT;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
sp = &m;
|
sp = &m;
|
||||||
|
@ -1778,25 +1783,29 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
||||||
dm = 1;
|
dm = 1;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
sp = &expl;
|
sp = &(dat.exp);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
f |= CMF_REMOVE;
|
dat.flags |= CMF_REMOVE;
|
||||||
sp = &rs;
|
sp = &(dat.rems);
|
||||||
e = "string expected after -%c";
|
e = "string expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
f |= CMF_REMOVE;
|
dat.flags |= CMF_REMOVE;
|
||||||
sp = &rf;
|
sp = &(dat.remf);
|
||||||
e = "function name expected after -%c";
|
e = "function name expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
sp = &apar;
|
sp = &(dat.apar);
|
||||||
e = "parameter name expected after -%c";
|
e = "parameter name expected after -%c";
|
||||||
break;
|
break;
|
||||||
case 'O':
|
case 'O':
|
||||||
sp = ⦷
|
sp = &(dat.opar);
|
||||||
|
e = "parameter name expected after -%c";
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
sp = &(dat.dpar);
|
||||||
e = "parameter name expected after -%c";
|
e = "parameter name expected after -%c";
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
|
@ -1830,12 +1839,11 @@ bin_compadd(char *name, char **argv, char *ops, int func)
|
||||||
if (!*argv)
|
if (!*argv)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
match = cpcmatcher(match);
|
dat.match = match = cpcmatcher(match);
|
||||||
a = addmatchesptr(ipre, isuf, ppre, psuf, prpre, pre, suf, group,
|
dm = addmatchesptr(&dat, argv);
|
||||||
rs, rf, ign, f, a, match, expl, apar, opar, argv);
|
|
||||||
freecmatcher(match);
|
freecmatcher(match);
|
||||||
|
|
||||||
return a;
|
return dm;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CVT_RANGENUM 0
|
#define CVT_RANGENUM 0
|
||||||
|
@ -2165,6 +2173,7 @@ static struct compparam {
|
||||||
{ "to_end", PM_SCALAR, VAL(comptoend), NULL, NULL },
|
{ "to_end", PM_SCALAR, VAL(comptoend), NULL, NULL },
|
||||||
{ "old_list", PM_SCALAR, VAL(compoldlist), NULL, NULL },
|
{ "old_list", PM_SCALAR, VAL(compoldlist), NULL, NULL },
|
||||||
{ "old_insert", PM_SCALAR, VAL(compoldins), NULL, NULL },
|
{ "old_insert", PM_SCALAR, VAL(compoldins), NULL, NULL },
|
||||||
|
{ "vared", PM_SCALAR, VAL(compvared), NULL, NULL },
|
||||||
{ NULL, 0, NULL, NULL, NULL }
|
{ NULL, 0, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2308,7 +2317,7 @@ compunsetfn(Param pm, int exp)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
comp_setunset(int set, int unset)
|
comp_setunset(unsigned int set, unsigned int unset)
|
||||||
{
|
{
|
||||||
Param *p;
|
Param *p;
|
||||||
|
|
||||||
|
@ -2334,11 +2343,11 @@ comp_wrapper(List list, FuncWrap w, char *name)
|
||||||
else {
|
else {
|
||||||
char *orest, *opre, *osuf, *oipre, *oisuf, **owords;
|
char *orest, *opre, *osuf, *oipre, *oisuf, **owords;
|
||||||
long ocur;
|
long ocur;
|
||||||
int unset = 0, m, sm;
|
unsigned int unset = 0, m, sm;
|
||||||
Param *pp;
|
Param *pp;
|
||||||
|
|
||||||
m = CP_WORDS | CP_CURRENT | CP_PREFIX | CP_SUFFIX |
|
m = CP_WORDS | CP_CURRENT | CP_PREFIX | CP_SUFFIX |
|
||||||
CP_IPREFIX | CP_RESTORE;
|
CP_IPREFIX | CP_ISUFFIX | CP_RESTORE;
|
||||||
for (pp = comppms, sm = 1; m; pp++, m >>= 1, sm <<= 1) {
|
for (pp = comppms, sm = 1; m; pp++, m >>= 1, sm <<= 1) {
|
||||||
if ((m & 1) && ((*pp)->flags & PM_UNSET))
|
if ((m & 1) && ((*pp)->flags & PM_UNSET))
|
||||||
unset |= sm;
|
unset |= sm;
|
||||||
|
@ -2373,7 +2382,8 @@ comp_wrapper(List list, FuncWrap w, char *name)
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
comp_setunset(CP_COMPSTATE |
|
comp_setunset(CP_COMPSTATE |
|
||||||
(~unset & (CP_WORDS | CP_CURRENT | CP_PREFIX |
|
(~unset & (CP_WORDS | CP_CURRENT | CP_PREFIX |
|
||||||
CP_SUFFIX | CP_IPREFIX | CP_RESTORE)),
|
CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX |
|
||||||
|
CP_RESTORE)),
|
||||||
unset);
|
unset);
|
||||||
} else
|
} else
|
||||||
comp_setunset(CP_COMPSTATE | (~unset & CP_RESTORE),
|
comp_setunset(CP_COMPSTATE | (~unset & CP_RESTORE),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
moddeps="comp1"
|
moddeps="comp1"
|
||||||
|
|
||||||
autobins="compctl complist compadd compset"
|
autobins="compctl compgen compadd compset"
|
||||||
|
|
||||||
autoprefixconds="prefix suffix between after"
|
autoprefixconds="prefix suffix between after"
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,6 @@ zleread(char *lp, char *rp, int flags)
|
||||||
|
|
||||||
baud = getiparam("BAUD");
|
baud = getiparam("BAUD");
|
||||||
costmult = (baud) ? 3840000L / baud : 0;
|
costmult = (baud) ? 3840000L / baud : 0;
|
||||||
tv.tv_sec = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ZLE doesn't currently work recursively. This is needed in case a *
|
/* ZLE doesn't currently work recursively. This is needed in case a *
|
||||||
|
@ -523,6 +522,7 @@ zleread(char *lp, char *rp, int flags)
|
||||||
#ifdef HAVE_SELECT
|
#ifdef HAVE_SELECT
|
||||||
if (baud && !(lastcmd & ZLE_MENUCMP)) {
|
if (baud && !(lastcmd & ZLE_MENUCMP)) {
|
||||||
FD_SET(SHTTY, &foofd);
|
FD_SET(SHTTY, &foofd);
|
||||||
|
tv.tv_sec = 0;
|
||||||
if ((tv.tv_usec = cost * costmult) > 500000)
|
if ((tv.tv_usec = cost * costmult) > 500000)
|
||||||
tv.tv_usec = 500000;
|
tv.tv_usec = 500000;
|
||||||
if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd,
|
if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd,
|
||||||
|
@ -656,14 +656,18 @@ handleprefixes(void)
|
||||||
initmodifier(&zmod);
|
initmodifier(&zmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this exports the argument we are currently vared'iting if != NULL */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
char *varedarg;
|
||||||
|
|
||||||
/* vared: edit (literally) a parameter value */
|
/* vared: edit (literally) a parameter value */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
bin_vared(char *name, char **args, char *ops, int func)
|
bin_vared(char *name, char **args, char *ops, int func)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s, *t, *ova = varedarg;
|
||||||
char *t;
|
|
||||||
Value v;
|
Value v;
|
||||||
Param pm = 0;
|
Param pm = 0;
|
||||||
int create = 0;
|
int create = 0;
|
||||||
|
@ -753,7 +757,9 @@ bin_vared(char *name, char **args, char *ops, int func)
|
||||||
PERMALLOC {
|
PERMALLOC {
|
||||||
pushnode(bufstack, ztrdup(s));
|
pushnode(bufstack, ztrdup(s));
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
|
varedarg = *args;
|
||||||
t = (char *) zleread(p1, p2, ops['h'] ? ZLRF_HISTORY : 0);
|
t = (char *) zleread(p1, p2, ops['h'] ? ZLRF_HISTORY : 0);
|
||||||
|
varedarg = ova;
|
||||||
if (!t || errflag) {
|
if (!t || errflag) {
|
||||||
/* error in editing */
|
/* error in editing */
|
||||||
errflag = 0;
|
errflag = 0;
|
||||||
|
@ -927,6 +933,8 @@ setup_zle(Module m)
|
||||||
/* initialise the keymap system */
|
/* initialise the keymap system */
|
||||||
init_keymaps();
|
init_keymaps();
|
||||||
|
|
||||||
|
varedarg = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -611,7 +611,7 @@ Thingy
|
||||||
executenamedcommand(char *prmt)
|
executenamedcommand(char *prmt)
|
||||||
{
|
{
|
||||||
Thingy cmd;
|
Thingy cmd;
|
||||||
int len, l = strlen(prmt);
|
int len, l = strlen(prmt), ols = listshown;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
char *okeymap = curkeymapname;
|
char *okeymap = curkeymapname;
|
||||||
|
|
||||||
|
@ -629,6 +629,10 @@ executenamedcommand(char *prmt)
|
||||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
selectkeymap(okeymap, 1);
|
selectkeymap(okeymap, 1);
|
||||||
|
if ((listshown = ols))
|
||||||
|
showinglist = -2;
|
||||||
|
else
|
||||||
|
clearlist = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(cmd == Th(z_clearscreen)) {
|
if(cmd == Th(z_clearscreen)) {
|
||||||
|
@ -669,6 +673,10 @@ executenamedcommand(char *prmt)
|
||||||
unrefthingy(r);
|
unrefthingy(r);
|
||||||
statusline = NULL;
|
statusline = NULL;
|
||||||
selectkeymap(okeymap, 1);
|
selectkeymap(okeymap, 1);
|
||||||
|
if ((listshown = ols))
|
||||||
|
showinglist = -2;
|
||||||
|
else
|
||||||
|
clearlist = 1;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
unrefthingy(r);
|
unrefthingy(r);
|
||||||
|
|
|
@ -96,6 +96,7 @@ static int more_start, /* more text before start of screen? */
|
||||||
olnct, /* previous number of lines */
|
olnct, /* previous number of lines */
|
||||||
ovln, /* previous video cursor position line */
|
ovln, /* previous video cursor position line */
|
||||||
lpromptw, rpromptw, /* prompt widths on screen */
|
lpromptw, rpromptw, /* prompt widths on screen */
|
||||||
|
lpromptwof, /* left prompt width with real end position */
|
||||||
lprompth, /* lines taken up by the prompt */
|
lprompth, /* lines taken up by the prompt */
|
||||||
rprompth, /* right prompt height */
|
rprompth, /* right prompt height */
|
||||||
vcs, vln, /* video cursor position column & line */
|
vcs, vln, /* video cursor position column & line */
|
||||||
|
@ -141,8 +142,14 @@ resetvideo(void)
|
||||||
*obuf[ln] = '\0';
|
*obuf[ln] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
countprompt(lpromptbuf, &lpromptw, &lprompth);
|
countprompt(lpromptbuf, &lpromptwof, &lprompth, 1);
|
||||||
countprompt(rpromptbuf, &rpromptw, &rprompth);
|
countprompt(rpromptbuf, &rpromptw, &rprompth, 0);
|
||||||
|
if (lpromptwof != winw)
|
||||||
|
lpromptw = lpromptwof;
|
||||||
|
else {
|
||||||
|
lpromptw = 0;
|
||||||
|
lprompth++;
|
||||||
|
}
|
||||||
|
|
||||||
if (lpromptw) {
|
if (lpromptw) {
|
||||||
memset(nbuf[0], ' ', lpromptw);
|
memset(nbuf[0], ' ', lpromptw);
|
||||||
|
@ -271,7 +278,7 @@ zrefresh(void)
|
||||||
clearflag = 0;
|
clearflag = 0;
|
||||||
resetneeded = 1;
|
resetneeded = 1;
|
||||||
}
|
}
|
||||||
listshown = 0;
|
listshown = showinglist = 0;
|
||||||
}
|
}
|
||||||
clearlist = 0;
|
clearlist = 0;
|
||||||
|
|
||||||
|
@ -327,7 +334,7 @@ zrefresh(void)
|
||||||
vcs = 0;
|
vcs = 0;
|
||||||
else if (!clearflag && lpromptbuf[0]) {
|
else if (!clearflag && lpromptbuf[0]) {
|
||||||
zputs(lpromptbuf, shout);
|
zputs(lpromptbuf, shout);
|
||||||
if (lpromptw == 0 && lprompth == 1)
|
if (lpromptwof == winw)
|
||||||
zputs("\n", shout); /* works with both hasam and !hasam */
|
zputs("\n", shout); /* works with both hasam and !hasam */
|
||||||
}
|
}
|
||||||
if (clearflag) {
|
if (clearflag) {
|
||||||
|
@ -947,7 +954,7 @@ tc_rightcurs(int cl)
|
||||||
zputc('\r', shout);
|
zputc('\r', shout);
|
||||||
tc_upcurs(lprompth - 1);
|
tc_upcurs(lprompth - 1);
|
||||||
zputs(lpromptbuf, shout);
|
zputs(lpromptbuf, shout);
|
||||||
if (lpromptw == 0 && lprompth == 1)
|
if (lpromptwof == winw)
|
||||||
zputs("\n", shout); /* works with both hasam and !hasam */
|
zputs("\n", shout); /* works with both hasam and !hasam */
|
||||||
}
|
}
|
||||||
i = lpromptw;
|
i = lpromptw;
|
||||||
|
|
|
@ -87,6 +87,10 @@ static int usemenu, useglob, useexact, useline, uselist;
|
||||||
|
|
||||||
static int oldlist, oldins;
|
static int oldlist, oldins;
|
||||||
|
|
||||||
|
/* Non-zero if we have to redisplay the list of matches. */
|
||||||
|
|
||||||
|
static int showagain = 0;
|
||||||
|
|
||||||
/* The match and group number to insert when starting menucompletion. */
|
/* The match and group number to insert when starting menucompletion. */
|
||||||
|
|
||||||
static int insmnum, insgnum, insgroup;
|
static int insmnum, insgnum, insgroup;
|
||||||
|
@ -555,7 +559,7 @@ acceptandmenucomplete(void)
|
||||||
/* These are flags saying if we are completing in the command *
|
/* These are flags saying if we are completing in the command *
|
||||||
* position, in a redirection, or in a parameter expansion. */
|
* position, in a redirection, or in a parameter expansion. */
|
||||||
|
|
||||||
static int lincmd, linredir, ispar, linwhat;
|
static int lincmd, linredir, ispar, linwhat, linarr;
|
||||||
|
|
||||||
/* The string for the redirection operator. */
|
/* The string for the redirection operator. */
|
||||||
|
|
||||||
|
@ -758,10 +762,14 @@ docomplete(int lst)
|
||||||
char *s, *ol;
|
char *s, *ol;
|
||||||
int olst = lst, chl = 0, ne = noerrs, ocs;
|
int olst = lst, chl = 0, ne = noerrs, ocs;
|
||||||
|
|
||||||
|
if (showagain && validlist)
|
||||||
|
showinglist = -2;
|
||||||
|
showagain = 0;
|
||||||
|
|
||||||
/* If we are doing a menu-completion... */
|
/* If we are doing a menu-completion... */
|
||||||
|
|
||||||
if (menucmp && lst != COMP_LIST_EXPAND && compwidget &&
|
if (menucmp && lst != COMP_LIST_EXPAND &&
|
||||||
compwidget == lastcompwidget) {
|
(!compwidget || compwidget == lastcompwidget)) {
|
||||||
do_menucmp(lst);
|
do_menucmp(lst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -872,7 +880,7 @@ docomplete(int lst)
|
||||||
}
|
}
|
||||||
if (lst == COMP_EXPAND_COMPLETE)
|
if (lst == COMP_EXPAND_COMPLETE)
|
||||||
do {
|
do {
|
||||||
/* check if there is a parameter expresiion. */
|
/* Check if there is a parameter expression. */
|
||||||
for (; *q && *q != String; q++);
|
for (; *q && *q != String; q++);
|
||||||
if (*q == String && q[1] != Inpar && q[1] != Inbrack) {
|
if (*q == String && q[1] != Inpar && q[1] != Inbrack) {
|
||||||
if (*++q == Inbrace) {
|
if (*++q == Inbrace) {
|
||||||
|
@ -1128,7 +1136,7 @@ unmetafy_line(void)
|
||||||
static char *
|
static char *
|
||||||
get_comp_string(void)
|
get_comp_string(void)
|
||||||
{
|
{
|
||||||
int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins, inarr, ia, parct;
|
int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins, ia, parct;
|
||||||
char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
|
char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
|
||||||
|
|
||||||
zsfree(brbeg);
|
zsfree(brbeg);
|
||||||
|
@ -1192,7 +1200,7 @@ get_comp_string(void)
|
||||||
inpush(dupstrspace((char *) linptr), 0, NULL);
|
inpush(dupstrspace((char *) linptr), 0, NULL);
|
||||||
strinbeg();
|
strinbeg();
|
||||||
stophist = 2;
|
stophist = 2;
|
||||||
i = tt0 = cp = rd = ins = oins = inarr = parct = ia = 0;
|
i = tt0 = cp = rd = ins = oins = linarr = parct = ia = 0;
|
||||||
|
|
||||||
/* This loop is possibly the wrong way to do this. It goes through *
|
/* This loop is possibly the wrong way to do this. It goes through *
|
||||||
* the previously massaged command line using the lexer. It stores *
|
* the previously massaged command line using the lexer. It stores *
|
||||||
|
@ -1211,11 +1219,11 @@ get_comp_string(void)
|
||||||
linredir = (inredir && !ins);
|
linredir = (inredir && !ins);
|
||||||
oins = ins;
|
oins = ins;
|
||||||
/* Get the next token. */
|
/* Get the next token. */
|
||||||
if (inarr)
|
if (linarr)
|
||||||
incmdpos = 0;
|
incmdpos = 0;
|
||||||
ctxtlex();
|
ctxtlex();
|
||||||
if (tok == ENVARRAY) {
|
if (tok == ENVARRAY) {
|
||||||
inarr = 1;
|
linarr = 1;
|
||||||
zsfree(varname);
|
zsfree(varname);
|
||||||
varname = ztrdup(tokstr);
|
varname = ztrdup(tokstr);
|
||||||
} else if (tok == INPAR)
|
} else if (tok == INPAR)
|
||||||
|
@ -1224,7 +1232,7 @@ get_comp_string(void)
|
||||||
if (parct)
|
if (parct)
|
||||||
parct--;
|
parct--;
|
||||||
else
|
else
|
||||||
inarr = 0;
|
linarr = 0;
|
||||||
}
|
}
|
||||||
if (inredir)
|
if (inredir)
|
||||||
rdstr = tokstrings[tok];
|
rdstr = tokstrings[tok];
|
||||||
|
@ -1267,7 +1275,7 @@ get_comp_string(void)
|
||||||
clwpos = i;
|
clwpos = i;
|
||||||
cp = lincmd;
|
cp = lincmd;
|
||||||
rd = linredir;
|
rd = linredir;
|
||||||
ia = inarr;
|
ia = linarr;
|
||||||
if (inwhat == IN_NOTHING && incond)
|
if (inwhat == IN_NOTHING && incond)
|
||||||
inwhat = IN_COND;
|
inwhat = IN_COND;
|
||||||
} else if (linredir)
|
} else if (linredir)
|
||||||
|
@ -1515,12 +1523,53 @@ get_comp_string(void)
|
||||||
*/
|
*/
|
||||||
for (i = 0, p = s; *p; p++, i++) {
|
for (i = 0, p = s; *p; p++, i++) {
|
||||||
/* careful, ${... is not a brace expansion...
|
/* careful, ${... is not a brace expansion...
|
||||||
* in fact, if it's got a substitution in it's too
|
* we try to get braces after a parameter expansion right,
|
||||||
* hard for us anyway. sorry.
|
* but this may fail sometimes. sorry.
|
||||||
*/
|
*/
|
||||||
if (*p == String || *p == Qstring) {
|
if (*p == String || *p == Qstring) {
|
||||||
tt = NULL;
|
if (p[1] == Inbrace || p[1] == Inpar || p[1] == Inbrack) {
|
||||||
break;
|
char *tp = p + 1;
|
||||||
|
if (skipparens(*tp, (*tp == Inbrace ? Outbrace :
|
||||||
|
(*tp == Inpar ? Outpar : Outbrack)),
|
||||||
|
&tp)) {
|
||||||
|
tt = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += tp - p;
|
||||||
|
p = tp;
|
||||||
|
} else {
|
||||||
|
char *tp = p + 1;
|
||||||
|
|
||||||
|
for (; *tp == '^' || *tp == Hat ||
|
||||||
|
*tp == '=' || *tp == Equals ||
|
||||||
|
*tp == '~' || *tp == Tilde ||
|
||||||
|
*tp == '#' || *tp == Pound || *tp == '+';
|
||||||
|
tp++);
|
||||||
|
if (*tp == Quest || *tp == Star || *tp == String ||
|
||||||
|
*tp == Qstring || *tp == '?' || *tp == '*' ||
|
||||||
|
*tp == '$' || *tp == '-' || *tp == '!' ||
|
||||||
|
*tp == '@')
|
||||||
|
p++, i++;
|
||||||
|
else {
|
||||||
|
if (idigit(*tp))
|
||||||
|
while (idigit(*tp))
|
||||||
|
tp++;
|
||||||
|
else if (iident(*tp))
|
||||||
|
while (iident(*tp))
|
||||||
|
tp++;
|
||||||
|
else {
|
||||||
|
tt = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*tp == Inbrace) {
|
||||||
|
tt = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tp--;
|
||||||
|
i += tp - p;
|
||||||
|
p = tp;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (*p == Inbrace) {
|
} else if (*p == Inbrace) {
|
||||||
if (tt) {
|
if (tt) {
|
||||||
/* too many inbraces */
|
/* too many inbraces */
|
||||||
|
@ -3472,14 +3521,10 @@ set_param(char *name, LinkList l)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
addmatches(char *ipre, char *isuf,
|
addmatches(Cadata dat, char **argv)
|
||||||
char *ppre, char *psuf, char *prpre, char *pre,
|
|
||||||
char *suf, char *group, char *rems, char *remf, char *ign,
|
|
||||||
int flags, int aflags, Cmatcher match, char *exp,
|
|
||||||
char *apar, char *opar, char **argv)
|
|
||||||
{
|
{
|
||||||
char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL;
|
char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL;
|
||||||
char **aign = NULL;
|
char **aign = NULL, **dparr;
|
||||||
int lpl, lsl, pl, sl, bpl, bsl, llpl = 0, llsl = 0, nm = mnum;
|
int lpl, lsl, pl, sl, bpl, bsl, llpl = 0, llsl = 0, nm = mnum;
|
||||||
int oisalt = 0, isalt, isexact, doadd;
|
int oisalt = 0, isalt, isexact, doadd;
|
||||||
Cline lc = NULL;
|
Cline lc = NULL;
|
||||||
|
@ -3487,45 +3532,52 @@ addmatches(char *ipre, char *isuf,
|
||||||
struct cmlist mst;
|
struct cmlist mst;
|
||||||
Cmlist oms = mstack;
|
Cmlist oms = mstack;
|
||||||
Comp cp = NULL;
|
Comp cp = NULL;
|
||||||
LinkList aparl = NULL, oparl = NULL;
|
LinkList aparl = NULL, oparl = NULL, dparl = NULL;
|
||||||
|
|
||||||
/* Switch back to the heap that was used when the completion widget
|
/* Switch back to the heap that was used when the completion widget
|
||||||
* was invoked. */
|
* was invoked. */
|
||||||
SWITCHHEAPS(compheap) {
|
SWITCHHEAPS(compheap) {
|
||||||
HEAPALLOC {
|
HEAPALLOC {
|
||||||
doadd = (!apar && !opar);
|
doadd = (!dat->apar && !dat->opar && !dat->dpar);
|
||||||
if (apar)
|
if (dat->apar)
|
||||||
aparl = newlinklist();
|
aparl = newlinklist();
|
||||||
if (opar)
|
if (dat->opar)
|
||||||
oparl = newlinklist();
|
oparl = newlinklist();
|
||||||
if (exp) {
|
if (dat->dpar) {
|
||||||
|
if (*(dat->dpar) == '(')
|
||||||
|
dparr = NULL;
|
||||||
|
else if ((dparr = get_user_var(dat->dpar)) && !*dparr)
|
||||||
|
dparr = NULL;
|
||||||
|
dparl = newlinklist();
|
||||||
|
}
|
||||||
|
if (dat->exp) {
|
||||||
expl = (Cexpl) zhalloc(sizeof(struct cexpl));
|
expl = (Cexpl) zhalloc(sizeof(struct cexpl));
|
||||||
expl->count = expl->fcount = 0;
|
expl->count = expl->fcount = 0;
|
||||||
expl->str = dupstring(exp);
|
expl->str = dupstring(dat->exp);
|
||||||
} else
|
} else
|
||||||
expl = NULL;
|
expl = NULL;
|
||||||
|
|
||||||
/* Store the matcher in our stack of matchers. */
|
/* Store the matcher in our stack of matchers. */
|
||||||
if (match) {
|
if (dat->match) {
|
||||||
mst.next = mstack;
|
mst.next = mstack;
|
||||||
mst.matcher = match;
|
mst.matcher = dat->match;
|
||||||
mstack = &mst;
|
mstack = &mst;
|
||||||
|
|
||||||
if (!mnum)
|
if (!mnum)
|
||||||
add_bmatchers(match);
|
add_bmatchers(dat->match);
|
||||||
|
|
||||||
addlinknode(matchers, match);
|
addlinknode(matchers, dat->match);
|
||||||
match->refc++;
|
dat->match->refc++;
|
||||||
}
|
}
|
||||||
if (mnum && (mstack || bmatchers))
|
if (mnum && (mstack || bmatchers))
|
||||||
update_bmatchers();
|
update_bmatchers();
|
||||||
|
|
||||||
/* Get the suffixes to ignore. */
|
/* Get the suffixes to ignore. */
|
||||||
if (ign)
|
if (dat->ign)
|
||||||
aign = get_user_var(ign);
|
aign = get_user_var(dat->ign);
|
||||||
/* Get the contents of the completion variables if we have
|
/* Get the contents of the completion variables if we have
|
||||||
* to perform matching. */
|
* to perform matching. */
|
||||||
if (aflags & CAF_MATCH) {
|
if (dat->aflags & CAF_MATCH) {
|
||||||
lipre = dupstring(compiprefix);
|
lipre = dupstring(compiprefix);
|
||||||
lisuf = dupstring(compisuffix);
|
lisuf = dupstring(compisuffix);
|
||||||
lpre = dupstring(compprefix);
|
lpre = dupstring(compprefix);
|
||||||
|
@ -3533,8 +3585,8 @@ addmatches(char *ipre, char *isuf,
|
||||||
llpl = strlen(lpre);
|
llpl = strlen(lpre);
|
||||||
llsl = strlen(lsuf);
|
llsl = strlen(lsuf);
|
||||||
/* Test if there is an existing -P prefix. */
|
/* Test if there is an existing -P prefix. */
|
||||||
if (pre && *pre) {
|
if (dat->pre && *dat->pre) {
|
||||||
pl = pfxlen(pre, lpre);
|
pl = pfxlen(dat->pre, lpre);
|
||||||
llpl -= pl;
|
llpl -= pl;
|
||||||
lpre += pl;
|
lpre += pl;
|
||||||
}
|
}
|
||||||
|
@ -3557,79 +3609,76 @@ addmatches(char *ipre, char *isuf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Now duplicate the strings we have from the command line. */
|
/* Now duplicate the strings we have from the command line. */
|
||||||
if (ipre)
|
if (dat->ipre)
|
||||||
ipre = (lipre ? dyncat(lipre, ipre) : dupstring(ipre));
|
dat->ipre = (lipre ? dyncat(lipre, dat->ipre) :
|
||||||
|
dupstring(dat->ipre));
|
||||||
else if (lipre)
|
else if (lipre)
|
||||||
ipre = lipre;
|
dat->ipre = lipre;
|
||||||
if (isuf)
|
if (dat->isuf)
|
||||||
isuf = (lisuf ? dyncat(lisuf, isuf) : dupstring(isuf));
|
dat->isuf = (lisuf ? dyncat(lisuf, dat->isuf) :
|
||||||
|
dupstring(dat->isuf));
|
||||||
else if (lisuf)
|
else if (lisuf)
|
||||||
isuf = lisuf;
|
dat->isuf = lisuf;
|
||||||
if (ppre) {
|
if (dat->ppre) {
|
||||||
ppre = dupstring(ppre);
|
dat->ppre = dupstring(dat->ppre);
|
||||||
lpl = strlen(ppre);
|
lpl = strlen(dat->ppre);
|
||||||
} else
|
} else
|
||||||
lpl = 0;
|
lpl = 0;
|
||||||
if (psuf) {
|
if (dat->psuf) {
|
||||||
psuf = dupstring(psuf);
|
dat->psuf = dupstring(dat->psuf);
|
||||||
lsl = strlen(psuf);
|
lsl = strlen(dat->psuf);
|
||||||
} else
|
} else
|
||||||
lsl = 0;
|
lsl = 0;
|
||||||
if (aflags & CAF_MATCH) {
|
if (dat->aflags & CAF_MATCH) {
|
||||||
s = ppre ? ppre : "";
|
s = dat->ppre ? dat->ppre : "";
|
||||||
if (llpl <= lpl && strpfx(lpre, s)) {
|
if (llpl <= lpl && strpfx(lpre, s))
|
||||||
llpl = 0;
|
|
||||||
lpre = "";
|
lpre = "";
|
||||||
} else if (llpl > lpl && strpfx(s, lpre)) {
|
else if (llpl > lpl && strpfx(s, lpre))
|
||||||
llpl -= lpl;
|
|
||||||
lpre += lpl;
|
lpre += lpl;
|
||||||
} else
|
else
|
||||||
*argv = NULL;
|
*argv = NULL;
|
||||||
s = psuf ? psuf : "";
|
s = dat->psuf ? dat->psuf : "";
|
||||||
if (llsl <= lsl && strsfx(lsuf, s)) {
|
if (llsl <= lsl && strsfx(lsuf, s))
|
||||||
llsl = 0;
|
|
||||||
lsuf = "";
|
lsuf = "";
|
||||||
} else if (llsl > lsl && strsfx(s, lsuf)) {
|
else if (llsl > lsl && strsfx(s, lsuf))
|
||||||
lsuf[llsl - lsl] = '\0';
|
lsuf[llsl - lsl] = '\0';
|
||||||
llsl -= lsl;
|
else
|
||||||
} else
|
|
||||||
*argv = NULL;
|
*argv = NULL;
|
||||||
}
|
}
|
||||||
if (*argv) {
|
if (*argv) {
|
||||||
if (pre)
|
if (dat->pre)
|
||||||
pre = dupstring(pre);
|
dat->pre = dupstring(dat->pre);
|
||||||
if (suf)
|
if (dat->suf)
|
||||||
suf = dupstring(suf);
|
dat->suf = dupstring(dat->suf);
|
||||||
if (!prpre && (prpre = ppre)) {
|
if (!dat->prpre && (dat->prpre = dat->ppre)) {
|
||||||
singsub(&prpre);
|
singsub(&(dat->prpre));
|
||||||
untokenize(prpre);
|
untokenize(dat->prpre);
|
||||||
} else
|
} else
|
||||||
prpre = dupstring(prpre);
|
dat->prpre = dupstring(dat->prpre);
|
||||||
/* Select the group in which to store the matches. */
|
/* Select the group in which to store the matches. */
|
||||||
if (group) {
|
if (dat->group) {
|
||||||
endcmgroup(NULL);
|
endcmgroup(NULL);
|
||||||
begcmgroup(group, (aflags & CAF_NOSORT));
|
begcmgroup(dat->group, (dat->aflags & CAF_NOSORT));
|
||||||
if (aflags & CAF_NOSORT)
|
if (dat->aflags & CAF_NOSORT)
|
||||||
mgroup->flags |= CGF_NOSORT;
|
mgroup->flags |= CGF_NOSORT;
|
||||||
} else {
|
} else {
|
||||||
endcmgroup(NULL);
|
endcmgroup(NULL);
|
||||||
begcmgroup("default", 0);
|
begcmgroup("default", 0);
|
||||||
}
|
}
|
||||||
/* Select the set of matches. */
|
/* Select the set of matches. */
|
||||||
oisalt = (aflags & CAF_ALT);
|
oisalt = (dat->aflags & CAF_ALT);
|
||||||
|
|
||||||
if (remf) {
|
if (dat->remf) {
|
||||||
remf = dupstring(remf);
|
dat->remf = dupstring(dat->remf);
|
||||||
rems = NULL;
|
dat->rems = NULL;
|
||||||
} else if (rems)
|
} else if (dat->rems)
|
||||||
rems = dupstring(rems);
|
dat->rems = dupstring(dat->rems);
|
||||||
|
|
||||||
/* Probably quote the prefix and suffix for testing. */
|
/* Probably quote the prefix and suffix for testing. */
|
||||||
if (!cp && (aflags & CAF_MATCH) && !(aflags & CAF_QUOTE)) {
|
if (!cp && (dat->aflags & CAF_MATCH) &&
|
||||||
|
!(dat->aflags & CAF_QUOTE)) {
|
||||||
lpre = quotename(lpre, NULL);
|
lpre = quotename(lpre, NULL);
|
||||||
lsuf = quotename(lsuf, NULL);
|
lsuf = quotename(lsuf, NULL);
|
||||||
llpl = strlen(lpre);
|
|
||||||
llsl = strlen(lsuf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Walk through the matches given. */
|
/* Walk through the matches given. */
|
||||||
|
@ -3638,7 +3687,7 @@ addmatches(char *ipre, char *isuf,
|
||||||
bpl = brpl;
|
bpl = brpl;
|
||||||
bsl = brsl;
|
bsl = brsl;
|
||||||
isalt = oisalt;
|
isalt = oisalt;
|
||||||
if ((!psuf || !*psuf) && aign) {
|
if ((!dat->psuf || !*(dat->psuf)) && aign) {
|
||||||
/* Do the suffix-test. If the match has one of the
|
/* Do the suffix-test. If the match has one of the
|
||||||
* suffixes from ign, we put it in the alternate set. */
|
* suffixes from ign, we put it in the alternate set. */
|
||||||
char **pt = aign;
|
char **pt = aign;
|
||||||
|
@ -3649,39 +3698,52 @@ addmatches(char *ipre, char *isuf,
|
||||||
&& !strcmp(*pt, s + sl - filell))
|
&& !strcmp(*pt, s + sl - filell))
|
||||||
isalt = 1;
|
isalt = 1;
|
||||||
|
|
||||||
if (isalt && !doadd)
|
if (isalt && !doadd) {
|
||||||
|
if (dparr && !*++dparr)
|
||||||
|
dparr = NULL;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(aflags & CAF_MATCH)) {
|
if (!(dat->aflags & CAF_MATCH)) {
|
||||||
ms = dupstring(s);
|
ms = dupstring(s);
|
||||||
lc = bld_parts(ms, sl, -1, NULL);
|
lc = bld_parts(ms, sl, -1, NULL);
|
||||||
isexact = 0;
|
isexact = 0;
|
||||||
} else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc,
|
} else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc,
|
||||||
!(aflags & CAF_QUOTE),
|
!(dat->aflags & CAF_QUOTE),
|
||||||
&bpl, &bsl, &isexact)))
|
&bpl, &bsl, &isexact))) {
|
||||||
|
if (dparr && !*++dparr)
|
||||||
|
dparr = NULL;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (doadd) {
|
if (doadd) {
|
||||||
cm = add_match_data(isalt, ms, lc, ipre, ipre, isuf, pre,
|
cm = add_match_data(isalt, ms, lc, dat->ipre, dat->ipre,
|
||||||
prpre, ppre, psuf, suf, bpl, bsl,
|
dat->isuf, dat->pre, dat->prpre,
|
||||||
flags, isexact);
|
dat->ppre, dat->psuf, dat->suf,
|
||||||
cm->rems = rems;
|
bpl, bsl, dat->flags, isexact);
|
||||||
cm->remf = remf;
|
cm->rems = dat->rems;
|
||||||
|
cm->remf = dat->remf;
|
||||||
} else {
|
} else {
|
||||||
if (apar)
|
if (dat->apar)
|
||||||
addlinknode(aparl, ms);
|
addlinknode(aparl, ms);
|
||||||
if (opar)
|
if (dat->opar)
|
||||||
addlinknode(oparl, s);
|
addlinknode(oparl, s);
|
||||||
|
if (dat->dpar && dparr) {
|
||||||
|
addlinknode(dparl, *dparr);
|
||||||
|
if (!*++dparr)
|
||||||
|
dparr = NULL;
|
||||||
|
}
|
||||||
free_cline(lc);
|
free_cline(lc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compnmatches = mnum;
|
compnmatches = mnum;
|
||||||
if (exp)
|
if (dat->exp)
|
||||||
addexpl();
|
addexpl();
|
||||||
if (apar)
|
if (dat->apar)
|
||||||
set_param(apar, aparl);
|
set_param(dat->apar, aparl);
|
||||||
if (opar)
|
if (dat->opar)
|
||||||
set_param(opar, oparl);
|
set_param(dat->opar, oparl);
|
||||||
|
if (dat->dpar)
|
||||||
|
set_param(dat->dpar, dparl);
|
||||||
} LASTALLOC;
|
} LASTALLOC;
|
||||||
} SWITCHBACKHEAPS;
|
} SWITCHBACKHEAPS;
|
||||||
|
|
||||||
|
@ -4128,6 +4190,7 @@ docompletion(char *s, int lst, int incmd)
|
||||||
(unset(ALWAYSLASTPROMPT) && zmult != 1)) ?
|
(unset(ALWAYSLASTPROMPT) && zmult != 1)) ?
|
||||||
"yes" : "");
|
"yes" : "");
|
||||||
movetoend = ((cs == we || isset(ALWAYSTOEND)) ? 2 : 1);
|
movetoend = ((cs == we || isset(ALWAYSTOEND)) ? 2 : 1);
|
||||||
|
showinglist = 0;
|
||||||
|
|
||||||
/* Make sure we have the completion list and compctl. */
|
/* Make sure we have the completion list and compctl. */
|
||||||
if (makecomplist(s, incmd, lst)) {
|
if (makecomplist(s, incmd, lst)) {
|
||||||
|
@ -4217,14 +4280,22 @@ callcompfunc(char *s, char *fn)
|
||||||
|
|
||||||
if ((list = getshfunc(fn)) != &dummy_list) {
|
if ((list = getshfunc(fn)) != &dummy_list) {
|
||||||
char **p, *tmp;
|
char **p, *tmp;
|
||||||
int set, aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext;
|
int aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext;
|
||||||
|
unsigned int set;
|
||||||
Param *ocpms = comppms;
|
Param *ocpms = comppms;
|
||||||
|
|
||||||
comppms = (Param *) zalloc(CP_NUM * sizeof(Param));
|
comppms = (Param *) zalloc(CP_NUM * sizeof(Param));
|
||||||
|
|
||||||
set = -1 & ~(CP_PARAMETER | CP_REDIRECT | CP_QUOTE | CP_QUOTING |
|
set = CP_ALLMASK &
|
||||||
CP_EXACTSTR | CP_FORCELIST | CP_OLDLIST | CP_OLDINS |
|
~(CP_PARAMETER | CP_REDIRECT | CP_QUOTE | CP_QUOTING |
|
||||||
(useglob ? 0 : CP_PATMATCH));
|
CP_EXACTSTR | CP_FORCELIST | CP_OLDLIST | CP_OLDINS |
|
||||||
|
(useglob ? 0 : CP_PATMATCH));
|
||||||
|
zsfree(compvared);
|
||||||
|
if (varedarg) {
|
||||||
|
compvared = ztrdup(varedarg);
|
||||||
|
set |= CP_VARED;
|
||||||
|
} else
|
||||||
|
compvared = ztrdup("");
|
||||||
if (!*complastprompt)
|
if (!*complastprompt)
|
||||||
set &= ~CP_LASTPROMPT;
|
set &= ~CP_LASTPROMPT;
|
||||||
zsfree(compcontext);
|
zsfree(compcontext);
|
||||||
|
@ -4257,7 +4328,7 @@ callcompfunc(char *s, char *fn)
|
||||||
} else
|
} else
|
||||||
switch (linwhat) {
|
switch (linwhat) {
|
||||||
case IN_ENV:
|
case IN_ENV:
|
||||||
compcontext = "array_value";
|
compcontext = (linarr ? "array_value" : "value");
|
||||||
compparameter = varname;
|
compparameter = varname;
|
||||||
set |= CP_PARAMETER;
|
set |= CP_PARAMETER;
|
||||||
if (!clwpos) {
|
if (!clwpos) {
|
||||||
|
@ -4551,6 +4622,7 @@ makecomplist(char *s, int incmd, int lst)
|
||||||
insmnum = insgnum = 1;
|
insmnum = insgnum = 1;
|
||||||
insgroup = oldlist = oldins = 0;
|
insgroup = oldlist = oldins = 0;
|
||||||
begcmgroup("default", 0);
|
begcmgroup("default", 0);
|
||||||
|
menucmp = 0;
|
||||||
|
|
||||||
ccused = newlinklist();
|
ccused = newlinklist();
|
||||||
ccstack = newlinklist();
|
ccstack = newlinklist();
|
||||||
|
@ -6717,11 +6789,13 @@ unambig_data(int *cp)
|
||||||
return scache;
|
return scache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert the given match. This returns the number of characters inserted.*/
|
/* Insert the given match. This returns the number of characters inserted.
|
||||||
|
* scs is used to return the position where a automatically created suffix
|
||||||
|
* has to be inserted. */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
instmatch(Cmatch m)
|
instmatch(Cmatch m, int *scs)
|
||||||
{
|
{
|
||||||
int l, r = 0, ocs, a = cs;
|
int l, r = 0, ocs, a = cs;
|
||||||
|
|
||||||
|
@ -6771,6 +6845,7 @@ instmatch(Cmatch m)
|
||||||
} else
|
} else
|
||||||
brscs = -1;
|
brscs = -1;
|
||||||
/* -S suffix */
|
/* -S suffix */
|
||||||
|
*scs = cs;
|
||||||
if (m->suf) {
|
if (m->suf) {
|
||||||
inststrlen(m->suf, 1, (l = strlen(m->suf)));
|
inststrlen(m->suf, 1, (l = strlen(m->suf)));
|
||||||
r += l;
|
r += l;
|
||||||
|
@ -6842,13 +6917,13 @@ do_ambiguous(void)
|
||||||
|
|
||||||
/* If REC_EXACT and AUTO_MENU are set and what we inserted is an *
|
/* If REC_EXACT and AUTO_MENU are set and what we inserted is an *
|
||||||
* exact match, we want menu completion the next time round *
|
* exact match, we want menu completion the next time round *
|
||||||
* so we set fromcomp,to ensure that the word on the line is not *
|
* so we set fromcomp, to ensure that the word on the line is not *
|
||||||
* taken as an exact match. Also we remember if we just moved the *
|
* taken as an exact match. Also we remember if we just moved the *
|
||||||
* cursor into the word. */
|
* cursor into the word. */
|
||||||
fromcomp = ((isset(AUTOMENU) ? FC_LINE : 0) |
|
fromcomp = ((isset(AUTOMENU) ? FC_LINE : 0) |
|
||||||
((atend && cs != lastend) ? FC_INWORD : 0));
|
((atend && cs != lastend) ? FC_INWORD : 0));
|
||||||
|
|
||||||
/* Probably move the cursor to then end. */
|
/* Probably move the cursor to the end. */
|
||||||
if (movetoend == 3)
|
if (movetoend == 3)
|
||||||
cs = lastend;
|
cs = lastend;
|
||||||
|
|
||||||
|
@ -6907,7 +6982,7 @@ ztat(char *nam, struct stat *buf, int ls)
|
||||||
static void
|
static void
|
||||||
do_single(Cmatch m)
|
do_single(Cmatch m)
|
||||||
{
|
{
|
||||||
int l, sr = 0;
|
int l, sr = 0, scs;
|
||||||
int havesuff = 0;
|
int havesuff = 0;
|
||||||
char *str = m->str, *ppre = m->ppre, *psuf = m->psuf, *prpre = m->prpre;
|
char *str = m->str, *ppre = m->ppre, *psuf = m->psuf, *prpre = m->prpre;
|
||||||
|
|
||||||
|
@ -6937,7 +7012,7 @@ do_single(Cmatch m)
|
||||||
foredel(l);
|
foredel(l);
|
||||||
|
|
||||||
/* And then we insert the new string. */
|
/* And then we insert the new string. */
|
||||||
menulen = instmatch(m);
|
menulen = instmatch(m, &scs);
|
||||||
menuend = cs;
|
menuend = cs;
|
||||||
cs = menupos + menulen;
|
cs = menupos + menulen;
|
||||||
|
|
||||||
|
@ -6956,6 +7031,7 @@ do_single(Cmatch m)
|
||||||
} else {
|
} else {
|
||||||
/* There is no user-specified suffix, *
|
/* There is no user-specified suffix, *
|
||||||
* so generate one automagically. */
|
* so generate one automagically. */
|
||||||
|
cs = scs;
|
||||||
if (m->ripre && (m->flags & CMF_PARBR)) {
|
if (m->ripre && (m->flags & CMF_PARBR)) {
|
||||||
/*{{*/
|
/*{{*/
|
||||||
/* Completing a parameter in braces. Add a removable `}' suffix. */
|
/* Completing a parameter in braces. Add a removable `}' suffix. */
|
||||||
|
@ -7006,6 +7082,8 @@ do_single(Cmatch m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!menuinsc)
|
||||||
|
cs = menupos + menulen;
|
||||||
}
|
}
|
||||||
/* If completing in a brace expansion... */
|
/* If completing in a brace expansion... */
|
||||||
if (brbeg) {
|
if (brbeg) {
|
||||||
|
@ -7018,7 +7096,7 @@ do_single(Cmatch m)
|
||||||
} else if (!menucmp) {
|
} else if (!menucmp) {
|
||||||
/*{{*/
|
/*{{*/
|
||||||
/* Otherwise, add a `,' suffix, and let `}' remove it. */
|
/* Otherwise, add a `,' suffix, and let `}' remove it. */
|
||||||
cs = menuend;
|
cs = scs;
|
||||||
havesuff = 1;
|
havesuff = 1;
|
||||||
inststrlen(",", 1, 1);
|
inststrlen(",", 1, 1);
|
||||||
menuinsc++;
|
menuinsc++;
|
||||||
|
@ -7492,7 +7570,12 @@ listlist(LinkList l)
|
||||||
struct cmgroup dg;
|
struct cmgroup dg;
|
||||||
Cmgroup am = amatches;
|
Cmgroup am = amatches;
|
||||||
int vl = validlist, sm = smatches;
|
int vl = validlist, sm = smatches;
|
||||||
|
char *oclp = complastprompt;
|
||||||
|
|
||||||
|
if (listshown)
|
||||||
|
showagain = 1;
|
||||||
|
|
||||||
|
complastprompt = ((zmult == 1) == !!isset(ALWAYSLASTPROMPT) ? "yes" : NULL);
|
||||||
smatches = 1;
|
smatches = 1;
|
||||||
validlist = 1;
|
validlist = 1;
|
||||||
amatches = &dg;
|
amatches = &dg;
|
||||||
|
@ -7503,6 +7586,7 @@ listlist(LinkList l)
|
||||||
amatches = am;
|
amatches = am;
|
||||||
validlist = vl;
|
validlist = vl;
|
||||||
smatches = sm;
|
smatches = sm;
|
||||||
|
complastprompt = oclp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expand the history references. */
|
/* Expand the history references. */
|
||||||
|
|
|
@ -120,7 +120,7 @@ static struct builtin builtins[] =
|
||||||
BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
|
BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsw", "c"),
|
||||||
|
|
||||||
#ifdef DYNAMIC
|
#ifdef DYNAMIC
|
||||||
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "LaudicI", NULL),
|
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "LaudicIp", NULL),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1485,7 +1485,7 @@ typeset_single(char *cname, char *pname, Param pm, int func,
|
||||||
int usepm, tc, keeplocal = 0;
|
int usepm, tc, keeplocal = 0;
|
||||||
|
|
||||||
/* use the existing pm? */
|
/* use the existing pm? */
|
||||||
usepm = pm && !(pm->flags & PM_UNSET);
|
usepm = pm && !(pm->flags & (PM_UNSET | PM_AUTOLOAD));
|
||||||
|
|
||||||
/* Always use an existing pm if special at current locallevel */
|
/* Always use an existing pm if special at current locallevel */
|
||||||
if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel)
|
if (pm && (pm->flags & PM_SPECIAL) && pm->level == locallevel)
|
||||||
|
@ -1793,7 +1793,9 @@ bin_typeset(char *name, char **argv, char *ops, int func)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!typeset_single(name, asg->name,
|
if (!typeset_single(name, asg->name,
|
||||||
(Param)paramtab->getnode(paramtab, asg->name),
|
(Param) (paramtab == realparamtab ?
|
||||||
|
gethashnode2(paramtab, asg->name) :
|
||||||
|
paramtab->getnode(paramtab, asg->name)),
|
||||||
func, on, off, roff, asg->value, NULL))
|
func, on, off, roff, asg->value, NULL))
|
||||||
returnval = 1;
|
returnval = 1;
|
||||||
}
|
}
|
||||||
|
@ -1945,7 +1947,7 @@ bin_unset(char *name, char **argv, char *ops, int func)
|
||||||
next = (Param) pm->next;
|
next = (Param) pm->next;
|
||||||
if ((!(pm->flags & PM_RESTRICTED) ||
|
if ((!(pm->flags & PM_RESTRICTED) ||
|
||||||
unset(RESTRICTED)) && domatch(pm->nam, com, 0)) {
|
unset(RESTRICTED)) && domatch(pm->nam, com, 0)) {
|
||||||
unsetparam(pm->nam);
|
unsetparam_pm(pm, 0, 1);
|
||||||
match++;
|
match++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1974,7 +1976,9 @@ bin_unset(char *name, char **argv, char *ops, int func)
|
||||||
}
|
}
|
||||||
*ss = 0;
|
*ss = 0;
|
||||||
}
|
}
|
||||||
pm = (Param) paramtab->getnode(paramtab, s);
|
pm = (Param) (paramtab == realparamtab ?
|
||||||
|
gethashnode2(paramtab, s) :
|
||||||
|
paramtab->getnode(paramtab, s));
|
||||||
if (!pm)
|
if (!pm)
|
||||||
returnval = 1;
|
returnval = 1;
|
||||||
else if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
|
else if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
|
||||||
|
|
|
@ -3379,16 +3379,14 @@ tokenize(char *s)
|
||||||
*t = Inang;
|
*t = Inang;
|
||||||
*s = Outang;
|
*s = Outang;
|
||||||
break;
|
break;
|
||||||
case '^':
|
|
||||||
case '#':
|
|
||||||
case '~':
|
|
||||||
if (unset(EXTENDEDGLOB))
|
|
||||||
break;
|
|
||||||
case '(':
|
case '(':
|
||||||
case '|':
|
case '|':
|
||||||
case ')':
|
case ')':
|
||||||
if (isset(SHGLOB))
|
if (isset(SHGLOB))
|
||||||
break;
|
break;
|
||||||
|
case '^':
|
||||||
|
case '#':
|
||||||
|
case '~':
|
||||||
case '[':
|
case '[':
|
||||||
case ']':
|
case ']':
|
||||||
case '*':
|
case '*':
|
||||||
|
|
|
@ -24,7 +24,7 @@ for x_mod in $x_mods; do
|
||||||
*" $x_mod "*) ;;
|
*" $x_mod "*) ;;
|
||||||
*) echo "/* non-linked-in known module \`$x_mod' */"
|
*) echo "/* non-linked-in known module \`$x_mod' */"
|
||||||
eval "loc=\$loc_$x_mod"
|
eval "loc=\$loc_$x_mod"
|
||||||
unset moddeps autobins autoinfixconds autoprefixconds
|
unset moddeps autobins autoinfixconds autoprefixconds autoparams
|
||||||
. $srcdir/../$loc/${x_mod}.mdd
|
. $srcdir/../$loc/${x_mod}.mdd
|
||||||
for bin in $autobins; do
|
for bin in $autobins; do
|
||||||
echo " add_autobin(\"$bin\", \"$x_mod\");"
|
echo " add_autobin(\"$bin\", \"$x_mod\");"
|
||||||
|
@ -35,6 +35,9 @@ for x_mod in $x_mods; do
|
||||||
for cond in $autoprefixconds; do
|
for cond in $autoprefixconds; do
|
||||||
echo " add_autocond(\"$cond\", 0, \"$x_mod\");"
|
echo " add_autocond(\"$cond\", 0, \"$x_mod\");"
|
||||||
done
|
done
|
||||||
|
for param in $autoparams; do
|
||||||
|
echo " add_autoparam(\"$param\", \"$x_mod\");"
|
||||||
|
done
|
||||||
for dep in $moddeps; do
|
for dep in $moddeps; do
|
||||||
case $bin_mods in
|
case $bin_mods in
|
||||||
*" $dep "*)
|
*" $dep "*)
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
# autoinfixconds infix condition codes defined by the module, for
|
# autoinfixconds infix condition codes defined by the module, for
|
||||||
# autoloading (without the leading `-')
|
# autoloading (without the leading `-')
|
||||||
# autoprefixconds like autoinfixconds, but for prefix condition codes
|
# autoprefixconds like autoinfixconds, but for prefix condition codes
|
||||||
|
# autoparams parameters defined by the module, for autoloading
|
||||||
# objects .o files making up this module (*must* be defined)
|
# objects .o files making up this module (*must* be defined)
|
||||||
# proto .pro files for this module (default generated from $objects)
|
# proto .pro files for this module (default generated from $objects)
|
||||||
# headers extra headers for this module (default none)
|
# headers extra headers for this module (default none)
|
||||||
|
@ -170,7 +171,7 @@ if $first_stage; then
|
||||||
for module in $here_modules; do
|
for module in $here_modules; do
|
||||||
|
|
||||||
unset moddeps nozshdep alwayslink hasexport
|
unset moddeps nozshdep alwayslink hasexport
|
||||||
unset autobins autoinfixconds autoprefixconds
|
unset autobins autoinfixconds autoprefixconds autoparams
|
||||||
unset objects proto headers hdrdeps otherincs
|
unset objects proto headers hdrdeps otherincs
|
||||||
. $top_srcdir/$the_subdir/${module}.mdd
|
. $top_srcdir/$the_subdir/${module}.mdd
|
||||||
test -n "${moddeps+set}" || moddeps=
|
test -n "${moddeps+set}" || moddeps=
|
||||||
|
|
160
Src/module.c
160
Src/module.c
|
@ -539,18 +539,24 @@ load_module(char const *name)
|
||||||
m = zcalloc(sizeof(*m));
|
m = zcalloc(sizeof(*m));
|
||||||
m->nam = ztrdup(name);
|
m->nam = ztrdup(name);
|
||||||
m->handle = handle;
|
m->handle = handle;
|
||||||
|
m->flags |= MOD_SETUP;
|
||||||
|
PERMALLOC {
|
||||||
|
node = addlinknode(modules, m);
|
||||||
|
} LASTALLOC;
|
||||||
if (setup_module(m) || init_module(m)) {
|
if (setup_module(m) || init_module(m)) {
|
||||||
finish_module(m);
|
finish_module(m);
|
||||||
|
remnode(modules, node);
|
||||||
zsfree(m->nam);
|
zsfree(m->nam);
|
||||||
zfree(m, sizeof(*m));
|
zfree(m, sizeof(*m));
|
||||||
|
m->flags &= ~MOD_SETUP;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PERMALLOC {
|
m->flags &= ~MOD_SETUP;
|
||||||
addlinknode(modules, m);
|
|
||||||
} LASTALLOC;
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
m = (Module) getdata(node);
|
m = (Module) getdata(node);
|
||||||
|
if (m->flags & MOD_SETUP)
|
||||||
|
return m;
|
||||||
if (m->flags & MOD_UNLOAD)
|
if (m->flags & MOD_UNLOAD)
|
||||||
m->flags &= ~MOD_UNLOAD;
|
m->flags &= ~MOD_UNLOAD;
|
||||||
else if (m->handle)
|
else if (m->handle)
|
||||||
|
@ -570,17 +576,22 @@ load_module(char const *name)
|
||||||
if (!m->handle) {
|
if (!m->handle) {
|
||||||
if (!(m->handle = do_load_module(name)))
|
if (!(m->handle = do_load_module(name)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
m->flags |= MOD_SETUP;
|
||||||
if (setup_module(m)) {
|
if (setup_module(m)) {
|
||||||
finish_module(m->handle);
|
finish_module(m->handle);
|
||||||
m->handle = NULL;
|
m->handle = NULL;
|
||||||
|
m->flags &= ~MOD_SETUP;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m->flags |= MOD_SETUP;
|
||||||
if (init_module(m)) {
|
if (init_module(m)) {
|
||||||
finish_module(m->handle);
|
finish_module(m->handle);
|
||||||
m->handle = NULL;
|
m->handle = NULL;
|
||||||
|
m->flags &= ~MOD_SETUP;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
m->flags &= ~MOD_SETUP;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,6 +701,8 @@ bin_zmodload(char *nam, char **args, char *ops, int func)
|
||||||
return bin_zmodload_auto(nam, args, ops);
|
return bin_zmodload_auto(nam, args, ops);
|
||||||
else if (ops['c'] || ops['C'])
|
else if (ops['c'] || ops['C'])
|
||||||
return bin_zmodload_cond(nam, args, ops);
|
return bin_zmodload_cond(nam, args, ops);
|
||||||
|
else if (ops['p'])
|
||||||
|
return bin_zmodload_param(nam, args, ops);
|
||||||
else
|
else
|
||||||
return bin_zmodload_load(nam, args, ops);
|
return bin_zmodload_load(nam, args, ops);
|
||||||
}
|
}
|
||||||
|
@ -888,6 +901,66 @@ bin_zmodload_cond(char *nam, char **args, char *ops)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
printautoparams(HashNode hn, int lon)
|
||||||
|
{
|
||||||
|
Param pm = (Param) hn;
|
||||||
|
|
||||||
|
if (pm->flags & PM_AUTOLOAD) {
|
||||||
|
if (lon)
|
||||||
|
printf("zmodload -p %s %s\n", pm->u.str, pm->nam);
|
||||||
|
else
|
||||||
|
printf("%s (%s)\n", pm->nam, pm->u.str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static int
|
||||||
|
bin_zmodload_param(char *nam, char **args, char *ops)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (ops['u']) {
|
||||||
|
/* remove autoloaded parameters */
|
||||||
|
for (; *args; args++) {
|
||||||
|
Param pm = (Param) gethashnode2(paramtab, *args);
|
||||||
|
|
||||||
|
if (!pm) {
|
||||||
|
if (!ops['i']) {
|
||||||
|
zwarnnam(nam, "%s: no such parameter", *args, 0);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
} else if (!(pm->flags & PM_AUTOLOAD)) {
|
||||||
|
zwarnnam(nam, "%s: parameter is already defined", *args, 0);
|
||||||
|
ret = 1;
|
||||||
|
} else
|
||||||
|
unsetparam_pm(pm, 0, 1);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} else if (!*args) {
|
||||||
|
scanhashtable(paramtab, 1, 0, 0, printautoparams, ops['L']);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* add autoloaded parameters */
|
||||||
|
char *modnam;
|
||||||
|
|
||||||
|
modnam = *args++;
|
||||||
|
if(isset(RESTRICTED) && strchr(modnam, '/')) {
|
||||||
|
zwarnnam(nam, "%s: restricted", modnam, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
char *pnam = *args ? *args++ : modnam;
|
||||||
|
if (strchr(pnam, '/')) {
|
||||||
|
zwarnnam(nam, "%s: `/' is illegal in a parameter", pnam, 0);
|
||||||
|
ret = 1;
|
||||||
|
} else
|
||||||
|
add_autoparam(pnam, modnam);
|
||||||
|
} while(*args);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
int
|
int
|
||||||
unload_module(Module m, LinkNode node)
|
unload_module(Module m, LinkNode node)
|
||||||
|
@ -1114,6 +1187,71 @@ addconddefs(char const *nam, Conddef c, int size)
|
||||||
return hadf ? hads : 1;
|
return hadf ? hads : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This adds the given parameter definition. The return value is zero on *
|
||||||
|
* success and 1 on failure. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
addparamdef(Paramdef d)
|
||||||
|
{
|
||||||
|
Param pm;
|
||||||
|
|
||||||
|
if ((pm = (Param) gethashnode2(paramtab, d->name)))
|
||||||
|
unsetparam_pm(pm, 0, 1);
|
||||||
|
|
||||||
|
if (!(pm = createparam(d->name, d->flags)) &&
|
||||||
|
!(pm = (Param) paramtab->getnode(paramtab, d->name)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
pm->level = 0;
|
||||||
|
pm->u.data = d->var;
|
||||||
|
pm->sets.ifn = (void (*)(Param, long)) d->set;
|
||||||
|
pm->gets.ifn = (long (*)(Param)) d->get;
|
||||||
|
pm->unsetfn = (void (*)(Param, int)) d->unset;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This adds multiple parameter definitions. This is like addbuiltins(). */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
addparamdefs(char const *nam, Paramdef d, int size)
|
||||||
|
{
|
||||||
|
int hads = 0, hadf = 0;
|
||||||
|
|
||||||
|
while (size--) {
|
||||||
|
if (addparamdef(d)) {
|
||||||
|
zwarnnam(nam, "error when adding parameter `%s'", d->name, 0);
|
||||||
|
hadf = 1;
|
||||||
|
} else
|
||||||
|
hads = 2;
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
return hadf ? hads : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete parameters defined. No error checking yet. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
deleteparamdef(Paramdef d)
|
||||||
|
{
|
||||||
|
unsetparam(d->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
deleteparamdefs(char const *nam, Paramdef d, int size)
|
||||||
|
{
|
||||||
|
while (size--) {
|
||||||
|
deleteparamdef(d);
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DYNAMIC
|
#ifdef DYNAMIC
|
||||||
|
|
||||||
/* This adds a definition for autoloading a module for a condition. */
|
/* This adds a definition for autoloading a module for a condition. */
|
||||||
|
@ -1188,4 +1326,20 @@ deleteconddefs(char const *nam, Conddef c, int size)
|
||||||
return hadf ? hads : 1;
|
return hadf ? hads : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This adds a definition for autoloading a module for a parameter. */
|
||||||
|
|
||||||
|
/**/
|
||||||
|
void
|
||||||
|
add_autoparam(char *nam, char *module)
|
||||||
|
{
|
||||||
|
Param pm;
|
||||||
|
|
||||||
|
if ((pm = (Param) gethashnode2(paramtab, nam)))
|
||||||
|
unsetparam_pm(pm, 0, 1);
|
||||||
|
|
||||||
|
pm = setsparam(ztrdup(nam), ztrdup(module));
|
||||||
|
|
||||||
|
pm->flags |= PM_AUTOLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
42
Src/params.c
42
Src/params.c
|
@ -255,7 +255,11 @@ static Param argvparam;
|
||||||
/* hash table containing the parameters */
|
/* hash table containing the parameters */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
HashTable paramtab;
|
HashTable paramtab, realparamtab;
|
||||||
|
|
||||||
|
#ifndef DYNAMIC
|
||||||
|
#define getparamnode gethashnode2
|
||||||
|
#endif /* DYNAMIC */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
HashTable
|
HashTable
|
||||||
|
@ -267,8 +271,8 @@ newparamtable(int size, char const *name)
|
||||||
ht->emptytable = emptyhashtable;
|
ht->emptytable = emptyhashtable;
|
||||||
ht->filltable = NULL;
|
ht->filltable = NULL;
|
||||||
ht->addnode = addhashnode;
|
ht->addnode = addhashnode;
|
||||||
ht->getnode = gethashnode2;
|
ht->getnode = getparamnode;
|
||||||
ht->getnode2 = gethashnode2;
|
ht->getnode2 = getparamnode;
|
||||||
ht->removenode = removehashnode;
|
ht->removenode = removehashnode;
|
||||||
ht->disablenode = NULL;
|
ht->disablenode = NULL;
|
||||||
ht->enablenode = NULL;
|
ht->enablenode = NULL;
|
||||||
|
@ -278,6 +282,25 @@ newparamtable(int size, char const *name)
|
||||||
return ht;
|
return ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DYNAMIC
|
||||||
|
/**/
|
||||||
|
static HashNode
|
||||||
|
getparamnode(HashTable ht, char *nam)
|
||||||
|
{
|
||||||
|
HashNode hn = gethashnode2(ht, nam);
|
||||||
|
Param pm = (Param) hn;
|
||||||
|
|
||||||
|
if (pm && pm->u.str && (pm->flags & PM_AUTOLOAD)) {
|
||||||
|
char *mn = dupstring(pm->u.str);
|
||||||
|
|
||||||
|
if (!load_module(mn))
|
||||||
|
return NULL;
|
||||||
|
hn = gethashnode2(ht, nam);
|
||||||
|
}
|
||||||
|
return hn;
|
||||||
|
}
|
||||||
|
#endif /* DYNAMIC */
|
||||||
|
|
||||||
/* Copy a parameter hash table */
|
/* Copy a parameter hash table */
|
||||||
|
|
||||||
static HashTable outtable;
|
static HashTable outtable;
|
||||||
|
@ -402,7 +425,7 @@ createparamtable(void)
|
||||||
char buf[50], *str, *iname;
|
char buf[50], *str, *iname;
|
||||||
int num_env;
|
int num_env;
|
||||||
|
|
||||||
paramtab = newparamtable(151, "paramtab");
|
paramtab = realparamtab = newparamtable(151, "paramtab");
|
||||||
|
|
||||||
/* Add the special parameters to the hash table */
|
/* Add the special parameters to the hash table */
|
||||||
for (ip = special_params; ip->nam; ip++)
|
for (ip = special_params; ip->nam; ip++)
|
||||||
|
@ -542,7 +565,9 @@ createparam(char *name, int flags)
|
||||||
Param pm, oldpm;
|
Param pm, oldpm;
|
||||||
|
|
||||||
if (name != nulstring) {
|
if (name != nulstring) {
|
||||||
oldpm = (Param) paramtab->getnode(paramtab, name);
|
oldpm = (Param) (paramtab == realparamtab ?
|
||||||
|
gethashnode2(paramtab, name) :
|
||||||
|
paramtab->getnode(paramtab, name));
|
||||||
|
|
||||||
if (oldpm && oldpm->level == locallevel) {
|
if (oldpm && oldpm->level == locallevel) {
|
||||||
if (!(oldpm->flags & PM_UNSET) || (oldpm->flags & PM_SPECIAL)) {
|
if (!(oldpm->flags & PM_UNSET) || (oldpm->flags & PM_SPECIAL)) {
|
||||||
|
@ -2703,6 +2728,8 @@ printparamnode(HashNode hn, int printflags)
|
||||||
|
|
||||||
/* Print the attributes of the parameter */
|
/* Print the attributes of the parameter */
|
||||||
if (printflags & PRINT_TYPE) {
|
if (printflags & PRINT_TYPE) {
|
||||||
|
if (p->flags & PM_AUTOLOAD)
|
||||||
|
printf("undefined ");
|
||||||
if (p->flags & PM_INTEGER)
|
if (p->flags & PM_INTEGER)
|
||||||
printf("integer ");
|
printf("integer ");
|
||||||
else if (p->flags & PM_ARRAY)
|
else if (p->flags & PM_ARRAY)
|
||||||
|
@ -2736,6 +2763,11 @@ printparamnode(HashNode hn, int printflags)
|
||||||
}
|
}
|
||||||
|
|
||||||
quotedzputs(p->nam, stdout);
|
quotedzputs(p->nam, stdout);
|
||||||
|
|
||||||
|
if (p->flags & PM_AUTOLOAD) {
|
||||||
|
putchar('\n');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (printflags & PRINT_KV_PAIR)
|
if (printflags & PRINT_KV_PAIR)
|
||||||
putchar(' ');
|
putchar(' ');
|
||||||
else
|
else
|
||||||
|
|
19
Src/prompt.c
19
Src/prompt.c
|
@ -232,7 +232,7 @@ putpromptchar(int doprint, int endchar)
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
*bp = '\0';
|
*bp = '\0';
|
||||||
countprompt(bufline, &t0, 0);
|
countprompt(bufline, &t0, 0, 0);
|
||||||
if (t0 >= arg)
|
if (t0 >= arg)
|
||||||
test = 1;
|
test = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -678,11 +678,15 @@ putstr(int d)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
countprompt(char *str, int *wp, int *hp)
|
countprompt(char *str, int *wp, int *hp, int overf)
|
||||||
{
|
{
|
||||||
int w = 0, h = 1;
|
int w = 0, h = 1;
|
||||||
int s = 1;
|
int s = 1;
|
||||||
for(; *str; str++) {
|
for(; *str; str++) {
|
||||||
|
if(w >= columns) {
|
||||||
|
w = 0;
|
||||||
|
h++;
|
||||||
|
}
|
||||||
if(*str == Meta)
|
if(*str == Meta)
|
||||||
str++;
|
str++;
|
||||||
if(*str == Inpar)
|
if(*str == Inpar)
|
||||||
|
@ -694,12 +698,15 @@ countprompt(char *str, int *wp, int *hp)
|
||||||
else if(s) {
|
else if(s) {
|
||||||
if(*str == '\t')
|
if(*str == '\t')
|
||||||
w = (w | 7) + 1;
|
w = (w | 7) + 1;
|
||||||
else if(*str == '\n')
|
else if(*str == '\n') {
|
||||||
w = columns;
|
w = 0;
|
||||||
else
|
h++;
|
||||||
|
} else
|
||||||
w++;
|
w++;
|
||||||
}
|
}
|
||||||
if(w >= columns) {
|
}
|
||||||
|
if(w >= columns) {
|
||||||
|
if (!overf || w > columns) {
|
||||||
w = 0;
|
w = 0;
|
||||||
h++;
|
h++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ addbuiltins
|
||||||
addconddefs
|
addconddefs
|
||||||
addedx
|
addedx
|
||||||
addhashnode
|
addhashnode
|
||||||
|
addparamdefs
|
||||||
addwrapper
|
addwrapper
|
||||||
arrvargetfn
|
arrvargetfn
|
||||||
arrvarsetfn
|
arrvarsetfn
|
||||||
|
@ -40,6 +41,7 @@ current_limits
|
||||||
deletebuiltins
|
deletebuiltins
|
||||||
deleteconddefs
|
deleteconddefs
|
||||||
deletehashtable
|
deletehashtable
|
||||||
|
deleteparamdefs
|
||||||
deletewrapper
|
deletewrapper
|
||||||
domatch
|
domatch
|
||||||
doshfunc
|
doshfunc
|
||||||
|
|
24
Src/zsh.h
24
Src/zsh.h
|
@ -231,6 +231,7 @@ typedef struct hashtable *HashTable;
|
||||||
typedef struct reswd *Reswd;
|
typedef struct reswd *Reswd;
|
||||||
typedef struct alias *Alias;
|
typedef struct alias *Alias;
|
||||||
typedef struct param *Param;
|
typedef struct param *Param;
|
||||||
|
typedef struct paramdef *Paramdef;
|
||||||
typedef struct cmdnam *Cmdnam;
|
typedef struct cmdnam *Cmdnam;
|
||||||
typedef struct shfunc *Shfunc;
|
typedef struct shfunc *Shfunc;
|
||||||
typedef struct funcwrap *FuncWrap;
|
typedef struct funcwrap *FuncWrap;
|
||||||
|
@ -850,6 +851,7 @@ struct module {
|
||||||
|
|
||||||
#define MOD_BUSY (1<<0)
|
#define MOD_BUSY (1<<0)
|
||||||
#define MOD_UNLOAD (1<<1)
|
#define MOD_UNLOAD (1<<1)
|
||||||
|
#define MOD_SETUP (1<<2)
|
||||||
|
|
||||||
/* node used in parameter hash table (paramtab) */
|
/* node used in parameter hash table (paramtab) */
|
||||||
|
|
||||||
|
@ -923,6 +925,7 @@ struct param {
|
||||||
#define PM_RESTRICTED (1<<15) /* cannot be changed in restricted mode */
|
#define PM_RESTRICTED (1<<15) /* cannot be changed in restricted mode */
|
||||||
#define PM_UNSET (1<<16) /* has null value */
|
#define PM_UNSET (1<<16) /* has null value */
|
||||||
#define PM_REMOVABLE (1<<17) /* special can be removed from paramtab */
|
#define PM_REMOVABLE (1<<17) /* special can be removed from paramtab */
|
||||||
|
#define PM_AUTOLOAD (1<<18) /* autoloaded from module */
|
||||||
|
|
||||||
/* Flags for extracting elements of arrays and associative arrays */
|
/* Flags for extracting elements of arrays and associative arrays */
|
||||||
#define SCANPM_WANTVALS (1<<0)
|
#define SCANPM_WANTVALS (1<<0)
|
||||||
|
@ -955,6 +958,27 @@ struct param {
|
||||||
#define PF_ASSIGN 0x02 /* argument handled like the RHS of foo=bar */
|
#define PF_ASSIGN 0x02 /* argument handled like the RHS of foo=bar */
|
||||||
#define PF_SINGLE 0x04 /* single word substitution */
|
#define PF_SINGLE 0x04 /* single word substitution */
|
||||||
|
|
||||||
|
struct paramdef {
|
||||||
|
char *name;
|
||||||
|
int flags;
|
||||||
|
void *var;
|
||||||
|
void *set;
|
||||||
|
void *get;
|
||||||
|
void *unset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PARAMDEF(name, flags, var, set, get, unset) \
|
||||||
|
{ name, flags, (void *) var, (void *) set, (void *) get, (void *) unset }
|
||||||
|
#define INTPARAMDEF(name, var) \
|
||||||
|
{ name, PM_INTEGER, (void *) var, (void *) intvarsetfn, \
|
||||||
|
(void *) intvargetfn, (void *) stdunsetfn }
|
||||||
|
#define STRPARAMDEF(name, var) \
|
||||||
|
{ name, PM_SCALAR, (void *) var, (void *) strvarsetfn, \
|
||||||
|
(void *) strvargetfn, (void *) stdunsetfn }
|
||||||
|
#define ARRPARAMDEF(name, var) \
|
||||||
|
{ name, PM_ARRAY, (void *) var, (void *) arrvarsetfn, \
|
||||||
|
(void *) arrvargetfn, (void *) stdunsetfn }
|
||||||
|
|
||||||
/* node for named directory hash table (nameddirtab) */
|
/* node for named directory hash table (nameddirtab) */
|
||||||
|
|
||||||
struct nameddir {
|
struct nameddir {
|
||||||
|
|
|
@ -127,6 +127,7 @@ variables:
|
||||||
- autoinfixconds infix condition codes defined by the module, for
|
- autoinfixconds infix condition codes defined by the module, for
|
||||||
autoloading (without the leading `-')
|
autoloading (without the leading `-')
|
||||||
- autoprefixconds like autoinfixconds, but for prefix condition codes
|
- autoprefixconds like autoinfixconds, but for prefix condition codes
|
||||||
|
- autoparams parameters defined by the module, for autoloading
|
||||||
- objects .o files making up this module (*must* be defined)
|
- objects .o files making up this module (*must* be defined)
|
||||||
- proto .pro files for this module (default generated from $objects)
|
- proto .pro files for this module (default generated from $objects)
|
||||||
- headers extra headers for this module (default none)
|
- headers extra headers for this module (default none)
|
||||||
|
@ -137,7 +138,7 @@ Be sure to put the values in quotes. For further enlightenment have a
|
||||||
look at the `mkmakemod.sh' script in the Src directory of the
|
look at the `mkmakemod.sh' script in the Src directory of the
|
||||||
distribution.
|
distribution.
|
||||||
|
|
||||||
Modules have to define four functions which will automatically called
|
Modules have to define four functions which will be called automatically
|
||||||
by the zsh core. The first one, named `setup_foo' for a module named
|
by the zsh core. The first one, named `setup_foo' for a module named
|
||||||
`foo', should set up any data needed in the module, at least any data
|
`foo', should set up any data needed in the module, at least any data
|
||||||
other modules may be interested in. The second one, named `boot_foo',
|
other modules may be interested in. The second one, named `boot_foo',
|
||||||
|
@ -323,6 +324,78 @@ almost exactly the same as for builtins, using the functions
|
||||||
Arguments and return values are the same as for the functions for
|
Arguments and return values are the same as for the functions for
|
||||||
builtins.
|
builtins.
|
||||||
|
|
||||||
|
For defining parameters, a module can call `createparam()' directly or
|
||||||
|
use a table to describe them, e.g.:
|
||||||
|
|
||||||
|
static struct paramdef patab[] = {
|
||||||
|
PARAMDEF("foo", PM_INTEGER, NULL, get_foo, set_foo, unset_foo),
|
||||||
|
INTPARAMDEF("exint", &intparam),
|
||||||
|
STRPARAMDEF("exstr", &strparam),
|
||||||
|
ARRPARAMDEF("exarr", &arrparam),
|
||||||
|
};
|
||||||
|
|
||||||
|
There are four macros used:
|
||||||
|
|
||||||
|
- PARAMDEF() gets as arguments:
|
||||||
|
- the name of the parameter
|
||||||
|
- the parameter flags to set for it (from the PM_* flags defined
|
||||||
|
in zsh.h)
|
||||||
|
- optionally a pointer to a variable holding the value of the
|
||||||
|
parameter
|
||||||
|
- three functions that will be used to get the value of the
|
||||||
|
parameter, store a value in the parameter, and unset the
|
||||||
|
parameter
|
||||||
|
- the other macros provide simple ways to define the most common
|
||||||
|
types of parameters; they get the name of the parameter and a
|
||||||
|
pointer to a variable holding the value as arguments; they are
|
||||||
|
used to define integer-, scalar-, and array-parameters, so the
|
||||||
|
variables whose addresses are given should be of type `long',
|
||||||
|
`char *', and `char **', respectively
|
||||||
|
|
||||||
|
For a description of how to write functions for getting or setting the
|
||||||
|
value of parameters, or how to write a function to unset a parameter,
|
||||||
|
see the description of the following functions in the `params.c' file:
|
||||||
|
|
||||||
|
- `intvargetfn()' and `intvarsetfn()' for integer parameters
|
||||||
|
- `strvargetfn()' and `strvarsetfn()' for scalar parameters
|
||||||
|
- `arrvargetfn()' and `arrvarsetfn()' for array parameters
|
||||||
|
- `stdunsetfn()' for unsetting parameters
|
||||||
|
|
||||||
|
Note that if one defines parameters using the last two macros (for
|
||||||
|
scalars and arrays), the variable holding the value should be
|
||||||
|
initialized to either `NULL' or to a a piece of memory created with
|
||||||
|
`zalloc()'. But this memory should *not* be freed in the
|
||||||
|
finish-function of the module because that will be taken care of by
|
||||||
|
the `deleteparamdefs()' function described below.
|
||||||
|
|
||||||
|
To register the parameters in the zsh core, the function
|
||||||
|
`addparamdefs()' is called as in:
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
boot_example(Module m)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = addparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab))
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
The arguments and the return value are as for the functions used to
|
||||||
|
add builtins and condition codes and like these, it should be called
|
||||||
|
in the boot-function of the module. To remove the parameters defined,
|
||||||
|
the function `deleteparamdefs()' should be called, again with the same
|
||||||
|
arguments and the same return value as for the functions to remove
|
||||||
|
builtins and condition codes:
|
||||||
|
|
||||||
|
/**/
|
||||||
|
int
|
||||||
|
cleanup_example(Module m)
|
||||||
|
{
|
||||||
|
deleteparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab));
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
Finally, modules can define wrapper functions. These functions are
|
Finally, modules can define wrapper functions. These functions are
|
||||||
called whenever a shell function is to be executed.
|
called whenever a shell function is to be executed.
|
||||||
|
|
||||||
|
|
|
@ -940,7 +940,7 @@ pws: 6053: compwid.yo
|
||||||
|
|
||||||
Sven: 6056: compwid.yo
|
Sven: 6056: compwid.yo
|
||||||
|
|
||||||
Sven: 6058: small changes
|
Sven: 6058: small changes in _path_files, compinit and documentation
|
||||||
|
|
||||||
Sven: 6060: don't invalidatelist() in zle_main.c before calling completion
|
Sven: 6060: don't invalidatelist() in zle_main.c before calling completion
|
||||||
functions
|
functions
|
||||||
|
@ -967,3 +967,52 @@ Tanaka Akira: 6085: _make can hang when no [mM]akefile
|
||||||
Tanaka Akira: 6092: _find, bad glob pattern
|
Tanaka Akira: 6092: _find, bad glob pattern
|
||||||
|
|
||||||
pws: 6101: multi-line prompt ending in '\n' got another newline
|
pws: 6101: multi-line prompt ending in '\n' got another newline
|
||||||
|
|
||||||
|
pws-17
|
||||||
|
|
||||||
|
Geoff: 6104: multi-line prompt fix (6101 backed off)
|
||||||
|
|
||||||
|
Sven: 6105: _make patch whitespace
|
||||||
|
|
||||||
|
Bart: 6106: short documentation fixes in expn.yo, options.yo, redirect.yo
|
||||||
|
|
||||||
|
Sven: 6109: completion in parameter assignment should set context `value'
|
||||||
|
|
||||||
|
Sven: 6113: compadd -D, nuke element in an array for each failed match
|
||||||
|
|
||||||
|
Sven: 6117: position of ignored suffix in inserted match
|
||||||
|
|
||||||
|
pws: 6118: _closequote and _oldlist completers
|
||||||
|
|
||||||
|
Sven: 6119: don't insert word separator before ignored suffix
|
||||||
|
|
||||||
|
Sven: 6121: try harder with braces after a parameter expansion
|
||||||
|
|
||||||
|
Sven: 6124: menu completion wasn't consistent between tabs
|
||||||
|
|
||||||
|
Sven: 6128: completion after an expansion; list after a non-completion list
|
||||||
|
|
||||||
|
Sven: 6129: comments for struct cadata
|
||||||
|
|
||||||
|
Ville Herva: 6131, see 6126: reset tv.tv_sec before select for Linux
|
||||||
|
|
||||||
|
Sven: 6132: compctl.mdd
|
||||||
|
|
||||||
|
Sven: 6133: autoloaded parameters
|
||||||
|
|
||||||
|
Sven: 6150: alwayslastprompt sometimes failed in M-x
|
||||||
|
|
||||||
|
Sven: 6152: compstate[vared]
|
||||||
|
|
||||||
|
Sven: 6153: realparamtab to smooth access to autoloaded parameters
|
||||||
|
|
||||||
|
Bart: 6162: autoloadable parameter code links without dynamic loading
|
||||||
|
|
||||||
|
pws: 6165: globsubst'd foo='~/bin' depended on extendedglob being set
|
||||||
|
|
||||||
|
Sven: 6167: show unloaded parameters as undefined
|
||||||
|
|
||||||
|
Bart: 6171 as rewritten in 6174: old RedHat Linux doesn't have normall
|
||||||
|
definitions for poll.
|
||||||
|
|
||||||
|
pws: 6180: Completion/Core/compinstall
|
||||||
|
|
Loading…
Reference in a new issue