about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Doc/Zsh/compwid.yo10
-rw-r--r--Src/Zle/comp.h2
-rw-r--r--Src/Zle/compcore.c52
-rw-r--r--Src/Zle/complete.c6
-rw-r--r--Src/params.c15
6 files changed, 77 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 23c297322..e904ecc3d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2000-05-23  Sven Wischnowsky  <wischnow@zsh.org>
 
+	* 11533: Doc/Zsh/compwid.yo, Src/params.c, Src/Zle/comp.h,
+ 	Src/Zle/compcore.c, Src/Zle/complete.c: add -[ak] options to
+ 	compadd
+	
 	* 11530: Doc/Zsh/mod_zutil.yo, Src/Modules/zutil.c: add -E option
  	to zparseopts
 	
diff --git a/Doc/Zsh/compwid.yo b/Doc/Zsh/compwid.yo
index e2083baba..ee2f7f2bd 100644
--- a/Doc/Zsh/compwid.yo
+++ b/Doc/Zsh/compwid.yo
@@ -415,7 +415,7 @@ sect(Builtin Commands)
 startitem()
 findex(compadd)
 cindex(completion widgets, adding specified matches)
-xitem(tt(compadd) [ tt(-qQfenUal12) ] [ tt(-F) var(array) ])
+xitem(tt(compadd) [ tt(-akqQfenUl12) ] [ tt(-F) var(array) ])
 xitem([ tt(-P) var(prefix) ] [ tt(-S) var(suffix) ])
 xitem([ tt(-p) var(hidden-prefix) ] [ tt(-s) var(hidden-suffix) ])
 xitem([ tt(-i) var(ignored-prefix) ] [ tt(-I) var(ignored-suffix) ])
@@ -480,6 +480,14 @@ match.
 item(tt(-I) var(ignored-suffix))(
 Like tt(-i), but gives an ignored suffix.
 )
+item(tt(-a))(
+With this flag the var(words) are taken as names of arrays and the
+possible matches are their values.
+)
+item(tt(-k))(
+With this flag the var(words) are taken as names of associative arrays
+and the possible matches are their keys.
+)
 item(tt(-d) var(array))(
 This adds per-match display strings. The var(array) should contain one 
 element per var(word) given. The completion code will then display the 
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index bd0401800..93e3c68eb 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -233,6 +233,8 @@ struct menuinfo {
 #define CAF_MATCH    4
 #define CAF_UNIQCON  8
 #define CAF_UNIQALL 16
+#define CAF_ARRAYS  32
+#define CAF_KEYS    64
 
 /* Data for compadd and addmatches() */
 
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 4c109ed4e..38cbe03a2 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -1538,6 +1538,17 @@ get_user_var(char *nam)
     }
 }
 
+static char **
+get_user_keys(char *nam)
+{
+    char **ret;
+
+    if ((ret = gethkparam(nam)))
+	return (incompfunc ? arrdup(ret) : ret);
+
+    return NULL;
+}
+
 /* This is used by compadd to add a couple of matches. The arguments are
  * the strings given via options. The last argument is the array with
  * the matches. */
@@ -1549,8 +1560,9 @@ addmatches(Cadata dat, char **argv)
     char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL;
     char **aign = NULL, **dparr = NULL, *oaq = autoq, *oppre = dat->ppre;
     char *oqp = qipre, *oqs = qisuf, qc, **disp = NULL, *ibuf = NULL;
+    char **arrays = NULL;
     int lpl, lsl, pl, sl, bcp = 0, bcs = 0, bpadd = 0, bsadd = 0;
-    int ppl = 0, psl = 0;
+    int ppl = 0, psl = 0, ilen = 0;
     int llpl = 0, llsl = 0, nm = mnum, gflags = 0, ohp = haspattern;
     int isexact, doadd, ois = instring, oib = inbackt;
     Cline lc = NULL, pline = NULL, sline = NULL;
@@ -1855,16 +1867,18 @@ addmatches(Cadata dat, char **argv)
 	/* Walk through the matches given. */
 	obpl = bpl;
 	obsl = bsl;
-	if (aign || pign) {
-	    int max = 0;
-	    char **ap = argv;
-
-	    ppl = (dat->ppre ? strlen(dat->ppre) : 0);
-	    while ((s = *ap++))
-		if ((sl = strlen(s)) > max)
-		    max = sl;
-	    psl = (dat->psuf ? strlen(dat->psuf) : 0);
-	    ibuf = (char *) zhalloc(1 + ppl + max + psl);
+	if (dat->aflags & CAF_ARRAYS) {
+	    arrays = argv;
+	    argv = NULL;
+	    while (*arrays && (!(argv = ((dat->aflags & CAF_KEYS) ?
+					 get_user_keys(*arrays) :
+					 get_user_var(*arrays))) || !*argv))
+		arrays++;
+	    arrays++;
+	    if (!argv) {
+		ms = NULL;
+		argv = &ms;
+	    }
 	}
 	for (; (s = *argv); argv++) {
 	    bpl = obpl;
@@ -1877,6 +1891,9 @@ addmatches(Cadata dat, char **argv)
 	    if (aign || pign) {
 		int il = ppl + sl + psl, addit = 1;
 
+		if (il > ilen)
+		    ibuf = (char *) zhalloc((ilen = il) + 1);
+
 		if (ppl)
 		    memcpy(ibuf, dat->ppre, ppl);
 		strcpy(ibuf + ppl, s);
@@ -1953,6 +1970,19 @@ addmatches(Cadata dat, char **argv)
 		}
 		free_cline(lc);
 	    }
+	    if ((dat->aflags & CAF_ARRAYS) && !argv[1]) {
+		argv = NULL;
+		while (*arrays && (!(argv = ((dat->aflags & CAF_KEYS) ?
+					     get_user_keys(*arrays) :
+					     get_user_var(*arrays))) || !*argv))
+		    arrays++;
+		arrays++;
+		if (!argv) {
+		    ms = NULL;
+		    argv = &ms;
+		}
+		argv--;
+	    }
 	}
 	if (dat->apar)
 	    set_list_array(dat->apar, aparl);
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 8c8950303..c87aac596 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -442,6 +442,12 @@ bin_compadd(char *name, char **argv, char *ops, int func)
 	    case 'e':
 		dat.flags |= CMF_ISPAR;
 		break;
+	    case 'a':
+		dat.aflags |= CAF_ARRAYS;
+		break;
+	    case 'k':
+		dat.aflags |= CAF_ARRAYS|CAF_KEYS;
+		break;
 	    case 'F':
 		sp = &(dat.ign);
 		e = "string expected after -%c";
diff --git a/Src/params.c b/Src/params.c
index 8c39ec2ac..aa20e79f4 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1741,6 +1741,21 @@ gethparam(char *s)
     return NULL;
 }
 
+/* Retrieve the keys of an assoc array parameter as an array */
+
+/**/
+mod_export char **
+gethkparam(char *s)
+{
+    struct value vbuf;
+    Value v;
+
+    if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
+	PM_TYPE(v->pm->flags) == PM_HASHED)
+	return paramvalarr(v->pm->gets.hfn(v->pm), SCANPM_WANTKEYS);
+    return NULL;
+}
+
 /**/
 mod_export Param
 setsparam(char *s, char *val)