about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2010-02-09 17:47:02 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2010-02-09 17:47:02 +0000
commitf4f0becb633709741253f0b9677fdde60ae87faf (patch)
tree66974ba12f74f1762e0ce461cf725a80f5533d4b
parenta13752e2cb20906cae5ced873639b25164f7c85f (diff)
downloadzsh-f4f0becb633709741253f0b9677fdde60ae87faf.tar.gz
zsh-f4f0becb633709741253f0b9677fdde60ae87faf.tar.xz
zsh-f4f0becb633709741253f0b9677fdde60ae87faf.zip
27694: add P glob qualifier for prepending
-rw-r--r--ChangeLog8
-rw-r--r--Completion/Zsh/Type/_globquals4
-rw-r--r--Doc/Zsh/expn.yo12
-rw-r--r--NEWS7
-rw-r--r--Src/glob.c40
-rw-r--r--Test/D02glob.ztst41
6 files changed, 104 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index fff4bc468..bc13d86f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 $
 *****************************************************
diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals
index 9ad948839..54d98ec0f 100644
--- a/Completion/Zsh/Type/_globquals
+++ b/Completion/Zsh/Type/_globquals
@@ -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
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 2578baff4..cff2048f8 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -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
diff --git a/NEWS b/NEWS
index 2a85bc36a..7e7ebadc0 100644
--- a/NEWS
+++ b/NEWS
@@ -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
 -----------------------------------------
 
diff --git a/Src/glob.c b/Src/glob.c
index 46a0ce9c0..f5e072c1c 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -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++;
 	    }
 	}
diff --git a/Test/D02glob.ztst b/Test/D02glob.ztst
index 74f933842..84453ee5c 100644
--- a/Test/D02glob.ztst
+++ b/Test/D02glob.ztst
@@ -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