about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/comp.h22
-rw-r--r--Src/Zle/compcore.c24
-rw-r--r--Src/Zle/complete.c20
-rw-r--r--Src/Zle/zle_main.c4
-rw-r--r--Src/Zle/zle_tricky.c29
5 files changed, 74 insertions, 25 deletions
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index 9d92b4a5c..20bfb0f99 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -298,25 +298,27 @@ typedef void (*CLPrintFunc)(Cmgroup, Cmatch *, int, int, int, int,
 
 #define CPN_WORDS      0
 #define CP_WORDS       (1 <<  CPN_WORDS)
-#define CPN_CURRENT    1
+#define CPN_REDIRS     1
+#define CP_REDIRS      (1 <<  CPN_REDIRS)
+#define CPN_CURRENT    2
 #define CP_CURRENT     (1 <<  CPN_CURRENT)
-#define CPN_PREFIX     2
+#define CPN_PREFIX     3
 #define CP_PREFIX      (1 <<  CPN_PREFIX)
-#define CPN_SUFFIX     3
+#define CPN_SUFFIX     4
 #define CP_SUFFIX      (1 <<  CPN_SUFFIX)
-#define CPN_IPREFIX    4
+#define CPN_IPREFIX    5
 #define CP_IPREFIX     (1 <<  CPN_IPREFIX)
-#define CPN_ISUFFIX    5
+#define CPN_ISUFFIX    6
 #define CP_ISUFFIX     (1 <<  CPN_ISUFFIX)
-#define CPN_QIPREFIX   6
+#define CPN_QIPREFIX   7
 #define CP_QIPREFIX    (1 <<  CPN_QIPREFIX)
-#define CPN_QISUFFIX   7
+#define CPN_QISUFFIX   8
 #define CP_QISUFFIX    (1 <<  CPN_QISUFFIX)
-#define CPN_COMPSTATE  8
+#define CPN_COMPSTATE  9
 #define CP_COMPSTATE   (1 <<  CPN_COMPSTATE)
 
-#define CP_REALPARAMS  9
-#define CP_ALLREALS    ((unsigned int) 0x1ff)
+#define CP_REALPARAMS  10
+#define CP_ALLREALS    ((unsigned int) 0x3ff)
 
 
 #define CPN_NMATCHES   0
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 1c3c31921..d92b492e3 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -618,6 +618,13 @@ callcompfunc(char *s, char *fn)
 	} else
 	    compwords = (char **) zcalloc(sizeof(char *));
 
+	if (compredirs)
+	    freearray(compredirs);
+        if (rdstrs)
+            compredirs = bld_list_array(rdstrs);
+        else
+            compredirs = (char **) zcalloc(sizeof(char *));
+
 	compparameter = ztrdup(compparameter);
 	compredirect = ztrdup(compredirect);
 	zsfree(compquote);
@@ -1459,11 +1466,11 @@ set_comp_sep(void)
     return 0;
 }
 
-/* This stores the strings from the list in an array. */
+/* This builds an array from a list of strings. */
 
 /**/
-mod_export void
-set_list_array(char *name, LinkList l)
+mod_export char **
+bld_list_array(LinkList l)
 {
     char **a, **p;
     LinkNode n;
@@ -1473,7 +1480,16 @@ set_list_array(char *name, LinkList l)
 	*p++ = ztrdup((char *) getdata(n));
     *p = NULL;
 
-    setaparam(name, a);
+    return a;
+}
+
+/* This stores the strings from the list in an array. */
+
+/**/
+mod_export void
+set_list_array(char *name, LinkList l)
+{
+    setaparam(name, bld_list_array(l));
 }
 
 /* Get the words from a variable or a (list of words). */
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index cd78796c9..a787528c2 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -43,6 +43,7 @@ zlong complistlines,
 /**/
 mod_export
 char **compwords,
+     **compredirs,
      *compprefix,
      *compsuffix,
      *compisuffix,
@@ -948,6 +949,7 @@ struct compparam {
 
 static struct compparam comprparams[] = {
     { "words", PM_ARRAY, VAL(compwords), NULL, NULL },
+    { "redirections", PM_ARRAY, VAL(compredirs), NULL, NULL },
     { "CURRENT", PM_INTEGER, VAL(compcurrent), NULL, NULL },
     { "PREFIX", PM_SCALAR, VAL(compprefix), NULL, NULL },
     { "SUFFIX", PM_SCALAR, VAL(compsuffix), NULL, NULL },
@@ -1239,13 +1241,13 @@ comp_wrapper(Eprog prog, FuncWrap w, char *name)
     if (incompfunc != 1)
 	return 1;
     else {
-	char *orest, *opre, *osuf, *oipre, *oisuf, **owords;
+	char *orest, *opre, *osuf, *oipre, *oisuf, **owords, **oredirs;
 	char *oqipre, *oqisuf, *oq, *oqi, *oqs, *oaq;
 	zlong ocur;
 	unsigned int runset = 0, kunset = 0, m, sm;
 	Param *pp;
 
-	m = CP_WORDS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | 
+	m = CP_WORDS | CP_REDIRS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | 
 	    CP_IPREFIX | CP_ISUFFIX | CP_QIPREFIX | CP_QISUFFIX;
 	for (pp = comprpms, sm = 1; m; pp++, m >>= 1, sm <<= 1) {
 	    if ((m & 1) && ((*pp)->flags & PM_UNSET))
@@ -1267,6 +1269,7 @@ comp_wrapper(Eprog prog, FuncWrap w, char *name)
 	oqs = ztrdup(compqstack);
 	oaq = ztrdup(autoq);
 	owords = zarrdup(compwords);
+	oredirs = zarrdup(compredirs);
 
 	runshfunc(prog, w, name);
 
@@ -1293,11 +1296,14 @@ comp_wrapper(Eprog prog, FuncWrap w, char *name)
 	    zsfree(autoq);
 	    autoq = oaq;
 	    freearray(compwords);
+	    freearray(compredirs);
 	    compwords = owords;
+            compredirs = oredirs;
 	    comp_setunset(CP_COMPSTATE |
-			  (~runset & (CP_WORDS | CP_CURRENT | CP_PREFIX |
-				     CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX |
-				     CP_QIPREFIX | CP_QISUFFIX)),
+			  (~runset & (CP_WORDS | CP_REDIRS |
+                                      CP_CURRENT | CP_PREFIX |
+                                      CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX |
+                                      CP_QIPREFIX | CP_QISUFFIX)),
 			  (runset & CP_ALLREALS),
 			  (~kunset & CP_RESTORE), (kunset & CP_ALLKEYS));
 	} else {
@@ -1390,7 +1396,7 @@ setup_(Module m)
     hasperm = 0;
 
     comprpms = compkpms = NULL;
-    compwords = NULL;
+    compwords = compredirs = NULL;
     compprefix = compsuffix = compiprefix = compisuffix = 
 	compqiprefix = compqisuffix =
 	compcontext = compparameter = compredirect = compquote =
@@ -1447,6 +1453,8 @@ finish_(Module m)
 {
     if (compwords)
 	freearray(compwords);
+    if (compredirs)
+	freearray(compredirs);
     zsfree(compprefix);
     zsfree(compsuffix);
     zsfree(compiprefix);
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 42c7a6bb3..5af18fbac 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1138,6 +1138,7 @@ setup_(Module m)
     stackhist = stackcs = -1;
     kungetbuf = (char *) zalloc(kungetsz = 32);
     comprecursive = 0;
+    rdstrs = NULL;
 
     /* initialise the keymap system */
     init_keymaps();
@@ -1192,7 +1193,8 @@ finish_(Module m)
     zfree(vichgbuf, vichgbufsz);
     zfree(kungetbuf, kungetsz);
     free_isrch_spots();
-
+    if (rdstrs)
+        freelinklist(rdstrs, freestr);
     zfree(cutbuf.buf, cutbuf.len);
     for(i = KRINGCT; i--; )
 	zfree(kring[i].buf, kring[i].len);
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 6ecfaa885..788f5f8ec 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -346,6 +346,13 @@ mod_export int lincmd, linredir, linarr;
 /**/
 mod_export char *rdstr;
 
+static char rdstrbuf[20];
+
+/* The list of redirections on the line. */
+
+/**/
+mod_export LinkList rdstrs;
+
 /* This holds the name of the current command (used to find the right *
  * compctl).                                                          */
 
@@ -978,7 +985,7 @@ get_comp_string(void)
 {
     int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins, ia, parct, varq = 0;
     int ona = noaliases;
-    char *s = NULL, *linptr, *tmp, *p, *tt = NULL;
+    char *s = NULL, *linptr, *tmp, *p, *tt = NULL, rdop[20];
 
     freebrinfo(brbeg);
     freebrinfo(brend);
@@ -987,6 +994,11 @@ get_comp_string(void)
     zsfree(lastprebr);
     zsfree(lastpostbr);
     lastprebr = lastpostbr = NULL;
+    if (rdstrs)
+        freelinklist(rdstrs, freestr);
+    rdstrs = znewlinklist();
+    rdop[0] = '\0';
+    rdstr = NULL;
 
     /* This global flag is used to signal the lexer code if it should *
      * expand aliases or not.                                         */
@@ -1074,8 +1086,14 @@ get_comp_string(void)
 	    else
 		linarr = 0;
 	}
-	if (inredir)
-	    rdstr = tokstrings[tok];
+	if (inredir) {
+            rdstr = rdstrbuf;
+            if (tokfd >= 0)
+                sprintf(rdop, "%d%s", tokfd, tokstrings[tok]);
+            else
+                strcpy(rdop, tokstrings[tok]);
+            strcpy(rdstr, rdop);
+        }
 	if (tok == DINPAR)
 	    tokstr = NULL;
 
@@ -1118,8 +1136,11 @@ get_comp_string(void)
 	    ia = linarr;
 	    if (inwhat == IN_NOTHING && incond)
 		inwhat = IN_COND;
-	} else if (linredir)
+	} else if (linredir) {
+            if (rdop[0] && tokstr)
+                zaddlinknode(rdstrs, tricat(rdop, ":", tokstr));
 	    continue;
+        }
 	if (incond) {
 	    if (tok == DBAR)
 		tokstr = "||";