mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-16 20:58:05 +02:00
zsh-3.1.5-pws-1
This commit is contained in:
parent
32c2ebbaa5
commit
a61dc2074a
44 changed files with 4986 additions and 1444 deletions
Config
Doc/Zsh
Misc
Src
.lastlocMakefile.in
acconfig.haczsh.m4configure.inModules
Zle
.lastloccomp.hcomp1.ccomp1.exportcomp1.mddcompctl.cdeltochar.ciwidgets.listzle.exportzle.hzle.mddzle_hist.czle_main.czle_misc.czle_refresh.czle_thingy.czle_tricky.czle_utils.czle_vi.c
builtin.cexec.cglob.cjobs.cmkmakemod.shmodentry.cmodule.csystem.hutils.czsh.exportzsh.hzsh.mdd
|
@ -56,6 +56,8 @@ EXELDFLAGS = @EXELDFLAGS@
|
|||
LIBS = @LIBS@
|
||||
DL_EXT = @DL_EXT@
|
||||
DLLD = @DLLD@
|
||||
EXPOPT = @EXPOPT@
|
||||
IMPOPT = @IMPOPT@
|
||||
|
||||
# utilities
|
||||
AWK = @AWK@
|
||||
|
|
|
@ -10,6 +10,7 @@ list(tt(compctl) [ tt(-CDT) ] var(options) \
|
|||
[ tt(-x) var(pattern) var(options) tt(-) ... tt(--) ] \
|
||||
[ tt(PLUS()) var(options) [ tt(-x) ... tt(--) ] ... [tt(PLUS())] ] \
|
||||
[ var(command) ... ])
|
||||
list(tt(compctl) tt(-M) var(match-specs) ...)
|
||||
list(tt(compctl) tt(-L) [ tt(-CDT) ] [ var(command) ... ])
|
||||
list(tt(compctl) tt(PLUS()) var(command) ...)
|
||||
endlist()
|
||||
|
@ -28,6 +29,7 @@ menu(Command Flags)
|
|||
menu(Option Flags)
|
||||
menu(Alternative Completion)
|
||||
menu(Extended Completion)
|
||||
menu(Matching Control)
|
||||
menu(Example)
|
||||
endmenu()
|
||||
texinode(Command Flags)(Option Flags)()(Programmable Completion)
|
||||
|
@ -44,7 +46,19 @@ item(var(command) ...)(
|
|||
controls completion for the named commands, which must be listed last
|
||||
on the command line. If completion is attempted for a command with a
|
||||
pathname containing slashes and no completion definition is found, the
|
||||
search is retried with the last pathname component. Note that aliases
|
||||
search is retried with the last pathname component. If the command starts
|
||||
with a tt(=), completion is tried with the pathname of the command.
|
||||
|
||||
The strings may also be patterns (i.e. they may contain an unquoted
|
||||
occurrence of characters used to form patterns in the shell). When
|
||||
completion is attempted, the shell first tries all such pattern compctls.
|
||||
If one matches the command name on the line or if the pathname of the
|
||||
command on the line matches a pattern, it is used. The patterns are tested
|
||||
in reverse order, i.e. the pattern compctl defined last overrides all
|
||||
previously defined pattern compctls. Unless the option list of that compctl
|
||||
contains an tt(-t) flag with a \tt(c) character, no more compctls are tried.
|
||||
|
||||
Note that aliases
|
||||
are expanded before the command name is determined unless the
|
||||
tt(COMPLETE_ALIASES) option is set. Commands should not be combined
|
||||
with the tt(-C), tt(-D) or tt(-T) flags.
|
||||
|
@ -63,7 +77,7 @@ been issued, filenames are completed.
|
|||
item(tt(-T))(
|
||||
supplies completion flags to be used before any other processing is
|
||||
done, even those given to specific commands with other compctl
|
||||
definitions. This is only useful when combined with extended
|
||||
definitions. This is especially useful when combined with extended
|
||||
completion (the tt(-x) flag, see noderef(Extended Completion) below).
|
||||
Using this flag you can define default behavior
|
||||
which will apply to all commands without exception, or you can alter
|
||||
|
@ -95,6 +109,9 @@ If the tt(PLUS()) flag is alone and followed immediately by the var(command)
|
|||
list, the completion behavior for all the commands in the list is reset to
|
||||
the default. In other words, completion will subsequently use the
|
||||
options specified by the tt(-D) flag.
|
||||
|
||||
The form with tt(-M) as the first and only option defines global
|
||||
matching specifications described below in noderef(Matching Control).
|
||||
texinode(Option Flags)(Alternative Completion)(Command Flags)(Programmable Completion)
|
||||
sect(Option Flags)
|
||||
startlist()
|
||||
|
@ -106,6 +123,8 @@ list([ tt(-Q) ] [ tt(-P) var(prefix) ] [ tt(-S) var(suffix) ])
|
|||
list([ tt(-W) var(file-prefix) ])
|
||||
list([ tt(-q) ] [ tt(-X) var(explanation) ] [ tt(-Y) var(explanation) ])
|
||||
list([ tt(-y) var(func-or-var) ] [ tt(-l) var(cmd) ] [ tt(-U) ])
|
||||
list([ tt(-t) var(continue) ] [ tt(-J) var(name) ] [ tt(-V) var(name) ])
|
||||
list([ tt(-M) var(match-spec) ])
|
||||
endlist()
|
||||
|
||||
The remaining var(options) specify the type of command arguments
|
||||
|
@ -256,7 +275,7 @@ passed two arguments: the prefix and the suffix of the word on which
|
|||
completion is to be attempted, in other words those characters before
|
||||
the cursor position, and those from the cursor position onwards. The
|
||||
whole command line can be accessed with the tt(-c) and tt(-l) flags
|
||||
of the tt(read) builtin. The
|
||||
of the tt(read) builtin. The
|
||||
function should set the variable tt(reply) to an array containing
|
||||
the completions (one completion per element); note that tt(reply)
|
||||
should not be made local to the function. From such a function the
|
||||
|
@ -322,6 +341,9 @@ nofill(tt(compctl -/ -W ~/Mail maildirs))
|
|||
|
||||
completes any subdirectories to any depth beneath the directory
|
||||
tt(~/Mail), although that prefix does not appear on the command line.
|
||||
The var(suffix) may also be of the form accepted by the tt(-k) flag, i.e.
|
||||
the name of an array or a literal list in parenthesis. In this cases all
|
||||
words are used as prefixes.
|
||||
)
|
||||
item(tt(-q))(
|
||||
If used with a suffix as specified by the tt(-S) option, this
|
||||
|
@ -331,7 +353,7 @@ tt(AUTO_REMOVE_SLASH) option). The option is most useful for list
|
|||
separators (comma, colon, etc.).
|
||||
)
|
||||
item(tt(-l) var(cmd))(
|
||||
This option cannot be combined with any other. It restricts the range
|
||||
This option restricts the range
|
||||
of command line words that are considered to be arguments. If
|
||||
combined with one of the extended completion patterns `tt(p[)...tt(])',
|
||||
`tt(r[)...tt(])', or `tt(R[)...tt(])' (see noderef(Extended Completion)
|
||||
|
@ -355,7 +377,10 @@ will be deleted. This is most useful with a function (given by the
|
|||
tt(-K) option) which can examine the word components passed to it
|
||||
(or via the tt(read) builtin's tt(-c) and tt(-l) flags) and
|
||||
use its own criteria to decide what matches. If there is no
|
||||
completion, the original word is retained.
|
||||
completion, the original word is retained. Since the produced
|
||||
possible completions seldom seldom have interesting common prefixes
|
||||
and suffixes, menucompletion is started immediatly if tt(AUTO_MENU) is
|
||||
set and this flag is used.
|
||||
)
|
||||
item(tt(-y) var(func-or-var))(
|
||||
The list provided by var(func-or-var) is displayed instead of the list
|
||||
|
@ -382,6 +407,8 @@ Print var(explanation) when trying completion on the current set of
|
|||
options. A `tt(%n)' in this string is replaced by the number of matches.
|
||||
The explanation only appears if completion was tried and there was
|
||||
no unique match, or when listing completions.
|
||||
The sequences tt(%B), tt(%b), tt(%S), tt(%s), tt(%U), and tt(%u) specify
|
||||
output attributes (bold, standout, and underline) as in prompts.
|
||||
)
|
||||
item(tt(-Y) var(explanation))(
|
||||
Identical to tt(-X), except that the var(explanation) first undergoes
|
||||
|
@ -389,6 +416,37 @@ expansion following the usual rules for strings in double quotes.
|
|||
The expansion will be carried out after any functions are called for
|
||||
the tt(-K) or tt(-y) options, allowing them to set variables.
|
||||
)
|
||||
item(tt(-J))(
|
||||
This gives the name of the group the matches should be placed in. Groups
|
||||
are listed and sorted separately. Also, menucompletion will offer the matches
|
||||
in the groups in the order, in which the groups were defined. If no group
|
||||
name is explicitly given, the matches are stored in a group named var(default).
|
||||
The first time a group name is encountered, a group with that name is created.
|
||||
After that all matches with the same group name are stored in that group.
|
||||
)
|
||||
item(tt(-V))(
|
||||
Like tt(-J), but the matches in the group will not be sorted in the listing and
|
||||
with menucompletion. These unsorted groups are in a different name space than
|
||||
the sorted ones. I.e. it is possible to have a sorted and a unsorted group
|
||||
with the same name and the matches in those groups will not be mixed.
|
||||
)
|
||||
item(tt(-t) var(continue))(
|
||||
The var(continue)-string contains a set of characters that specify if
|
||||
and when completion should continue to produce matches where it normally
|
||||
would not do that. The character tt(c) means that completion continues
|
||||
with the next suitable compctl (i.e. if you don't specify this in a
|
||||
tt(compctl -T), compctls for commands are never used). The character
|
||||
tt(PLUS()) is used to continue with the matches for the next alternative
|
||||
completion (see below). The characters tt(-) and tt(x) may be used in
|
||||
sub-lists for extended completion (see below). They will make the completion
|
||||
code use the flag list after the next tt(-) (if the corresponding pattern
|
||||
matches) and the default flag list (those before the tt(-x)), respectively.
|
||||
)
|
||||
item(tt(-M) var(match-spec))(
|
||||
This defines additional matching control specifications that should be used
|
||||
only when testing words for the list of flags this flag appears in. The format
|
||||
of the var(match-spec) string is described below in noderef(Matching Control).
|
||||
)
|
||||
enditem()
|
||||
texinode(Alternative Completion)(Extended Completion)(Option Flags)(Programmable Completion)
|
||||
sect(Alternative Completion)
|
||||
|
@ -402,7 +460,9 @@ tried with the options before the first `tt(PLUS())'. If this produces no
|
|||
matches completion is tried with the flags after the `tt(PLUS())' and so on. If
|
||||
there are no flags after the last `tt(PLUS())' and a match has not been found
|
||||
up to that point, default completion is tried.
|
||||
texinode(Extended Completion)(Example)(Alternative Completion)(Programmable Completion)
|
||||
If the list of flags contains a tt(-t) with a tt(PLUS()) character, the next
|
||||
list of flags is used even if the current list produced matches.
|
||||
texinode(Extended Completion)(Matching Control)(Alternative Completion)(Programmable Completion)
|
||||
sect(Extended Completion)
|
||||
startlist()
|
||||
list(tt(compctl) [ tt(-CDT) ] var(options) \
|
||||
|
@ -498,13 +558,187 @@ var(max) inclusive.
|
|||
item(tt(r[)var(str1)tt(,)var(str2)tt(])...)(
|
||||
Matches if the cursor is after a word with prefix var(str1). If there
|
||||
is also a word with prefix var(str2) on the command line it matches
|
||||
only if the cursor is before this word.
|
||||
only if the cursor is before this word. If the comma and var(str2) are
|
||||
omitted, it matches if the cursor is after a word with prefix var(str1).
|
||||
)
|
||||
item(tt(R[)var(str1)tt(,)var(str2)tt(])...)(
|
||||
Like tt(r) but using pattern matching instead.
|
||||
)
|
||||
enditem()
|
||||
texinode(Example)()(Extended Completion)(Programmable Completion)
|
||||
texinode(Matching Control)(Example)(Extended Completion)(Programmable Completion)
|
||||
sect(Matching Control)
|
||||
|
||||
Matching specifications are used to describe that certain strings
|
||||
on the command line match possibly different strings in the words produced
|
||||
by the completion code.
|
||||
|
||||
Matching specification strings consist of one or more matching
|
||||
descriptions separated by whitespace. Each description consists of
|
||||
a letter followed by a colon and the patterns describing which character
|
||||
sequences on the line match which character sequences in the words.
|
||||
|
||||
The letters understood are: tt(l), tt(r), tt(m), tt(L), tt(R), and tt(M).
|
||||
startitem()
|
||||
item(tt(m) and tt(M))(
|
||||
These describe patterns that match anywhere in the words. The colon should
|
||||
be followed by two patterns separated by an equal sign. The pattern on the
|
||||
left side describes the substrings that are to be matched on the command line,
|
||||
the pattern on the right side describes the substrings matched in the word.
|
||||
)
|
||||
item(tt(l) and tt(L))(
|
||||
These letters are for patterns that are anchored by another pattern on
|
||||
the left side. In this case the colon has to be followed by the pattern
|
||||
for the anchor, a pipe symbol, the pattern for the command line, an equal
|
||||
sign, and the pattern for the word. Patterns anchored on the left side match
|
||||
only if the anchor-pattern matches directly before the line pattern and if
|
||||
the string in the word before the word pattern matches the string before
|
||||
the line pattern in the line string.
|
||||
)
|
||||
item(tt(r) and tt(R))(
|
||||
Like tt(l) and tt(L) with the difference that the line and word patterns
|
||||
are anchored on the right side. Also, here the pattern for the anchor has
|
||||
to come after the pattern for the line, again separated by a pipe symbol.
|
||||
)
|
||||
enditem()
|
||||
|
||||
Each pattern is either an empty string or consists of a sequence of
|
||||
character (possibly quoted), question marks, character classes, and
|
||||
correspondence classes. Normal characters match only themselves, question
|
||||
marks match any character, and character classes are formed as for
|
||||
globbing and match the same characters as there.
|
||||
Correspondence classes are formed like character classes with two
|
||||
differences: they are delimited by a pair of braces and negated
|
||||
classes are not allowed (i.e. the characters tt(!) and tt(^) have no
|
||||
special meaning directly after the opening brace).
|
||||
|
||||
Correspondence classes are used to conveniently describe that several
|
||||
characters on the line match several other characters in the word. For
|
||||
example, if you want to define the any lowercase letter on the line
|
||||
matches the corresponding uppercase letter in the word all you need to
|
||||
write down is: `tt(m:{a-z}={A-Z})'. More than one correspondence class
|
||||
may be given on either side of the equal sign, in this case the first
|
||||
class on the left says which character matches for the first class on
|
||||
the right, the second class on either side work together, and so on.
|
||||
If one side has more such classes than the other side, the superfluous
|
||||
classes behave like normal character classes. In anchor patterns
|
||||
correspondence classes always behave like normal character classes.
|
||||
|
||||
The word pattern may also be a single star (tt(*)). This means that
|
||||
the line pattern matches any number of characters in the word. In this
|
||||
case the pattern has to be anchored (on any side) and the line pattern
|
||||
matches all characters in the word up to a character sequence that
|
||||
matches the anchor.
|
||||
|
||||
For anchors the empty string as a pattern has a special meaning. Such
|
||||
empty anchors match only the beginning (in the case of an left side
|
||||
anchor) or end (for right side anchors) of the command line string or
|
||||
word.
|
||||
|
||||
The distinction between the lowercase and the uppercase forms of the
|
||||
specification characters is used to define which matched substring
|
||||
should be put in the match and the generated command line. The
|
||||
lowercase forms use the substring from the word, so this should be
|
||||
used if the exact words produced by the completion code need to be
|
||||
used. The uppercase forms use the substring from the command line and
|
||||
should be used if the typed string need to be retained.
|
||||
|
||||
Examples:
|
||||
|
||||
startitem()
|
||||
The option tt(-o) produces option names in all-lowercase form, without
|
||||
underscores, and without the optional tt(no) at the beginning even
|
||||
though the buitlins tt(setopt) and tt(unsetopt) understand opotion
|
||||
names with uppercase letters, underscores, and the optional tt(no).
|
||||
So we want to be able to say, that in this case an prefix tt(no) and
|
||||
any underscore may be ignored when trying to match the produced words,
|
||||
and that uppercase letters on the line match the corresponding
|
||||
lowercase letters in the words. This can be done with:
|
||||
|
||||
indent(
|
||||
tt(compctl -M 'L:|[nN][oO]= M:_= M:{A-Z}={a-z}' -o setopt unsetopt)
|
||||
)
|
||||
|
||||
The first part says that the pattern `tt([nN][oO])' at the beginning
|
||||
(note the empty anchor before the pipe symbol) of the string on the
|
||||
line matches the the empty string in the produced words, i.e. it need
|
||||
not be there. The second part says that an underscore anywhere on the
|
||||
line need not be present in the word, and the third part uses
|
||||
correspondence classes as in the example above to say that any
|
||||
uppercase letter on the line matches the corresponding lowercase
|
||||
letter in the word. The use of the uppercase forms of the
|
||||
specification characters (tt(L) and tt(M)) guarantees that the special
|
||||
wrinting on the command line (and especially the option tt(no)) will
|
||||
not be erased.
|
||||
|
||||
As a second example we will make completion case insensitive. For this
|
||||
we use the form of tt(compctl) that defines matching specification that
|
||||
are to be used everywhere, i.e. a tt(compctl) with tt(-M) as the only
|
||||
option given.
|
||||
|
||||
The pattern needed was already explained above, this gives us:
|
||||
|
||||
indent(
|
||||
tt(compctl -M 'm:{a-z}={A-Z}')
|
||||
)
|
||||
|
||||
This makes lowercase letters match their uppercase counterparts. If we
|
||||
want to make uppercase letters match the lowercase forms, we would
|
||||
have to use:
|
||||
|
||||
indent(
|
||||
tt(compctl -M 'm:{a-z}={A-Z} m:{A-Z}={a-z}')
|
||||
)
|
||||
|
||||
A nice example for the use of tt(*) patterns is partial word
|
||||
completion. Sometimes you would like to make strings like tt(c.s.u)
|
||||
complete to strings like tt(comp.source.unix), i.e. you consider the
|
||||
word to consist of multiple parts (separated by the dot in the
|
||||
example) and each part should be completed separately. Defining such
|
||||
forms of matching is simple, for example if we want to separately
|
||||
complete word parts separated by dots, commas, underscores, and
|
||||
hyphens, we can do this by saying:
|
||||
|
||||
indent(
|
||||
tt(compctl -M 'r:|[.,_-]=* r:|=*')
|
||||
)
|
||||
|
||||
The first specification says that an empty string on the line before
|
||||
one of our special characters matches any number of characters in the
|
||||
word which has the effect we wanted. The second specification is
|
||||
needed to make this work when the cursor is in the middle of the word
|
||||
and the option tt(COMPLETE_IN_WORD) is set. In this case the
|
||||
completion code would normally try to match word that end with the
|
||||
string that is already on the command line, but in our example we
|
||||
would like the code to match words even if they contain extra
|
||||
characters after the string on the line. Hence we say that the empty
|
||||
string at the end of the string on the line matches any characters at
|
||||
the end of the word.
|
||||
|
||||
The form of tt(compctl) that defines the global matching
|
||||
specifications is a bit more powerful than described until now. It
|
||||
accepts not only one specification strin, but any number of them. When
|
||||
completion is attempted, the code first uses the definitions from the
|
||||
first string. If no words could be matched with these specifications,
|
||||
it tries the whole thing again with the specifications from the second
|
||||
string, and so on. This allows one to define simple and fast matches
|
||||
to be used first, more powerful matchers as a second choice, and so on.
|
||||
|
||||
As an example we would like to make the code match words that contain
|
||||
the string on the line as a substring (anywhere, not just at the
|
||||
beginning). But since this could produce more matches than we want,
|
||||
this should be tried only if the matchers described above don't
|
||||
produce any matches. E.g.:
|
||||
|
||||
indent(
|
||||
tt(compctl -M 'r:|[.,_-]=* r:|=*' 'l:|=* r:|=*')
|
||||
)
|
||||
|
||||
If using the first specification string does not produce matches, the
|
||||
second one is tried. The two descriptions it this string say that the
|
||||
empty string at the beginning and end of the string on the line
|
||||
matches any characters at the beginning or end of the word.
|
||||
enditem()
|
||||
texinode(Example)()(Matching Control)(Programmable Completion)
|
||||
sect(Example)
|
||||
nofill(tt(compctl -u -x 's[tt(PLUS())] c[-1,-f],s[-f+PLUS()]' -g '~/Mail/*(:t)' \
|
||||
- 's[-f],c[-1,-f]' -f -- mail))
|
||||
|
|
|
@ -777,6 +777,9 @@ Matches the enclosed pattern. This is used for grouping.
|
|||
If the tt(KSH_GLOB) option is set, then a
|
||||
`tt(@)', `tt(*)', `tt(+)', `tt(?)' or `tt(!)' immediately preceding
|
||||
the `tt(LPAR())' is treated specially, as detailed below.
|
||||
Note that grouping cannot currently extend over multiple directories:
|
||||
a `tt(/)' separating a directory terminates processing of the current
|
||||
group; processing resumes after the end of the group.
|
||||
)
|
||||
item(var(x)tt(|)var(y))(
|
||||
Matches either var(x) or var(y).
|
||||
|
@ -840,6 +843,43 @@ Match anything but the expression in parentheses.
|
|||
(Like `tt(LPAR()^LPAR())...tt(RPAR()RPAR())'.)
|
||||
)
|
||||
enditem()
|
||||
subsect(Globbing Flags)
|
||||
There are various flags which affect any text to their right up to the
|
||||
end of the enclosing group or to the end of the pattern; they require
|
||||
the tt(EXTENDED_GLOB) option. All take the form
|
||||
tt(LPAR()#)var(X)tt(RPAR()) where var(X) may be one of the following
|
||||
characters:
|
||||
|
||||
startitem()
|
||||
item(i)(
|
||||
Case insensitive: upper or lower case characters in the pattern match
|
||||
upper or lower case characters.
|
||||
)
|
||||
item(l)(
|
||||
Lower case characters in the pattern match upper or lower case
|
||||
characters; upper case characters in the pattern still only match
|
||||
upper case characters.
|
||||
)
|
||||
item(I)(
|
||||
Case sensitive: locally negates the effect of tt(i) or tt(l) from
|
||||
that point on.
|
||||
)
|
||||
enditem()
|
||||
|
||||
For example, the test string tt(fooxx) can be matched by the pattern
|
||||
tt(LPAR()#i)tt(RPAR()FOOXX), but not by tt(LPAR()#l)tt(RPAR()FOOXX),
|
||||
tt(LPAR()#i)tt(RPAR()FOO)tt(LPAR()#I)tt(RPAR()XX) or
|
||||
tt(LPAR()LPAR()#i)tt(RPAR()FOOX)tt(RPAR()X).
|
||||
|
||||
When using the ksh syntax for grouping both tt(KSH_GLOB) and
|
||||
tt(EXTENDED_GLOB) must be set and the left parenthesis should be
|
||||
preceded by tt(@). Note also that the flags do not affect letters
|
||||
inside tt([...]) groups, in other words tt(LPAR()#i)tt(RPAR()[a-z])
|
||||
still matches only lowercase letters. Finally, note that when
|
||||
examining whole paths case-insensitively every directory must be
|
||||
searched for all files which match, so that a pattern of the form
|
||||
tt(LPAR()#i)tt(RPAR()/foo/bar/...) is potentially slow.
|
||||
|
||||
subsect(Recursive Globbing)
|
||||
A pathname component of the form `tt(LPAR())var(foo)tt(/RPAR()#)'
|
||||
matches a path consisting of zero or more directories
|
||||
|
|
|
@ -157,6 +157,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) ])
|
||||
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:
|
||||
|
@ -184,6 +185,23 @@ 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(var(widget))(
|
||||
Invoke the specified widget. This can only be done when ZLE is
|
||||
active; normally this will be within a user-defined widget.
|
||||
|
|
|
@ -103,5 +103,14 @@ t :] [:]]#
|
|||
t [ [[]
|
||||
t ] []]
|
||||
t [] [^]]]
|
||||
t fooxx (#i)FOOXX
|
||||
f fooxx (#l)FOOXX
|
||||
t FOOXX (#l)fooxx
|
||||
f fooxx (#i)FOO(#I)X(#i)X
|
||||
t fooXx (#i)FOO(#I)X(#i)X
|
||||
t fooxx ((#i)FOOX)x
|
||||
f fooxx ((#i)FOOX)X
|
||||
f BAR (bar|(#i)foo)
|
||||
t FOO (bar|(#i)foo)
|
||||
EOT
|
||||
print "$failed tests failed."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/local/bin/zsh -f
|
||||
|
||||
setopt kshglob
|
||||
setopt kshglob extendedglob
|
||||
|
||||
failed=0
|
||||
while read res str pat; do
|
||||
|
@ -87,5 +87,14 @@ t zoox @(!(z*)|*x)
|
|||
t foo *(!(foo))
|
||||
f foob !(foo)b*
|
||||
t foobb !(foo)b*
|
||||
t fooxx (#i)FOOXX
|
||||
f fooxx (#l)FOOXX
|
||||
t FOOXX (#l)fooxx
|
||||
f fooxx (#i)FOO@(#I)X@(#i)X
|
||||
t fooXx (#i)FOO@(#I)X@(#i)X
|
||||
t fooxx @((#i)FOOX)x
|
||||
f fooxx @((#i)FOOX)X
|
||||
f BAR @(bar|(#i)foo)
|
||||
t FOO @(bar|(#i)foo)
|
||||
EOT
|
||||
print "$failed tests failed."
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
# Runs as a filter. Should ignore anything which isn't a "complete".
|
||||
# It expects each "complete" statement to be the first thing on a line.
|
||||
# All the examples in the tcsh manual give sensible results.
|
||||
# Author: Peter Stephenson <pws@ibmth.df.unipi.it>
|
||||
#
|
||||
# Option:
|
||||
# -x (exact): only applies in the case of command disambiguation (is
|
||||
|
@ -38,6 +39,11 @@
|
|||
# (5) Make sure all command names with wildcards are processed together --
|
||||
# they need to be lumped into one "compctl -C" or "compctl -D"
|
||||
# statement for zsh.
|
||||
# (6) Group completion (complete's g flag) is not built into zsh, so
|
||||
# you need perl to be available to generate the groups. If this
|
||||
# script is useful, I assume that's not a problem.
|
||||
# (7) I don't know what `completing completions' means, so the X
|
||||
# flag to complete is not handled.
|
||||
|
||||
# Handle options
|
||||
if (@ARGV) {
|
||||
|
@ -113,6 +119,13 @@ sub gettype {
|
|||
# Nothing (n) can be handled by returning nothing. (C.f. King Lear, I.i.)
|
||||
if ($c =~ /[abcjuv]/) {
|
||||
$ret = "-$c";
|
||||
} elsif ($c eq 'C') {
|
||||
if (defined($glob)) {
|
||||
$ret = "-W $glob -/g '*(.*)'";
|
||||
undef($glob);
|
||||
} else {
|
||||
$ret = '-c';
|
||||
}
|
||||
} elsif ($c eq 'S') {
|
||||
$ret = '-k signals';
|
||||
} elsif ($c eq 'd') {
|
||||
|
@ -121,18 +134,42 @@ sub gettype {
|
|||
} else {
|
||||
$ret = '-/';
|
||||
}
|
||||
} elsif ($c eq 'D') {
|
||||
if (defined($glob)) {
|
||||
$ret = "-W $glob -/";
|
||||
undef($glob);
|
||||
} else {
|
||||
$ret = '-/';
|
||||
}
|
||||
} elsif ($c eq 'e') {
|
||||
$ret = '-E';
|
||||
} elsif ($c eq 'f' && !$glob) {
|
||||
$ret = '-f';
|
||||
} elsif ($c eq 'F') {
|
||||
if (defined($glob)) {
|
||||
$ret = "-W $glob -f";
|
||||
undef($glob);
|
||||
} else {
|
||||
$ret = '-f';
|
||||
}
|
||||
} elsif ($c eq 'g') {
|
||||
$ret = "-s '\$(perl -e '\\''while ((\$name) = getgrent)\n" .
|
||||
"{ print \$name, \"\\n\"; }'\\'')'";
|
||||
} elsif ($c eq 'l') {
|
||||
$ret = q!-k "(`limit | awk '{print $1}'`)"!;
|
||||
} elsif ($c eq 'p') {
|
||||
$ret = "-W $glob -f", undef($glob) if defined($glob);
|
||||
$ret = "-W $glob -f", undef($glob) if defined($glob);
|
||||
} elsif ($c eq 's') {
|
||||
$ret = '-p';
|
||||
$ret = '-p';
|
||||
} elsif ($c eq 't') {
|
||||
$qual = '.';
|
||||
} elsif ($c eq 'T') {
|
||||
if (defined($glob)) {
|
||||
$ret = "-W $glob -g '*(.)'";
|
||||
undef($glob);
|
||||
} else {
|
||||
$ret = "-g '*(.)'";
|
||||
}
|
||||
} elsif ($c eq 'x') {
|
||||
$glob =~ s/'/'\\''/g;
|
||||
$ret = "-X '$glob'";
|
||||
|
@ -190,7 +227,7 @@ $" = " - ";
|
|||
|
||||
while (<>) {
|
||||
if (/^\s*complete\s/) {
|
||||
undef(@stuff);
|
||||
undef(@stuff);
|
||||
$default = '';
|
||||
$_ = $';
|
||||
while (/\\$/) {
|
||||
|
@ -211,7 +248,7 @@ while (<>) {
|
|||
# Loop over remaining arguments to "complete".
|
||||
$sep = substr($word,1,1);
|
||||
$sep =~ s/(\W)/\\$1/g;
|
||||
@split = split(/$sep/,$word);
|
||||
@split = split(/$sep/,$word,4);
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
while ($split[$i] =~ /\\$/) {
|
||||
substr($split[$i],-1,1) = "";
|
||||
|
@ -225,7 +262,9 @@ while (<>) {
|
|||
# The "complete" catch-all: treat this as compctl\'s
|
||||
# default (requiring no pattern matching).
|
||||
$default .= &gettype($type) . ' ';
|
||||
defined($suffix) && ($defsuf .= $suffix);
|
||||
defined($suffix) &&
|
||||
(defined($defsuf) ? ($defsuf .= $suffix)
|
||||
: ($defsuf = $suffix));
|
||||
} else {
|
||||
$pat = &getpat($pat,$arg);
|
||||
$type = &gettype($type);
|
||||
|
|
5
Src/.lastloc
Normal file
5
Src/.lastloc
Normal file
|
@ -0,0 +1,5 @@
|
|||
(("/home/user2/pws/src/zsh-3.1.5/Src/glob.c" . 15475)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/zsh.export" . 794)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/utils.c" . 10946)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Makefile" . 4282)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/mkmakemod.sh" . 6832))
|
|
@ -55,12 +55,17 @@ NLIST = `cat stamp-modobjs`
|
|||
LIBZSH = libzsh-$(VERSION).$(DL_EXT)
|
||||
NIBZSH =
|
||||
|
||||
ZSH_EXPORT = $(EXPOPT)$(sdir)/zsh.export
|
||||
ZSH_NXPORT =
|
||||
ENTRYOBJ = modentry..o
|
||||
NNTRYOBJ =
|
||||
|
||||
LDRUNPATH = LD_RUN_PATH=$(libdir)/zsh
|
||||
NDRUNPATH =
|
||||
|
||||
zsh: $(@L@IBZSH) $(@L@STMP) $(MAIN_OBJS)
|
||||
rm -f $@
|
||||
$(@L@DRUNPATH) $(LINK) $(MAIN_OBJS) $(@L@LIST) $(@L@IBZSH) $(LIBS)
|
||||
$(@L@DRUNPATH) $(LINK) $(MAIN_OBJS) $(@L@LIST) $(ZSH_@E@XPORT) $(@L@IBZSH) $(LIBS)
|
||||
|
||||
$(LIBZSH): $(LIBOBJS) $(NSTMP)
|
||||
rm -f $@
|
||||
|
@ -114,6 +119,11 @@ modules-bltin:
|
|||
echo > $@; \
|
||||
fi
|
||||
|
||||
modules: $(@E@NTRYOBJ)
|
||||
|
||||
$(ENTRYOBJ): FORCE
|
||||
@$(MAKE) -f Makemod $(MAKEDEFS) $@
|
||||
|
||||
# ========== ANSI TO K&R CONVERSION ==========
|
||||
|
||||
ANSI_KNR = ansi2knr
|
||||
|
|
|
@ -85,6 +85,7 @@ statmodeprint(mode_t mode, char *outbuf, int flags)
|
|||
|
||||
for (i = 1; i <= 9; i++)
|
||||
pm[i] = (mode & *mfp++) ? modes[i] : '-';
|
||||
pm[10] = '\0';
|
||||
|
||||
if (mode & S_ISUID)
|
||||
pm[3] = (mode & S_IXUSR) ? 's' : 'S';
|
||||
|
|
10
Src/Zle/.lastloc
Normal file
10
Src/Zle/.lastloc
Normal file
|
@ -0,0 +1,10 @@
|
|||
(("/home/user2/pws/src/zsh-3.1.5/Src/Zle/zle.h" . 2619)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/zle.export" . 35)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/zle_main.c" . 13806)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/iwidgets.list" . 7831)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/comp.h" . 8512)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/zle_tricky.c" . 72920)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/comp1.c" . 9640)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/zle_vi.c" . 16035)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/zle_utils.c" . 8406)
|
||||
("/home/user2/pws/src/zsh-3.1.5/Src/Zle/comp1.export" . 81))
|
137
Src/Zle/comp.h
137
Src/Zle/comp.h
|
@ -32,6 +32,11 @@
|
|||
typedef struct compctlp *Compctlp;
|
||||
typedef struct compctl *Compctl;
|
||||
typedef struct compcond *Compcond;
|
||||
typedef struct patcomp *Patcomp;
|
||||
typedef struct cmatcher *Cmatcher;
|
||||
typedef struct cmlist *Cmlist;
|
||||
typedef struct cpattern *Cpattern;
|
||||
typedef struct cline *Cline;
|
||||
|
||||
/* node for compctl hash table (compctltab) */
|
||||
|
||||
|
@ -42,6 +47,14 @@ struct compctlp {
|
|||
Compctl cc; /* pointer to the compctl desc. */
|
||||
};
|
||||
|
||||
/* for the list of pattern compctls */
|
||||
|
||||
struct patcomp {
|
||||
Patcomp next;
|
||||
char *pat;
|
||||
Compctl cc;
|
||||
};
|
||||
|
||||
/* compctl -x condition */
|
||||
|
||||
struct compcond {
|
||||
|
@ -85,7 +98,7 @@ struct compcond {
|
|||
struct compctl {
|
||||
int refc; /* reference count */
|
||||
Compctl next; /* next compctl for -x */
|
||||
unsigned long mask; /* mask of things to complete (CC_*) */
|
||||
unsigned long mask, mask2; /* mask of things to complete (CC_*) */
|
||||
char *keyvar; /* for -k (variable) */
|
||||
char *glob; /* for -g (globbing) */
|
||||
char *str; /* for -s (expansion) */
|
||||
|
@ -97,12 +110,15 @@ struct compctl {
|
|||
char *withd; /* for -w (with directory */
|
||||
char *hpat; /* for -H (history pattern) */
|
||||
int hnum; /* for -H (number of events to search) */
|
||||
char *gname;
|
||||
Compctl ext; /* for -x (first of the compctls after -x) */
|
||||
Compcond cond; /* for -x (condition for this compctl) */
|
||||
Compctl xor; /* for + (next of the xor'ed compctls) */
|
||||
Cmatcher matcher; /* matcher control (-M) */
|
||||
char *mstr; /* matcher string */
|
||||
};
|
||||
|
||||
/* objects to complete */
|
||||
/* objects to complete (mask) */
|
||||
#define CC_FILES (1<<0)
|
||||
#define CC_COMMPATH (1<<1)
|
||||
#define CC_REMOVE (1<<2)
|
||||
|
@ -135,3 +151,120 @@ struct compctl {
|
|||
|
||||
#define CC_EXPANDEXPL (1<<30)
|
||||
#define CC_RESERVED (1<<31)
|
||||
|
||||
/* objects to complete (mask2) */
|
||||
#define CC_NOSORT (1<<0)
|
||||
#define CC_XORCONT (1<<1)
|
||||
#define CC_CCCONT (1<<2)
|
||||
#define CC_PATCONT (1<<3)
|
||||
#define CC_DEFCONT (1<<4)
|
||||
|
||||
typedef struct cexpl *Cexpl;
|
||||
typedef struct cmgroup *Cmgroup;
|
||||
typedef struct cmatch *Cmatch;
|
||||
|
||||
/* This is for explantion strings. */
|
||||
|
||||
struct cexpl {
|
||||
char *str; /* the string */
|
||||
int count; /* the number of matches */
|
||||
int fcount; /* number of matches with fignore ignored */
|
||||
|
||||
};
|
||||
|
||||
/* This describes a group of matches. */
|
||||
|
||||
struct cmgroup {
|
||||
char *name; /* the name of this group */
|
||||
Cmgroup prev; /* previous on the list */
|
||||
Cmgroup next; /* next one in list */
|
||||
int flags; /* see CGF_* below */
|
||||
int mcount; /* number of matches */
|
||||
Cmatch *matches; /* the matches */
|
||||
int lcount; /* number of things to list here */
|
||||
char **ylist; /* things to list */
|
||||
int ecount; /* number of explanation string */
|
||||
Cexpl *expls; /* explanation strings */
|
||||
int ccount; /* number of compctls used */
|
||||
Compctl *ccs; /* the compctls used */
|
||||
LinkList lexpls; /* list of explanation string while building */
|
||||
LinkList lmatches; /* list of matches */
|
||||
LinkList lfmatches; /* list of matches without fignore */
|
||||
LinkList lallccs; /* list of used compctls */
|
||||
};
|
||||
|
||||
|
||||
#define CGF_NOSORT 1 /* don't sort this group */
|
||||
#define CGF_LINES 2 /* these are to be printed on different lines */
|
||||
|
||||
/* This is the struct used to hold matches. */
|
||||
|
||||
struct cmatch {
|
||||
char *str; /* the match itself */
|
||||
char *ipre; /* ignored prefix, has to be re-inserted */
|
||||
char *ripre; /* ignored prefix, unquoted */
|
||||
char *ppre; /* the path prefix */
|
||||
char *psuf; /* the path suffix */
|
||||
char *prpre; /* path prefix for opendir */
|
||||
char *pre; /* prefix string from -P */
|
||||
char *suf; /* suffix string from -S */
|
||||
int flags; /* see CMF_* below */
|
||||
int brpl; /* the place where to put the brace prefix */
|
||||
int brsl; /* ...and the suffix */
|
||||
};
|
||||
|
||||
#define CMF_FILE 1 /* this is a file */
|
||||
#define CMF_REMOVE 2 /* remove the suffix */
|
||||
#define CMF_PARBR 4 /* paramter expansion with a brace */
|
||||
#define CMF_NOLIST 8 /* should not be listed */
|
||||
|
||||
|
||||
/* Stuff for completion matcher control. */
|
||||
|
||||
struct cmlist {
|
||||
Cmlist next; /* next one in the list of global matchers */
|
||||
Cmatcher matcher; /* the matcher definition */
|
||||
char *str; /* the string for it */
|
||||
};
|
||||
|
||||
struct cmatcher {
|
||||
Cmatcher next; /* next matcher */
|
||||
int flags; /* see CMF_* below */
|
||||
Cpattern line; /* what matches on the line */
|
||||
int llen; /* length of line pattern */
|
||||
Cpattern word; /* what matches in the word */
|
||||
int wlen; /* length of word pattern */
|
||||
Cpattern left; /* left anchor */
|
||||
int lalen; /* length of left anchor */
|
||||
Cpattern right; /* right anchor */
|
||||
int ralen; /* length of right anchor */
|
||||
};
|
||||
|
||||
|
||||
#define CMF_LINE 1
|
||||
#define CMF_LEFT 2
|
||||
#define CMF_RIGHT 4
|
||||
|
||||
|
||||
struct cpattern {
|
||||
Cpattern next; /* next sub-pattern */
|
||||
unsigned char tab[256]; /* table of matched characters */
|
||||
int equiv; /* if this is a {...} class */
|
||||
};
|
||||
|
||||
|
||||
struct cline {
|
||||
Cline next; /* next chunk */
|
||||
char *line; /* string to insert if !word */
|
||||
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 */
|
||||
};
|
||||
|
||||
#define CLF_END 1
|
||||
#define CLF_MID 2
|
||||
#define CLF_MISS 4
|
||||
#define CLF_DIFF 8
|
||||
#define CLF_SUF 16
|
||||
|
|
174
Src/Zle/comp1.c
174
Src/Zle/comp1.c
|
@ -31,16 +31,34 @@
|
|||
|
||||
#include "comp1.pro"
|
||||
|
||||
/* default completion infos */
|
||||
/* Default completion infos */
|
||||
|
||||
/**/
|
||||
struct compctl cc_compos, cc_default, cc_first, cc_dummy;
|
||||
|
||||
/* hash table for completion info for commands */
|
||||
/* Global matcher. */
|
||||
|
||||
/**/
|
||||
Cmlist cmatcher;
|
||||
|
||||
/* pointers to functions required by zle */
|
||||
|
||||
/**/
|
||||
void (*printcompctlptr) _((char *, Compctl, int));
|
||||
|
||||
/**/
|
||||
Compctl (*compctl_widgetptr) _((char *, char **));
|
||||
|
||||
/* Hash table for completion info for commands */
|
||||
|
||||
/**/
|
||||
HashTable compctltab;
|
||||
|
||||
/* List of pattern compctls */
|
||||
|
||||
/**/
|
||||
Patcomp patcomps;
|
||||
|
||||
/* Words on the command line, for use in completion */
|
||||
|
||||
/**/
|
||||
|
@ -54,6 +72,16 @@ char **clwords;
|
|||
/**/
|
||||
int incompctlfunc;
|
||||
|
||||
|
||||
/* This variable and the functions rembslash() and quotename() came from *
|
||||
* zle_tricky.c, but are now used in compctl.c, too. */
|
||||
|
||||
/* 1 if we are completing in a string */
|
||||
|
||||
/**/
|
||||
int instring;
|
||||
|
||||
|
||||
/**/
|
||||
static void
|
||||
createcompctltable(void)
|
||||
|
@ -71,6 +99,8 @@ createcompctltable(void)
|
|||
compctltab->enablenode = NULL;
|
||||
compctltab->freenode = freecompctlp;
|
||||
compctltab->printnode = NULL;
|
||||
|
||||
patcomps = NULL;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
@ -103,6 +133,7 @@ freecompctl(Compctl cc)
|
|||
zsfree(cc->prefix);
|
||||
zsfree(cc->suffix);
|
||||
zsfree(cc->hpat);
|
||||
zsfree(cc->gname);
|
||||
zsfree(cc->subcmd);
|
||||
if (cc->cond)
|
||||
freecompcond(cc->cond);
|
||||
|
@ -119,6 +150,9 @@ freecompctl(Compctl cc)
|
|||
}
|
||||
if (cc->xor && cc->xor != &cc_default)
|
||||
freecompctl(cc->xor);
|
||||
if (cc->matcher)
|
||||
freecmatcher(cc->matcher);
|
||||
zsfree(cc->mstr);
|
||||
zfree(cc, sizeof(struct compctl));
|
||||
}
|
||||
|
||||
|
@ -166,6 +200,56 @@ freecompcond(void *a)
|
|||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
freecmlist(Cmlist l)
|
||||
{
|
||||
Cmlist n;
|
||||
|
||||
while (l) {
|
||||
n = l->next;
|
||||
freecmatcher(l->matcher);
|
||||
zsfree(l->str);
|
||||
|
||||
zfree(l, sizeof(struct cmlist));
|
||||
|
||||
l = n;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
freecmatcher(Cmatcher m)
|
||||
{
|
||||
Cmatcher n;
|
||||
|
||||
while (m) {
|
||||
n = m->next;
|
||||
freecpattern(m->line);
|
||||
freecpattern(m->word);
|
||||
freecpattern(m->left);
|
||||
freecpattern(m->right);
|
||||
|
||||
zfree(m, sizeof(struct cmatcher));
|
||||
|
||||
m = n;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
freecpattern(Cpattern p)
|
||||
{
|
||||
Cpattern n;
|
||||
|
||||
while (p) {
|
||||
n = p->next;
|
||||
zfree(p, sizeof(struct cpattern));
|
||||
|
||||
p = n;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
compctlread(char *name, char **args, char *ops, char *reply)
|
||||
|
@ -261,6 +345,89 @@ compctlread(char *name, char **args, char *ops, char *reply)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the given string and remove backslashes from the copy and return it. */
|
||||
|
||||
/**/
|
||||
char *
|
||||
rembslash(char *s)
|
||||
{
|
||||
char *t = s = dupstring(s);
|
||||
|
||||
while (*s)
|
||||
if (*s == '\\') {
|
||||
chuck(s);
|
||||
if (*s)
|
||||
s++;
|
||||
} else
|
||||
s++;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Quote the string s and return the result. If e is non-zero, the *
|
||||
* pointer it points to may point to a position in s and in e the position *
|
||||
* of the corresponding character in the quoted string is returned. Like *
|
||||
* e, te may point to a position in the string and pl is used to return *
|
||||
* the position of the character pointed to by te in the quoted string. *
|
||||
* The string is metafied and may contain tokens. */
|
||||
|
||||
/**/
|
||||
char *
|
||||
quotename(const char *s, char **e, char *te, int *pl)
|
||||
{
|
||||
const char *u, *tt;
|
||||
char *v, buf[PATH_MAX * 2];
|
||||
int sf = 0;
|
||||
|
||||
tt = v = buf;
|
||||
u = s;
|
||||
for (; *u; u++) {
|
||||
if (e && *e == u)
|
||||
*e = v, sf |= 1;
|
||||
if (te == u)
|
||||
*pl = v - tt, sf |= 2;
|
||||
if (ispecial(*u) &&
|
||||
(!instring || (isset(BANGHIST) &&
|
||||
*u == (char)bangchar) ||
|
||||
(instring == 2 &&
|
||||
(*u == '$' || *u == '`' || *u == '\"')) ||
|
||||
(instring == 1 && *u == '\''))) {
|
||||
if (*u == '\n' || (instring == 1 && *u == '\'')) {
|
||||
if (unset(RCQUOTES)) {
|
||||
*v++ = '\'';
|
||||
if (*u == '\'')
|
||||
*v++ = '\\';
|
||||
*v++ = *u;
|
||||
*v++ = '\'';
|
||||
} else if (*u == '\n')
|
||||
*v++ = '"', *v++ = '\n', *v++ = '"';
|
||||
else
|
||||
*v++ = '\'', *v++ = '\'';
|
||||
continue;
|
||||
} else
|
||||
*v++ = '\\';
|
||||
}
|
||||
if(*u == Meta)
|
||||
*v++ = *u++;
|
||||
*v++ = *u;
|
||||
}
|
||||
*v = '\0';
|
||||
if (strcmp(buf, s))
|
||||
tt = dupstring(buf);
|
||||
else
|
||||
tt = s;
|
||||
v += tt - buf;
|
||||
if (e && (sf & 1))
|
||||
*e += tt - buf;
|
||||
|
||||
if (e && *e == u)
|
||||
*e = v;
|
||||
if (te == u)
|
||||
*pl = v - tt;
|
||||
|
||||
return (char *) tt;
|
||||
}
|
||||
|
||||
/**/
|
||||
int
|
||||
boot_comp1(Module m)
|
||||
|
@ -269,10 +436,13 @@ boot_comp1(Module m)
|
|||
clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *));
|
||||
createcompctltable();
|
||||
cc_compos.mask = CC_COMMPATH;
|
||||
cc_compos.mask2 = 0;
|
||||
cc_default.refc = 10000;
|
||||
cc_default.mask = CC_FILES;
|
||||
cc_default.mask2 = 0;
|
||||
cc_first.refc = 10000;
|
||||
cc_first.mask = 0;
|
||||
cc_first.mask2 = CC_CCCONT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
22
Src/Zle/comp1.export
Normal file
22
Src/Zle/comp1.export
Normal file
|
@ -0,0 +1,22 @@
|
|||
#!
|
||||
cc_compos
|
||||
cc_default
|
||||
cc_dummy
|
||||
cc_first
|
||||
clwnum
|
||||
clwords
|
||||
clwpos
|
||||
clwsize
|
||||
cmatcher
|
||||
compctl_widgetptr
|
||||
compctltab
|
||||
freecmatcher
|
||||
freecmlist
|
||||
freecompcond
|
||||
freecompctl
|
||||
incompctlfunc
|
||||
instring
|
||||
patcomps
|
||||
printcompctlptr
|
||||
quotename
|
||||
rembslash
|
|
@ -1,3 +1,5 @@
|
|||
hasexport=1
|
||||
|
||||
objects="comp1.o"
|
||||
|
||||
headers="comp.h"
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#include "compctl.mdh"
|
||||
#include "compctl.pro"
|
||||
#define GLOBAL_PROTOTYPES
|
||||
#include "zle_tricky.pro"
|
||||
#undef GLOBAL_PROTOTYPES
|
||||
|
||||
#define COMP_LIST (1<<0) /* -L */
|
||||
#define COMP_COMMAND (1<<1) /* -C */
|
||||
|
@ -44,6 +47,328 @@ static int cclist;
|
|||
/* Mask for determining what to print */
|
||||
static unsigned long showmask = 0;
|
||||
|
||||
/* This is a special return value for parse_cmatcher(), *
|
||||
* signalling an error. */
|
||||
|
||||
#define pcm_err ((Cmatcher) 1)
|
||||
|
||||
/* Copy a list of completion matchers. */
|
||||
|
||||
static Cmlist
|
||||
cpcmlist(Cmlist l)
|
||||
{
|
||||
Cmlist r = NULL, *p = &r, n;
|
||||
|
||||
while (l) {
|
||||
*p = n = (Cmlist) zalloc(sizeof(struct cmlist));
|
||||
n->next = NULL;
|
||||
n->matcher = cpcmatcher(l->matcher);
|
||||
n->str = ztrdup(l->str);
|
||||
|
||||
p = &(n->next);
|
||||
l = l->next;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Copy a completion matcher list. */
|
||||
|
||||
/**/
|
||||
static Cmatcher
|
||||
cpcmatcher(Cmatcher m)
|
||||
{
|
||||
Cmatcher r = NULL, *p = &r, n;
|
||||
|
||||
while (m) {
|
||||
*p = n = (Cmatcher) zalloc(sizeof(struct cmatcher));
|
||||
|
||||
n->next = NULL;
|
||||
n->flags = m->flags;
|
||||
n->line = cpcpattern(m->line);
|
||||
n->llen = m->llen;
|
||||
n->word = cpcpattern(m->word);
|
||||
n->wlen = m->wlen;
|
||||
n->left = cpcpattern(m->left);
|
||||
n->lalen = m->lalen;
|
||||
n->right = cpcpattern(m->right);
|
||||
n->ralen = m->ralen;
|
||||
|
||||
p = &(n->next);
|
||||
m = m->next;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Copy a completion matcher pattern. */
|
||||
|
||||
/**/
|
||||
static Cpattern
|
||||
cpcpattern(Cpattern o)
|
||||
{
|
||||
Cpattern r = NULL, *p = &r, n;
|
||||
|
||||
while (o) {
|
||||
*p = n = (Cpattern) zalloc(sizeof(struct cpattern));
|
||||
|
||||
n->next = NULL;
|
||||
memcpy(n->tab, o->tab, 256);
|
||||
n->equiv = o->equiv;
|
||||
|
||||
p = &(n->next);
|
||||
o = o->next;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Try to get the global matcher from the given compctl. */
|
||||
|
||||
/**/
|
||||
static int
|
||||
get_gmatcher(char *name, char **argv)
|
||||
{
|
||||
if (!strcmp(*argv, "-M")) {
|
||||
char **p = ++argv;
|
||||
Cmlist l = NULL, *q = &l, n;
|
||||
Cmatcher m;
|
||||
|
||||
while (*p) {
|
||||
if (**p++ == '-')
|
||||
return 0;
|
||||
}
|
||||
while (*argv) {
|
||||
if ((m = parse_cmatcher(name, *argv)) == pcm_err)
|
||||
return 2;
|
||||
*q = n = (Cmlist) halloc(sizeof(struct cmlist));
|
||||
n->next = NULL;
|
||||
n->matcher = m;
|
||||
n->str = *argv++;
|
||||
|
||||
q = &(n->next);
|
||||
}
|
||||
freecmlist(cmatcher);
|
||||
PERMALLOC {
|
||||
cmatcher = cpcmlist(l);
|
||||
} LASTALLOC;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This prints the global matcher definitions. */
|
||||
|
||||
/**/
|
||||
static void
|
||||
print_gmatcher(int ac)
|
||||
{
|
||||
Cmlist p;
|
||||
|
||||
if ((p = cmatcher)) {
|
||||
printf((ac ? "compctl -M" : "MATCH"));
|
||||
|
||||
while (p) {
|
||||
printf(" \'%s\'", p->str);
|
||||
|
||||
p = p->next;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse a string for matcher control, containing multiple matchers. */
|
||||
|
||||
/**/
|
||||
static Cmatcher
|
||||
parse_cmatcher(char *name, char *s)
|
||||
{
|
||||
Cmatcher ret = NULL, r, n;
|
||||
Cpattern line, word, left, right;
|
||||
int fl, ll, wl, lal, ral, err;
|
||||
|
||||
if (!*s)
|
||||
return NULL;
|
||||
|
||||
while (*s) {
|
||||
while (*s && inblank(*s)) s++;
|
||||
|
||||
if (!*s) break;
|
||||
|
||||
switch (*s) {
|
||||
case 'l': fl = CMF_LEFT; break;
|
||||
case 'r': fl = CMF_RIGHT; break;
|
||||
case 'm': fl = 0; break;
|
||||
case 'L': fl = CMF_LEFT | CMF_LINE; break;
|
||||
case 'R': fl = CMF_RIGHT | CMF_LINE; break;
|
||||
case 'M': fl = CMF_LINE; break;
|
||||
default:
|
||||
zwarnnam(name, "unknown match specification character `%c'", NULL, *s);
|
||||
return pcm_err;
|
||||
}
|
||||
if (s[1] != ':') {
|
||||
zwarnnam(name, "missing `:'", NULL, 0);
|
||||
return pcm_err;
|
||||
}
|
||||
s += 2;
|
||||
if (!*s) {
|
||||
zwarnnam(name, "missing patterns", NULL, 0);
|
||||
return pcm_err;
|
||||
}
|
||||
if (fl & CMF_LEFT) {
|
||||
left = parse_pattern(name, &s, &lal, '|', &err);
|
||||
if (err)
|
||||
return pcm_err;
|
||||
if (!*s || !*++s) {
|
||||
zwarnnam(name, "missing line pattern", NULL, 0);
|
||||
return pcm_err;
|
||||
}
|
||||
} else
|
||||
left = NULL;
|
||||
|
||||
line = parse_pattern(name, &s, &ll, ((fl & CMF_RIGHT) ? '|' : '='),
|
||||
&err);
|
||||
if (err)
|
||||
return pcm_err;
|
||||
if (!*s || !*++s) {
|
||||
zwarnnam(name, ((fl & CMF_RIGHT) ? "missing right anchor" : "missing word pattern"), NULL, 0);
|
||||
return pcm_err;
|
||||
}
|
||||
if (fl & CMF_RIGHT) {
|
||||
right = parse_pattern(name, &s, &ral, '=', &err);
|
||||
if (err)
|
||||
return pcm_err;
|
||||
if (!*s || !*++s) {
|
||||
zwarnnam(name, "missing word pattern", NULL, 0);
|
||||
return pcm_err;
|
||||
}
|
||||
} else
|
||||
right = NULL;
|
||||
|
||||
if (*s == '*') {
|
||||
if (!(fl & (CMF_LEFT | CMF_RIGHT))) {
|
||||
zwarnnam(name, "need anchor for `*'", NULL, 0);
|
||||
return pcm_err;
|
||||
}
|
||||
word = NULL;
|
||||
wl = -1;
|
||||
s++;
|
||||
} else {
|
||||
word = parse_pattern(name, &s, &wl, 0, &err);
|
||||
|
||||
if (!word && !line) {
|
||||
zwarnnam(name, "need non-empty word or line pattern", NULL, 0);
|
||||
return pcm_err;
|
||||
}
|
||||
}
|
||||
if (err)
|
||||
return pcm_err;
|
||||
|
||||
n = (Cmatcher) zcalloc(sizeof(*ret));
|
||||
n->next = NULL;
|
||||
n->flags = fl;
|
||||
n->line = line;
|
||||
n->llen = ll;
|
||||
n->word = word;
|
||||
n->wlen = wl;
|
||||
n->left = left;
|
||||
n->lalen = lal;
|
||||
n->right = right;
|
||||
n->ralen = ral;
|
||||
|
||||
if (ret) r->next = n;
|
||||
else ret = n;
|
||||
|
||||
r = n;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parse a pattern for matcher control. */
|
||||
|
||||
/**/
|
||||
static Cpattern
|
||||
parse_pattern(char *name, char **sp, int *lp, char e, int *err)
|
||||
{
|
||||
Cpattern ret = NULL, r, n;
|
||||
unsigned char *s = (unsigned char *) *sp;
|
||||
int l = 0;
|
||||
|
||||
*err = 0;
|
||||
|
||||
while (*s && (e ? (*s != e) : !inblank(*s))) {
|
||||
n = (Cpattern) hcalloc(sizeof(*n));
|
||||
n->next = NULL;
|
||||
n->equiv = 0;
|
||||
|
||||
if (*s == '[') {
|
||||
s = parse_class(n, s + 1, ']');
|
||||
if (!*s) {
|
||||
*err = 1;
|
||||
zwarnnam(name, "unterminated character class", NULL, 0);
|
||||
return NULL;
|
||||
}
|
||||
} else if (*s == '{') {
|
||||
n->equiv = 1;
|
||||
s = parse_class(n, s + 1, '}');
|
||||
if (!*s) {
|
||||
*err = 1;
|
||||
zwarnnam(name, "unterminated character class", NULL, 0);
|
||||
return NULL;
|
||||
}
|
||||
} else if (*s == '?') {
|
||||
memset(n->tab, 1, 256);
|
||||
} else if (*s == '*' || *s == '(' || *s == ')' || *s == '=') {
|
||||
*err = 1;
|
||||
zwarnnam(name, "invalid pattern character `%c'", NULL, *s);
|
||||
return NULL;
|
||||
} else {
|
||||
if (*s == '\\' && s[1])
|
||||
s++;
|
||||
|
||||
memset(n->tab, 0, 256);
|
||||
n->tab[*s] = 1;
|
||||
}
|
||||
if (ret)
|
||||
r->next = n;
|
||||
else
|
||||
ret = n;
|
||||
|
||||
r = n;
|
||||
|
||||
l++;
|
||||
s++;
|
||||
}
|
||||
*sp = (char *) s;
|
||||
*lp = l;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parse a character class for matcher control. */
|
||||
|
||||
/**/
|
||||
static unsigned char *
|
||||
parse_class(Cpattern p, unsigned char *s, unsigned char e)
|
||||
{
|
||||
int n = 0, i = 1, j, eq = (e == '}'), k = 1;
|
||||
|
||||
if (!eq && (*s == '!' || *s == '^') && s[1] != e) { n = 1; s++; }
|
||||
|
||||
memset(p->tab, n, 256);
|
||||
|
||||
n = !n;
|
||||
while (*s && (k || *s != e)) {
|
||||
if (s[1] == '-' && s[2] != e) {
|
||||
/* a run of characters */
|
||||
for (j = (int) *s; j <= (int) s[2]; j++)
|
||||
p->tab[j] = (eq ? i++ : n);
|
||||
|
||||
s += 3;
|
||||
} else
|
||||
p->tab[*s++] = (eq ? i++ : n);
|
||||
k = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Parse the basic flags for `compctl' */
|
||||
|
||||
/**/
|
||||
|
@ -176,6 +501,44 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
|||
case '/':
|
||||
cct.mask |= CC_DIRS;
|
||||
break;
|
||||
case 't':
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((*argv)[1]) {
|
||||
p = (*argv) + 1;
|
||||
*argv = "" - 1;
|
||||
} else if (!argv[1]) {
|
||||
zwarnnam(name, "retry specification expected after -%c", NULL,
|
||||
**argv);
|
||||
return 1;
|
||||
} else {
|
||||
p = *++argv;
|
||||
*argv = "" - 1;
|
||||
}
|
||||
while (*p) {
|
||||
switch (*p) {
|
||||
case '+':
|
||||
cct.mask2 |= CC_XORCONT;
|
||||
break;
|
||||
case 'c':
|
||||
cct.mask2 |= CC_CCCONT;
|
||||
break;
|
||||
case '-':
|
||||
cct.mask2 |= CC_PATCONT;
|
||||
break;
|
||||
case 'x':
|
||||
cct.mask2 |= CC_DEFCONT;
|
||||
break;
|
||||
default:
|
||||
zwarnnam(name, "invalid retry specification character `%c'",
|
||||
NULL, *p);
|
||||
return 1;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'k':
|
||||
if ((*argv)[1]) {
|
||||
cct.keyvar = (*argv) + 1;
|
||||
|
@ -307,6 +670,58 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef)
|
|||
*argv = "" - 1;
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
if ((*argv)[1]) {
|
||||
cct.gname = (*argv) + 1;
|
||||
*argv = "" - 1;
|
||||
} else if (!argv[1]) {
|
||||
zwarnnam(name, "group name expected after -%c", NULL,
|
||||
**argv);
|
||||
return 1;
|
||||
} else {
|
||||
cct.gname = *++argv;
|
||||
*argv = "" - 1;
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
if ((*argv)[1]) {
|
||||
cct.gname = (*argv) + 1;
|
||||
*argv = "" - 1;
|
||||
} else if (!argv[1]) {
|
||||
zwarnnam(name, "group name expected after -%c", NULL,
|
||||
**argv);
|
||||
return 1;
|
||||
} else {
|
||||
cct.gname = *++argv;
|
||||
*argv = "" - 1;
|
||||
}
|
||||
cct.mask2 |= CC_NOSORT;
|
||||
break;
|
||||
case 'M':
|
||||
if ((*argv)[1]) {
|
||||
if ((cct.matcher =
|
||||
parse_cmatcher(name, (cct.mstr = (*argv) + 1))) ==
|
||||
pcm_err) {
|
||||
cct.matcher = NULL;
|
||||
cct.mstr = NULL;
|
||||
return 1;
|
||||
}
|
||||
*argv = "" - 1;
|
||||
} else if (!argv[1]) {
|
||||
zwarnnam(name, "matching specification expected after -%c", NULL,
|
||||
**argv);
|
||||
return 1;
|
||||
} else {
|
||||
if ((cct.matcher =
|
||||
parse_cmatcher(name, (cct.mstr = *++argv))) ==
|
||||
pcm_err) {
|
||||
cct.matcher = NULL;
|
||||
cct.mstr = NULL;
|
||||
return 1;
|
||||
}
|
||||
*argv = "" - 1;
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
if ((*argv)[1])
|
||||
cct.hnum = atoi((*argv) + 1);
|
||||
|
@ -600,27 +1015,34 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
|
|||
c->u.s.s[l] = ztrdup(tt);
|
||||
} else if (c->type == CCT_RANGESTR ||
|
||||
c->type == CCT_RANGEPAT) {
|
||||
int hc;
|
||||
|
||||
/* -r[..,..] or -R[..,..]: two strings expected */
|
||||
for (; *t && *t != '\201'; t++);
|
||||
for (; *t && *t != '\201' && *t != '\200'; t++);
|
||||
if (!*t) {
|
||||
zwarnnam(name, "error in condition", NULL, 0);
|
||||
freecompcond(m);
|
||||
return 1;
|
||||
}
|
||||
hc = (*t == '\201');
|
||||
*t = '\0';
|
||||
c->u.l.a[l] = ztrdup(tt);
|
||||
tt = ++t;
|
||||
/* any more commas are text, not active */
|
||||
for (; *t && *t != '\200'; t++)
|
||||
if (*t == '\201')
|
||||
*t = ',';
|
||||
if (!*t) {
|
||||
zwarnnam(name, "error in condition", NULL, 0);
|
||||
freecompcond(m);
|
||||
return 1;
|
||||
if (hc) {
|
||||
tt = ++t;
|
||||
/* any more commas are text, not active */
|
||||
for (; *t && *t != '\200'; t++)
|
||||
if (*t == '\201')
|
||||
*t = ',';
|
||||
if (!*t) {
|
||||
zwarnnam(name, "error in condition", NULL, 0);
|
||||
freecompcond(m);
|
||||
return 1;
|
||||
}
|
||||
*t = '\0';
|
||||
c->u.l.b[l] = ztrdup(tt);
|
||||
}
|
||||
*t = '\0';
|
||||
c->u.l.b[l] = ztrdup(tt);
|
||||
else
|
||||
c->u.l.b[l] = NULL;
|
||||
} else {
|
||||
/* remaining patterns are number followed by string */
|
||||
for (; *t && *t != '\200' && *t != '\201'; t++);
|
||||
|
@ -700,13 +1122,6 @@ cc_assign(char *name, Compctl *ccptr, Compctl cct, int reass)
|
|||
/* Copy over the details from the values in cct to those in *ccptr */
|
||||
Compctl cc;
|
||||
|
||||
if (cct->subcmd && (cct->keyvar || cct->glob || cct->str ||
|
||||
cct->func || cct->explain || cct->ylist ||
|
||||
cct->prefix)) {
|
||||
zwarnnam(name, "illegal combination of options", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Handle assignment of new default or command completion */
|
||||
if (reass && !(cclist & COMP_LIST)) {
|
||||
/* if not listing */
|
||||
|
@ -746,11 +1161,15 @@ cc_assign(char *name, Compctl *ccptr, Compctl cct, int reass)
|
|||
zsfree(cc->subcmd);
|
||||
zsfree(cc->withd);
|
||||
zsfree(cc->hpat);
|
||||
|
||||
zsfree(cc->gname);
|
||||
zsfree(cc->mstr);
|
||||
freecmatcher(cc->matcher);
|
||||
|
||||
/* and copy over the new stuff, (permanently) allocating
|
||||
* space for strings.
|
||||
*/
|
||||
cc->mask = cct->mask;
|
||||
cc->mask2 = cct->mask2;
|
||||
cc->keyvar = ztrdup(cct->keyvar);
|
||||
cc->glob = ztrdup(cct->glob);
|
||||
cc->str = ztrdup(cct->str);
|
||||
|
@ -761,8 +1180,13 @@ cc_assign(char *name, Compctl *ccptr, Compctl cct, int reass)
|
|||
cc->suffix = ztrdup(cct->suffix);
|
||||
cc->subcmd = ztrdup(cct->subcmd);
|
||||
cc->withd = ztrdup(cct->withd);
|
||||
cc->gname = ztrdup(cct->gname);
|
||||
cc->hpat = ztrdup(cct->hpat);
|
||||
cc->hnum = cct->hnum;
|
||||
PERMALLOC {
|
||||
cc->matcher = cpcmatcher(cct->matcher);
|
||||
} LASTALLOC;
|
||||
cc->mstr = ztrdup(cct->mstr);
|
||||
|
||||
/* careful with extended completion: it's already allocated */
|
||||
cc->ext = cct->ext;
|
||||
|
@ -790,16 +1214,62 @@ cc_reassign(Compctl cc)
|
|||
cc->ext = cc->xor = NULL;
|
||||
}
|
||||
|
||||
/* Check if the given string is a pattern. If so, return one and tokenize *
|
||||
* it. If not, we just remove the backslashes. */
|
||||
|
||||
static int
|
||||
compctl_name_pat(char **p)
|
||||
{
|
||||
char *s = *p;
|
||||
|
||||
tokenize(s = dupstring(s));
|
||||
remnulargs(s);
|
||||
|
||||
if (haswilds(s)) {
|
||||
*p = s;
|
||||
return 1;
|
||||
} else
|
||||
*p = rembslash(*p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Delete the pattern compctl with the given name. */
|
||||
|
||||
static void
|
||||
delpatcomp(char *n)
|
||||
{
|
||||
Patcomp p, q;
|
||||
|
||||
for (q = 0, p = patcomps; p; q = p, p = p->next) {
|
||||
if (!strcmp(n, p->pat)) {
|
||||
if (q)
|
||||
q->next = p->next;
|
||||
else
|
||||
patcomps = p->next;
|
||||
zsfree(p->pat);
|
||||
freecompctl(p->cc);
|
||||
free(p);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
static void
|
||||
compctl_process_cc(char **s, Compctl cc)
|
||||
{
|
||||
Compctlp ccp;
|
||||
char *n;
|
||||
|
||||
if (cclist & COMP_REMOVE) {
|
||||
/* Delete entries for the commands listed */
|
||||
for (; *s; s++) {
|
||||
if ((ccp = (Compctlp) compctltab->removenode(compctltab, *s)))
|
||||
n = *s;
|
||||
if (compctl_name_pat(&n))
|
||||
delpatcomp(n);
|
||||
else if ((ccp = (Compctlp) compctltab->removenode(compctltab, n)))
|
||||
compctltab->freenode((HashNode) ccp);
|
||||
}
|
||||
} else {
|
||||
|
@ -807,10 +1277,23 @@ compctl_process_cc(char **s, Compctl cc)
|
|||
|
||||
cc->refc = 0;
|
||||
for (; *s; s++) {
|
||||
n = *s;
|
||||
|
||||
cc->refc++;
|
||||
ccp = (Compctlp) zalloc(sizeof *ccp);
|
||||
ccp->cc = cc;
|
||||
compctltab->addnode(compctltab, ztrdup(*s), ccp);
|
||||
if (compctl_name_pat(&n)) {
|
||||
Patcomp pc;
|
||||
|
||||
delpatcomp(n);
|
||||
pc = zalloc(sizeof *pc);
|
||||
pc->pat = ztrdup(n);
|
||||
pc->cc = cc;
|
||||
pc->next = patcomps;
|
||||
patcomps = pc;
|
||||
} else {
|
||||
ccp = (Compctlp) zalloc(sizeof *ccp);
|
||||
ccp->cc = cc;
|
||||
compctltab->addnode(compctltab, ztrdup(n), ccp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -819,15 +1302,21 @@ compctl_process_cc(char **s, Compctl cc)
|
|||
|
||||
/**/
|
||||
static void
|
||||
printcompctl(char *s, Compctl cc, int printflags)
|
||||
printcompctl(char *s, Compctl cc, int printflags, int ispat)
|
||||
{
|
||||
Compctl cc2;
|
||||
char *css = "fcqovbAIFpEjrzBRGudeNOZUnQmw/";
|
||||
char *mss = " pcCwWsSnNmrR";
|
||||
unsigned long t = 0x7fffffff;
|
||||
unsigned long flags = cc->mask;
|
||||
unsigned long flags = cc->mask, flags2 = cc->mask2;
|
||||
unsigned long oldshowmask;
|
||||
|
||||
/* Printflags is used outside the standard compctl commands*/
|
||||
if (printflags & PRINT_LIST)
|
||||
cclist |= COMP_LIST;
|
||||
else if (printflags & PRINT_TYPE)
|
||||
cclist &= ~COMP_LIST;
|
||||
|
||||
if ((flags & CC_EXCMDS) && !(flags & CC_DISCMDS))
|
||||
flags &= ~CC_EXCMDS;
|
||||
|
||||
|
@ -851,8 +1340,13 @@ printcompctl(char *s, Compctl cc, int printflags)
|
|||
printf(" -D");
|
||||
if (cc == &cc_first)
|
||||
printf(" -T");
|
||||
} else if (ispat) {
|
||||
char *p = dupstring(s);
|
||||
|
||||
untokenize(p);
|
||||
quotedzputs(p, stdout);
|
||||
} else
|
||||
quotedzputs(s, stdout);
|
||||
quotedzputs(quotename(s, NULL, NULL, NULL), stdout);
|
||||
}
|
||||
|
||||
/* loop through flags w/o args that are set, printing them if so */
|
||||
|
@ -868,9 +1362,23 @@ printcompctl(char *s, Compctl cc, int printflags)
|
|||
t >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags2 & (CC_XORCONT | CC_CCCONT | CC_PATCONT | CC_DEFCONT)) {
|
||||
printf(" -t");
|
||||
if (flags2 & CC_XORCONT)
|
||||
putchar('+');
|
||||
if (flags2 & CC_CCCONT)
|
||||
putchar('c');
|
||||
if (flags2 & CC_PATCONT)
|
||||
putchar('-');
|
||||
if (flags2 & CC_DEFCONT)
|
||||
putchar('x');
|
||||
}
|
||||
/* now flags with arguments */
|
||||
flags = cc->mask;
|
||||
printif(cc->mstr, 'M');
|
||||
if (flags2 & CC_NOSORT)
|
||||
printif(cc->gname, 'V');
|
||||
else
|
||||
printif(cc->gname, 'J');
|
||||
printif(cc->keyvar, 'k');
|
||||
printif(cc->func, 'K');
|
||||
printif(cc->explain, (cc->mask & CC_EXPANDEXPL) ? 'Y' : 'X');
|
||||
|
@ -940,7 +1448,7 @@ printcompctl(char *s, Compctl cc, int printflags)
|
|||
c = cc2->cond;
|
||||
cc2->cond = NULL;
|
||||
/* now print the flags for the current condition */
|
||||
printcompctl(NULL, cc2, 0);
|
||||
printcompctl(NULL, cc2, 0, 0);
|
||||
cc2->cond = c;
|
||||
if ((cc2 = (Compctl) (cc2->next)))
|
||||
printf(" -");
|
||||
|
@ -952,7 +1460,7 @@ printcompctl(char *s, Compctl cc, int printflags)
|
|||
/* print xor'd (+) completions */
|
||||
printf(" +");
|
||||
if (cc->xor != &cc_default)
|
||||
printcompctl(NULL, cc->xor, 0);
|
||||
printcompctl(NULL, cc->xor, 0, 0);
|
||||
}
|
||||
if (s) {
|
||||
if ((cclist & COMP_LIST) && (cc != &cc_compos)
|
||||
|
@ -960,7 +1468,17 @@ printcompctl(char *s, Compctl cc, int printflags)
|
|||
if(s[0] == '-' || s[0] == '+')
|
||||
printf(" -");
|
||||
putchar(' ');
|
||||
quotedzputs(s, stdout);
|
||||
if (ispat) {
|
||||
char *p = dupstring(s);
|
||||
|
||||
untokenize(p);
|
||||
quotedzputs(p, stdout);
|
||||
} else {
|
||||
char *p = dupstring(s);
|
||||
|
||||
untokenize(p);
|
||||
quotedzputs(quotename(p, NULL, NULL, NULL), stdout);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
@ -975,7 +1493,7 @@ printcompctlp(HashNode hn, int printflags)
|
|||
Compctlp ccp = (Compctlp) hn;
|
||||
|
||||
/* Function needed for use by scanhashtable() */
|
||||
printcompctl(ccp->nam, ccp->cc, printflags);
|
||||
printcompctl(ccp->nam, ccp->cc, printflags, 0);
|
||||
}
|
||||
|
||||
/* Main entry point for the `compctl' builtin */
|
||||
|
@ -991,8 +1509,14 @@ bin_compctl(char *name, char **argv, char *ops, int func)
|
|||
cclist = 0;
|
||||
showmask = 0;
|
||||
|
||||
instring = 0;
|
||||
|
||||
/* Parse all the arguments */
|
||||
if (*argv) {
|
||||
/* Let's see if this is a global matcher definition. */
|
||||
if ((ret = get_gmatcher(name, argv)))
|
||||
return ret - 1;
|
||||
|
||||
cc = (Compctl) zcalloc(sizeof(*cc));
|
||||
if (get_compctl(name, &argv, cc, 1, 0)) {
|
||||
freecompctl(cc);
|
||||
|
@ -1013,10 +1537,16 @@ bin_compctl(char *name, char **argv, char *ops, int func)
|
|||
* If some flags (other than -C, -T, or -D) were given, then *
|
||||
* only print compctl containing those flags. */
|
||||
if (!*argv && !(cclist & COMP_SPECIAL)) {
|
||||
Patcomp pc;
|
||||
|
||||
for (pc = patcomps; pc; pc = pc->next)
|
||||
printcompctl(pc->pat, pc->cc, 0, 1);
|
||||
|
||||
scanhashtable(compctltab, 1, 0, 0, compctltab->printnode, 0);
|
||||
printcompctl((cclist & COMP_LIST) ? "" : "COMMAND", &cc_compos, 0);
|
||||
printcompctl((cclist & COMP_LIST) ? "" : "DEFAULT", &cc_default, 0);
|
||||
printcompctl((cclist & COMP_LIST) ? "" : "FIRST", &cc_first, 0);
|
||||
printcompctl((cclist & COMP_LIST) ? "" : "COMMAND", &cc_compos, 0, 0);
|
||||
printcompctl((cclist & COMP_LIST) ? "" : "DEFAULT", &cc_default, 0, 0);
|
||||
printcompctl((cclist & COMP_LIST) ? "" : "FIRST", &cc_first, 0, 0);
|
||||
print_gmatcher((cclist & COMP_LIST));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1024,23 +1554,35 @@ bin_compctl(char *name, char **argv, char *ops, int func)
|
|||
* or a COMP_SPECIAL flag (-D, -C, -T), so print only those. */
|
||||
if (cclist & COMP_LIST) {
|
||||
HashNode hn;
|
||||
char **ptr;
|
||||
char **ptr, *n;
|
||||
|
||||
showmask = 0;
|
||||
for (ptr = argv; *ptr; ptr++) {
|
||||
if ((hn = compctltab->getnode(compctltab, *ptr))) {
|
||||
n = *ptr;
|
||||
if (compctl_name_pat(&n)) {
|
||||
Patcomp pc;
|
||||
|
||||
for (pc = patcomps; pc; pc = pc->next)
|
||||
if (!strcmp(n, pc->pat)) {
|
||||
printcompctl(pc->pat, pc->cc, 0, 1);
|
||||
n = NULL;
|
||||
break;
|
||||
}
|
||||
} else if ((hn = compctltab->getnode(compctltab, n))) {
|
||||
compctltab->printnode(hn, 0);
|
||||
} else {
|
||||
zwarnnam(name, "no compctl defined for %s", *ptr, 0);
|
||||
n = NULL;
|
||||
}
|
||||
if (n) {
|
||||
zwarnnam(name, "no compctl defined for %s", n, 0);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
if (cclist & COMP_COMMAND)
|
||||
printcompctl("", &cc_compos, 0);
|
||||
printcompctl("", &cc_compos, 0, 0);
|
||||
if (cclist & COMP_DEFAULT)
|
||||
printcompctl("", &cc_default, 0);
|
||||
printcompctl("", &cc_default, 0, 0);
|
||||
if (cclist & COMP_FIRST)
|
||||
printcompctl("", &cc_first, 0);
|
||||
printcompctl("", &cc_first, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1058,6 +1600,38 @@ bin_compctl(char *name, char **argv, char *ops, int func)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Externally callable version of get_compctl. Used for completion widgets */
|
||||
|
||||
/**/
|
||||
static Compctl
|
||||
compctl_widget(char *name, char **argv)
|
||||
{
|
||||
Compctl cc = (Compctl) zcalloc(sizeof(*cc));
|
||||
cclist = 0;
|
||||
showmask = 0;
|
||||
|
||||
if (get_compctl(name, &argv, cc, 1, 0)) {
|
||||
freecompctl(cc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cclist & COMP_REMOVE) {
|
||||
zwarnnam(name, "use -D to delete widget", NULL, 0);
|
||||
return NULL;
|
||||
} else if (cclist) {
|
||||
zwarnnam(name, "special options illegal in widget", NULL, 0);
|
||||
freecompctl(cc);
|
||||
return NULL;
|
||||
} else if (*argv) {
|
||||
zwarnnam(name, "command names illegal in widget", NULL, 0);
|
||||
freecompctl(cc);
|
||||
return NULL;
|
||||
}
|
||||
cc->refc++;
|
||||
|
||||
return cc;
|
||||
}
|
||||
|
||||
static struct builtin bintab[] = {
|
||||
BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL),
|
||||
};
|
||||
|
@ -1069,6 +1643,8 @@ boot_compctl(Module m)
|
|||
if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)))
|
||||
return 1;
|
||||
compctltab->printnode = printcompctlp;
|
||||
printcompctlptr = printcompctl;
|
||||
compctl_widgetptr = compctl_widget;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1080,6 +1656,8 @@ cleanup_compctl(Module m)
|
|||
{
|
||||
compctltab->printnode = NULL;
|
||||
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
|
||||
printcompctlptr = NULL;
|
||||
compctl_widgetptr = NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,7 @@ deltochar(void)
|
|||
if (dest != ll) {
|
||||
dest++;
|
||||
if (!n) {
|
||||
foredel(dest - cs);
|
||||
forekill(dest - cs, 0);
|
||||
ok++;
|
||||
}
|
||||
}
|
||||
|
@ -57,9 +57,13 @@ deltochar(void)
|
|||
while (n++ && dest != 0) {
|
||||
while (dest != 0 && line[dest] != c)
|
||||
dest--;
|
||||
if (line[dest] == c && !n) {
|
||||
backdel(cs - dest);
|
||||
ok++;
|
||||
if (line[dest] == c) {
|
||||
if (!n) {
|
||||
backkill(cs - dest, 1);
|
||||
ok++;
|
||||
}
|
||||
if (dest)
|
||||
dest--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +75,8 @@ deltochar(void)
|
|||
int
|
||||
boot_deltochar(Module m)
|
||||
{
|
||||
w_deletetochar = addzlefunction("delete-to-char", deltochar, ZLE_KEEPSUFFIX);
|
||||
w_deletetochar = addzlefunction("delete-to-char", deltochar,
|
||||
ZLE_KILL | ZLE_KEEPSUFFIX);
|
||||
if (w_deletetochar)
|
||||
return 0;
|
||||
zwarnnam(m->nam, "name clash when adding ZLE function `delete-to-char'",
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
"beginning-of-line", beginningofline, 0
|
||||
"beginning-of-line-hist", beginningoflinehist, 0
|
||||
"capitalize-word", capitalizeword, 0
|
||||
"clear-screen", clearscreen, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"clear-screen", clearscreen, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||
"complete-word", completeword, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
||||
"copy-prev-word", copyprevword, 0
|
||||
"copy-region-as-kill", copyregionaskill, ZLE_KEEPSUFFIX
|
||||
|
@ -32,7 +32,7 @@
|
|||
"delete-char-or-list", deletecharorlist, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
||||
"delete-word", deleteword, ZLE_KEEPSUFFIX
|
||||
"describe-key-briefly", describekeybriefly, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"digit-argument", digitargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"digit-argument", digitargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||
"down-case-word", downcaseword, 0
|
||||
"down-history", downhistory, 0
|
||||
"down-line-or-history", downlineorhistory, ZLE_LINEMOVE | ZLE_LASTCOL
|
||||
|
@ -73,7 +73,7 @@
|
|||
"magic-space", magicspace, 0
|
||||
"menu-complete", menucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
||||
"menu-expand-or-complete", menuexpandorcomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
||||
"neg-argument", negargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"neg-argument", negargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||
"overwrite-mode", overwritemode, 0
|
||||
"pound-insert", poundinsert, 0
|
||||
"push-input", pushinput, 0
|
||||
|
@ -95,7 +95,7 @@
|
|||
"transpose-words", transposewords, 0
|
||||
"undefined-key", undefinedkey, 0
|
||||
"undo", undo, 0
|
||||
"universal-argument", universalargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"universal-argument", universalargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND
|
||||
"up-case-word", upcaseword, 0
|
||||
"up-history", uphistory, 0
|
||||
"up-line-or-history", uplineorhistory, ZLE_LINEMOVE | ZLE_LASTCOL
|
||||
|
@ -145,8 +145,8 @@
|
|||
"vi-open-line-below", viopenlinebelow, 0
|
||||
"vi-oper-swap-case", vioperswapcase, 0
|
||||
"vi-pound-insert", vipoundinsert, 0
|
||||
"vi-put-after", viputafter, ZLE_YANK
|
||||
"vi-put-before", viputbefore, ZLE_YANK
|
||||
"vi-put-after", viputafter, ZLE_YANK | ZLE_KEEPSUFFIX
|
||||
"vi-put-before", viputbefore, ZLE_YANK | ZLE_KEEPSUFFIX
|
||||
"vi-quoted-insert", viquotedinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX
|
||||
"vi-repeat-change", virepeatchange, 0
|
||||
"vi-repeat-find", virepeatfind, 0
|
||||
|
@ -168,5 +168,5 @@
|
|||
"what-cursor-position", whatcursorposition, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"where-is", whereis, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"which-command", processcmd, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
|
||||
"yank", yank, ZLE_YANK
|
||||
"yank-pop", yankpop, ZLE_YANK
|
||||
"yank", yank, ZLE_YANK | ZLE_KEEPSUFFIX
|
||||
"yank-pop", yankpop, ZLE_YANK | ZLE_KEEPSUFFIX
|
||||
|
|
10
Src/Zle/zle.export
Normal file
10
Src/Zle/zle.export
Normal file
|
@ -0,0 +1,10 @@
|
|||
#!
|
||||
addzlefunction
|
||||
backdel
|
||||
backkill
|
||||
deletezlefunction
|
||||
feep
|
||||
foredel
|
||||
forekill
|
||||
getkey
|
||||
zmod
|
|
@ -31,7 +31,7 @@
|
|||
#undef zleread
|
||||
#undef spaceinline
|
||||
#undef gotword
|
||||
#undef refresh
|
||||
#undef zrefresh
|
||||
|
||||
typedef struct widget *Widget;
|
||||
typedef struct thingy *Thingy;
|
||||
|
@ -46,16 +46,23 @@ struct widget {
|
|||
union {
|
||||
ZleIntFunc fn; /* pointer to internally implemented widget */
|
||||
char *fnnam; /* name of the shell function for user-defined widget */
|
||||
Compctl cc; /* for use with a WIDGET_COMP widget */
|
||||
} u;
|
||||
};
|
||||
|
||||
#define WIDGET_INT (1<<0) /* widget is internally implemented */
|
||||
#define ZLE_MENUCMP (1<<1) /* DON'T invalidate completion list */
|
||||
#define WIDGET_COMP (1<<1) /* Special completion widget */
|
||||
#define ZLE_MENUCMP (1<<2) /* DON'T invalidate completion list */
|
||||
#define ZLE_YANK (1<<3)
|
||||
#define ZLE_LINEMOVE (1<<4) /* command is a line-oriented movement */
|
||||
#define ZLE_LASTCOL (1<<5) /* command maintains lastcol correctly */
|
||||
#define ZLE_KILL (1<<6)
|
||||
#define ZLE_KEEPSUFFIX (1<<9) /* DON'T remove added suffix */
|
||||
#define ZLE_USEMENU (1<<10) /* Do ) use menu completion for */
|
||||
#define ZLE_NOMENU (1<<11) /* Don't ) widget, else use default */
|
||||
#define ZLE_USEGLOB (1<<12) /* Do ) use glob completion for */
|
||||
#define ZLE_NOGLOB (1<<13) /* Don't ) widget, else use default */
|
||||
#define ZLE_NOTCOMMAND (1<<14) /* widget should not alter lastcmd */
|
||||
|
||||
/* thingies */
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
hasexport=1
|
||||
|
||||
moddeps="comp1"
|
||||
|
||||
autobins="bindkey vared zle"
|
||||
|
|
|
@ -291,73 +291,86 @@ downhistory(void)
|
|||
feep();
|
||||
}
|
||||
|
||||
static int histpos, srch_hl, srch_cs = -1;
|
||||
static char *srch_str;
|
||||
|
||||
/**/
|
||||
void
|
||||
historysearchbackward(void)
|
||||
{
|
||||
int histpos, histmpos, hl = histline;
|
||||
int hl = histline;
|
||||
int n = zmult;
|
||||
char *s;
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
if (n < 0) {
|
||||
if (zmult < 0) {
|
||||
zmult = -n;
|
||||
historysearchforward();
|
||||
zmult = n;
|
||||
return;
|
||||
}
|
||||
for (histpos = histmpos = 0; histpos < ll && !iblank(line[histpos]);
|
||||
histpos++, histmpos++)
|
||||
if(imeta(line[histpos]))
|
||||
histmpos++;
|
||||
if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0
|
||||
|| memcmp(srch_str, line, histpos) != 0) {
|
||||
zfree(srch_str, histpos);
|
||||
for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ;
|
||||
if (histpos < ll)
|
||||
histpos++;
|
||||
srch_str = zalloc(histpos);
|
||||
memcpy(srch_str, line, histpos);
|
||||
}
|
||||
for (;;) {
|
||||
hl--;
|
||||
if (!(s = zle_get_event(hl))) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (metadiffer(s, (char *) line, histpos) < 0 &&
|
||||
iblank(s[histmpos] == Meta ? s[histmpos+1]^32 : s[histmpos]) &&
|
||||
metadiffer(s, (char *) line, ll) && !--n)
|
||||
break;
|
||||
if (metadiffer(s, srch_str, histpos) < 0 &&
|
||||
metadiffer(s, srch_str, ll)) {
|
||||
if (--n <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
zle_goto_hist(hl);
|
||||
srch_hl = hl;
|
||||
srch_cs = cs;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
historysearchforward(void)
|
||||
{
|
||||
int histpos, histmpos, hl = histline;
|
||||
int hl = histline;
|
||||
int n = zmult;
|
||||
char *s;
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
if (n < 0) {
|
||||
if (zmult < 0) {
|
||||
zmult = -n;
|
||||
historysearchbackward();
|
||||
zmult = n;
|
||||
return;
|
||||
}
|
||||
for (histpos = histmpos = 0; histpos < ll && !iblank(line[histpos]);
|
||||
histpos++, histmpos++)
|
||||
if(imeta(line[histpos]))
|
||||
histmpos++;
|
||||
if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0
|
||||
|| memcmp(srch_str, line, histpos) != 0) {
|
||||
zfree(srch_str, histpos);
|
||||
for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ;
|
||||
if (histpos < ll)
|
||||
histpos++;
|
||||
srch_str = zalloc(histpos);
|
||||
memcpy(srch_str, line, histpos);
|
||||
}
|
||||
for (;;) {
|
||||
hl++;
|
||||
if (!(s = zle_get_event(hl))) {
|
||||
feep();
|
||||
return;
|
||||
}
|
||||
if (metadiffer(s, (char *) line, histpos) < (histline == curhist) &&
|
||||
(!s[histmpos] ||
|
||||
iblank(s[histmpos] == Meta ? s[histmpos+1]^32 : s[histmpos])) &&
|
||||
metadiffer(s, (char *) line, ll) && !--n)
|
||||
break;
|
||||
if (metadiffer(s, srch_str, histpos) < (hl == curhist) &&
|
||||
metadiffer(s, srch_str, ll))
|
||||
if (--n <= 0)
|
||||
break;
|
||||
}
|
||||
zle_goto_hist(hl);
|
||||
srch_hl = hl;
|
||||
srch_cs = cs;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
@ -721,7 +734,7 @@ doisearch(int dir)
|
|||
sbuf[sbptr] = '_';
|
||||
statusll = sbuf - statusline + sbptr + 1;
|
||||
ref:
|
||||
refresh();
|
||||
zrefresh();
|
||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||
int i;
|
||||
get_isrch_spot(0, &hl, &pos, &i, &sbptr, &dir, &nomatch);
|
||||
|
@ -809,7 +822,7 @@ doisearch(int dir)
|
|||
cmd == Th(z_quotedinsert)) {
|
||||
if(cmd == Th(z_viquotedinsert)) {
|
||||
sbuf[sbptr] = '^';
|
||||
refresh();
|
||||
zrefresh();
|
||||
}
|
||||
if ((c = getkey(0)) == EOF)
|
||||
feep();
|
||||
|
@ -936,7 +949,7 @@ getvisrchstr(void)
|
|||
while (sptr) {
|
||||
sbuf[sptr] = '_';
|
||||
statusll = sptr + 1;
|
||||
refresh();
|
||||
zrefresh();
|
||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||
ret = 0;
|
||||
break;
|
||||
|
@ -971,7 +984,7 @@ getvisrchstr(void)
|
|||
} else if(cmd == Th(z_viquotedinsert) || cmd == Th(z_quotedinsert)) {
|
||||
if(cmd == Th(z_viquotedinsert)) {
|
||||
sbuf[sptr] = '^';
|
||||
refresh();
|
||||
zrefresh();
|
||||
}
|
||||
if ((c = getkey(0)) == EOF)
|
||||
feep();
|
||||
|
@ -1030,9 +1043,7 @@ virepeatsearch(void)
|
|||
feep();
|
||||
return;
|
||||
}
|
||||
if (!n)
|
||||
return;
|
||||
if (n < 0) {
|
||||
if (zmult < 0) {
|
||||
n = -n;
|
||||
visrchsense = -visrchsense;
|
||||
}
|
||||
|
@ -1078,9 +1089,7 @@ historybeginningsearchbackward(void)
|
|||
int n = zmult;
|
||||
char *s;
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
if (n < 0) {
|
||||
if (zmult < 0) {
|
||||
zmult = -n;
|
||||
historybeginningsearchforward();
|
||||
zmult = n;
|
||||
|
@ -1114,9 +1123,7 @@ historybeginningsearchforward(void)
|
|||
int n = zmult;
|
||||
char *s;
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
if (n < 0) {
|
||||
if (zmult < 0) {
|
||||
zmult = -n;
|
||||
historybeginningsearchbackward();
|
||||
zmult = n;
|
||||
|
|
|
@ -69,6 +69,9 @@ static int baud;
|
|||
/**/
|
||||
int lastcmd;
|
||||
|
||||
/**/
|
||||
Widget compwidget;
|
||||
|
||||
/* the status line, and its length */
|
||||
|
||||
/**/
|
||||
|
@ -112,7 +115,7 @@ int feepflag;
|
|||
|
||||
/**/
|
||||
void
|
||||
setterm(void)
|
||||
zsetterm(void)
|
||||
{
|
||||
struct ttyinfo ti;
|
||||
|
||||
|
@ -362,7 +365,7 @@ getkey(int keytmout)
|
|||
ret = opts[MONITOR];
|
||||
opts[MONITOR] = 1;
|
||||
attachtty(mypgrp);
|
||||
refresh(); /* kludge! */
|
||||
zrefresh(); /* kludge! */
|
||||
opts[MONITOR] = ret;
|
||||
die = 1;
|
||||
} else if (errno != 0) {
|
||||
|
@ -372,7 +375,7 @@ getkey(int keytmout)
|
|||
}
|
||||
}
|
||||
if (cc == '\r') /* undo the exchange of \n and \r determined by */
|
||||
cc = '\n'; /* setterm() */
|
||||
cc = '\n'; /* zsetterm() */
|
||||
else if (cc == '\n')
|
||||
cc = '\r';
|
||||
|
||||
|
@ -485,7 +488,7 @@ zleread(char *lp, char *rp, int ha)
|
|||
initmodifier(&zmod);
|
||||
prefixflag = 0;
|
||||
feepflag = 0;
|
||||
refresh();
|
||||
zrefresh();
|
||||
while (!done && !errflag) {
|
||||
|
||||
statusline = NULL;
|
||||
|
@ -516,11 +519,11 @@ zleread(char *lp, char *rp, int ha)
|
|||
tv.tv_usec = 500000;
|
||||
if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd,
|
||||
NULL, NULL, &tv) <= 0)
|
||||
refresh();
|
||||
zrefresh();
|
||||
} else
|
||||
#endif
|
||||
if (!kungetct)
|
||||
refresh();
|
||||
zrefresh();
|
||||
handlefeep();
|
||||
}
|
||||
statusline = NULL;
|
||||
|
@ -562,12 +565,17 @@ execzlefunc(Thingy func)
|
|||
showmsg(msg);
|
||||
zsfree(msg);
|
||||
feep();
|
||||
} else if((w = func->widget)->flags & WIDGET_INT) {
|
||||
} else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_COMP)) {
|
||||
int wflags = w->flags;
|
||||
|
||||
if(!(wflags & ZLE_KEEPSUFFIX))
|
||||
removesuffix();
|
||||
if(!(wflags & ZLE_MENUCMP)) {
|
||||
if(!(wflags & ZLE_MENUCMP) ||
|
||||
((wflags & WIDGET_COMP) && compwidget != w)) {
|
||||
/* If we are doing a special completion, and the widget
|
||||
* is not the one currently in use for special completion,
|
||||
* we are starting a new completion.
|
||||
*/
|
||||
fixsuffix();
|
||||
invalidatelist();
|
||||
}
|
||||
|
@ -575,8 +583,13 @@ execzlefunc(Thingy func)
|
|||
vilinerange = 1;
|
||||
if(!(wflags & ZLE_LASTCOL))
|
||||
lastcol = -1;
|
||||
w->u.fn();
|
||||
lastcmd = wflags;
|
||||
if (wflags & WIDGET_COMP) {
|
||||
compwidget = w;
|
||||
completespecial();
|
||||
} else
|
||||
w->u.fn();
|
||||
if (!(wflags & ZLE_NOTCOMMAND))
|
||||
lastcmd = wflags;
|
||||
} else {
|
||||
List l = getshfunc(w->u.fnnam);
|
||||
|
||||
|
@ -743,7 +756,7 @@ describekeybriefly(void)
|
|||
return;
|
||||
statusline = "Describe key briefly: _";
|
||||
statusll = strlen(statusline);
|
||||
refresh();
|
||||
zrefresh();
|
||||
seq = getkeymapcmd(curkeymap, &func, &str);
|
||||
statusline = NULL;
|
||||
if(!*seq)
|
||||
|
@ -811,14 +824,14 @@ void
|
|||
trashzle(void)
|
||||
{
|
||||
if (zleactive) {
|
||||
/* This refresh() is just to get the main editor display right and *
|
||||
* get the cursor in the right place. For that reason, we disable *
|
||||
* list display (which would otherwise result in infinite *
|
||||
* recursion [at least, it would if refresh() didn't have its *
|
||||
* extra `inlist' check]). */
|
||||
/* This zrefresh() is just to get the main editor display right and *
|
||||
* get the cursor in the right place. For that reason, we disable *
|
||||
* list display (which would otherwise result in infinite *
|
||||
* recursion [at least, it would if zrefresh() didn't have its *
|
||||
* extra `inlist' check]). */
|
||||
int sl = showinglist;
|
||||
showinglist = 0;
|
||||
refresh();
|
||||
zrefresh();
|
||||
showinglist = sl;
|
||||
moveto(nlnct, 0);
|
||||
if (clearflag && tccan(TCCLEAREOD)) {
|
||||
|
@ -838,7 +851,7 @@ trashzle(void)
|
|||
static struct builtin bintab[] = {
|
||||
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL),
|
||||
BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL),
|
||||
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANL", NULL),
|
||||
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgG", NULL),
|
||||
};
|
||||
|
||||
/**/
|
||||
|
@ -848,7 +861,7 @@ boot_zle(Module m)
|
|||
/* Set up editor entry points */
|
||||
trashzleptr = trashzle;
|
||||
gotwordptr = gotword;
|
||||
refreshptr = refresh;
|
||||
refreshptr = zrefresh;
|
||||
spaceinlineptr = spaceinline;
|
||||
zlereadptr = zleread;
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ quotedinsert(void)
|
|||
#endif
|
||||
c = getkey(0);
|
||||
#ifndef HAS_TIO
|
||||
setterm();
|
||||
zsetterm();
|
||||
#endif
|
||||
if (c < 0)
|
||||
feep();
|
||||
|
@ -621,7 +621,7 @@ executenamedcommand(char *prmt)
|
|||
for (;;) {
|
||||
*ptr = '_';
|
||||
statusll = l + len + 1;
|
||||
refresh();
|
||||
zrefresh();
|
||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||
statusline = NULL;
|
||||
selectkeymap(okeymap, 1);
|
||||
|
@ -633,7 +633,7 @@ executenamedcommand(char *prmt)
|
|||
redisplay();
|
||||
} else if(cmd == Th(z_viquotedinsert)) {
|
||||
*ptr = '^';
|
||||
refresh();
|
||||
zrefresh();
|
||||
c = getkey(0);
|
||||
if(c == EOF || !c || len == NAMLEN)
|
||||
feep();
|
||||
|
|
|
@ -47,7 +47,7 @@ int nlnct;
|
|||
|
||||
/* Most lines of the buffer we've shown at once with the current list *
|
||||
* showing. == 0 if there is no list. == -1 if a new list has just *
|
||||
* been put on the screen. == -2 if refresh() needs to put up a new *
|
||||
* been put on the screen. == -2 if zrefresh() needs to put up a new *
|
||||
* list. */
|
||||
|
||||
/**/
|
||||
|
@ -55,7 +55,7 @@ int showinglist;
|
|||
|
||||
/* Non-zero if ALWAYS_LAST_PROMPT has been used, meaning that the *
|
||||
* screen below the buffer display should not be cleared by *
|
||||
* refresh(), but should be by trashzle(). */
|
||||
* zrefresh(), but should be by trashzle(). */
|
||||
|
||||
/**/
|
||||
int clearflag;
|
||||
|
@ -75,7 +75,7 @@ int cost;
|
|||
#endif
|
||||
|
||||
/* Oct/Nov 94: <mason> some code savagely redesigned to fix several bugs -
|
||||
refreshline() & tc_rightcurs() majorly rewritten; refresh() fixed -
|
||||
refreshline() & tc_rightcurs() majorly rewritten; zrefresh() fixed -
|
||||
I've put my fingers into just about every routine in here -
|
||||
any queries about updates to mason@werple.net.au */
|
||||
|
||||
|
@ -224,7 +224,7 @@ static int cleareol, /* clear to end-of-line (if can't cleareod) */
|
|||
|
||||
/**/
|
||||
void
|
||||
refresh(void)
|
||||
zrefresh(void)
|
||||
{
|
||||
static int inlist; /* avoiding recursion */
|
||||
int canscroll = 0, /* number of lines we are allowed to scroll */
|
||||
|
@ -240,7 +240,7 @@ refresh(void)
|
|||
char **qbuf; /* tmp */
|
||||
|
||||
/* If this is called from listmatches() (indirectly via trashzle()), and *
|
||||
* that was called from the end of refresh(), then we don't need to do *
|
||||
* that was called from the end of zrefresh(), then we don't need to do *
|
||||
* anything. All this `inlist' code is actually unnecessary, but it *
|
||||
* improves speed a little in a common case. */
|
||||
if (inlist)
|
||||
|
@ -263,7 +263,7 @@ refresh(void)
|
|||
termflags &= ~TERM_SHORT;
|
||||
if (resetneeded) {
|
||||
onumscrolls = 0;
|
||||
setterm();
|
||||
zsetterm();
|
||||
#ifdef TIOCGWINSZ
|
||||
if (winchanged) {
|
||||
moveto(0, 0);
|
||||
|
@ -547,7 +547,7 @@ individually */
|
|||
inlist = 1;
|
||||
listmatches();
|
||||
inlist = 0;
|
||||
refresh();
|
||||
zrefresh();
|
||||
}
|
||||
if (showinglist == -1)
|
||||
showinglist = nlnct;
|
||||
|
|
|
@ -244,7 +244,9 @@ unbindwidget(Thingy t, int override)
|
|||
static void
|
||||
freewidget(Widget w)
|
||||
{
|
||||
if(!(w->flags & WIDGET_INT))
|
||||
if ((w->flags & WIDGET_COMP) && w->u.cc)
|
||||
freecompctl(w->u.cc);
|
||||
else if(!(w->flags & WIDGET_INT))
|
||||
zsfree(w->u.fnnam);
|
||||
zfree(w, sizeof(*w));
|
||||
}
|
||||
|
@ -334,6 +336,7 @@ bin_zle(char *name, char **args, char *ops, int func)
|
|||
{ 'D', bin_zle_del, 1, -1 },
|
||||
{ 'A', bin_zle_link, 2, 2 },
|
||||
{ 'N', bin_zle_new, 1, 2 },
|
||||
{ 'C', bin_zle_compctl, 1, -1},
|
||||
{ 0, bin_zle_call, 0, -1 },
|
||||
};
|
||||
struct opn const *op, *opp;
|
||||
|
@ -385,17 +388,24 @@ scanlistwidgets(HashNode hn, int list)
|
|||
if(w->flags & WIDGET_INT)
|
||||
return;
|
||||
if(list) {
|
||||
fputs("zle -N ", stdout);
|
||||
fputs((w->flags & WIDGET_COMP) ? "zle -C " : "zle -N ", stdout);
|
||||
if(t->nam[0] == '-')
|
||||
fputs("-- ", stdout);
|
||||
quotedzputs(t->nam, stdout);
|
||||
if(strcmp(t->nam, w->u.fnnam)) {
|
||||
if (w->flags & WIDGET_COMP) {
|
||||
if (printcompctlptr && w->u.cc)
|
||||
printcompctlptr(NULL, w->u.cc, PRINT_LIST);
|
||||
} else if(strcmp(t->nam, w->u.fnnam)) {
|
||||
fputc(' ', stdout);
|
||||
quotedzputs(w->u.fnnam, stdout);
|
||||
}
|
||||
} else {
|
||||
nicezputs(t->nam, stdout);
|
||||
if(strcmp(t->nam, w->u.fnnam)) {
|
||||
if (w->flags & WIDGET_COMP) {
|
||||
fputs(" -C", stdout);
|
||||
if (printcompctlptr && w->u.cc)
|
||||
printcompctlptr(NULL, w->u.cc, PRINT_TYPE);
|
||||
} else if(strcmp(t->nam, w->u.fnnam)) {
|
||||
fputs(" (", stdout);
|
||||
nicezputs(w->u.fnnam, stdout);
|
||||
fputc(')', stdout);
|
||||
|
@ -456,6 +466,44 @@ bin_zle_new(char *name, char **args, char *ops, char func)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zle_compctl(char *name, char **args, char *ops, char func)
|
||||
{
|
||||
Compctl cc = NULL;
|
||||
Widget w;
|
||||
char *wname = args[0];
|
||||
|
||||
if (!compctl_widgetptr) {
|
||||
zwarnnam(name, "compctl module is not loaded", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
args++;
|
||||
|
||||
if (*args && !(cc = compctl_widgetptr(name, args)))
|
||||
return 1;
|
||||
|
||||
w = zalloc(sizeof(*w));
|
||||
w->flags = WIDGET_COMP|ZLE_MENUCMP|ZLE_KEEPSUFFIX;
|
||||
w->first = NULL;
|
||||
w->u.cc = cc;
|
||||
if(bindwidget(w, rthingy(wname))) {
|
||||
freewidget(w);
|
||||
zerrnam(name, "widget name `%s' is protected", wname, 0);
|
||||
return 1;
|
||||
}
|
||||
if (ops['m'])
|
||||
w->flags |= ZLE_USEMENU;
|
||||
else if (ops['M'])
|
||||
w->flags |= ZLE_NOMENU;
|
||||
if (ops['g'])
|
||||
w->flags |= ZLE_USEGLOB;
|
||||
else if (ops['G'])
|
||||
w->flags |= ZLE_NOGLOB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
bin_zle_call(char *name, char **args, char *ops, char func)
|
||||
|
|
4057
Src/Zle/zle_tricky.c
4057
Src/Zle/zle_tricky.c
File diff suppressed because it is too large
Load diff
|
@ -420,7 +420,7 @@ void
|
|||
handlefeep(void)
|
||||
{
|
||||
if(feepflag)
|
||||
beep();
|
||||
zbeep();
|
||||
feepflag = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ vigetkey(void)
|
|||
char sav = line[cs];
|
||||
|
||||
line[cs] = '^';
|
||||
refresh();
|
||||
zrefresh();
|
||||
c = getkey(0);
|
||||
line[cs] = sav;
|
||||
if(c == EOF) {
|
||||
|
@ -814,10 +814,10 @@ viswapcase(void)
|
|||
void
|
||||
vicapslockpanic(void)
|
||||
{
|
||||
beep();
|
||||
zbeep();
|
||||
statusline = "press a lowercase key to continue";
|
||||
statusll = strlen(statusline);
|
||||
refresh();
|
||||
zrefresh();
|
||||
while (!islower(getkey(0)));
|
||||
statusline = NULL;
|
||||
}
|
||||
|
@ -891,7 +891,7 @@ viquotedinsert(void)
|
|||
|
||||
spaceinline(1);
|
||||
line[cs] = '^';
|
||||
refresh();
|
||||
zrefresh();
|
||||
#ifndef HAS_TIO
|
||||
sob = shttyinfo.sgttyb;
|
||||
sob.sg_flags = (sob.sg_flags | RAW) & ~ECHO;
|
||||
|
@ -899,7 +899,7 @@ viquotedinsert(void)
|
|||
#endif
|
||||
c = getkey(0);
|
||||
#ifndef HAS_TIO
|
||||
setterm();
|
||||
zsetterm();
|
||||
#endif
|
||||
foredel(1);
|
||||
if(c < 0)
|
||||
|
|
|
@ -2627,14 +2627,14 @@ bin_getopts(char *name, char **argv, char *ops, int func)
|
|||
if(opch == ':' || !(p = memchr(optstr, opch, lenoptstr))) {
|
||||
p = "?";
|
||||
err:
|
||||
zsfree(zoptarg);
|
||||
zsfree(zoptarg);
|
||||
if(quiet) {
|
||||
setsparam(var, ztrdup(p));
|
||||
zoptarg = metafy(optbuf, lenoptbuf, META_DUP);
|
||||
} else {
|
||||
zerr(*p == '?' ? "bad option: -%c" :
|
||||
"argument expected after -%c option", NULL, opch);
|
||||
zoptarg=ztrdup("");
|
||||
zoptarg=ztrdup("");
|
||||
errflag = 0;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1992,8 +1992,8 @@ restore_params(LinkList restorelist, LinkList removelist)
|
|||
}
|
||||
} else
|
||||
paramtab->addnode(paramtab, pm->nam, pm);
|
||||
if (pm->flags & PM_EXPORTED)
|
||||
pm->env = addenv(pm->nam, getsparam(pm->nam));
|
||||
if ((pm->flags & PM_EXPORTED) && ((s = getsparam(pm->nam))))
|
||||
pm->env = addenv(pm->nam, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
169
Src/glob.c
169
Src/glob.c
|
@ -110,6 +110,8 @@ struct comp {
|
|||
#define C_CLOSURE (C_ONEHASH|C_TWOHASH|C_OPTIONAL|C_STAR)
|
||||
#define C_LAST 16
|
||||
#define C_PATHADD 32
|
||||
#define C_LCMATCHUC 64
|
||||
#define C_IGNCASE 128
|
||||
|
||||
/* Test macros for the above */
|
||||
#define CLOSUREP(c) (c->stat & C_CLOSURE)
|
||||
|
@ -305,15 +307,24 @@ scanner(Complist q)
|
|||
if (!q)
|
||||
return;
|
||||
|
||||
if ((closure = q->closure)) /* (foo/)# - match zero or more dirs */
|
||||
if ((closure = q->closure)) {
|
||||
/* (foo/)# - match zero or more dirs */
|
||||
if (q->closure == 2) /* (foo/)## - match one or more dirs */
|
||||
q->closure = 1;
|
||||
else
|
||||
scanner(q->next);
|
||||
}
|
||||
c = q->comp;
|
||||
/* Now the actual matching for the current path section. */
|
||||
if (!(c->next || c->left) && !haswilds(c->str)) {
|
||||
/* It's a straight string to the end of the path section. */
|
||||
if (!(c->next || c->left) && !haswilds(c->str)
|
||||
&& (!(c->stat & (C_LCMATCHUC|C_IGNCASE))
|
||||
|| !strcmp(".", c->str) || !strcmp("..", c->str))) {
|
||||
/*
|
||||
* We always need to match . and .. explicitly, even if we're
|
||||
* checking other strings for case-insensitive matches.
|
||||
*
|
||||
* It's a straight string to the end of the path section.
|
||||
*/
|
||||
int l = strlen(c->str);
|
||||
|
||||
if (l + !l + pathpos - pathbufcwd >= PATH_MAX) {
|
||||
|
@ -436,6 +447,52 @@ scanner(Complist q)
|
|||
|
||||
/* Parse a series of path components pointed to by pptr */
|
||||
|
||||
/* Flags to apply to current level of grourping */
|
||||
|
||||
static int addflags;
|
||||
|
||||
/**/
|
||||
static Comp
|
||||
compalloc(void)
|
||||
{
|
||||
Comp c = (Comp) alloc(sizeof *c);
|
||||
c->stat |= addflags;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
getglobflags()
|
||||
{
|
||||
/* (#X): assumes we are still positioned on the initial '(' */
|
||||
pptr++;
|
||||
while (*++pptr && *pptr != Outpar) {
|
||||
switch (*pptr) {
|
||||
case 'l':
|
||||
/* Lowercase in pattern matches lower or upper in target */
|
||||
addflags |= C_LCMATCHUC;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
/* Fully case insensitive */
|
||||
addflags |= C_IGNCASE;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
/* Restore case sensitivity */
|
||||
addflags &= ~(C_LCMATCHUC|C_IGNCASE);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (*pptr != Outpar)
|
||||
return 1;
|
||||
pptr++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* enum used with ksh-like patterns, @(...) etc. */
|
||||
|
||||
enum { KF_NONE, KF_AT, KF_QUEST, KF_STAR, KF_PLUS, KF_NOT };
|
||||
|
@ -447,7 +504,7 @@ static Comp
|
|||
parsecomp(int gflag)
|
||||
{
|
||||
int kshfunc;
|
||||
Comp c = (Comp) alloc(sizeof *c), c1, c2;
|
||||
Comp c = compalloc(), c1, c2;
|
||||
char *cstr, *ls = NULL;
|
||||
|
||||
/* In case of alternatives, code coming up is stored in tail. */
|
||||
|
@ -468,10 +525,10 @@ parsecomp(int gflag)
|
|||
c->str = dupstrpfx(cstr, pptr - cstr);
|
||||
pptr++;
|
||||
|
||||
c1 = (Comp) alloc(sizeof *c1);
|
||||
c1 = compalloc();
|
||||
c1->stat |= C_STAR;
|
||||
|
||||
c2 = (Comp) alloc(sizeof *c2);
|
||||
c2 = compalloc();
|
||||
if (!(c2->exclude = parsecomp(gflag)))
|
||||
return NULL;
|
||||
if (!*pptr || *pptr == '/')
|
||||
|
@ -513,6 +570,39 @@ parsecomp(int gflag)
|
|||
pptr++;
|
||||
}
|
||||
|
||||
if (*pptr == Inpar && pptr[1] == Pound) {
|
||||
/* Found some globbing flags */
|
||||
char *eptr = pptr;
|
||||
if (kshfunc != KF_NONE)
|
||||
eptr--;
|
||||
if (getglobflags())
|
||||
return NULL;
|
||||
if (eptr == cstr) {
|
||||
/* if no string yet, carry on and get one. */
|
||||
c->stat = addflags;
|
||||
cstr = pptr;
|
||||
continue;
|
||||
}
|
||||
c->str = dupstrpfx(cstr, eptr - cstr);
|
||||
/*
|
||||
* The next bit simply handles the case where . or ..
|
||||
* is followed by a set of flags, but we need to force
|
||||
* them to be handled as a string. Hardly worth it.
|
||||
*/
|
||||
if (!*pptr || (!mode && *pptr == '/') || *pptr == Bar ||
|
||||
(isset(EXTENDEDGLOB) && *pptr == Tilde &&
|
||||
pptr[1] && pptr[1] != Outpar && pptr[1] != Bar) ||
|
||||
*pptr == Outpar) {
|
||||
if (*pptr == '/' || !*pptr ||
|
||||
(isset(EXTENDEDGLOB) && *pptr == Tilde &&
|
||||
(gflag & GF_TOPLEV)))
|
||||
c->stat |= C_LAST;
|
||||
return c;
|
||||
}
|
||||
if (!(c->next = parsecomp(gflag)))
|
||||
return NULL;
|
||||
return c;
|
||||
}
|
||||
if (*pptr == Inpar) {
|
||||
/* Found a group (...) */
|
||||
char *startp = pptr, *endp;
|
||||
|
@ -552,16 +642,16 @@ parsecomp(int gflag)
|
|||
pptr = startp;
|
||||
c->str = dupstrpfx(cstr, (pptr - cstr) - (kshfunc != KF_NONE));
|
||||
pptr++;
|
||||
c2 = (Comp) alloc(sizeof *c);
|
||||
c2 = compalloc();
|
||||
c->next = c2;
|
||||
c2->next = (dpnd || kshfunc == KF_NOT) ?
|
||||
c1 : (Comp) alloc(sizeof *c);
|
||||
c1 : compalloc();
|
||||
if (!(c2->left = parsecompsw(0)))
|
||||
return NULL;
|
||||
if (kshfunc == KF_NOT) {
|
||||
/* we'd actually rather it didn't match. Instead, match *
|
||||
* a star and put the parsed pattern into exclude. */
|
||||
Comp c3 = (Comp) alloc(sizeof *c3);
|
||||
Comp c3 = compalloc();
|
||||
c3->stat |= C_STAR;
|
||||
|
||||
c2->exclude = c2->left;
|
||||
|
@ -584,7 +674,7 @@ parsecomp(int gflag)
|
|||
*/
|
||||
c->str = dupstrpfx(cstr, pptr - cstr);
|
||||
pptr++;
|
||||
c1 = (Comp) alloc(sizeof *c1);
|
||||
c1 = compalloc();
|
||||
c1->stat |= C_STAR;
|
||||
if (!(c2 = parsecomp(gflag)))
|
||||
return NULL;
|
||||
|
@ -596,13 +686,13 @@ parsecomp(int gflag)
|
|||
/* repeat whatever we've just had (ls) zero or more times */
|
||||
if (!ls)
|
||||
return NULL;
|
||||
c2 = (Comp) alloc(sizeof *c);
|
||||
c2 = compalloc();
|
||||
c2->str = dupstrpfx(ls, pptr - ls);
|
||||
pptr++;
|
||||
if (*pptr == Pound) {
|
||||
/* need one or more matches: cheat by copying previous char */
|
||||
pptr++;
|
||||
c->next = c1 = (Comp) alloc(sizeof *c);
|
||||
c->next = c1 = compalloc();
|
||||
c1->str = c2->str;
|
||||
} else
|
||||
c1 = c;
|
||||
|
@ -669,6 +759,7 @@ static Comp
|
|||
parsecompsw(int gflag)
|
||||
{
|
||||
Comp c1, c2, c3, excl = NULL, stail = tail;
|
||||
int oaddflags = addflags;
|
||||
char *sptr;
|
||||
|
||||
/*
|
||||
|
@ -709,7 +800,7 @@ parsecompsw(int gflag)
|
|||
tail = stail;
|
||||
if (*pptr == Bar || excl) {
|
||||
/* found an alternative or something to exclude */
|
||||
c2 = (Comp) alloc(sizeof *c2);
|
||||
c2 = compalloc();
|
||||
if (*pptr == Bar) {
|
||||
/* get the next alternative after the | */
|
||||
pptr++;
|
||||
|
@ -728,8 +819,10 @@ parsecompsw(int gflag)
|
|||
c2->next = stail;
|
||||
if (gflag & GF_PATHADD)
|
||||
c2->stat |= C_PATHADD;
|
||||
return c2;
|
||||
c1 = c2;
|
||||
}
|
||||
if (!(gflag & GF_TOPLEV))
|
||||
addflags = oaddflags;
|
||||
return c1;
|
||||
}
|
||||
|
||||
|
@ -758,7 +851,7 @@ parsecomplist(void)
|
|||
errflag = 1;
|
||||
return NULL;
|
||||
}
|
||||
p1->comp = (Comp) alloc(sizeof *p1->comp);
|
||||
p1->comp = compalloc();
|
||||
p1->comp->stat |= C_LAST; /* end of path component */
|
||||
p1->comp->str = dupstring("*");
|
||||
*p1->comp->str = Star; /* match anything... */
|
||||
|
@ -814,8 +907,28 @@ static Complist
|
|||
parsepat(char *str)
|
||||
{
|
||||
mode = 0; /* path components present */
|
||||
addflags = 0;
|
||||
pptr = str;
|
||||
tail = NULL;
|
||||
/*
|
||||
* Check for initial globbing flags, so that they don't form
|
||||
* a bogus path component.
|
||||
*/
|
||||
if (*pptr == Inpar && pptr[1] == Pound && isset(EXTENDEDGLOB) &&
|
||||
getglobflags())
|
||||
return NULL;
|
||||
|
||||
/* Now there is no (#X) in front, we can check the path. */
|
||||
if (!pathbuf)
|
||||
pathbuf = zalloc(pathbufsz = PATH_MAX);
|
||||
DPUTS(pathbufcwd, "BUG: glob changed directory");
|
||||
if (*pptr == '/') { /* pattern has absolute path */
|
||||
pptr++;
|
||||
pathbuf[0] = '/';
|
||||
pathbuf[pathpos = 1] = '\0';
|
||||
} else /* pattern is relative to pwd */
|
||||
pathbuf[pathpos = 0] = '\0';
|
||||
|
||||
return parsecomplist();
|
||||
}
|
||||
|
||||
|
@ -897,7 +1010,7 @@ glob(LinkList list, LinkNode np)
|
|||
if (*s == Bar || *s == Outpar ||
|
||||
(isset(EXTENDEDGLOB) && *s == Tilde))
|
||||
break;
|
||||
if (*s == Inpar) {
|
||||
if (*s == Inpar && (!isset(EXTENDEDGLOB) || s[1] != Pound)) {
|
||||
/* Real qualifiers found. */
|
||||
int sense = 0; /* bit 0 for match (0)/don't match (1) */
|
||||
/* bit 1 for follow links (2), don't (0) */
|
||||
|
@ -1234,15 +1347,6 @@ glob(LinkList list, LinkNode np)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!pathbuf)
|
||||
pathbuf = zalloc(pathbufsz = PATH_MAX);
|
||||
DPUTS(pathbufcwd, "BUG: glob changed directory");
|
||||
if (*str == '/') { /* pattern has absolute path */
|
||||
str++;
|
||||
pathbuf[0] = '/';
|
||||
pathbuf[pathpos = 1] = '\0';
|
||||
} else /* pattern is relative to pwd */
|
||||
pathbuf[pathpos = 0] = '\0';
|
||||
q = parsepat(str);
|
||||
if (!q || errflag) { /* if parsing failed */
|
||||
if (unset(BADPATTERN)) {
|
||||
|
@ -1267,7 +1371,7 @@ glob(LinkList list, LinkNode np)
|
|||
/* Deal with failures to match depending on options */
|
||||
if (matchct)
|
||||
badcshglob |= 2; /* at least one cmd. line expansion O.K. */
|
||||
else if (!gf_nullglob)
|
||||
else if (!gf_nullglob) {
|
||||
if (isset(CSHNULLGLOB)) {
|
||||
badcshglob |= 1; /* at least one cmd. line expansion failed */
|
||||
} else if (isset(NOMATCH)) {
|
||||
|
@ -1279,6 +1383,7 @@ glob(LinkList list, LinkNode np)
|
|||
untokenize(*matchptr++ = dupstring(ostr));
|
||||
matchct = 1;
|
||||
}
|
||||
}
|
||||
/* Sort arguments in to lexical (and possibly numeric) order. *
|
||||
* This is reversed to facilitate insertion into the list. */
|
||||
qsort((void *) & matchbuf[0], matchct, sizeof(char *),
|
||||
|
@ -1373,11 +1478,12 @@ hasbraces(char *str)
|
|||
*str++ = '{', *str = '}';
|
||||
else
|
||||
bc++;
|
||||
} else if (*str == Outbrace)
|
||||
} else if (*str == Outbrace) {
|
||||
if (!bc)
|
||||
*str = '}';
|
||||
else if (!--bc)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* Otherwise we need to look for... */
|
||||
|
@ -1554,11 +1660,12 @@ xpandbraces(LinkList list, LinkNode *np)
|
|||
else if (*str2 == Outbrace) {
|
||||
if (--bc == 0)
|
||||
break;
|
||||
} else if (bc == 1)
|
||||
} else if (bc == 1) {
|
||||
if (*str2 == Comma)
|
||||
++comma; /* we have {foo,bar} */
|
||||
else if (*str2 == '.' && str2[1] == '.')
|
||||
dotdot++; /* we have {num1..num2} */
|
||||
}
|
||||
DPUTS(bc, "BUG: unmatched brace in xpandbraces()");
|
||||
if (!comma && dotdot) {
|
||||
/* Expand range like 0..10 numerically: comma or recursive
|
||||
|
@ -2489,7 +2596,10 @@ matchonce(Comp c)
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (*pptr == *pat) {
|
||||
if (*pptr == *pat ||
|
||||
(((c->stat & C_IGNCASE) ? (tulower(*pat) == tulower(*pptr)) :
|
||||
(c->stat & C_LCMATCHUC) ?
|
||||
(islower(*pat) && tuupper(*pat) == *pptr) : 0))) {
|
||||
/* just plain old characters */
|
||||
pptr++;
|
||||
pat++;
|
||||
|
@ -2508,6 +2618,7 @@ parsereg(char *str)
|
|||
{
|
||||
remnulargs(str);
|
||||
mode = 1; /* no path components */
|
||||
addflags = 0;
|
||||
pptr = str;
|
||||
tail = NULL;
|
||||
return parsecompsw(GF_TOPLEV);
|
||||
|
|
|
@ -214,7 +214,7 @@ update_job(Job jn)
|
|||
if ((isset(NOTIFY) || job == thisjob) && (jn->stat & STAT_LOCKED)) {
|
||||
printjob(jn, !!isset(LONGLISTJOBS), 0);
|
||||
if (zleactive)
|
||||
refresh();
|
||||
zrefresh();
|
||||
}
|
||||
if (sigtrapped[SIGCHLD] && job != thisjob)
|
||||
dotrap(SIGCHLD);
|
||||
|
|
|
@ -145,6 +145,11 @@ if $first_stage; then
|
|||
echo "PROTOS =$all_proto"
|
||||
echo "SUBDIRS =$all_subdirs"
|
||||
echo
|
||||
echo "ENTRYOBJ = \$(dir_src)/modentry..o"
|
||||
echo "NNTRYOBJ ="
|
||||
echo "ENTRYOPT = -emodentry"
|
||||
echo "NNTRYOPT ="
|
||||
echo
|
||||
|
||||
echo "##### ===== INCLUDING Makemod.in.in ===== #####"
|
||||
echo
|
||||
|
@ -161,7 +166,7 @@ if $first_stage; then
|
|||
remote_mdhs=
|
||||
for module in $here_modules; do
|
||||
|
||||
unset moddeps nozshdep alwayslink
|
||||
unset moddeps nozshdep alwayslink hasexport
|
||||
unset autobins
|
||||
unset objects proto headers hdrdeps otherincs
|
||||
. $top_srcdir/$the_subdir/${module}.mdd
|
||||
|
@ -172,8 +177,10 @@ if $first_stage; then
|
|||
|
||||
dobjects=`echo $objects '' | sed 's,\.o ,..o ,g'`
|
||||
modhdeps=
|
||||
imports=
|
||||
for dep in $moddeps; do
|
||||
eval "loc=\$loc_$dep"
|
||||
imports="$imports \$(IMPOPT)\$(sdir_top)/$loc/$dep.export"
|
||||
case $the_subdir in
|
||||
$loc)
|
||||
mdh="${dep}.mdh"
|
||||
|
@ -199,9 +206,11 @@ if $first_stage; then
|
|||
echo "##### ===== DEPENDENCIES GENERATED FROM ${module}.mdd ===== #####"
|
||||
echo
|
||||
echo "MODOBJS_${module} = $objects"
|
||||
echo "MODDOBJS_${module} = $dobjects"
|
||||
echo "MODDOBJS_${module} = $dobjects \$(@E@NTRYOBJ)"
|
||||
echo "PROTO_${module} = $proto"
|
||||
echo "INCS_${module} = \$(PROTO_${module}) $otherincs"
|
||||
echo "EXPIMP_${module} = $imports ${hasexport+\$(EXPOPT)\$(sdir)/$module.export}"
|
||||
echo "NXPIMP_${module} ="
|
||||
echo
|
||||
echo "proto.${module}: \$(PROTO_${module})"
|
||||
echo "\$(PROTO_${module}): \$(PROTODEPS)"
|
||||
|
@ -212,7 +221,7 @@ if $first_stage; then
|
|||
if test -z "$alwayslink"; then
|
||||
echo "${module}.\$(DL_EXT): \$(MODDOBJS_${module})"
|
||||
echo ' rm -f $@'
|
||||
echo " \$(DLLINK) \$(MODDOBJS_${module}) \$(LIBS)"
|
||||
echo " \$(DLLINK) \$(@E@XPIMP_$module) \$(@E@NTRYOPT) \$(MODDOBJS_${module}) \$(LIBS)"
|
||||
echo
|
||||
fi
|
||||
echo "${module}.mdhi: ${module}.mdhs \$(INCS_${module})"
|
||||
|
|
15
Src/modentry.c
Normal file
15
Src/modentry.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include "zsh.mdh"
|
||||
|
||||
int boot_ _((Module));
|
||||
int cleanup_ _((Module));
|
||||
int modentry _((int boot, Module m));
|
||||
|
||||
/**/
|
||||
int
|
||||
modentry(int boot, Module m)
|
||||
{
|
||||
if (boot)
|
||||
return boot_(m);
|
||||
else
|
||||
return cleanup_(m);
|
||||
}
|
136
Src/module.c
136
Src/module.c
|
@ -161,6 +161,44 @@ deletebuiltins(char const *nam, Builtin binl, int size)
|
|||
return hadf ? hads : 1;
|
||||
}
|
||||
|
||||
#ifdef AIXDYNAMIC
|
||||
|
||||
#include <sys/ldr.h>
|
||||
|
||||
static char *dlerrstr[256];
|
||||
|
||||
/**/
|
||||
static void *
|
||||
load_and_bind(const char *fn)
|
||||
{
|
||||
void *ret = (void *) load((char *) fn, L_NOAUTODEFER, NULL);
|
||||
|
||||
if (ret) {
|
||||
LinkNode node;
|
||||
int err = loadbind(0, (void *) addbuiltin, ret);
|
||||
for (node = firstnode(modules); !err && node; incnode(node)) {
|
||||
Module m = (Module) getdata(node);
|
||||
if (m->handle)
|
||||
err |= loadbind(0, m->handle, ret);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
loadquery(L_GETMESSAGES, dlerrstr, sizeof(dlerrstr));
|
||||
unload(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
} else
|
||||
loadquery(L_GETMESSAGES, dlerrstr, sizeof(dlerrstr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define dlopen(X,Y) load_and_bind(X)
|
||||
#define dlclose(X) unload(X)
|
||||
#define dlerror() (dlerrstr[0])
|
||||
|
||||
#else
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
# include <dlfcn.h>
|
||||
#else
|
||||
|
@ -168,12 +206,6 @@ deletebuiltins(char const *nam, Builtin binl, int size)
|
|||
# include <nlist.h>
|
||||
# include <link.h>
|
||||
#endif
|
||||
#ifndef RTLD_LAZY
|
||||
# define RTLD_LAZY 1
|
||||
#endif
|
||||
#ifndef RTLD_GLOBAL
|
||||
# define RTLD_GLOBAL 0
|
||||
#endif
|
||||
#ifndef HAVE_DLCLOSE
|
||||
# define dlclose(X) ((X), 0)
|
||||
#endif
|
||||
|
@ -189,6 +221,16 @@ deletebuiltins(char const *nam, Builtin binl, int size)
|
|||
# define STR_CLEANUP "cleanup_"
|
||||
# define STR_CLEANUP_S "cleanup_%s"
|
||||
#endif /* !DLSYM_NEEDS_UNDERSCORE */
|
||||
|
||||
#endif /* !AIXDYNAMIC */
|
||||
|
||||
#ifndef RTLD_LAZY
|
||||
# define RTLD_LAZY 1
|
||||
#endif
|
||||
#ifndef RTLD_GLOBAL
|
||||
# define RTLD_GLOBAL 0
|
||||
#endif
|
||||
|
||||
typedef int (*Module_func) _((Module));
|
||||
|
||||
/**/
|
||||
|
@ -257,6 +299,24 @@ find_module(const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef AIXDYNAMIC
|
||||
|
||||
/**/
|
||||
static int
|
||||
init_module(Module m)
|
||||
{
|
||||
return ((int (*)_((int,Module))) m->handle)(1, m);
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
cleanup_module(Module m)
|
||||
{
|
||||
return ((int (*)_((int,Module))) m->handle)(0, m);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/**/
|
||||
static int
|
||||
init_module(Module m)
|
||||
|
@ -288,6 +348,39 @@ init_module(Module m)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
cleanup_module(Module m)
|
||||
{
|
||||
char *s, *t;
|
||||
#ifndef DYNAMIC_NAME_CLASH_OK
|
||||
char buf[PATH_MAX + 1];
|
||||
#endif
|
||||
Module_func fn;
|
||||
|
||||
s = strrchr(m->nam, '/');
|
||||
if (s)
|
||||
s = dupstring(++s);
|
||||
else
|
||||
s = m->nam;
|
||||
if ((t = strrchr(s, '.')))
|
||||
*t = '\0';
|
||||
#ifdef DYNAMIC_NAME_CLASH_OK
|
||||
fn = (Module_func) dlsym(m->handle, STR_CLEANUP);
|
||||
#else /* !DYNAMIC_NAME_CLASH_OK */
|
||||
if (strlen(s) + 9 > PATH_MAX)
|
||||
return 1;
|
||||
sprintf(buf, STR_CLEANUP_S, s);
|
||||
fn = (Module_func) dlsym(m->handle, buf);
|
||||
#endif /* !DYNAMIC_NAME_CLASH_OK */
|
||||
if(fn)
|
||||
return fn(m);
|
||||
zwarnnam(m->nam, "no cleanup function", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* !AIXDYNAMIC */
|
||||
|
||||
/**/
|
||||
Module
|
||||
load_module(char const *name)
|
||||
|
@ -337,37 +430,6 @@ load_module(char const *name)
|
|||
return m;
|
||||
}
|
||||
|
||||
/**/
|
||||
static int
|
||||
cleanup_module(Module m)
|
||||
{
|
||||
char *s, *t;
|
||||
#ifndef DYNAMIC_NAME_CLASH_OK
|
||||
char buf[PATH_MAX + 1];
|
||||
#endif
|
||||
Module_func fn;
|
||||
|
||||
s = strrchr(m->nam, '/');
|
||||
if (s)
|
||||
s = dupstring(++s);
|
||||
else
|
||||
s = m->nam;
|
||||
if ((t = strrchr(s, '.')))
|
||||
*t = '\0';
|
||||
#ifdef DYNAMIC_NAME_CLASH_OK
|
||||
fn = (Module_func) dlsym(m->handle, STR_CLEANUP);
|
||||
#else /* !DYNAMIC_NAME_CLASH_OK */
|
||||
if (strlen(s) + 9 > PATH_MAX)
|
||||
return 1;
|
||||
sprintf(buf, STR_CLEANUP_S, s);
|
||||
fn = (Module_func) dlsym(m->handle, buf);
|
||||
#endif /* !DYNAMIC_NAME_CLASH_OK */
|
||||
if(fn)
|
||||
return fn(m);
|
||||
zwarnnam(m->nam, "no cleanup function", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**/
|
||||
void
|
||||
add_dep(char *name, char *from)
|
||||
|
|
|
@ -593,6 +593,12 @@ extern char PC, *BC, *UP;
|
|||
extern short ospeed;
|
||||
#endif
|
||||
|
||||
/* Rename some global zsh variables to avoid *
|
||||
* possible name clashes with libc */
|
||||
|
||||
#define cs zshcs
|
||||
#define ll zshll
|
||||
|
||||
#ifndef O_NOCTTY
|
||||
# define O_NOCTTY 0
|
||||
#endif
|
||||
|
|
16
Src/utils.c
16
Src/utils.c
|
@ -510,6 +510,10 @@ adduserdir(char *s, char *t, int flags, int always)
|
|||
if ((flags & ND_USERNAME) && nameddirtab->getnode2(nameddirtab, s))
|
||||
return;
|
||||
|
||||
/* Never hash PWD, because it's never useful */
|
||||
if (!strcmp(s, "PWD"))
|
||||
return;
|
||||
|
||||
/* Normal parameter assignments generate calls to this function, *
|
||||
* with always==0. Unless the AUTO_NAME_DIRS option is set, we *
|
||||
* don't let such assignments actually create directory names. *
|
||||
|
@ -854,7 +858,7 @@ adjustwinsize(void)
|
|||
setiparam("LINES", shttyinfo.winsize.ws_row);
|
||||
if (zleactive && (oldcols != columns || oldrows != lines)) {
|
||||
resetneeded = winchanged = 1;
|
||||
refresh();
|
||||
zrefresh();
|
||||
}
|
||||
#endif /* TIOCGWINSZ */
|
||||
}
|
||||
|
@ -1129,13 +1133,13 @@ checkrmall(char *s)
|
|||
if(isset(RMSTARWAIT)) {
|
||||
fputs("? (waiting ten seconds)", shout);
|
||||
fflush(shout);
|
||||
beep();
|
||||
zbeep();
|
||||
sleep(10);
|
||||
fputc('\n', shout);
|
||||
}
|
||||
fputs(" [yn]? ", shout);
|
||||
fflush(shout);
|
||||
beep();
|
||||
zbeep();
|
||||
return (getquery("ny", 1) == 'y');
|
||||
}
|
||||
|
||||
|
@ -1181,7 +1185,7 @@ getquery(char *valid_chars, int purge)
|
|||
write(SHTTY, "\n", 1);
|
||||
break;
|
||||
}
|
||||
beep();
|
||||
zbeep();
|
||||
if (icntrl(c))
|
||||
write(SHTTY, "\b \b", 3);
|
||||
write(SHTTY, "\b \b", 3);
|
||||
|
@ -1327,7 +1331,7 @@ spckword(char **s, int hist, int cmd, int ask)
|
|||
zputs(pptbuf, shout);
|
||||
free(pptbuf);
|
||||
fflush(shout);
|
||||
beep();
|
||||
zbeep();
|
||||
x = getquery("nyae ", 0);
|
||||
} else
|
||||
x = 'y';
|
||||
|
@ -2286,7 +2290,7 @@ mkarray(char *s)
|
|||
|
||||
/**/
|
||||
void
|
||||
beep(void)
|
||||
zbeep(void)
|
||||
{
|
||||
if (isset(BEEP))
|
||||
write(SHTTY, "\07", 1);
|
||||
|
|
235
Src/zsh.export
Normal file
235
Src/zsh.export
Normal file
|
@ -0,0 +1,235 @@
|
|||
#!
|
||||
SHTTY
|
||||
addbuiltins
|
||||
addedx
|
||||
addhashnode
|
||||
aliastab
|
||||
alloc_stackp
|
||||
appstr
|
||||
arrdup
|
||||
arrlen
|
||||
attachtty
|
||||
bangchar
|
||||
bin_notavail
|
||||
breaks
|
||||
bufstack
|
||||
builtintab
|
||||
chline
|
||||
chuck
|
||||
clearjobtab
|
||||
closem
|
||||
cmdnamtab
|
||||
columns
|
||||
compctlreadptr
|
||||
coprocin
|
||||
coprocout
|
||||
countlinknodes
|
||||
countprompt
|
||||
createparam
|
||||
ctxtlex
|
||||
curhist
|
||||
current_limits
|
||||
deletebuiltins
|
||||
deletehashtable
|
||||
domatch
|
||||
doshfunc
|
||||
dputs
|
||||
dquotedztrdup
|
||||
dummy_list
|
||||
dupstring
|
||||
dupstrpfx
|
||||
dyncat
|
||||
emptyhashtable
|
||||
endparamscope
|
||||
errflag
|
||||
excs
|
||||
execstring
|
||||
exlast
|
||||
expanding
|
||||
fallback_compctlread
|
||||
fallback_zleread
|
||||
fignore
|
||||
file_type
|
||||
filesub
|
||||
filesubstr
|
||||
findcmd
|
||||
firsthist
|
||||
freearray
|
||||
freeheap
|
||||
getaparam
|
||||
gethashnode
|
||||
gethashnode2
|
||||
getiparam
|
||||
getkeystring
|
||||
getlinknode
|
||||
getshfunc
|
||||
getsparam
|
||||
glob_pre
|
||||
glob_suf
|
||||
global_heapalloc
|
||||
global_permalloc
|
||||
globlist
|
||||
gotwordptr
|
||||
halloc
|
||||
hasam
|
||||
hashcmd
|
||||
hasher
|
||||
hasspecial
|
||||
haswilds
|
||||
hcalloc
|
||||
hgetc
|
||||
hgetline
|
||||
histentarr
|
||||
histentct
|
||||
hptr
|
||||
hrealloc
|
||||
inbufct
|
||||
incmdpos
|
||||
incond
|
||||
init_io
|
||||
init_shout
|
||||
init_term
|
||||
inpop
|
||||
inpush
|
||||
inredir
|
||||
insertlinknode
|
||||
intr
|
||||
inwhat
|
||||
isfirstln
|
||||
jobtab
|
||||
lastpid
|
||||
lastval
|
||||
lchdir
|
||||
lexrestore
|
||||
lexsave
|
||||
lexstop
|
||||
limits
|
||||
line
|
||||
lines
|
||||
locallevel
|
||||
metadiffer
|
||||
metafy
|
||||
metalen
|
||||
mode_to_octal
|
||||
mypgrp
|
||||
mypid
|
||||
nameddirtab
|
||||
ncalloc
|
||||
newhashtable
|
||||
newlinklist
|
||||
nicechar
|
||||
nicezputs
|
||||
niceztrdup
|
||||
niceztrlen
|
||||
noaliases
|
||||
noerrs
|
||||
noop_function
|
||||
noop_function_int
|
||||
optiontab
|
||||
opts
|
||||
paramtab
|
||||
parbegin
|
||||
parend
|
||||
parsereg
|
||||
parsestr
|
||||
path
|
||||
pathchecked
|
||||
popheap
|
||||
postedit
|
||||
ppid
|
||||
prefork
|
||||
prepromptfns
|
||||
printif
|
||||
printqt
|
||||
promptexpand
|
||||
pushheap
|
||||
putshout
|
||||
pwd
|
||||
quietgetevent
|
||||
quietgethist
|
||||
quotedzputs
|
||||
refreshptr
|
||||
remlpaths
|
||||
remnulargs
|
||||
removehashnode
|
||||
resetneeded
|
||||
restoredir
|
||||
reswdtab
|
||||
retflag
|
||||
scanhashtable
|
||||
setaparam
|
||||
setlimits
|
||||
setsparam
|
||||
settyinfo
|
||||
shfunctab
|
||||
shingetline
|
||||
shout
|
||||
shttyinfo
|
||||
singsub
|
||||
skipparens
|
||||
spaceinlineptr
|
||||
spacesplit
|
||||
spckword
|
||||
startparamscope
|
||||
stdunsetfn
|
||||
stophist
|
||||
stopmsg
|
||||
strinbeg
|
||||
strinend
|
||||
strpfx
|
||||
strsfx
|
||||
strucpy
|
||||
struncpy
|
||||
tclen
|
||||
tcstr
|
||||
termflags
|
||||
tgoto
|
||||
tok
|
||||
tokenize
|
||||
tokstr
|
||||
tputs
|
||||
trashzleptr
|
||||
tricat
|
||||
tsetcap
|
||||
ttystrname
|
||||
tulower
|
||||
tuupper
|
||||
txtchange
|
||||
typtab
|
||||
ugetnode
|
||||
uinsertlinknode
|
||||
unmeta
|
||||
unmetafy
|
||||
untokenize
|
||||
uremnode
|
||||
useheap
|
||||
winchanged
|
||||
wordbeg
|
||||
zalloc
|
||||
zbeep
|
||||
zcalloc
|
||||
zchdir
|
||||
zerr
|
||||
zerrnam
|
||||
zexit
|
||||
zfree
|
||||
zgetdir
|
||||
zgetenv
|
||||
zjoin
|
||||
zleactive
|
||||
zleparse
|
||||
zlereadptr
|
||||
zputs
|
||||
zreaddir
|
||||
zsetlimit
|
||||
zsfree
|
||||
zshcs
|
||||
zshll
|
||||
zstrtol
|
||||
ztokens
|
||||
ztrdup
|
||||
ztrduppfx
|
||||
ztrftime
|
||||
ztrlen
|
||||
ztrsub
|
||||
zwarnnam
|
|
@ -31,7 +31,7 @@
|
|||
#define zleread(X,Y,H) zlereadptr(X,Y,H)
|
||||
#define spaceinline(X) spaceinlineptr(X)
|
||||
#define gotword() gotwordptr()
|
||||
#define refresh() refreshptr()
|
||||
#define zrefresh() refreshptr()
|
||||
|
||||
#define compctlread(N,A,O,R) compctlreadptr(N,A,O,R)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ headers="../config.h system.h zsh.h sigcount.h signals.h \
|
|||
prototypes.h hashtable.h ztype.h"
|
||||
|
||||
:<<\Make
|
||||
signames.c: signames.awk @SIGNAL_H@
|
||||
signames.c: signames.awk ../config.h @SIGNAL_H@
|
||||
$(AWK) -f $(sdir)/signames.awk @SIGNAL_H@ > $@
|
||||
|
||||
sigcount.h: signames.c
|
||||
|
|
|
@ -219,3 +219,6 @@
|
|||
|
||||
/* Define to 1 if you want to use dynamically loaded modules */
|
||||
#undef DYNAMIC
|
||||
|
||||
/* Define to 1 if you want to use dynamically loaded modules on AIX */
|
||||
#undef AIXDYNAMIC
|
||||
|
|
1
aczsh.m4
1
aczsh.m4
|
@ -207,6 +207,7 @@ main()
|
|||
[zsh_cv_sys_dynamic_rtld_global=no],
|
||||
[zsh_cv_sys_dynamic_rtld_global=no]
|
||||
)
|
||||
LDFLAGS=$save_ldflags
|
||||
else
|
||||
zsh_cv_sys_dynamic_rtld_global=no
|
||||
fi
|
||||
|
|
81
configure.in
81
configure.in
|
@ -210,11 +210,11 @@ if test -n "$auto_cflags"; then
|
|||
fi
|
||||
fi
|
||||
if test -n "$auto_ldflags"; then
|
||||
if test "${enable_zsh_debug}" = yes; then
|
||||
LDFLAGS=-g
|
||||
else
|
||||
LDFLAGS=-s
|
||||
fi
|
||||
case "${enable_zsh_debug}$host_os" in
|
||||
yesaix*) ;; # AIX ld does not accept -g
|
||||
yes*) LDFLAGS=-g ;;
|
||||
*) LDFLAGS=-s ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
dnl ----------
|
||||
|
@ -401,12 +401,10 @@ AC_CHECK_LIB(c, printf)
|
|||
|
||||
dnl Prefer BSD termcap library to SysV curses library, except on certain
|
||||
dnl versions of AIX and HP-UX.
|
||||
if test `echo $host_os | sed 's/^.*\(aix\)[[1-9]]\.[[0-9]].*$/\1/'` = aix ||
|
||||
test `echo $host_os | sed 's/^.*\(hpux\)10\..*$/\1/'` = hpux; then
|
||||
termcap_curses_order="curses ncurses termcap"
|
||||
else
|
||||
termcap_curses_order="termcap curses ncurses"
|
||||
fi
|
||||
case "$host_os" in
|
||||
aix*|hpux10.*) termcap_curses_order="curses ncurses termcap" ;;
|
||||
*) termcap_curses_order="termcap curses ncurses" ;;
|
||||
esac
|
||||
|
||||
for lib in $termcap_curses_order; do
|
||||
AC_CHECK_LIB(${lib}, tgetent, [LIBS="-l$lib $LIBS"; break])
|
||||
|
@ -617,8 +615,9 @@ AC_CHECK_FUNCS(memcpy memmove \
|
|||
sigprocmask setuid seteuid setreuid setresuid setsid strerror \
|
||||
nis_list initgroups fchdir cap_get_proc readlink nice \
|
||||
getgrgid getgrnam getpwent getpwnam getpwuid)
|
||||
|
||||
if test $dynamic = yes; then
|
||||
AC_CHECK_FUNCS(dlopen dlerror dlsym dlclose)
|
||||
AC_CHECK_FUNCS(dlopen dlerror dlsym dlclose load loadquery loadbind unload)
|
||||
fi
|
||||
|
||||
|
||||
|
@ -900,14 +899,37 @@ dnl ---------------
|
|||
dnl dynamic loading
|
||||
dnl ---------------
|
||||
L=N
|
||||
if test "$ac_cv_func_dlopen" != yes; then
|
||||
dynamic=no
|
||||
elif test "$ac_cv_func_dlsym" != yes; then
|
||||
dynamic=no
|
||||
elif test "$ac_cv_func_dlerror" != yes; then
|
||||
dynamic=no
|
||||
aixdynamic=no
|
||||
if test "$ac_cv_func_dlopen" != yes ||
|
||||
test "$ac_cv_func_dlsym" != yes ||
|
||||
test "$ac_cv_func_dlerror" != yes; then
|
||||
if test "$ac_cv_func_load" != yes ||
|
||||
test "$ac_cv_func_unload" != yes ||
|
||||
test "$ac_cv_func_loadbind" != yes ||
|
||||
test "$ac_cv_func_loadquery" != yes; then
|
||||
dynamic=no
|
||||
elif test "x$dynamic" = xyes; then
|
||||
aixdynamic=yes
|
||||
fi
|
||||
fi
|
||||
if test "x$dynamic" = xyes; then
|
||||
|
||||
test -n "$GCC" && LDARG=-Wl,
|
||||
|
||||
if test "x$aixdynamic" = xyes; then
|
||||
DL_EXT="${DL_EXT=so}"
|
||||
DLLD="${DLLD=$CC}"
|
||||
zsh_cv_func_dlsym_needs_underscore=no
|
||||
DLLDFLAGS=${DLLDFLAGS=}
|
||||
EXTRA_LDFLAGS=${EXTRA_LDFLAGS=}
|
||||
EXPOPT=${LDARG}-bE:
|
||||
IMPOPT=${LDARG}-bI:
|
||||
zsh_cv_sys_dynamic_clash_ok="${zsh_cv_sys_dynamic_clash_ok=yes}"
|
||||
zsh_cv_sys_dynamic_rtld_global="${zsh_cv_sys_dynamic_rtld_global=yes}"
|
||||
zsh_cv_sys_dynamic_execsyms="${zsh_cv_sys_dynamic_execsyms=yes}"
|
||||
zsh_cv_sys_dynamic_strip_exe="${zsh_cv_sys_dynamic_strip_exe=yes}"
|
||||
zsh_cv_sys_dynamic_strip_lib="${zsh_cv_sys_dynamic_strip_lib=yes}"
|
||||
zsh_cv_sys_dynamic_broken="${zsh_cv_sys_dynamic_broken=no}"
|
||||
elif test "x$dynamic" = xyes; then
|
||||
AC_CACHE_CHECK(if your system use ELF binaries,
|
||||
zsh_cv_sys_elf,
|
||||
[AC_TRY_RUN([/* Test for whether ELF binaries are produced */
|
||||
|
@ -947,10 +969,11 @@ char *argv[];
|
|||
case "$host_os" in
|
||||
hpux*) DLLDFLAGS="${DLLDFLAGS=-b}" ;;
|
||||
linux*|irix*|osf*) DLLDFLAGS="${DLLDFLAGS=-shared}" ;;
|
||||
solaris*) DLLDFLAGS="${DLLDFLAGS=-G}" ;;
|
||||
sunos*) DLLDFLAGS="${DLLDFLAGS=-assert nodefinitions}" ;;
|
||||
sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G $ldflags}" ;;
|
||||
netbsd*) DLLDFLAGS="${DLLDFLAGS=-x -shared --whole-archive}" ;;
|
||||
aix*) DLLDFLAGS="${DLLDFLAGS=-G -bexpall -lc}" ;;
|
||||
solaris*|sysv4*|esix*) DLLDFLAGS="${DLLDFLAGS=-G}" ;;
|
||||
esac
|
||||
case "$host_os" in
|
||||
hpux*) EXTRA_LDFLAGS="${EXTRA_LDFLAGS=-Wl,-E}" ;;
|
||||
|
@ -958,7 +981,7 @@ char *argv[];
|
|||
esac
|
||||
AC_CACHE_CHECK(if your dlsym() needs a leading underscore,
|
||||
zsh_cv_func_dlsym_needs_underscore,
|
||||
[cat >conftest.c <<EOM
|
||||
[echo failed >conftestval && cat >conftest.c <<EOM
|
||||
fred () { }
|
||||
EOM
|
||||
$CC -c $CFLAGS $CPPFLAGS $DLCFLAGS conftest.c 1>&5 2>&5 &&
|
||||
|
@ -1006,8 +1029,12 @@ main()
|
|||
zsh_cv_func_dlsym_needs_underscore=failed
|
||||
dynamic=no,
|
||||
zsh_cv_func_dlsym_needs_underscore=no)])
|
||||
if test "$zsh_cv_func_dlsym_needs_underscore" = yes; then
|
||||
if test "x$zsh_cv_func_dlsym_needs_underscore" = xyes; then
|
||||
AC_DEFINE(DLSYM_NEEDS_UNDERSCORE)
|
||||
elif test "x$zsh_cv_func_dlsym_needs_underscore" != xno; then
|
||||
dnl Do not cache failed value
|
||||
unset zsh_cv_func_dlsym_needs_underscore
|
||||
dynamic=no
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -1045,13 +1072,23 @@ else
|
|||
D=N
|
||||
fi
|
||||
|
||||
if test "x$aixdynamic" = xyes; then
|
||||
E=E
|
||||
AC_DEFINE(AIXDYNAMIC)dnl
|
||||
else
|
||||
E=N
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(DL_EXT, "$DL_EXT")dnl
|
||||
AC_SUBST(D)dnl
|
||||
AC_SUBST(DL_EXT)dnl
|
||||
AC_SUBST(DLLD)dnl
|
||||
AC_SUBST(DLCFLAGS)dnl
|
||||
AC_SUBST(DLLDFLAGS)dnl
|
||||
AC_SUBST(E)dnl
|
||||
AC_SUBST(EXTRA_LDFLAGS)dnl
|
||||
AC_SUBST(EXPOPT)dnl
|
||||
AC_SUBST(IMPOPT)dnl
|
||||
AC_SUBST(L)dnl
|
||||
AC_SUBST(RTLD_GLOBAL_OK)dnl
|
||||
|
||||
|
|
Loading…
Reference in a new issue