27694: add P glob qualifier for prepending

This commit is contained in:
Peter Stephenson 2010-02-09 17:47:02 +00:00
parent a13752e2cb
commit f4f0becb63
6 changed files with 104 additions and 8 deletions

View File

@ -1,5 +1,9 @@
2010-02-09 Peter Stephenson <pws@csr.com>
* 27694: NEWS, Completion/Zsh/Type/_globquals, Doc/Zsh/expn.yo,
Src/glob.c, Test/D02glob.ztst: add "P" glob qualifier for
prepending words.
* Frank: 27696: Completion/Unix/Command/_tmux: another update
* Geoff: 27693: Src/exec.c, Src/init.c, Src/params.c, Src/init.c,
@ -26,7 +30,7 @@
better logic.
* Michael Hwang: 27675: Src/builtin.c: fix crash from error in
has builtin.
hash builtin.
2010-02-04 Peter Stephenson <pws@csr.com>
@ -12714,5 +12718,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
* $Revision: 1.4890 $
* $Revision: 1.4891 $
*****************************************************

View File

@ -31,10 +31,10 @@ while [[ -n $PREFIX ]]; do
fi
;;
(e)
([eP])
# complete/skip delimited command line
if [[ -z $PREFIX ]]; then
_delimiters qualifer-e
_delimiters qualifer-$char
return
elif ! _globqual_delims; then
# still completing command to eval

View File

@ -2296,6 +2296,18 @@ expressions. As in parameter subscripting they may be negative to make
them count from the last match backward. E.g.: `tt(*(-OL[1,3]))'
gives a list of the names of the three largest files.
)
item(tt(P))(var(string))(
The var(string) will be prepended to each glob match as a separate
word. var(string) is delimited in the same way as arguments to the
tt(e) glob qualifier described above. The qualifier can be repeated;
the words are prepended separately so that the resulting command
line contains the words in the same order they were given in the
list of glob qualifiers.
A typical use for this is to prepend an option before all occurrences
of a file name; for example, the pattern `tt(*(P:-f:))' produces the
command line arguments `tt(-f) var(file1) tt(-f) var(file2) ...'
)
enditem()
More than one of these lists can be combined, separated by commas. The

7
NEWS
View File

@ -4,6 +4,13 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH
Note also the list of incompatibilities in the README file.
Changes between versions 4.3.10 and 4.3.11
------------------------------------------
The glob qualifier P can be used to add a separate word before each
match. For example, *(P:-f:) produces the command line
`-f file1 -f file2 ...'.
Changes between versions 4.3.9 and 4.3.10
-----------------------------------------

View File

@ -176,6 +176,7 @@ struct globdata {
int gd_gf_numsort;
int gd_gf_follow, gd_gf_sorts, gd_gf_nsorts;
struct globsort gd_gf_sortlist[MAX_SORTS];
LinkList gd_gf_pre_words;
char *gd_glob_pre, *gd_glob_suf;
};
@ -206,6 +207,7 @@ static struct globdata curglobdata;
#define gf_sorts (curglobdata.gd_gf_sorts)
#define gf_nsorts (curglobdata.gd_gf_nsorts)
#define gf_sortlist (curglobdata.gd_gf_sortlist)
#define gf_pre_words (curglobdata.gd_gf_pre_words)
/* and macros for save/restore */
@ -1031,8 +1033,8 @@ static struct qual *dup_qual_list(struct qual *orig, struct qual **lastp)
/*
* Get a glob string for execution, following e or + qualifiers.
* Pointer is character after the e or +.
* Get a glob string for execution, following e, P or + qualifiers.
* Pointer is character after the e, P or +.
*/
/**/
@ -1072,6 +1074,23 @@ glob_exec_string(char **sp)
return sdata;
}
/*
* Insert a glob match.
* If there were words to prepend given by the P glob qualifier, do so.
*/
static void
insert_glob_match(LinkList list, LinkNode next, char *data)
{
if (gf_pre_words) {
LinkNode added;
for (added = firstnode(gf_pre_words); added; incnode(added)) {
next = insertlinknode(list, next, dupstring(getdata(added)));
}
}
insertlinknode(list, next, data);
}
/* Main entry point to the globbing code for filename globbing. *
* np points to a node in the list list which will be expanded *
* into a series of nodes. */
@ -1606,6 +1625,19 @@ zglob(LinkList list, LinkNode np, int nountok)
end = v.end;
break;
}
case 'P':
{
char *tt;
tt = glob_exec_string(&s);
if (tt != NULL)
{
if (!gf_pre_words)
gf_pre_words = newlinklist();
addlinknode(gf_pre_words, tt);
}
break;
}
default:
zerr("unknown file attribute");
restore_globstate(saved);
@ -1816,14 +1848,14 @@ zglob(LinkList list, LinkNode np, int nountok)
matchptr = matchbuf + matchct - first - 1;
while (end-- > 0) {
/* insert matches in the arg list */
insertlinknode(list, node, matchptr->name);
insert_glob_match(list, node, matchptr->name);
matchptr--;
}
} else {
matchptr = matchbuf + matchct - first - end;
while (end-- > 0) {
/* insert matches in the arg list */
insertlinknode(list, node, matchptr->name);
insert_glob_match(list, node, matchptr->name);
matchptr++;
}
}

View File

@ -343,6 +343,47 @@
0:Exclusions with complicated path specifications
>glob.tmp/dir1 glob.tmp/dir2 glob.tmp/dir4
print -l -- glob.tmp/*(P:-f:)
0:Prepending words to each argument
>-f
>glob.tmp/a
>-f
>glob.tmp/b
>-f
>glob.tmp/c
>-f
>glob.tmp/dir1
>-f
>glob.tmp/dir2
>-f
>glob.tmp/dir3
>-f
>glob.tmp/dir4
print -l -- glob.tmp/*(P:one word:P:another word:)
0:Prepending two words to each argument
>one word
>another word
>glob.tmp/a
>one word
>another word
>glob.tmp/b
>one word
>another word
>glob.tmp/c
>one word
>another word
>glob.tmp/dir1
>one word
>another word
>glob.tmp/dir2
>one word
>another word
>glob.tmp/dir3
>one word
>another word
>glob.tmp/dir4
[[ "" = "" ]] && echo OK
0:Empty strings
>OK