1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-06-17 21:18:06 +02:00

zsh-3.1.5-pws-9

This commit is contained in:
Tanaka Akira 1999-04-15 18:16:27 +00:00
parent ba4f5e80ec
commit b4a5b9db8b
99 changed files with 3672 additions and 478 deletions

View file

@ -27,5 +27,5 @@
# This must also serve as a shell script, so do not add spaces around the
# `=' signs.
VERSION=3.1.5-pws-8
VERSION_DATE='February 13, 1999'
VERSION=3.1.5-pws-9
VERSION_DATE='February 18, 1999'

View file

@ -38,7 +38,7 @@ TEXI2HTML = texi2html -expandinfo -split_chapter
.SUFFIXES: .yo .1
# man pages to install
MAN = zsh.1 zshbuiltins.1 zshcompctl.1 \
MAN = zsh.1 zshbuiltins.1 zshcompctl.1 zshcompwid.1 \
zshexpn.1 zshmisc.1 zshmodules.1 \
zshoptions.1 zshparam.1 zshzle.1 zshall.1
@ -48,7 +48,7 @@ YODLSRC = zmacros.yo zman.yo ztexi.yo Zsh/arith.yo Zsh/builtins.yo \
Zsh/compat.yo Zsh/compctl.yo Zsh/cond.yo Zsh/exec.yo Zsh/expn.yo \
Zsh/filelist.yo Zsh/files.yo Zsh/func.yo Zsh/grammar.yo Zsh/guide.yo \
Zsh/index.yo Zsh/intro.yo Zsh/invoke.yo Zsh/jobs.yo Zsh/metafaq.yo \
Zsh/modules.yo Zsh/mod_cap.yo \
Zsh/modules.yo Zsh/mod_cap.yo Zsh/compwid.yo \
Zsh/mod_clone.yo Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_deltochar.yo \
Zsh/mod_example.yo Zsh/mod_files.yo Zsh/mod_stat.yo \
Zsh/mod_zle.yo Zsh/options.yo \

View file

@ -1,9 +1,9 @@
DISTFILES_SRC='
.distfiles
arith.yo builtins.yo compat.yo compctl.yo cond.yo exec.yo expn.yo
filelist.yo files.yo func.yo grammar.yo guide.yo index.yo intro.yo
arith.yo builtins.yo compat.yo compctl.yo compwid.yo cond.yo exec.yo
expn.yo filelist.yo files.yo func.yo grammar.yo guide.yo index.yo intro.yo
invoke.yo jobs.yo metafaq.yo mod_cap.yo mod_clone.yo mod_comp1.yo
mod_compctl.yo mod_deltochar.yo mod_example.yo mod_files.yo mod_sched.yo
mod_stat.yo mod_zle.yo modules.yo options.yo params.yo prompt.yo
redirect.yo restricted.yo seealso.yo zle.yo
mod_stat.yo mod_zftp.yo mod_zle.yo modules.yo options.yo params.yo
prompt.yo redirect.yo restricted.yo seealso.yo zle.yo
'

View file

@ -1,4 +1,4 @@
texinode(Programmable Completion)(Zsh Modules)(Zsh Line Editor)(Top)
texinode(Programmable Completion)(Completion Widgets)(Zsh Line Editor)(Top)
chapter(Programmable Completion)
cindex(completion, programmable)
cindex(completion, controlling)
@ -89,7 +89,7 @@ to the user database is too slow and/or it contains too many users (so
that completion after `tt(~)' is too slow to be usable), you can use
indent(
tt(compctl -T -x 'C[0,*/*]' -f - 's[~]' -k friends -S/ -tn)
tt(compctl -T -x 's[~] C[0,[^/]#]' -k friends -S/ -tn)
)
to complete the strings in the array tt(friends) after a `tt(~)'.

428
Doc/Zsh/compwid.yo Normal file
View file

@ -0,0 +1,428 @@
texinode(Completion Widgets)(Zsh Modules)(Programmable Completion)(Top)
chapter(Completion Widgets)
cindex(completion, widgets)
cindex(completion, programmable)
cindex(completion, controlling)
sect(Description)
Completion widgets are defined using the tt(-C) option to the tt(zle)
builtin command provided by the tt(zle) module (see
ifzman(zmanref(zshzle))\
ifnzman(noderef(The zle Module))\
). For example, the invocation:
indent(nofill(
tt(zle -C complete expand-or-complete completer)))
defines a widget named tt(complete). If this widget is bound to a key
using the tt(bindkey) builtin command defined in the tt(zle) module
(see
ifzman(zmanref(zshzle))\
ifnzman(noderef(Zsh Line Editor))\
) typing that key will make the completion code call the shell
function tt(completer). This function is responsible for generating
the possible matches using the builtins described below. Once the
function returns, the completion code takes over control again and
treats the matches the way the builtin widget tt(expand-or-complete)
would do it. For this second argument, the name of any of the builtin
widgets that handle completions can be given, i.e. it may be any of
tt(complete-word), tt(expand-or-complete),
tt(expand-or-complete-prefix), tt(menu-complete),
tt(menu-expand-or-complete), tt(reverse-menu-complete),
tt(list-choices), or tt(delete-char-or-list).
startmenu()
menu(Special Parameters)
menu(Builtin Commands)
menu(Condition Codes)
menu(Examples)
endmenu()
texinode(Special Parameters)(Builtin Commands)()(Completion Widgets)
sect(Special Parameters)
Inside completion widgets some parameters have special meaning. They
will be used inside the widget function and other shell functions
called from it. Outside of these function they are not special to the
shell in any way.
The parameters are used to give information about the internal state
from the completion code to the completion widget and can be set to
give information to the completion code from the completion
widget. Some of the builtin commands and the condition codes use or
change the current values of these parameters. While the completion
widget is active, these parameters are reseton each function exit to
the values they had when the function was entered.
startitem()
item(tt(argv))(
The positional parameters are set to the arguments on the command line
when the widget function is invoked from the completion code.
)
item(tt(CURRENT))(
This is the number of the current word, i.e. the word the cursor is
currently on in the tt(argv) array.
)
item(tt(CONTEXT))(
This will be set by the completion code to the overall context
completion is attempted in. Possible values are:
startitem()
item(tt(command))(
when completing in a command position, e.g. in the first word on the
command line
)
item(tt(argument))(
when completing an argument for a command
)
item(tt(redirect))(
when completing after a redirection operator; in this case the
positional parameters contain not only the arguments but also the
command name itself as the first element
)
item(tt(condition))(
when completing inside a `tt([[)...tt(]])' conditional expressing; in
this case the positional parameters are set to the words inside the
conditional expressions
)
item(tt(math))(
when completing in a mathematical environment such as a
`tt(LPAR()LPAR())...tt(RPAR()RPAR())' construct
)
item(tt(value))(
when completing the value of a parameter assignment; in case of an
array value the positional parameters are set to the words in
parentheses
)
item(tt(subscript))(
when completing inside a parameter expansion subscript
)
enditem()
)
item(tt(COMMAND))(
In most cases this is set to name of the command for which completion
is tried. When completing after a redirection operator it contains the
string forming that operator. Also, when completing in the value of a
parameter assignment or in a parameter subscript it is set to the name
of the parameter.
)
item(tt(PREFIX))(
This should be set to that part of the current word that should be
taken as the string every possible match has to begin with. Initially
this will be set to the part of the current word from the beginning of
the word up to the position of the cursor. When
)
item(tt(IPREFIX))(
When a part of the current word should not be considered part of the
matches, this part should be taken from the tt(PREFIX) parameter and
appended to this parameter. This will initially be set to the empty
string when called from the completion code.
)
item(tt(SUFFIX))(
This should be set to that part of the current word that should be
taken as the string every possible match has to end with. The
completion code sets this to the part of the current word from the
cursor position to the end.
)
item(tt(NMATCHES))(
This is always set to the number of matches generated and accepted by
the completion code so far.
)
item(tt(MATCHER))(
When completion is used with a global match specification (i.e. a
tt(compctl) with only a tt(-M) option), this parameter is set to the
number of the specification string which is currently used.
)
enditem()
texinode(Builtin Commands)(Condition Codes)(Special Parameters)(Completion Widgets)
sect(Builtin Commands)
startitem()
findex(complist)
item(tt(complist) var(flags ...))(
Generate matches according to the given var(flags) which can be any of
the option flags supported by the tt(compctl) builtin command (see
ifzman(zmanref(zshcompctl))\
ifnzman(noderef(Programmable Completion))\
) except for the tt(-t) and tt(-l) flags. Also, when using the tt(-K)
flag, the function given as argument to it can not access the command
line with the tt(read) builtin command.
The matches will be generated in the same way as if the completion code
generated them directly from a tt(compctl)-definition with the same
flags. The completion code will consider only those matches as
possible completions that match the prefix and suffix from the special
parameters desribed above. These strings will be compared with the
generated matches using the normal matching rules and any matching
specifications given with the tt(-M) flag to tt(complist) and the
global matching specifications given to the tt(compctl) builtin
command.
)
xitem(tt(compadd) [ tt(-qQfnUam) ] [ tt(-F) var(array) ])
xitem([ tt(-P) var(prefix) ] [ tt(-S) var(suffix) ])
xitem([ tt(-p) var(hidden-prefix) ] [ tt(-s) var(hidden-suffix) ])
xitem([ tt(-i) var(ignored-prefix) ] [ tt(-W) var(file-prefix) ])
xitem([ tt(-J) var(name) ] [ tt(-V) var(name) ])
xitem([ tt(-r) var(remove-chars) ] [ tt(-R) var(remove-func) ])
item([ tt(-M) var(match-spec) ] [ tt(--) ] [ var(words) ... ])(
This builtin command can be used to add matches and directly control
all the information the completion code stores with each possible
match.
The supported flags are:
startitem()
item(tt(-P) var(prefix))(
The same as for tt(compctl) and tt(complist), it gives a string that
should be inserted before the given words when they are completed. The
string given is not considered to be part of the match.
)
item(tt(-S) var(suffix))(
Like tt(-P) but gives a string that has to be inserted after the match.
)
item(tt(-p) var(hidden-prefix))(
This gives a string that should be
...
)
item(tt(-s) var(hidden-suffix))(
...
)
item(tt(-i) var(ignored-prefix))(
...
)
item(tt(-J) var(name))(
As for tt(compctl) and tt(complist) this gives the name of the group
of matches the words should be stored in.
)
item(tt(-V) var(name))(
Like tt(-J) but naming a unsorted group.
)
item(tt(-q))(
This flag has the same meaning as for tt(compctl) and tt(complist),
too. It makes the suffix given with tt(-S) be automatically removed if
the next character typed is a blank or does not insert anything or if
the suffix consists of only one character and the next character typed
is the same character.
)
item(tt(-r) var(remove-chars))(
This makes the suffix given with tt(-S) be automatically removed if
the next character typed inserts one of the characters given in the
var(remove-chars). This string is parsed as a characters class with
the usual backslash-sequences understood, e.g. using `tt(-r "a-z\t")'
removes the suffix if the next character typed inserts one of the
lower case letters or a TAB, and `tt(-r "^0-9")' removes the suffix if
the next character typed inserts anything but a digit. One extra
backslash sequence is understood in this string: `tt(\-)' stands for
all characters that insert nothing. Thus `tt(-S "=" -q)' is the same
as `tt(-S "=" -r "= \t\n\-")'.
)
item(tt(-R) var(remove-func))(
For the cases where one wants to remove suffix and the tt(-r) option
does not give enough control, this option can be used. It stores the
name of the shell function var(remove-func) in the matches. If one of
the matches is finally accepted and the tt(-S)-suffix inserted, this
function will be called after the next character typed. It gets the
length of the suffix as its argument and can use the special
parameters available in zle widgets (see
ifzman(zmanref(zshzle))\
ifnzman(noderef(Zsh Line Editor))\
) to analyse and modify the command line.
)
item(tt(-f))(
If this flag is given, the matches build are marked as being the names
of files. They need not be actual filenames, though. But if they are
and the option tt(LIST_TYPES) is set, the characters describing the
types of the files in the completion lists will be shown. This also
makes a slash automatically be added when the name of a directory is
completed.
)
item(tt(-W) var(file-prefix))(
This option has the same meaning as for the tt(compctl) and
tt(complist) builtin commands. Here, however, only one string may be
given, not an array. This string is used as a pathname that will be
prepended to the given words and the prefix given with the tt(-p)
option to perform the file-tests when showing completion
listings. Hence it is only useful if combined with the tt(-f) flag,
since the tests will only be performed if that flag is given.
)
item(tt(-a))(
When used by tt(compctl) or tt(complist) the completion code normally
builds two sets of matches: the normal one where words with one of the
suffixes in the array parameter tt(fignore) are not considered
possible matches, and the alternate set where the words excluded
from the first set are stored. Normally only the matches in the first
set are used. But if this set is empty, the words from the alternate
set are used.
The tt(compadd) builtin does not use tt(fignore) parameter and
normally stores all words in the first set. With the tt(-a)-flag
given, however, they are all stored in the alternate set unless this
flag is overridden by the tt(-F) option.
)
item(tt(-F) var(array))(
This can be used to give an array containing suffixes like the
tt(fignore) parameter. Words with one of these suffixes are stored in
the alternate set of matches and words without one of these suffixes
are stored in the normal set.
The var(array) may be the name of an array parameter or a list of
literal suffixes enclosed in parentheses as in `tt(-F "(.o .h)")'. If
the name of an array is given, the elements of the array are taken as
the suffixes.
)
item(tt(-Q))(
As for tt(compctl) and tt(complist) this flag instructs the completion
code not to quote any metacharacters in the words when inserting them
in the command line.
)
item(tt(-m))(
Normally the matches added by tt(compadd) will not be compared with
what is already on the line. If this flag is given, this comparison is
performed as usual and the match specifications given with the tt(-M)
option to tt(compadd) and the global match specifications defined with
tt(compctl) will be used. This means that probably not all the word
given will be stored as matches since some of them may not match the
string on the line.
)
item(tt(-M) var(match-spec))(
This option allows one to give local match specifications with the
same meaning and format as for the tt(compctl) and tt(complist)
builtin commands. Note that they will only be used if the tt(-m) is
given, too.
)
item(tt(-n))(
Words added with tt(compadd) with this flag will be used as possible
matches as usual but they not appear in the completion listing.
)
item(tt(-U))(
If this flag is given to one of the calls to tt(compadd) and the
option tt(AUTO_MENU) is set, the completion code will immediatly
switch to menucompletion.
)
item(tt(-), tt(--))(
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
hyphens.
)
enditem()
)
item(tt(compcall) [ tt(-TD) ])(
This allows one to use completion definitions given with the
tt(compctl) builtin from within completion widgets. It makes
completion code complete the current word according to the
tt(compctl)s defined. Normally only tt(compctl)s given for specific
commands are used. To make the code use the completion flags given to
the tt(-T) option of tt(compctl), one can give the tt(-T) flag to
tt(compctl). Likewise, the tt(-D) flag to tt(compcall) makes the
default completion flags given to tt(compctl) with the tt(-D) option
be used.
)
enditem()
texinode(Condition Codes)(Examples)(Builtin Commands)(Completion Widgets)
sect(Condition Codes)
Inside completion widgets not only the builtin commands described
above can be used, but also some additional condition codes. These
work on the special parameters and can be used to easily build
completion functions that generate different matches depending on the
strings on the line.
The following condition codes are made available inside completion
widgets:
startitem()
item(tt(-prefix) var(string))(
true if the content of tt(PREFIX) starts with var(string)
)
item(tt(-iprefix) var(string))(
like tt(-prefix), but the var(string) is removed from tt(PREFIX) and
added to tt(IPREFIX)
)
item(tt(-position) var(beg) [ var(end) ])(
true if tt(CURRENT) is equal to var(beg) or, if var(end) is given,
equal to or greater than var(beg) and equal to or less than var(end);
both of var(beg) and var(end) may be arithmetic expressions, if they
are less than zero the number of words in tt(argv) are added to them
before comparing them to tt(CURRENT); thus, tt(-1) is the last word,
tt(-2) is the word before that and so on
)
item(tt(-word) var(index) var(string))(
true if the word number var(index) in tt(argv) is equal to
var(string); again, var(index) may be negative, counting backwards
)
item(tt(-mword) var(index) var(pattern))(
like tt(-word) but using pattern matching
)
item(tt(-current) var(offset) var(string))(
like tt(-word) but var(offset) is relative to the value of
tt(CURRENT)
)
item(tt(-mcurrent) var(offset) var(pattern))(
like tt(-current) but using pattern matching
)
item(tt(-string) [ var(number) ] var(string))(
true if the current word contains var(string); anything up to the last
occurrence of this string will be ingnored by removing it from
tt(PREFIX) and adding it to tt(IPREFIX); if var(number) is given,
anything up to the var(number)'th occurrence of the var(string) will
be ignored; again, var(nmuber) may be any arithmetic expression and
negative values count backward
)
item(tt(-class) [ var(number) ] var(class))(
like tt(-string) but the var(class) is used as a character class so
that anything up to and including the last or the var(number)'th
occurrence of any character from the string var(class) is ignored
)
item(tt(-words) var(min) [ var(max) ])(
true if the number of words is equal to var(min); if var(max) is
given, it is true if the number of words is equal to or greater than
var(min) and equal to or less than var(max)
)
item(tt(-after) var(string))(
true if the cursor is after a word that is equal to var(string)
)
item(tt(-mafter) var(pattern))(
like tt(-after) but using pattern matching
)
item(tt(-between) var(string1) var(string2))(
true if the cursor is after a word that is equal to var(string1), if
there is also a word that is equal to va(string2), this is true only
if the cursor is before it
)
item(tt(-mbetween) var(pattern1) var(pattern2))(
like tt(-between) but using pattern matching
)
item(tt(-nmatches) var(number))(
true if the the value of tt(NMATCHES) is equal to var(number)
)
item(tt(-matcher) var(number))(
true if the value of tt(MATCHER) is equal to var(number)
)
enditem()
texinode(Examples)()(Condition Codes)(Completion Widgets)
sect(Examples)
The first step is to define the widget:
indent(nofill(
tt(zle -C complete complete-word complete-history)))
Then the widget can be bound to a key using the tt(bindkey) builtin
command:
indent(nofill(
tt(bindkey '^X\t' complete)))
After that the shell function tt(complete-history) will be invoked
after typing control-X and TAB. The function should then generte the
matches, e.g.:
indent(nofill(
tt(complete-history LPAR()RPAR() { complist -H 0 '' })))
In this the function will complete words from the history matching the
current word.

View file

@ -29,6 +29,7 @@ menu(Options)
menu(Shell Builtin Commands)
menu(Zsh Line Editor)
menu(Programmable Completion)
menu(Completion Widgets)
menu(Zsh Modules)
--- Indices ---
@ -103,6 +104,13 @@ menu(Alternative Completion)
menu(Extended Completion)
menu(Example)
Completion Widgets
menu(Special Parameters)
menu(Builtin Commands)
menu(Condition Codes)
menu(Examples)
Zsh Modules
menu(The cap Module)

View file

@ -21,6 +21,7 @@ list(em(zshoptions) Zsh options)
list(em(zshbuiltins) Zsh built-in functions)
list(em(zshzle) Zsh command line editing)
list(em(zshcompctl) Zsh completion control)
list(em(zshcompwid) Zsh completion widgets)
list(em(zshmodules) Zsh loadable modules)
ifzshone(\
list(em(zshall) Meta-man page containing all of the above)

View file

@ -11,7 +11,7 @@ sect(Author)
cindex(author)
Zsh was originally written by Paul Falstad tt(<pf@zsh.org>).
Zsh is now maintained by the members of the zsh-workers mailing
list tt(<zsh-workers@math.gatech.edu>). The development is currently
list tt(<zsh-workers@sunsite.auc.dk>). The development is currently
coordinated by Andrew Main (Zefram) tt(<zefram@zsh.org>). The coordinator
can be contacted at tt(<coordinator@zsh.org>), but matters relating to
the code should generally go to the mailing list.

View file

@ -1,7 +1,12 @@
texinode(The compctl Module)(The deltochar Module)(The comp1 Module)(Zsh Modules)
sect(The compctl Module)
The tt(compctl) module makes available one builtin command, tt(compctl),
which is the standard way to control completions for ZLE. See
The tt(compctl) module makes available several builtin commands. tt(compctl),
is the standard way to control completions for ZLE. See
ifzman(zmanref(zshcompctl))\
ifnzman(noderef(Programmable Completion))\
.
The other builtin commands can be used in user-defined completion widgets,
see
ifzman(zmanref(zshcompwid))\
ifnzman(noderef(Completion Widgets))\
.

View file

@ -439,4 +439,8 @@ until the next call to tt(zftp). Other status changes in subshells
will not be reflected by changes to the variables (but should
be otherwise harmless).
On some operatings systems, the control connection is not valid after a
fork(), so that operations in subshells or on the left hand side of a
pipeline are not possible.
enditem()

View file

@ -165,7 +165,7 @@ xitem(tt(zle) tt(-l) [ tt(-L) ])
xitem(tt(zle) tt(-D) var(widget) ...)
xitem(tt(zle) tt(-A) var(old-widget) var(new-widget))
xitem(tt(zle) tt(-N) var(widget) [ var(function) ])
xitem(tt(zle) tt(-C) [ tt(-mMgG) ] var(widget) [ var(compctl-options) ])
xitem(tt(zle) tt(-C) var(widget) var(completion-widget) var(function))
item(tt(zle) var(widget))(
The tt(zle) builtin performs a number of different actions concerning
ZLE. Which operation it performs depends on its options:
@ -193,22 +193,15 @@ widget is invoked from within the editor, the specified shell var(function)
is called. If no function name is specified, it defaults to
the same name as the widget.
)
item(tt(-C) [ tt(-mMgG) ] var(widget) [ var(compctl-options) ])(
Create a user-defined widget which will perform completion according
to var(compctl-options). These are passed directly to the
tt(compctl) command, see
ifzman(zmanref(zshcompctl))\
ifnzman(noderef(Programmable Completion))\
; no command names or special options (tt(-LDCT)) may be used. If the
var(compctl-options) are missing the widget will have normal
completion behaviour as modified by the tt(zle) options.
There are four additional tt(zle) options, which must precede the
widget name: tt(-m) and tt(-M) force the widget to use or not to use
menu completion, respectively, while tt(-g) and tt(-G) likewise force
the widget to use or not to use glob completion. The defaults are to
use the current settings of tt(MENU_COMPLETE) and tt(GLOB_COMPLETE)
as with normal completion.
item(tt(-C) var(widget) var(completion-widget) var(function))(
Create a user-defined completion widget names var(widget). The
completion widget will behave like the built-in completion-widget
whose name is given as var(completion-widget). To generate the
completions, the shell function var(function) will be called.
For further information, see
ifzman(zmanref(zshcompwid))\
ifnzman(noderef(Completion Widgets))\
.
)
item(var(widget))(
Invoke the specified widget. This can only be done when ZLE is

View file

@ -1,4 +1,4 @@
texinode(Zsh Modules)()(Programmable Completion)(Top)
texinode(Zsh Modules)()(Completion Widgets)(Top)
chapter(Zsh Modules)
cindex(modules)
sect(Description)
@ -19,7 +19,8 @@ item(tt(comp1))(
Base of the completion system. Used by the tt(compctl) and tt(zle) modules.
)
item(tt(compctl))(
The tt(compctl) builtin for controlling completion.
The tt(compctl) builtin for controlling completion and the builtins for
completion widgets.
)
item(tt(deltochar))(
A ZLE function duplicating EMACS' tt(zap-to-char).

View file

@ -544,12 +544,14 @@ List jobs in the long format by default.
)
pindex(MAGIC_EQUAL_SUBST)
item(tt(MAGIC_EQUAL_SUBST))(
All unquoted arguments of the form `var(identifier)tt(=)var(expression)'
All unquoted arguments of the form `var(anything)tt(=)var(expression)'
appearing after the command name have filename expansion (that is,
where var(expression) has a leading `tt(~)' or `tt(=)') performed on
var(expression) as if it were a parameter assignment. The argument is
not otherwise treated specially; it is passed to the command as a single
argument, and not used as an actual parameter assignment.
argument, and not used as an actual parameter assignment. For example, in
tt(echo foo=~/bar:~/rod), both occurrences of tt(~) would be replaced.
Note that this happens anyway with tt(typeset) and similar statements.
)
pindex(MAIL_WARNING)
cindex(mail, warning of reading)

View file

@ -10,6 +10,7 @@ ifzshone(\
,
zmanref(zshbuiltins),
zmanref(zshcompctl),
zmanref(zshcompwid),
zmanref(zshexpn),
zmanref(zshmisc),
zmanref(zshmodules),

View file

@ -64,6 +64,7 @@ ifnzman(includefile(Zsh/options.yo))
ifnzman(includefile(Zsh/builtins.yo))
ifnzman(includefile(Zsh/zle.yo))
ifnzman(includefile(Zsh/compctl.yo))
ifnzman(includefile(Zsh/compwid.yo))
ifnzman(includefile(Zsh/modules.yo))
ifzshall(\
def(source)(1)(NOTRANS(.so )man1/ARG1NOTRANS(.)1)\
@ -75,6 +76,7 @@ source(zshoptions)
source(zshbuiltins)
source(zshzle)
source(zshcompctl)
source(zshcompwid)
source(zshmodules)
manpage(ZSHALL)(1)(date())(zsh version())
)\

3
Doc/zshcompwid.yo Normal file
View file

@ -0,0 +1,3 @@
manpage(ZSHCOMPWID)(1)(date())(zsh version())
manpagename(zshcompwid)(zsh completion widgets)
includefile(Zsh/compwid.yo)

View file

@ -76,9 +76,12 @@ Reliant: SINIX
linking; configure now detects this and will disable dynamic
linking even if you requested it.
SGI: IRIX 5.1.1.1, 5.2, 5.3, 6.2, 6.3
SGI: IRIX 5.1.1.1, 5.2, 5.3, 6.2, 6.3, 6.5
Should build `out-of-the-box'.
On 6.5.2, zsh malloc routines are reported not to work; also
full optimization (cc -O3 -OPT:Olimit=0) causes problems.
Sun: SunOS 4.1.*
Under 4.1.3 if yellow pages is used, username completion may cause
segmentation violation. This is a bug in the shared library not

View file

@ -0,0 +1,3 @@
#defcomp unalias
complist -a

View file

@ -0,0 +1,3 @@
#defcomp shift
complist -A

View file

@ -0,0 +1,3 @@
#defcomp autoload
complist -s '${^fpath}/*(N:t)'

View file

@ -0,0 +1,3 @@
#defcomp bg
complist -z -P '%'

View file

@ -0,0 +1,7 @@
#defcomp bindkey
if [[ -mword 1 -*[DAN]* || -mcurrent -1 -*M ]]; then
complist -s '$(bindkey -l)'
else
complist -b
fi

View file

@ -0,0 +1,7 @@
#defcomp builtin
if [[ -position 2 -1 ]]; then
compsub
else
complist -eB
fi

3
Functions/Completion/_cd Normal file
View file

@ -0,0 +1,3 @@
#defcomp cd
_files -W cdpath -g '*(-/)'

View file

@ -0,0 +1,7 @@
#defcomp command
if [[ -position 2 -1 ]]; then
_normal "$@"
else
complist -em
fi

View file

@ -0,0 +1,3 @@
#defcomp -command-
complist -c

View file

@ -0,0 +1,3 @@
#defcomp compress
_files -g '*~*.Z'

View file

@ -0,0 +1,10 @@
#defcomp -condition-
if [[ -current -1 -o ]]; then
complist -o -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}'
elif [[ -current -1 -nt || -current -1 -ot || -current -1 -ef ]]; then
_files
else
_files
complist -v
fi

View file

@ -0,0 +1,12 @@
#defcomp configure
if [[ $PREFIX = *=* ]]; then
# Complete filenames after e.g. --prefix=
IPREFIX=${PREFIX%%=*}=
PREFIX=${PREFIX#*=}
complist -f
else
# Generate a list of options from configure --help
complist -s '$($COMMAND --help |
sed -n -e '\''s/^ *\(--[-a-z0-9]*\)[ =,].*$/\1/p'\'')'
fi

13
Functions/Completion/_dd Normal file
View file

@ -0,0 +1,13 @@
#defcomp dd
if [[ -iprefix conv= ]]; then
# If there's a comma present, ignore up to the last one. The
# test alone will have that effect.
[[ -string , ]]
complist -S, -q \
-k '(ascii ebcdic ibm block unblock lcase ucase swab noerror sync)'
elif [[ -iprefix 'if=' || -iprefix 'of=' ]]; then
_files
else
complist -S '=' -k '(if of ibs obs bs cbs skip files seek count conv)'
fi

View file

@ -0,0 +1,13 @@
#defcomp -default-
# We first try the `compctl's. This is without first (-T) and default (-D)
# completion. If you want them add `-T' and/or `-D' to this command.
# If there is a `compctl' for the command we are working on, we return
# immediatly. If you want to use new style completion anyway, remove the
# `|| return'. Also, you may want to use new style completion if the
# `compctl' didn't produce any matches. In that case remove the `|| return'
# and at the line `[[ -nmatches 0 ]] || return' after `compcall'.
compcall || return
_files

View file

@ -0,0 +1,3 @@
#defcomp rmdir df du dircmp
_files -/ '*(-/)'

View file

@ -0,0 +1,6 @@
#defcomp disable
[[ -mcurrent -1 -*a* ]] && complist -ea
[[ -mcurrent -1 -*f* ]] && complist -eF
[[ -mcurrent -1 -*r* ]] && complist -ew
[[ ! -mcurrent -1 -* ]] && complist -eB

View file

@ -0,0 +1,3 @@
#defcomp xdvi dvips dvibook dviconcat dvicopy dvidvi dviselect dvitodvi dvitype
_files -g '*.(dvi|DVI)'

View file

@ -0,0 +1,3 @@
#defcomp echotc
complist -k '(al dc dl do le up al bl cd ce cl cr dc dl do ho is le ma nd nl se so up)'

View file

@ -0,0 +1,6 @@
#defcomp enable
[[ -mcurrent -1 -*a* ]] && complist -da
[[ -mcurrent -1 -*f* ]] && complist -dF
[[ -mcurrent -1 -*r* ]] && complist -dw
[[ ! -mcurrent -1 -* ]] && complist -dB

7
Functions/Completion/_fc Normal file
View file

@ -0,0 +1,7 @@
#defcomp fc
if [[ -mcurrent -1 -*e ]]; then
complist -c
elif [[ -mcurrent -1 -[ARWI]## ]]; then
_files
fi

View file

@ -0,0 +1,10 @@
#autoload
# Utility function for completing files of a given type or any file.
# In many cases you will want to call this one instead of _path_files().
local nm=$NMATCHES
_path_files "$@"
[[ $# -ne 0 && -nmatches nm ]] && _path_files

View file

@ -0,0 +1,21 @@
#defcomp find
if [[ -mbetween -(ok|exec) \\\; ]]; then
_normal "$@"
elif [[ -iprefix - ]]; then
complist -s 'daystart {max,min,}depth follow noleaf version xdev \
{a,c,}newer {a,c,m}{min,time} empty false {fs,x,}type gid inum links \
{i,}{l,}name {no,}{user,group} path perm regex size true uid used \
exec {f,}print{f,0,} ok prune ls'
elif [[ -position 1 ]]; then
complist -g '. ..'
_files -g '(-/)'
elif [[ -mcurrent -1 -((a|c|)newer|fprint(|0|f)) ]]; then
_files
elif [[ -current -1 -fstype ]]; then
complist -k '(ufs 4.2 4.3 nfs tmp mfs S51K S52K)'
elif [[ -current -1 -group ]]; then
complist -k groups
elif [[ -current -1 -user ]]; then
complist -u
fi

View file

@ -0,0 +1,3 @@
#defcomp unfunction
complist -F

View file

@ -0,0 +1,3 @@
#defcomp gunzip zcat
_files -g '*.[gG][z]'

View file

@ -0,0 +1,3 @@
#defcomp gzip
_files -g '*~*.[gG][zZ]'

View file

@ -0,0 +1,13 @@
#defcomp hash
if [[ -mword 1 -*d* ]]; then
if [[ -string 1 '=' ]]; then
_path_files -g '*(-/)'
else
complist -n -q -S '='
fi
elif [[ -string 1 '=' ]]; then
_files -g '*(*)' '*(-/)'
else
complist -m -q -S '='
fi

View file

@ -0,0 +1,3 @@
#defcomp ftp ncftp ping rwho rup xping traceroute nslookup
complist -k hosts

View file

@ -0,0 +1,3 @@
#defcomp fg jobs
complist -j -P '%'

View file

@ -0,0 +1,8 @@
#defcomp kill
if [[ -iprefix '-' ]]; then
complist -k "($signals[1,-3])"
else
complist -P '%' -j
complist -y _kill_helper -s '`ps 2>/dev/null | tail +2 | cut -c1-5`'
fi

View file

@ -0,0 +1,3 @@
#autoload
reply=( "$(ps 2>/dev/null)" )

View file

@ -0,0 +1,3 @@
#defcomp limit unlimit
complist -k "(${(j: :)${(f)$(limit)}%% *})"

View file

@ -0,0 +1,48 @@
#autoload
# The main loop of the completion code. This is what is called when
# completion is attempted from the command line.
# The completion code gives us the special variables and the arguments
# from the command line are given as positional parameters.
local comp name
setopt localoptions nullglob rcexpandparam globdots
unsetopt markdirs globsubst shwordsplit nounset
# An entry for `-first-' is the replacement for `compctl -T'
# Completion functions may set `COMPSKIP' to any value to make the
# main loops stop calling other completion functions.
comp="$comps[-first-]"
if [[ ! -z "$comp" ]]; then
"$comp" "$@"
if (( $+COMPSKIP )); then
unset COMPSKIP
return
fi
fi
# For arguments we use the `_normal function.
if [[ $CONTEXT == argument || $CONTEXT == command ]]; then
_normal "$@"
else
# Let's see if we have a special completion definition for the other
# possible contexts.
comp=''
case $CONTEXT in
redirect) comp="$comps[-redirect-]";;
math) comp="$comps[-math-]";;
subscript) comp="$comps[-subscript-]";;
value) comp="$comps[-value-]";;
condition) comp="$comps[-condition-]";;
esac
# If not, we use default completion, if any.
[[ -z "$comp" ]] && comp="$comps[-default-]"
[[ -z "$comp" ]] || "$comp" "$@"
fi

View file

@ -0,0 +1,3 @@
#defcomp make gmake pmake
complist -s "\$(awk '/^[a-zA-Z0-9][^/ ]+:/ {print \$1}' FS=: [mM]akefile)"

11
Functions/Completion/_man Normal file
View file

@ -0,0 +1,11 @@
#defcomp man
setopt localoptions rcexpandparam
local rep
if [[ $2 = (<->*|ln) ]]; then
rep=( $manpath/(man|cat)$2/$PREFIX*$SUFFIX.<->*(N:t:r) )
else
rep=( $manpath/(man|cat)*/$PREFIX*$SUFFIX.<->*(N:t:r) )
fi
(( $#rep )) && compadd -m $rep

70
Functions/Completion/_mh Normal file
View file

@ -0,0 +1,70 @@
#defcomp folder comp inc mark refile repl scan show next prev rmm pick whom mhn mhpath mhpatch
# Completion for all possible MH commands.
# Alter the following two to your own mh directory and the directory
# where standard mh library files live. (It works anyway, but this
# will save a little time.)
local mymhdir=~/Mail
local mhlib=/usr/lib/mh
# To be on the safe side, check this exists and if not, get it anyway.
[[ -d $mymhdir ]] || mymhdir=$(mhpath +)
if [[ -iprefix - ]]; then
# get list of options, which MH commands can generate themselves
# awk is just too icky to use for this, sorry. send me one if
# you come up with it.
compadd -m $($COMMAND -help | perl -ne 'if (/^\s*-\(?(\S+)/) {
$n = $1;
$n =~ s/\)//g;
print $n =~ s/^\[([a-z]+)\]// ? "$n\n$1$n\n" : "$n\n";
}')
return
elif [[ -iprefix '+' || -iprefix '@' || -current -1 -draftfolder ]]; then
# Complete folder names.
local mhpath
if [[ $IPREFIX != '@' ]]; then
[[ $IPREFIX = '+' ]] || IPREFIX=+
mhpath=$mymhdir
else
mhpath=$(mhpath)
fi
# painless, or what?
complist -W mhpath -/
elif [[ -mcurrent -1 -(editor|(whatnow|rmm|show|more)proc) ]]; then
complist -c
elif [[ -current -1 -file ]]; then
complist -f
elif [[ -mcurrent -1 -(form|audit|filter) ]]; then
# Need some MH template file, which may be in our own MH directory
# or with the standard library.
local mhfpath
# This is the only place we need mhlib, so leave the test till here.
[[ -d $mhlib ]] || { mhlib=$(mhparam mhlproc); mhlib=$mhlib:h; }
mhfpath=($mymhdir $mhlib)
complist -W mhfpath -g '*(.)'
elif [[ -mcurrent -1 -(no|)cc ]]; then
compadd -m all to cc me
elif [[ -mcurrent -1 -[rw]cache ]]; then
compadd -m public private never ask
else
# Generate sequences.
local foldnam folddir f
for f in $argv; do
[[ $f = [@+]* ]] && foldnam=$f
done
if [[ $foldnam = '+'* ]]; then
folddir=$mymhdir/${foldnam#+}
elif [[ $foldnam = '@'* ]]; then
folddir=$(mhpath)/${foldnam#@}
else
folddir=$(mhpath)
# leaving foldnam empty works here
fi
complist -s '$(mark $foldnam | awk -F: '\''{ print $1 }'\'')'
compadd -m reply next cur prev first last all unseen
complist -W folddir -g '<->'
fi

View file

@ -0,0 +1,3 @@
#defkeycomp expand-or-complete \C-xm
complist -g '*(om[1])'

View file

@ -0,0 +1,56 @@
#autoload
local comp cmd1 cmd2 pat val name
# Completing in command position? If not we set up `cmd1' and `cmd2' as
# two strings we have search in the completion definition arrays (e.g.
# a path and the last path name component).
if [[ $CONTEXT == command ]]; then
comp="$comps[-command-]"
[[ -z "$comp" ]] || "$comp" "$@"
return
elif [[ "$COMMAND[1]" == '=' ]]; then
eval cmd1\=$COMMAND
cmd2="$COMMAND[2,-1]"
elif [[ "$COMMAND" == */* ]]; then
cmd1="$COMMAND"
cmd2="${COMMAND:t}"
else
cmd1="$COMMAND"
eval cmd2=$(whence -p $COMMAND)
fi
# See if there are any matching pattern completions.
if (( $#patcomps )); then
for i in "$patcomps[@]"; do
pat="${i% *}"
val="${i#* }"
if [[ "$cmd1" == $~pat || "$cmd2" == $~pat ]]; then
"$val" "$@"
if (( $+COMPSKIP )); then
unset COMPSKIP
return
fi
fi
done
fi
# Now look up the two names in the normal completion array.
name="$cmd1"
comp="$comps[$cmd1]"
if [[ -z "$comp" ]]; then
name="$cmd2"
comp="$comps[$cmd2]"
fi
# And generate the matches, probably using default completion.
if [[ -z "$comp" ]]; then
name=-default-
comp="$comps[-default-]"
fi
[[ -z "$comp" ]] || "$comp" "$@"

View file

@ -0,0 +1,272 @@
#autoload
# Utility function for in-path completion.
# First argument should be an complist-option (e.g. -f, -/, -g). The other
# arguments should be glob patterns, one per argument.
#
# E.g.: _path_files -g '*.tex' '*.texi'
#
# This is intended as a replacement for `complist -f', `complist -/', and
# `complist -g ...' (but don't use it with other options).
#
# You may also give the `-W <spec>' option as with `compctl' and `complist',
# but only as the first argument.
#
# This function also accepts an optional `-F <string>' option as its first
# argument or just after the `-W <spec>'. This can be used to define file
# name extension (a la `fignore'). Files with such an extension will not
# be considered possible completions.
#
# This function behaves as if you have a matcher definition like:
# compctl -M 'r:|[-.,_/]=* r:|=* m:{a-z}={A-Z} m:-=_ m:.=,' \
# 'm:{a-z}={A-Z} l:|=* r:|=*'
# so you may want to modify this.
local nm prepaths str linepath realpath donepath patstr prepath testpath rest
local tmp1 collect tmp2 suffixes i ignore
setopt localoptions nullglob rcexpandparam globdots extendedglob
unsetopt markdirs globsubst shwordsplit nounset
# Get the optional `-W' option and its argument.
if [[ "$1" = -W ]]; then
tmp1="$2"
if [[ "$tmp1[1]" = '(' ]]; then
prepaths=( $tmp1[2,-2]/ )
else
prepaths=( ${(P)${tmp1}} )
[[ $#prepaths -eq 0 ]] && prepaths=( $tmp1/ )
fi
[[ $#prepaths -eq 0 ]] && prepaths=( '' )
shift 2
else
prepaths=( '' )
fi
# Get the optional `-F' option and its argument.
if [[ "$1" = -F ]]; then
ignore=(-F "$2")
shift 2
else
ignore=''
fi
# str holds the whole string from the command line with a `*' between
# the prefix and the suffix.
str="${PREFIX:q}*${SUFFIX:q}"
# We will first try normal completion called with `complist', but only if we
# weren't given a `-F' option.
if [[ -z "$ignore" ]]; then
# First build an array containing the `-W' option, if there is any and we
# want to use it. We don't want to use it if the string from the command line
# is a absolute path or relative to the current directory.
if [[ -z "$tmp1[1]" || "$str[1]" = [~/] || "$str" = (.|..)/* ]]; then
tmp1=()
else
tmp1=(-W "( $prepaths )")
fi
# Now call complist.
nm=$NMATCHES
if [[ $# -eq 0 ]]; then
complist "$tmp1[@]" -f
elif [[ "$1" = -g ]]; then
complist "$tmp1[@]" -g "$argv[2,-1]"
shift
else
complist "$tmp1[@]" $1
shift
fi
# If this generated any matches, we don't wnat to do in-path completion.
[[ -nmatches nm ]] || return
# No `-F' option, so we want to use `fignore'.
ignore=(-F fignore)
fi
# If we weren't given any file patterns as arguments, we trick ourselves
# into believing that we were given the pattern `*'. This is just to simplify
# the following code.
[[ -z "$1" ]] && 1='*'
# Now let's have a closer look at the string to complete.
if [[ "$str[1]" = \~ ]]; then
# It begins with `~', so remember anything before the first slash to be able
# to report it to the completion code. Also get an expanded version of it
# (in `realpath'), so that we can generate the matches. Then remove that
# prefix from the string to complete, set `donepath' to build the correct
# paths and make sure that the loop below is run only once with an empty
# prefix path by setting `prepaths'.
linepath="${str%%/*}/"
eval realpath\=path
str="${str#*/}"
donepath=''
prepaths=( '' )
else
# If the string does not start with a `~' we don't remove a prefix from the
# string.
liniepath=''
realpath=''
if [[ "$str[1]" = / ]]; then
# If it is a absolut path name, we remove the first slash and put it in
# `donepath' meaning that we treat it as the path that was already handled.
# Also, we don't use the paths from `-W'.
str="$str[2,-1]"
donepath='/'
prepaths=( '' )
else
# The common case, we just use the string as it is, unless it begins with
# `./' or `../' in which case we don't use the paths from `-W'.
[[ "$str" = (.|..)/* ]] && prepaths=( '' )
donepath=''
fi
fi
# First we skip over all pathname components in `str' which really exist in
# the file-system, so that `/usr/lib/l<TAB>' doesn't offer you `lib' and
# `lib5'. Pathname components skipped this way are taken from `str' and added
# to `donepath'.
while [[ "$str" = */* ]] do
[[ -e "$realpath$donepath${str%%/*}" ]] || break
donepath="$donepath${str%%/*}/"
str="${str#*/}"
done
# Now build the glob pattern. As noted above, this function behaves as if
# a global matcher with two matching specifications are given.
if [[ -matcher 1 ]]; then
patstr="$str:gs/,/*,/:gs/_/*_/:gs./.*/.:gs/-/*[-_]/:gs/./*[.,]/:gs-*[.,]*[.,]*/-../-:gs.**.*."
else
patstr="${str%/*}/*${str##*/}*"
patstr="$patstr:gs./.*/.:gs.**.*."
fi
# Finally, generate the matches. First we loop over all the paths from `-W'.
# Note that in this loop `str' is used as a modifyable version of `patstr'
# and `testpath' is a modifyable version of `donepath'.
for prepath in "$prepaths[@]"; do
str="$patstr"
testpath="$donepath"
# The second loop tests the components of the path in `str' to get the
# possible matches.
while [[ "$str" = */* ]] do
# `rest' is the pathname after the first slash that is left. In `tmp1'
# we get the globbing matches for the pathname component currently
# handled.
rest="${str#*/}"
tmp1="${prepath}${realpath}${testpath}(#l)${str%%/*}(-/)"
tmp1=( $~tmp1 )
if [[ $#tmp1 -eq 0 ]]; then
# If this didn't produce any matches, we don't need to test this path
# any further, so continue with the next `-W' path, if any.
continue 2
elif [[ $#tmp1 -gt 1 ]]; then
# If it produced more than one match, we want to remove those which
# don't have possible following pathname components matching the
# rest of the string we are completing. (The case with only one
# match is handled below.)
# In `collect' we will collect those of the produced pathnames that
# have a matching possible path-suffix. In `suffixes' we build an
# array containing strings build from the rest of the string to
# complete and the glob patterns we were given as arguments.
collect=()
suffixes=( $rest$@ )
suffixes=( "${(@)suffixes:gs.**.*.}" )
# In the loop the prefixes from the `tmp1' array produced above and
# the suffixes we just built are used to produce possible matches
# via globbing.
for i in $tmp1; do
tmp2=( $~i/(#l)$~suffixes )
[[ $#tmp2 -ne 0 ]] && collect=( $collect $i )
done
# If this test showed that none of the matches from the glob in `tmp1'
# has a possible sub-path matching what's on the line, we give up and
# continue with the next `-W' path.
if [[ $#collect -eq 0 ]]; then
continue 2
elif [[ $#collect -ne 1 ]]; then
# If we have more than one possible match, this means that the
# pathname component currently handled is ambiguous, so we give
# it to the completion code.
# First we build the full path prefix in `tmp1'.
tmp1="$prepath$realpath$testpath"
# Now produce all matching pathnames in `collect'.
collect=( $~collect/(#l)$~suffixes )
# And then remove the common path prefix from all these matches.
collect=( ${collect#$tmp1} )
# Finally, we add all these matches with the common (unexpanded)
# pathprefix (the `-p' option), the path-prefix (the `-W' option)
# to allow the completion code to test file type, and the path-
# suffix (the `-s' option). We also tell the completion code that
# these are file names and that `fignore' should be used as usual
# (the `-f' and `-F' options).
for i in $collect; do
compadd -p "$linepath$testpath" -W "$tmp1" -s "/${i#*/}" -f "$ignore[@]" - "${i%%/*}"
done
# We have just finished handling all the matches from above, so we
# can continue with the next `-W' path.
continue 2
fi
# We reach this point if only one of the path prefixes in `tmp1'
# has a existing path-suffix matching the string from the line.
# In this case we accept this match and continue with the next
# path-name component.
tmp1=( "$collect[1]" )
fi
# This is also reached if the first globbing produced only one match
# in this case we just continue with the next pathname component, too.
tmp1="$tmp1[1]"
testpath="$testpath${tmp1##*/}/"
str="$rest"
done
# We are here if all pathname components except the last one (which is still
# not tested) are unambiguous. So we add matches with the full path prefix,
# no path suffix, the `-W' we are currently handling, all the matches we
# can produce in this directory, if any.
tmp1="$prepath$realpath$testpath"
suffixes=( $str$@ )
suffixes=( "${(@)suffixes:gs.**.*.}" )
tmp2=( $~tmp1(#l)$~suffixes )
compadd -p "$linepath$testpath" -W "$prepath$realpath$testpath" -f "$ignore[@]" - ${tmp2#$tmp1}
done

View file

@ -0,0 +1,3 @@
function acroread
_files -g '*.(pdf|PDF)'

View file

@ -0,0 +1,5 @@
#defcomp - nohup nice eval time rusage noglob nocorrect exec
[[ -position 1 -1 ]]
_normal "$@"

3
Functions/Completion/_ps Normal file
View file

@ -0,0 +1,3 @@
#defcomp gs ghostview gview psnup psselect pswrap pstops pstruct lpr
_files -g '*([pP][sS]|eps)'

View file

@ -0,0 +1,9 @@
#defcomp co ci rcs
[[ $COMMAND = ci || $COMMAND = rcs ]] && _files
if [[ $NMATCHES -eq 0 && -d RCS && $COMMAND != ci ]]; then
local rep
rep=(RCS/$PREFIX*$SUFFIX,v(:t:s/\,v//))
(( $#rep )) && compadd -m $rep
fi

View file

@ -0,0 +1,9 @@
#defcomp rlogin rsh ssh
if [[ -position 1 ]]; then
complist -k hosts
elif [[ -position 2 ]]; then
complist -k '(-l)'
else
complist -u
fi

View file

@ -0,0 +1,3 @@
#defcomp sched
[[ -position 2 -1 ]] && compsub

View file

@ -0,0 +1,7 @@
#defcomp set
if [[ -mcurrent -1 [-+]o ]]; then
complist -o
elif [[ -current -1 -A ]]; then
complist -A
fi

View file

@ -0,0 +1,7 @@
#defcomp setopt
local nm=$NMATCHES
complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
-s '$({ unsetopt kshoptionprint; unsetopt } 2>/dev/null)'
[[ -nmatches nm ]] && complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o

View file

@ -0,0 +1,7 @@
#defcomp source
if [[ -position 2 -1 ]]; then
compsub
else
_files
fi

View file

@ -0,0 +1,2 @@
#defcomp strip
_files -g '*(*)'

View file

@ -0,0 +1,16 @@
#defcomp stty
if [[ -mcurrent -1 \
(*erase|discard|status|dsusp|intr|kill|lnext|quit|reprint|start|s*p) ]]
then
compadd -m -Q '^-' '^h' '^?' '^c' '^u'
else
[[ -string '-' || -string '+' ]]
compadd -m rows columns intr quit erase kill eof eol \
eol2 start stop susp dsusp reprint discard werase lnext \
parenb parodd cs8 cstopb hupcl cread clocal parext \
ignbrk brkint ignpar parmrk inpck istrip inlcr igncr icrnl iuclc \
ixon ixany ixoff imaxbel isig icanon xcase echo echoe echok \
echonl noflsh tostop echoctl echoprt echoke flusho pending iexten \
opost olcuc onlcr ocrnl onocr onlret ofill ofdel
fi

View file

@ -0,0 +1,4 @@
#defcomp -subscript-
_compalso -math- "$@"
[[ ${(Pt)${COMMAND}} = assoc* ]] && complist -k "( ${(kP)${COMMAND}} )"

11
Functions/Completion/_tar Normal file
View file

@ -0,0 +1,11 @@
#defcomp tar
local nm=$NMATCHES tf="$2"
if [[ ( -mword 1 *t*f* || -mword 1 *x*f* ) && -position 3 100000 ]]; then
complist -k "( $(tar tf $tf) )"
elif [[ -mword 1 *c*f* && -position 3 100000 ]]; then
_files
elif [[ -mcurrent -1 *f* && -position 2 ]]; then
_files -g '*.(tar|TAR)'
fi

View file

@ -0,0 +1,3 @@
#defcomp tex latex slitex
_files -g '*.(tex|TEX|texinfo|texi)'

View file

@ -0,0 +1,7 @@
#defcomp trap
if [[ -position 1 ]]; then
complist -c
else
complist -k signals
fi

View file

@ -0,0 +1,3 @@
#defcomp uncompress zmore
_files -g '*.Z'

View file

@ -0,0 +1,6 @@
#defcomp unhash
[[ -mword 1 -*d* ]] && complist -n
[[ -mword 1 -*a* ]] && complist -a
[[ -mword 1 -*f* ]] && complist -F
[[ ! -mword 1 -* ]] && complist -m

View file

@ -0,0 +1,7 @@
#defcomp unsetopt
local nm=$NMATCHES
complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' \
-s '$({ unsetopt kshoptionprint; setopt } 2>/dev/null)'
[[ -nmatches nm ]] && complist -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o

View file

@ -0,0 +1,3 @@
#defcomp -math- getopts read unset vared
complist -v

View file

@ -0,0 +1,3 @@
#defcomp declare export integer local readonly typeset
complist -v -q -S '='

View file

@ -0,0 +1,4 @@
#defcomp wait
complist -P '%' -j
complist -y _kill_helper -s '`ps 2>/dev/null | tail +2 | cut -c1-5`'

View file

@ -0,0 +1,3 @@
#defcomp which whence where type
complist -caF

View file

@ -0,0 +1,5 @@
#defpatcomp */X11/*
# A simple pattern completion, just as an example.
complist -J options -k '(-display -name -xrm)'

View file

@ -0,0 +1,3 @@
#defcomp xfig
_files -g '*.fig'

View file

@ -0,0 +1,50 @@
#defpatcomp zf*
# Don't try any more completion after this.
COMPSKIP=1
# Completion for zftp builtin and zf* functions. The functions
# zfcd_match and zfget_match (used for old-style completion)
# need to be installed for remote file and directory completion to work.
local subcom
if [[ $COMMAND = zftp ]]; then
if [[ $CURRENT -eq 1 ]]; then
compadd -m open params user login type ascii binary mode put \
putat get getat append appendat ls dir local remote mkdir rmdir
return
fi
subcom=$1
else
subcom=$COMMAND
fi
case $subcom in
*(cd|ls|dir))
# complete remote directories; we could be smarter about hiding prefixes
zfcd_match $PREFIX $SUFFIX
(( $#reply )) && compadd -m -S/ -q $reply
;;
*(get(|at)|gcp|delete|remote))
# complete remote files
zfget_match $PREFIX $SUFFIX
(( $#reply )) && compadd -F fignore -m $reply
;;
*(put(|at)|pcp))
# complete local files
_files
;;
*(open|anon|params))
# complete hosts: should do cleverer stuff with user names
complist -k hosts
;;
*)
# dunno... try ordinary completion after all.
unset COMPSKIP
;;
esac

View file

@ -0,0 +1,7 @@
#defcomp zle
if [[ -word 1 -N && -position 3 ]]; then
complist -F
else
complist -b
fi

View file

@ -0,0 +1,9 @@
#defcomp zmodload
if [[ -mword 1 -*(a*u|u*a)* || -mword 1 -*a* && -position 3 -1 ]]; then
complist -B
elif [[ -mword 1 -*u* ]]; then
complist -s '$(zmodload)'
else
complist -s '${^module_path}/*(N:t:r)'
fi

89
Functions/Completion/dump Normal file
View file

@ -0,0 +1,89 @@
# This is a file to be sourced to dump the definitions for new-style
# completion defined by 'init' in the same directory. For best results,
# it should be run immediately after init, before any of the completions
# have been autoloaded. The output should be directed into the "init.dump"
# in the same directory as init. If you rename init, just stick .dump onto
# the end of whatever you have called it and put it in the same directory.
#
# You will need to update the dump every time you add a new completion.
# To do this, simply remove the .dump file, start a new shell, and
# create the .dump file as before.
#
# It relies on KSH_ARRAYS not being set.
# Print the number of files used for completion. This is used in init
# to see if auto-dump should re-dump the dump-file.
_d_file=${COMPDUMP-${0:h}/init.dump}
_d_files=( ${^~fpath}/_*~*~ )
print "#files: $#_d_files" > $_d_file
unset _d_files
# First dump the arrays comps and patcomps. The quoting hieroglyphyics
# ensure that a single quote inside a variable is itself correctly quoted.
print "comps=(" >> $_d_file
for _d_f in ${(k)comps}; do
print -r - "'${_d_f//\'/'\\''}'" "'${comps[$_d_f]//\'/'\\''}'"
done >> $_d_file
print ")" >> $_d_file
if (( $#patcomps )); then
print "\npatcomps=(" >> $_d_file
for _d_f in "$patcomps[@]"; do
print -r - "'${_d_f//\'/'\\''}'"
done >> $_d_file
print ")" >> $_d_file
fi
print >> $_d_file
# Now dump the key bindings. We dump all bindings for zle widgets
# whose names start with a underscore.
# We need both the zle -C's and the bindkey's to recreate.
_d_bks=()
zle -lL |
while read -rA _d_line; do
if [[ ${_d_line[5]} = _* ]]; then
print -r - ${_d_line}
_d_bks=($_d_bks ${_d_line[3]})
fi
done >> $_d_file
bindkey |
while read -rA _d_line; do
if [[ ${_d_line[2]} = (${(j.|.)~_d_bks}) ]]; then
print -r "bindkey '${_d_line[1][2,-2]}' ${_d_line[2]}"
fi
done >> $_d_file
print >> $_d_file
# Autoloads: whence -w produces "_d_foo: function", so look for
# all functions beginning with `_'.
_d_als=($(whence -wm '_*' |
while read -rA _d_line; do
[[ ${_d_line[2]} = function ]] && print -r - ${_d_line[1]%:}
done))
# print them out: about six to a line looks neat
while (( $#_d_als )); do
print -n autoload
for (( _i = 0; _i < 6; _i++ )); do
if (( $#_d_als )); then
print -n " $_d_als[1]"
shift _d_als
fi
done
print
done >> $_d_file
print >> $_d_file
unset _d_line _d_zle _d_bks _d_als _d_f _f_file

View file

@ -3,34 +3,22 @@
# directory that will automatically be made autoloaded (see the end of this
# file).
# The names of the files that will be considered for autoloading have to
# start with two underscores (like `__setopt).
# start with a underscores (like `_setopt).
# The first line of these files will be read and has to say what should be
# done with its contents:
#
# `#function <names ...>'
# `#defcomp <names ...>'
# if the first line looks like this, the file is
# autoloaded as a function and that function will
# be called to generate the matches when completing
# for one of the commands whose <name> is given
#
# `#array <names ...>'
# with a first line like this, the filename is taken as
# the name of an array; when trying to generate matches
# for the command <name>, the file will be sourced and
# should define this array, the builtin `complist' will
# then be called with the elements of this array as its
# arguments; this is intended for simple definitions
# for which you don't need a shell function
#
# `#pattern-function <pattern>'
# `#defpatcomp <pattern>'
# this defines a function that should be called to generate
# matches for commands whose name matches <pattern>; note
# that only one pattern may be given
#
# `#pattern-array <pattern>'
# like `#pattern-function' but defining an array
#
# `#key-function <style> [ <key-sequence> ... ]
# `#defkeycomp <style> [ <key-sequence> ... ]
# this is used to bind special completions to all the given
# <key-sequence>(s). The <style> is the name of one of the built-in
# completion widgets (complete-word, delete-char-or-list,
@ -41,45 +29,47 @@
# rather than by the context. The widget has the same name as
# the autoload file and can be bound using bindkey in the normal way.
#
# `#key-array <style> [ <key-sequence> ... ]
# like `#key-function', but defining an array instead
#
# `#helper'
# `#autoload'
# this is for helper functions that are not used to
# generate matches, but should automatically be loaded
# when they are called
#
# Note that no white space is allowed between the `#' and the rest of
# the string.
#
# See the file `dump' for how to speed up initialiation.
# If we got the `-d'-flag, we will automatically dump the new state (at
# the end).
# An associative array for completions definitions. The keys of the entries
# are the names of the command, the values are names of functions or variables
# that are to be used to generate the matches.
# Pattern completions will be stored in an normal array named `patcomps'.
# Completion definitions bound directly to keys are stored in an assoc array
# named `keycomps'.
if [[ "$1" = -d ]]; then
_i_autodump=1
else
_i_autodump=0
fi
# The associative array containing the definitions for the commands.
# Definitions for patterns will be stored in the normal array `patcomps'.
typeset -A comps
typeset -A keycomps
# This may be used to define completion handlers. The first argument is the
# name of the function or variable containing the definition, the other
# arguments are the command names for which this definition should be used.
# With only one argument the function/variable-name __$1 is used.
# name of the function containing the definition, the other arguments are the
# command names for which this definition should be used.
# With only one argument the function/variable-name _$1 is used.
# If given the `-a' option, the function is defined as being autoloaded.
defcomp() {
local name autol=''
local name
if [[ "$1" = -a ]]; then
shift
autol=yes
fi
if [[ $# -eq 1 ]]; then
comps[$1]="__$1"
[[ -z "$autol" ]] || autoload "__$1"
comps[$1]="_$1"
[[ -z "$autol" ]] || autoload "_$1"
else
name="$1"
shift
@ -90,10 +80,9 @@ defcomp() {
fi
}
# Almost like `defcomp', but this always gets two arguments: the name of a
# variable or function describing what should be completed and the pattern
# that will be compared to the command names for which completion is attempted.
# function describing what should be completed and the pattern that will be
# compared to the command names for which completion is attempted.
defpatcomp() {
if [[ "$1" = -a ]]; then
@ -101,13 +90,12 @@ defpatcomp() {
autoload "$1"
fi
if (( $+patcomps )) then
patcomps=("$patcomps[@]" "$2 $1" )
patcomps=("$patcomps[@]" "$2 $1")
else
patcomps=( "$2 $1" )
patcomps=("$2 $1")
fi
}
# This is used to define completion handlers directly bound to keys. The
# first argument is as for `defcomp', giving the handler. The second
# argument is the name of one of the built-in completion widgets. Any
@ -122,15 +110,10 @@ defkeycomp() {
if [[ "$1" = -a ]]; then
shift
autoload "$1"
name="$1"
elif [[ "${1[1]}" = ' ' ]]; then
name="${1:t}"
else
name="$1"
fi
keycomps[$name]="$1"
name="$1"
shift
zle -C "$name" "$1" __main_key_complete
zle -C "$name" "$1" "$name"
shift
while (( $# )); do
bindkey "$1" "$name"
@ -138,116 +121,101 @@ defkeycomp() {
done
}
# These can be used to easily save and restore the state of the special
# variables used by the completion code.
alias compsave='local _oprefix _oiprefix _oargv _ocurrent; \
_oprefix="$PREFIX"; \
_oiprefix="$IPREFIX"; \
_oargv=( "$@" ); \
_ocurrent="$CURRENT"'
alias compreset='PREFIX="$_oprefix"; \
IPREFIX="$_oiprefix"; \
argv=( "$_oargv[@]" ); \
CURRENT="$_ocur"'
# This is an easy way to get completion for sub-commands.
alias compsub='__normal "$@" || return 1'
# This searches $1 in the array for normal completions and calls the result.
compalso() {
_compalso() {
local tmp
tmp="$comps[$1]"
[[ -z "$tmp" ]] || callcomplete comps "$1" "$@"
[[ -z "$tmp" ]] || "$tmp" "$@"
}
# These can be used to easily save and restore the state of the special
# variables used by the completion code.
# This generates matches. The first argument is the name of one of the
# arrays containing completion definitions. The second argument is the index
# into this array. The other arguments are the positional parameters to give
# to the completion function (containing the arguments from the command line).
alias _compsave='local _oprefix$_level _oiprefix$_level _oargv$_level _ocurrent$_level _ocommand$_level _ocontext$_level; \
eval "_oprefix${_level}=\"\$PREFIX\"; \
_oiprefix${_level}=\"\$IPREFIX\"; \
_oargv${_level}=( \"\$@\" ); \
_ocurrent${_level}=\"\$CURRENT\"; \
_ocommand${_level}=\"\$COMMAND\"; \
_ocontext${_level}=\"\$CONTEXT\""'
alias _compreset='eval "PREFIX=\"\$_oprefix${_level}\"; \
IPREFIX=\"\$_oiprefix${_level}\"; \
argv=( \"\$_oargv${_level}[@]\" ); \
CURRENT=\"\$_ocur${_level}\"; \
COMMAND=\"\$_ocommand${_level}\"; \
CONTEXT=\"\$_ocontext${_level}\""'
callcomplete() {
local file def
# These can be used to build tests that modify the special parameters
# without having to reset them by hand.
# Get the definition from the array.
alias _if='(( $+_level )) || local _level=0; (( _level++ )); _compsave; if'
alias _elif='_compreset; elif'
alias _else='_compreset; else'
alias _fi='_compreset; fi; unset _oprefix$_level _oiprefix$_level _oargv$_level _ocurrent$_level _ocommand$_level _ocontext$_level; (( _level-- ))'
eval "def=\$${1}[${2}]"
# If the definition starts with a space then this means that we should
# source a file to get the definition for an array.
# Now we automatically make the definition files autoloaded.
if [[ "$def[1]" = ' ' ]]; then
# The definition starts with a space, so source the file and change
# the definition.
# First we get the name of a dump file if this will be used.
file="$def[2,-1]"
builtin . "$file"
def="${file:t}"
eval "${1}[${2}]=$def"
: ${COMPDUMP:=$0.dump}
_i_files=( ${^~fpath}/_*~*~ )
_i_initname=$0
_i_done=''
# If we have a dump file, load it.
if [[ -f "$COMPDUMP" ]]; then
read -rA _i_line < "$COMPDUMP"
if [[ _i_autodump -eq 1 || $_i_line[2] -eq $#_i_files ]]; then
builtin . "$COMPDUMP"
_i_done=yes
fi
unset _i_line
fi
if [[ -z "$_i_done" ]]; then
# Get rid of the array-name and -index.
shift 2
if [[ ${(P)+def} -eq 1 ]]; then
# It is a parameter name, call complist directly.
complist "${(@P)def}"
else
# Otherwise it's a function name, call this function.
"$def" "$@"
fi
}
# Now we make the files automatically autoloaded.
local dir file line func
for dir in $fpath; do
[[ $dir = . ]] && continue
for file in $dir/__*~*~(N); do
read -rA line < $file
func=$line[1]
shift line
if [[ $func = '#function' ]]; then
defcomp -a ${file:t} "${line[@]}"
elif [[ $func = '#array' ]]; then
defcomp " $file" "${line[@]}"
elif [[ $func = '#pattern-function' ]]; then
defpatcomp -a ${file:t} "${line[@]}"
elif [[ $func = '#pattern-array' ]]; then
defcomp " $file" "${line[@]}"
elif [[ $func = '#key-function' ]]; then
defkeycomp -a "${file:t}" "${line[@]}"
elif [[ $func = '#key-array' ]]; then
defkeycomp " $file" "${line[@]}"
elif [[ $func = '#helper' ]]; then
autoload ${file:t}
fi
for _i_dir in $fpath; do
[[ $_i_dir = . ]] && continue
for _i_file in $_i_dir/_*~*~(N); do
read -rA _i_line < $_i_file
_i_tag=$_i_line[1]
shift _i_line
if [[ $_i_tag = '#defcomp' ]]; then
defcomp -a ${_i_file:t} "${_i_line[@]}"
elif [[ $_i_tag = '#defpatcomp' ]]; then
defpatcomp -a "${_i_file:t}" "${_i_line[@]}"
elif [[ $_i_tag = '#defkeycomp' ]]; then
defkeycomp -a "${_i_file:t}" "${_i_line[@]}"
elif [[ $_i_tag = '#autoload' ]]; then
autoload ${_i_file:t}
fi
done
done
done
bindkey |
while read -rA _i_line; do
if [[ "$_i_line[2]" = complete-word ||
"$_i_line[2]" = delete-char-or-list ||
"$_i_line[2]" = expand-or-complete ||
"$_i_line[2]" = expand-or-complete-prefix ||
"$_i_line[2]" = list-choices ||
"$_i_line[2]" = menu-complete ||
"$_i_line[2]" = menu-expand-or-complete ||
"$_i_line[2]" = reverse-menu-complete ]]; then
zle -C _complete_$_i_line[2] $_i_line[2] _main_complete
bindkey "${_i_line[1][2,-2]}" _complete_$_i_line[2]
fi
done
# Finally we make all this be called by changing the key bindings.
unset _i_dir _i_line _i_file _i_tag
bindkey | while read -A line; do
if [[ "$line[2]" = complete-word ||
"$line[2]" = delete-char-or-list ||
"$line[2]" = expand-or-complete ||
"$line[2]" = expand-or-complete-prefix ||
"$line[2]" = list-choices ||
"$line[2]" = menu-complete ||
"$line[2]" = menu-expand-or-complete ||
"$line[2]" = reverse-menu-complete ]]; then
zle -C __complete_$line[2] $line[2] __main_complete
bindkey "${line[1][2,-2]}" __complete_$line[2]
fi
done
# if autodumping was requested, do it now.
(( _i_autodump )) && builtin . ${_i_initname:h}/dump
fi
unset _i_files _i_initname _i_done _i_autodump

View file

@ -164,18 +164,21 @@ alias zfuget='noglob zfuget'
setopt completealiases
#
# zftp completions
# zftp completions: only use these if new-style completion is not
# active.
#
compctl -f -x 'p[1]' \
-k '(open params user login type ascii binary mode put putat
get getat append appendat ls dir local remote mkdir rmdir delete
close quit)' - \
'w[1,cd][1,ls][1,dir][1,rmdir]' -K zfcd_match -S/ -q - \
'W[1,get*]' -K zfget_match - 'w[1,delete][1,remote]' -K zfget_match - \
'w[1,open][1,params]' -k hosts -- zftp
compctl -K zfcd_match -S/ -q zfcd zfdir zfls
compctl -K zfget_match zfget zfgcp zfuget zfcget
compctl -k hosts zfopen zfparams
if [[ ${#patcomps} -eq 0 || ${patcomps[(i)zf*]} -gt ${#patcomps} ]]; then
compctl -f -x 'p[1]' \
-k '(open params user login type ascii binary mode put putat
get getat append appendat ls dir local remote mkdir rmdir delete
close quit)' - \
'w[1,cd][1,ls][1,dir][1,rmdir]' -K zfcd_match -S/ -q - \
'W[1,get*]' -K zfget_match - 'w[1,delete][1,remote]' -K zfget_match - \
'w[1,open][1,params]' -k hosts -- zftp
compctl -K zfcd_match -S/ -q zfcd zfdir zfls
compctl -K zfget_match zfget zfgcp zfuget zfcget
compctl -k hosts zfanon zfopen zfparams
fi
function zfanon {
local opt optlist once
@ -245,6 +248,40 @@ function zfanon {
fi
}
function zfautocheck {
# This function is used to implement auto-open behaviour.
#
# With first argument including n, don't change to the old directory; else do.
#
# Set do_close to 1 if the connection was not previously open, 0 otherwise
# With first arguemnt including d, don't set do_close to 1. Broadly
# speaking, we use this mechanism to shut the connection after use
# if the connection had been explicitly closed (i.e. didn't time out,
# which zftp test investigates) and we are not using a directory
# command, which implies we are looking for something so should stay open
# for it.
# Remember the old session: zflastsession will be overwritten by
# a successful open.
local lastsession=$zflastsession
if [[ -z $ZFTP_HOST ]]; then
zfopen || return 1
[[ $1 = *d* ]] || do_close=1
elif zftp test 2>/dev/null; then
return 0
else
zfopen || return 1
fi
if [[ $1 = *n* ]]; then
return 0
else
zfcd ${lastsession#*:}
fi
}
function zfcd {
# zfcd: change directory on the remote server.
#
@ -266,9 +303,11 @@ function zfcd {
# second, we can no do 'zfcd $PWD' and the like, and that will
# work just as long as the directory structures under the home match.
# Autoopen: if not already open, hope there are parameters set up to
# do so. If not, we get the right error message, so no harm done.
[[ -z $ZFTP_HOST ]] && { zfopen || return 1; }
if [[ $1 = /* ]]; then
zfautocheck -dn
else
zfautocheck -d
fi
if [[ $1 = $HOME || $1 = $HOME/* ]]; then
1="~${1#$HOME}"
@ -291,6 +330,7 @@ function zfcd {
local lastdir=$ZFTP_PWD
zftp cd "$@" && zflastdir=$lastdir
print $zflastsession
}
function zfcd_match {
@ -303,6 +343,8 @@ function zfcd_match {
local ZFTP_VERBOSE=45
# should we redirect 2>/dev/null or let the user see it?
local tmpf=${TMPPREFIX}zfcm$$
if [[ $ZFTP_SYSTEM = UNIX* ]]; then
# hoo, aren't we lucky: this makes things so much easier
setopt localoptions rcexpandparam
@ -315,8 +357,9 @@ function zfcd_match {
# If we're using -F, we get away with using a directory
# to list, but not a glob. Don't ask me why.
# I hate having to rely on awk here.
reply=($(zftp ls -F $dir |
awk '/\/$/ { print substr($1, 0, length($1)-1) }'))
zftp ls -F $dir >$tmpf
reply=($(awk '/\/$/ { print substr($1, 0, length($1)-1) }' $tmpf))
rm -f $tmpf
if [[ $dir = / ]]; then
reply=(${dir}$reply)
elif [[ -n $dir ]]; then
@ -423,6 +466,84 @@ function zfclose {
zftp close
}
function zfcput {
# Continuation put of files from remote server.
# For each file, if it's shorter over there, put the remainder from
# over here. This uses append, which is standard, so unlike zfcget it's
# expected to work on any reasonable server... err, as long as it
# supports SIZE and MDTM. (It could be enhanced so you can enter the
# size so far by hand.) You should probably be in binary transfer
# mode, thought it's not enforced.
#
# To read from midway through a local file, `tail +<n>c' is used.
# It would be nice to find a way of doing this which works on all OS's.
setopt localoptions
unsetopt ksharrays shwordsplit
local loc rem stat=0 locst remst offs tailtype
local tmpfile=${TMPPREFIX}zfcget$$ rstat
# find how tail works. this is intensely annoying, since it's completely
# standard in C. od's no use, since we can only skip whole blocks.
if [[ $(echo abcd | tail +2c) = bcd ]]; then
tailtype=c
elif [[ $(echo abcd | tail --bytes=+2) = bcd ]]; then
tailtype=b
else
print "I can't get your \`tail' to start from from arbitrary characters.\n" \
"If you know how to do this, let me know." 2>&1
return 1
fi
for loc in $*; do
# zfcd directory hack to put the front back to ~
rem=$loc
if [[ $rem = $HOME || $rem = $HOME/* ]]; then
rem="~${rem#$HOME}"
fi
if [[ ! -r $loc ]]; then
print "Can't read file $loc"
stat=1
else
# Compare the sizes.
locst=($(zftp local $loc))
zftp remote $rem >$tmpfile
rstat=$?
remst=($(<$tmpfile))
rm -f $tmpfile
if [[ $rstat = 2 ]]; then
print "Server does not support remote status commands.\n" \
"You will have to find out the size by hand and use zftp append." 2>&1
stat=1
continue
elif [[ $rstat = 1 ]]; then
# Not found, so just do a standard put.
zftp put $rem <$loc
elif [[ $remst[1] -gt $locst[1] ]]; then
print "Remote file is larger!" 2>&1
continue;
elif [[ $locst[1] == $remst[1] ]]; then
print "Files are already the same size." 2>&1
continue
else
# tail +<N>c takes the count of the character
# to start from, not the offset from zero. if we did
# this with years, then 2000 would be 1999. no y2k bug!
# brilliant.
(( offs = $remst[1] + 1 ))
if [[ $tailtype = c ]]; then
tail +${offs}c $loc | zftp append $rem || stat=1
else
tail --bytes=+$offs $loc | zftp append $rem || stat=1
fi
fi
fi
done
return $stat
}
function zfdir {
# Long directory of remote server.
# The remote directory is cached. In fact, two caches are kept:
@ -440,9 +561,11 @@ function zfdir {
# zfdir -f will force the existing cache to be ignored, e.g. if you know
# or suspect the directory has changed.
# zfdir -d will remove both caches without listing anything.
# If you need to pass -r, -f or -d to the dir itself, use zfdir -- -d etc.
# If you need to pass -r, -f or -d to the dir itself, use zfdir -- -d etc.;
# unrecognised options are passed through to dir, but zfdir options must
# appear first and unmixed with the others.
setopt localoptions unset
setopt localoptions unset extendedglob
unsetopt shwordsplit ksharrays
local file opt optlist redir i newargs force
@ -451,6 +574,9 @@ function zfdir {
if [[ $1 = - || $1 = -- ]]; then
shift;
break;
elif [[ $1 != -[rfd]## ]]; then
# pass options through to ls
break;
fi
optlist=${1#-}
for (( i = 1; i <= $#optlist; i++)); do
@ -465,13 +591,13 @@ function zfdir {
zftp_fcache=()
return 0
;;
*) print option $opt not recognised >&2
;;
esac
done
shift
done
zfautocheck -d
# directory hack, see zfcd
for (( i = 1; i <= $#argv; i++ )); do
if [[ $argv[$i] = $HOME || $argv[$i] = $HOME/* ]]; then
@ -507,27 +633,38 @@ function zfdir {
if [[ -n $file && -f $file ]]; then
eval ${PAGER:-more} \$file
else
zftp dir $* | tee $file | eval ${PAGER-:more}
if (zftp test); then
# Works OK in subshells
zftp dir $* | tee $file | eval ${PAGER-:more}
else
# Doesn't work in subshells (IRIX 6.2 --- why?)
zftp dir $* >$file
eval ${PAGER-:more} >$file
fi
fi
}
function zfgcp {
# ZFTP get as copy: i.e. first arguments are remote, last is local.
# Supposed to work exactly like a normal copy otherwise, i.e.
# zfcp rfile lfile
# zfgcp rfile lfile
# or
# zfcp rfile1 rfile2 rfile3 ... ldir
# zfgcp rfile1 rfile2 rfile3 ... ldir
# Options:
# -G don't to remote globbing, else do
# -t update the local file times to the same time as the remote.
# Currently this only works if you have the `perl' command,
# and that perl is version 5 with the standard library.
# See the function zfrtime for more gory details.
#
# If there is no current connection, try to use the existing set of open
# parameters to establish one and close it immediately afterwards.
setopt localoptions
unsetopt shwordsplit
local opt optlist nglob remlist rem loc stat=0 time
local opt optlist nglob remlist rem loc time
integer stat do_close
while [[ $1 == -* ]]; do
if [[ $1 == - || $1 == -- ]]; then
@ -549,6 +686,8 @@ function zfgcp {
shift
done
zfautocheck
# hmm, we should really check this after expanding the glob,
# but we shouldn't expand the last argument remotely anyway.
if [[ $# -gt 2 && ! -d $argv[-1] ]]; then
@ -584,6 +723,9 @@ function zfgcp {
else
zftp get $1 >$2 || stat=$?
fi
(( $do_close )) && zfclose
return $stat
}
@ -594,8 +736,14 @@ function zfget {
# Currently this only works if you have the `perl' command,
# and that perl is version 5 with the standard library.
# See the function zfrtime for more gory details.
#
# If the connection is not currently open, try to open it with the current
# parameters (set by a previous zfopen or zfparams), then close it after
# use. The file is put in the current directory (i.e. using the basename
# of the remote file only); for more control, use zfgcp.
local loc rem stat=0 optlist opt nglob remlist time
local loc rem optlist opt nglob remlist time
integer stat do_close
while [[ $1 == -* ]]; do
if [[ $1 == - || $1 == -- ]]; then
@ -617,6 +765,8 @@ function zfget {
shift
done
zfautocheck
for remlist in $*; do
# zfcd directory hack to put the front back to ~
if [[ $remlist == $HOME || $remlist == $HOME/* ]]; then
@ -637,6 +787,8 @@ function zfget {
fi
done
(( $do_close )) && zfclose
return $stat
}
@ -646,15 +798,20 @@ function zfget_match {
1="~${1#$HOME}"
fi
local tmpf=${TMPPREFIX}zfgm$$
if [[ $ZFTP_SYSTEM == UNIX* && $1 == */* ]]; then
# On the first argument to ls, we usually get away with a glob.
reply=($(zftp ls "$1*$2"))
zftp ls "$1*$2" >$tmpf
reply=($(<$tmpf))
rm -f $tmpf
else
if (( $#zftp_fcache == 0 )); then
# Always cache the current directory and use it
# even if the system is UNIX.
zftp_fcache=($(zftp ls))
zftp ls >$tmpf
zftp_fcache=($(<$tmpf))
rm -f $tmpf
fi
reply=($zftp_fcache);
fi
@ -671,6 +828,9 @@ function zfls {
if [[ $1 = $HOME || $1 = $HOME/* ]]; then
1="~${1#$HOME}"
fi
zfautocheck -d
zftp ls $*
}
@ -725,15 +885,62 @@ function zfparams {
zftp params $*
}
function zfpcp {
# ZFTP put as copy: i.e. first arguments are remote, last is local.
# Currently only supports
# zfcp lfile rfile
# if and only if there are two arguments
# or
# zfcp lfile1 lfile2 lfile3 ... rdir
# if and only if there are more than two (because otherwise it doesn't
# know if the last argument is a directory on the remote machine).
# argument.
setopt localoptions
unsetopt shwordsplit
local rem loc
integer stat do_close
zfautocheck
if (( $# > 2 )); then
local dir=$argv[-1]
argv[-1]=
# zfcd directory hack to put the front back to ~
if [[ $dir = $HOME || $dir = $HOME/* ]]; then
dir="~${dir#$HOME}"
fi
for loc in $*; do
rem=$dir/${loc:t}
zftp put $rem <$loc || stat=1
done
else
zftp put $2 <$1 || stat=$?
fi
(( $do_close )) && zfclose
return $stat
}
function zfput {
# Simple put: dump every file under the same name, but stripping
# off any directory parts.
local loc rem stat=0
local loc rem
integer stat do_close
zfautocheck
for loc in $*; do
rem=${loc:t}
zftp put $rem <$loc
[[ $? == 0 ]] || stat=$?
done
(( $do_close )) && zfclose
return $stat
}
@ -764,13 +971,16 @@ function zfrglob {
# globbing characters, and if extendedglob is set and we are
# using zsh for the actual pattern matching also look for
# extendedglob characters.
if [[ $remlist != *[][*?]* &&
( -n $zfrglob || ! -o extendedglob || $remlist != *[(|)~#^]* ) ]]; then
if [[ $pat != *[][*?]* &&
( -n $zfrglob || ! -o extendedglob || $pat != *[(|)#^]* ) ]]; then
return 0
fi
local tmpf={$TMPPREFIX}zfrglob$$
if [[ $zfrglob != '' ]]; then
eval "$1=(\$(zftp ls \"$pat\" 2>/dev/null))"
zftp ls "$pat" >$tmpf 2>/dev/null
eval "$1=(\$(<\$tmpf))"
rm -f $tmpf
else
if [[ $ZFTP_SYSTEM = UNIX* && $pat = */* ]]; then
# not the current directory and we know how to handle paths
@ -781,12 +991,18 @@ function zfrglob {
dir=/
fi
nondir=${pat##*/}
files=($(zftp ls "$dir" 2>/dev/null))
zftp ls "$dir" 2>/dev/null >$tmpf
files=($(<$tmpf))
files=(${files:t})
rm -f $tmpf
else
# we just have to do an ls and hope that's right
nondir=$pat
if (( $#zftp_fcache == 0 )); then
zftp_fcache=($(zftp ls))
# Why does `zftp_fcache=($(zftp ls))' sometimes not work?
zftp ls >$tmpf
zftp_fcache=($(<$tmpf))
rm -f $tmpf
fi
files=($zftp_fcache)
fi
@ -848,7 +1064,7 @@ function zfrtime {
function zfstat {
# Give a zftp status report using local variables.
# With option -v, connect the remote host and ask it what it
# With option -v, connect to the remote host and ask it what it
# thinks the status is.
setopt localoptions unset
@ -874,10 +1090,6 @@ function zfstat {
shift
done
# hack: in case the status from a subshell process hasn't been
# fixed yet
zftp type >&/dev/null
if [[ -n $ZFTP_HOST ]]; then
print "Host:\t\t$ZFTP_HOST"
print "IP:\t\t$ZFTP_IP"
@ -907,12 +1119,14 @@ function zfstat {
fi
else
print "Not connected."
[[ -n $zflastsession ]] && print "Last session:\t$zflastsession"
stat=1
fi
# things which may be set even if not connected:
[[ -n $ZFTP_REPLY ]] && print "Last reply:\t$ZFTP_REPLY"
print "Verbosity:\t$ZFTP_VERBOSE"
print "Timeout:\t$ZFTP_TMOUT"
print -n "Preferences:\t"
for (( i = 1; i <= ${#ZFTP_PREFS}; i++ )); do
case $ZFTP_PREFS[$i] in
@ -928,6 +1142,7 @@ function zfstat {
print
if [[ -n $ZFTP_HOST && $verbose = 1 ]]; then
zfautocheck -d
print "Status of remote server:"
# make sure we print the reply
local ZFTP_VERBOSE=045
@ -939,8 +1154,6 @@ function zfstat {
function zftp_chpwd {
# You may want to alter chpwd to call this when $ZFTP_USER is set.
# If so, call it with a non-zero first argument so it doesn't
# print the new FTP directory.
# Cancel the filename cache for the current directory.
zftp_fcache=()
@ -948,26 +1161,26 @@ function zftp_chpwd {
# As this function is called when we close the connection, this
# is the only place we need to do these two things.
[[ -n $zfcurdir && -f $zfcurdir ]] && rm -f $zfcurdir
zfotherargs=
if [[ -z $ZFTP_USER ]]; then
# last call, after an FTP logout
# delete the non-current cached directory
[[ -n $zfotherdir && -f $zfotherdir ]] && rm -f $zfotherdir
zfotherargs=
# don't keep zflastdir between opens
# don't keep zflastdir between opens (do keep zflastsession)
zflastdir=
# return the display to standard
# uncomment the following line if you have a chpwd which shows directories
# chpwd
chpwd
else
[[ -z $zflastdir ]] && zflastdir=$ZFTP_PWD
[[ -n $ZFTP_PWD ]] && zflastdir=$ZFTP_PWD
zflastsession="$ZFTP_HOST:$ZFTP_PWD"
local args
if [[ -t 1 && -t 2 ]]; then
local str="$ZFTP_HOST:$ZFTP_PWD"
[[ -z $1 ]] && print $str
local str=$zflastsession
[[ ${#str} -lt 70 ]] && str="%m: %~ $str"
case $TERM in
sun-cmd) print -n -P "\033]l$str\033\\"
@ -999,10 +1212,14 @@ function zftp_progress {
}
function zftype {
local type
local type zftmp=${TMPPREFIX}zftype$$
zfautocheck -d
if (( $# == 0 )); then
type=$(zftp type)
zftp type >$zftmp
type=$(<$zftmp)
rm -f $zftmp
if [[ $type = I ]]; then
print "Current type is image (binary)"
return 0
@ -1054,8 +1271,9 @@ function zfuget {
setopt localoptions
unsetopt ksharrays shwordsplit
local loc rem stat=0 locstats remstats doit tmpfile=${TMPPREFIX}zfuget$$
local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuget$$
local rstat remlist verbose optlist opt bad i silent nglob time
integer stat do_close
zfuget_print_time() {
local tim=$1
@ -1097,6 +1315,8 @@ function zfuget {
[[ -n $bad ]] && return 1
zfautocheck
for remlist in $*; do
# zfcd directory hack to put the front back to ~
if [[ $remlist == $HOME || $remlist == $HOME/* ]]; then
@ -1166,6 +1386,9 @@ function zfuget {
done
fi
done
(( do_close )) && zfclose
return $stat
}
@ -1183,8 +1406,9 @@ function zfuput {
setopt localoptions
unsetopt ksharrays shwordsplit
local loc rem stat=0 locstats remstats doit tmpfile=${TMPPREFIX}zfuput$$
local loc rem locstats remstats doit tmpfile=${TMPPREFIX}zfuput$$
local rstat verbose optlist opt bad i silent
integer stat do_close
zfuput_print_time() {
local tim=$1
@ -1222,6 +1446,8 @@ function zfuput {
[[ -n $bad ]] && return 1
zfautocheck
if [[ $ZFTP_VERBOSE = *5* ]]; then
# should we turn it off locally?
print "Messages with code 550 are harmless." >&2
@ -1277,5 +1503,8 @@ function zfuput {
zftp put $rem <$loc || stat=$?
fi
done
(( do_close )) && zfclose
return $stat
}

View file

@ -554,7 +554,7 @@ zfgetline(char *ln, int lnsize, int tmout)
if (setjmp(zfalrmbuf)) {
alarm(0);
zwarnnam("zftp", "timeout getting response", NULL, 0);
return 5;
return 6;
}
zfalarm(tmout);
@ -676,7 +676,7 @@ zfgetmsg()
int stopit, printing = 0, tmout;
if (zcfd == -1)
return 5;
return 6;
if (!(verbose = getsparam("ZFTP_VERBOSE")))
verbose = "";
zsfree(lastmsg);
@ -763,7 +763,7 @@ zfgetmsg()
zfclose();
/* unexpected, so tell user */
zwarnnam("zftp", "remote server has closed connection", NULL, 0);
return 6; /* pretend it failed, because it did */
return 6;
}
if (lastcode == 530) {
/* user not logged in */
@ -802,20 +802,21 @@ zfsendcmd(char *cmd)
int ret, tmout;
if (zcfd == -1)
return 5;
return 6;
tmout = getiparam("ZFTP_TMOUT");
if (setjmp(zfalrmbuf)) {
alarm(0);
zwarnnam("zftp", "timeout sending message", NULL, 0);
return 5;
return 6;
}
zfalarm(tmout);
ret = write(zcfd, cmd, strlen(cmd));
alarm(0);
if (ret <= 0) {
zwarnnam("zftp send", "failed sending control message", NULL, 0);
return 5; /* FTP status code */
zwarnnam("zftp send", "failure sending control message: %e",
NULL, errno);
return 6;
}
return zfgetmsg();
@ -1023,11 +1024,11 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
/* accept the connection */
len = sizeof(zdsock);
newfd = zfmovefd(accept(zdfd, (struct sockaddr *)&zdsock, &len));
if (newfd < 0)
zwarnnam(name, "unable to accept data: %e", NULL, errno);
zfclosedata();
if (newfd < 0) {
zwarnnam(name, "unable to accept data.", NULL, 0);
if (newfd < 0)
return 1;
}
zdfd = newfd; /* this is now the actual data fd */
} else {
/*
@ -1270,7 +1271,7 @@ zfread_block(int fd, char *bf, size_t sz, int tmout)
n = zfread(fd, (char *)&hdr, sizeof(hdr), tmout);
} while (n < 0 && errno == EINTR);
if (n != 3 && !zfdrrrring) {
zwarnnam("zftp", "failed to read FTP block header", NULL, 0);
zwarnnam("zftp", "failure reading FTP block header", NULL, 0);
return n;
}
/* size is stored in network byte order */
@ -1324,7 +1325,7 @@ zfwrite_block(int fd, char *bf, size_t sz, int tmout)
n = zfwrite(fd, (char *)&hdr, sizeof(hdr), tmout);
} while (n < 0 && errno == EINTR);
if (n != 3 && !zfdrrrring) {
zwarnnam("zftp", "failed to write FTP block header", NULL, 0);
zwarnnam("zftp", "failure writing FTP block header", NULL, 0);
return n;
}
bfptr = bf;

View file

@ -261,15 +261,19 @@ struct cline {
int llen; /* length of line */
char *word; /* prefered string to insert */
int wlen; /* length of word */
Cmatcher matcher; /* which matcher was used */
int flags; /* see CLF_* below */
Cline prefix; /* prefix we've build for new parts */
Cline suffix; /* suffix we've build for new parts */
};
#define CLF_END 1
#define CLF_MID 2
#define CLF_MISS 4
#define CLF_DIFF 8
#define CLF_SUF 16
#define CLF_END 1
#define CLF_MID 2
#define CLF_MISS 4
#define CLF_DIFF 8
#define CLF_SUF 16
#define CLF_NEW 32
#define CLF_VAR 64
#define CLF_JOIN 128
/* Flags for makecomplist*(). Things not to do. */

View file

@ -1685,6 +1685,10 @@ bin_compadd(char *name, char **argv, char *ops, int func)
return 1;
}
for (; *argv && **argv == '-'; argv++) {
if (!(*argv)[1]) {
argv++;
break;
}
for (p = *argv + 1; *p; p++) {
sp = NULL;
dm = 0;
@ -1945,9 +1949,9 @@ restrict_range(int b, int e)
pparams = p;
zsfree(compcontext);
if ((compcurrent -= b + 1))
compcontext = ztrdup("arg");
compcontext = ztrdup("argument");
else
compcontext = ztrdup("cmd");
compcontext = ztrdup("command");
}
/**/

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,13 @@
#include "zsh.mdh"
#include "cond.pro"
int tracingcond;
static char *condstr[COND_MOD] = {
"!", "&&", "||", "==", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
"-ne", "-lt", "-gt", "-le", "-ge"
};
/**/
int
evalcond(Cond c)
@ -38,11 +45,23 @@ evalcond(Cond c)
switch (c->type) {
case COND_NOT:
if (tracingcond)
fprintf(stderr, " %s", condstr[c->type]);
return !evalcond(c->left);
case COND_AND:
return evalcond(c->left) && evalcond(c->right);
if (evalcond(c->left)) {
if (tracingcond)
fprintf(stderr, " %s", condstr[c->type]);
return evalcond(c->right);
} else
return 0;
case COND_OR:
return evalcond(c->left) || evalcond(c->right);
if (!evalcond(c->left)) {
if (tracingcond)
fprintf(stderr, " %s", condstr[c->type]);
return evalcond(c->right);
} else
return 1;
case COND_MOD:
case COND_MODI:
{
@ -58,6 +77,9 @@ evalcond(Cond c)
return 0;
}
}
if (tracingcond)
tracemodcond((char *)c->left, (char **)c->right,
c->type == COND_MODI);
return cd->handler((char **) c->right, cd->condid);
}
else {
@ -71,6 +93,8 @@ evalcond(Cond c)
zerr("unrecognized condition: `%s'", (char *) c->left, 0);
return 0;
}
if (tracingcond)
tracemodcond((char *)c->left, a, c->type == COND_MODI);
a[0] = (char *) c->left;
return cd->handler(a, cd->condid);
} else
@ -86,6 +110,20 @@ evalcond(Cond c)
if (c->type != COND_STREQ && c->type != COND_STRNEQ)
untokenize(c->right);
}
if (tracingcond) {
if (c->type < COND_MOD) {
char *rt = (char *)c->right;
if (c->type == COND_STREQ || c->type == COND_STRNEQ) {
rt = dupstring(rt);
untokenize(rt);
}
fprintf(stderr, " %s %s %s", (char *)c->left, condstr[c->type],
rt);
} else
fprintf(stderr, " -%c %s", c->type, (char *)c->left);
}
switch (c->type) {
case COND_STREQ:
return matchpat(c->left, c->right);
@ -294,3 +332,21 @@ cond_match(char **args, int num, char *str)
return matchpat(str, s);
}
/**/
static void
tracemodcond(char *name, char **args, int inf)
{
char **aptr;
MUSTUSEHEAP("tracemodcond");
args = duparray(args, (VFunc) dupstring);
for (aptr = args; *aptr; aptr++)
untokenize(*aptr);
if (inf) {
fprintf(stderr, " %s %s %s", args[0], name, args[1]);
} else {
fprintf(stderr, " %s", name);
while (*args)
fprintf(stderr, " %s", *args++);
}
}

View file

@ -1208,7 +1208,7 @@ addvars(LinkList l, int export)
addlinknode(vl, v->str);
} else
vl = v->arr;
prefork(vl, v->type == PM_SCALAR ? 7 : 3);
prefork(vl, v->type == PM_SCALAR ? (PF_SINGLE|PF_ASSIGN) : PF_ASSIGN);
if (errflag)
return;
if (isset(GLOBASSIGN) || v->type != PM_SCALAR)
@ -1356,7 +1356,7 @@ execcmd(Cmd cmd, int input, int output, int how, int last1)
}
/* Do prefork substitutions */
prefork(args, assign ? 2 : isset(MAGICEQUALSUBST));
prefork(args, (assign || isset(MAGICEQUALSUBST)) ? PF_TYPESET : 0);
if (type == SIMPLE) {
int unglobbed = 0;
@ -2519,13 +2519,26 @@ spawnpipes(LinkList l)
}
}
extern int tracingcond;
/* evaluate a [[ ... ]] */
/**/
static int
execcond(Cmd cmd)
{
return !evalcond(cmd->u.cond);
int stat;
if (isset(XTRACE)) {
fprintf(stderr, "%s[[", prompt4 ? prompt4 : "");
tracingcond++;
}
stat = !evalcond(cmd->u.cond);
if (isset(XTRACE)) {
fprintf(stderr, " ]]\n");
fflush(stderr);
tracingcond--;
}
return stat;
}
/* evaluate a ((...)) arithmetic command */
@ -2537,8 +2550,17 @@ execarith(Cmd cmd)
char *e;
long val = 0;
while ((e = (char *) ugetnode(cmd->args)))
if (isset(XTRACE))
fprintf(stderr, "%s((", prompt4 ? prompt4 : "");
while ((e = (char *) ugetnode(cmd->args))) {
if (isset(XTRACE))
fprintf(stderr, " %s", e);
val = matheval(e);
}
if (isset(XTRACE)) {
fprintf(stderr, " ))\n", stderr);
fflush(stderr);
}
errflag = 0;
return !val;
}
@ -2613,6 +2635,18 @@ execshfunc(Cmd cmd, Shfunc shf)
deletejob(jobtab + thisjob);
}
if (isset(XTRACE)) {
LinkNode lptr;
fprintf(stderr, "%s", prompt4 ? prompt4 : prompt4);
for (lptr = firstnode(cmd->args); lptr; incnode(lptr)) {
if (lptr != firstnode(cmd->args))
fputc(' ', stderr);
fprintf(stderr, "%s", (char *)getdata(lptr));
}
fputc('\n', stderr);
fflush(stderr);
}
doshfunc(shf->nam, shf->funcdef, cmd->args, shf->flags, 0);
if (!list_pipe)

View file

@ -1810,7 +1810,7 @@ xpandredir(struct redir *fn, LinkList tab)
fake = newlinklist();
addlinknode(fake, fn->name);
/* ...which undergoes all the usual shell expansions */
prefork(fake, isset(MULTIOS) ? 0 : 4);
prefork(fake, isset(MULTIOS) ? 0 : PF_SINGLE);
/* Globbing is only done for multios. */
if (!errflag && isset(MULTIOS))
globlist(fake);

View file

@ -568,8 +568,10 @@ createparam(char *name, int flags)
if (isset(ALLEXPORT) && !oldpm)
flags |= PM_EXPORTED;
} else
} else {
pm = (Param) alloc(sizeof *pm);
pm->nam = nulstring;
}
pm->flags = flags;
if(!(pm->flags & PM_SPECIAL))
@ -1835,6 +1837,12 @@ arrhashsetfn(Param pm, char **val)
while (*aptr) {
/* The parameter name is ztrdup'd... */
v->pm = createparam(*aptr, PM_SCALAR|PM_UNSET);
/*
* createparam() doesn't return anything if the parameter
* already existed.
*/
if (!v->pm)
v->pm = (Param) paramtab->getnode(paramtab, *aptr);
zsfree(*aptr++);
/* ...but we can use the value without copying. */
setstrvalue(v, *aptr++);

View file

@ -42,11 +42,7 @@ char nulstring[] = {Nularg, '\0'};
* - Brace expansion
* - Tilde and equals substitution
*
* Bits 0 and 1 of flags are used in filesub.
* bit 0 is set when we are doing MAGIC_EQUALSUBST or normal
* assignment but not a typeset.
* bit 1 is set on a real assignment (both typeset and normal).
* bit 2 is a flag to paramsubst (single word sub)
* PF_* flags are defined in zsh.h
*/
/**/
@ -70,20 +66,22 @@ prefork(LinkList list, int flags)
return;
} else {
if (isset(SHFILEEXPANSION))
filesub((char **)getaddrdata(node), flags & 3);
if (!(node = stringsubst(list, node, flags & 4)))
filesub((char **)getaddrdata(node),
flags & (PF_TYPESET|PF_ASSIGN));
if (!(node = stringsubst(list, node, flags & PF_SINGLE)))
return;
}
}
for (node = firstnode(list); node; incnode(node)) {
if (*(char *)getdata(node)) {
remnulargs(getdata(node));
if (unset(IGNOREBRACES) && !(flags & 4))
if (unset(IGNOREBRACES) && !(flags & PF_SINGLE))
while (hasbraces(getdata(node)))
xpandbraces(list, &node);
if (unset(SHFILEEXPANSION))
filesub((char **)getaddrdata(node), flags & 3);
} else if (!(flags & 4))
filesub((char **)getaddrdata(node),
flags & (PF_TYPESET|PF_ASSIGN));
} else if (!(flags & PF_SINGLE))
uremnode(list, node);
if (errflag)
return;
@ -234,7 +232,7 @@ singsub(char **s)
foo = newlinklist();
addlinknode(foo, *s);
prefork(foo, 4);
prefork(foo, PF_SINGLE);
if (errflag)
return;
*s = (char *) ugetnode(foo);
@ -287,8 +285,10 @@ multsub(char **s, char ***a, int *isarr, char *sep)
return !l;
}
/* ~, = subs: assign = 2 => typeset; assign = 1 => something that looks
like an assignment but may not be; assign = 3 => normal assignment */
/*
* ~, = subs: assign & PF_TYPESET => typeset or magic equals
* assign & PF_ASSIGN => normal assignment
*/
/**/
void
@ -302,12 +302,8 @@ filesub(char **namptr, int assign)
if (!assign)
return;
if (assign < 3) {
if (assign & PF_TYPESET) {
if ((*namptr)[1] && (sub = strchr(*namptr + 1, Equals))) {
if (assign == 1)
for (ptr = *namptr; ptr != sub; ptr++)
if (!iident(*ptr) && !INULL(*ptr))
return;
str = sub + 1;
if ((sub[1] == Tilde || sub[1] == Equals) && filesubstr(&str, assign)) {
sub[1] = '\0';

View file

@ -2261,7 +2261,7 @@ duplist(LinkList l, VFunc func)
}
/**/
static char **
char **
duparray(char **arr, VFunc func)
{
char **ret, **rr;

View file

@ -950,6 +950,11 @@ struct param {
#define SUB_ALL 0x0100 /* match complete string */
#define SUB_GLOBAL 0x0200 /* global substitution ${..//all/these} */
/* Flags as the second argument to prefork */
#define PF_TYPESET 0x01 /* argument handled like typeset foo=bar */
#define PF_ASSIGN 0x02 /* argument handled like the RHS of foo=bar */
#define PF_SINGLE 0x04 /* single word substitution */
/* node for named directory hash table (nameddirtab) */
struct nameddir {

3
config.guess vendored
View file

@ -526,6 +526,9 @@ EOF
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`

View file

@ -1036,7 +1036,7 @@ char *argv[];
#
sni_cc_version=`$CC -V 2>&1 | head -1`
case "$sni_cc_version" in
CDS* )
*CDS* )
EXTRA_LDFLAGS="${EXTRA_LDFLAGS=-Wl,-Blargedynsym}"
;;
* )

View file

@ -445,3 +445,61 @@ new-style completions: not posted
Me: 5281 now works, 5364
Me: make dependencies for main.o, Makemod, zshpaths.h, 5365
pws-9
Bart: CVS should ignore version.h, 5367
Oliver Kiddle: another change of mailing list host, 5372
Oliver: compctl -T documentation for ~dirs, 5374
Andrej: Reliant UNIX configuration, 5377
Sven: Manual for new completion (so far), 5384, 5397
Me: dump new completion status for fast initialisation, 5393
Me: bug fixlet for __path_files, 5398
Sven: overhaul of do_ambiguous with some bug-fixage, 5399, 5407
Sven: print needs - in Functions/Completion/dump, 5400; auto-dump and use
$COMPDUMP file, 5402
Sven: files -> __files, 5401
Me: magicequalsubst now affects all arguments ...=~...:~..., 5403
Me: set -x output for [[ ... ]], 5408
Me: IRIX 6.5 problems in Etc/MACHINES (see 5410 from Helmut Jarausch).
Sven: 5412: better matcher control.
Sven: 5415: anchors in matchers shouldn't match variable part of completion
Sven: 5417: multiple subscripts with undefined array
Sven: 5418: small addmatches fixes
Me: 5421: setting same element of assoc array in full array assignment crashed
Sven: 5422: braces in completions were not tokenized; array parameters were
used uncopied
Sven: 5423: compadd accepts either - or -- to end options
Sven: 5424: addmatches fix when not doing matching
Me: 5425: fix pattern matching for new completion
Sven: 5429: $CONTEXT strings
Sven: 5430: rewrite Functions/Completions with simplified syntax (no #array
type completions).
Me: 5436: set -x for function calls and ((...)).
Me: unposted (but see 5440): zftp changes: more return 6's, functions now
do auto-open and avoid subshells.