Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: Re: complete (real C) tags



Peter Stephenson wrote:

> Sven wrote:
> >   Actually, I've been tempted from the beginning to allow compadd to
> >   get the matches not only from its positional parameters, but also
> >   from arrays whose names are given as arguments. That would allow us
> >   to stuff the matches into some array and then call:
> > 
> >     foo=(...)
> >     _wanted ... compadd -a foo
> > 
> >   or some such.
> 
> This sounds a simple and effective solution.  I presume it could be done
> with minimal changes --- just modify compadd argument handling and then
> pass down the argument `-a carefully_chosen_parameter_name' (so as no to
> clash with any parameters in the middle).

Exactly. This adds -a to make the words be used as names of arrays
(actually I used get_user_var(), so '(foo bar)' is possible, should we 
document this?) and complete their values. It also adds -k to make the 
words be taken as names of assocs and complete their keys.

It's small and easily separatable enough to make me commit it when
this mail comes back. So, if anyone has objections (to -k or to both
options), I can take them out again. Partly because of this I also
haven't changed any completion functions yet, but there are several
functions that could be made faster with this...

Bye
 Sven

Index: Doc/Zsh/compwid.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compwid.yo,v
retrieving revision 1.15
diff -u -r1.15 compwid.yo
--- Doc/Zsh/compwid.yo	2000/05/22 11:28:29	1.15
+++ Doc/Zsh/compwid.yo	2000/05/23 14:15:19
@@ -415,7 +415,7 @@
 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) ])
@@ -479,6 +479,14 @@
 )
 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 
Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.10
diff -u -r1.10 params.c
--- Src/params.c	2000/05/19 18:22:51	1.10
+++ Src/params.c	2000/05/23 14:15:20
@@ -1741,6 +1741,21 @@
     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)
Index: Src/Zle/comp.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/comp.h,v
retrieving revision 1.5
diff -u -r1.5 comp.h
--- Src/Zle/comp.h	2000/05/17 11:59:33	1.5
+++ Src/Zle/comp.h	2000/05/23 14:15:20
@@ -233,6 +233,8 @@
 #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() */
 
Index: Src/Zle/compcore.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compcore.c,v
retrieving revision 1.23
diff -u -r1.23 compcore.c
--- Src/Zle/compcore.c	2000/05/22 11:28:29	1.23
+++ Src/Zle/compcore.c	2000/05/23 14:15:21
@@ -1538,6 +1538,17 @@
     }
 }
 
+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 @@
     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 @@
 	/* 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 @@
 	    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);
@@ -1952,6 +1969,19 @@
 			dparr = NULL;
 		}
 		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)
Index: Src/Zle/complete.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/complete.c,v
retrieving revision 1.7
diff -u -r1.7 complete.c
--- Src/Zle/complete.c	2000/05/02 10:31:11	1.7
+++ Src/Zle/complete.c	2000/05/23 14:15:21
@@ -442,6 +442,12 @@
 	    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";

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author