summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/compcore.c72
-rw-r--r--Src/Zle/compctl.c5
-rw-r--r--Src/Zle/complist.c2
-rw-r--r--Src/Zle/computil.c29
-rw-r--r--Src/zsh.h4
5 files changed, 76 insertions, 36 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 62d63000a..ad87fe619 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -1553,14 +1553,17 @@ get_user_var(char *nam)
 }
 
 static char **
-get_user_keys(char *nam)
+get_data_arr(char *name, int keys)
 {
-    char **ret;
+    struct value vbuf;
+    Value v;
 
-    if ((ret = gethkparam(nam)))
-	return (incompfunc ? arrdup(ret) : ret);
+    if (!(v = fetchvalue(&vbuf, &name, 1,
+			 (keys ? SCANPM_WANTKEYS : SCANPM_WANTVALS) |
+			 SCANPM_MATCHMANY)))
+	return NULL;
 
-    return NULL;
+    return getarrvalue(v);
 }
 
 /* This is used by compadd to add a couple of matches. The arguments are
@@ -1586,9 +1589,10 @@ addmatches(Cadata dat, char **argv)
     Patprog cp = NULL, *pign = NULL;
     LinkList aparl = NULL, oparl = NULL, dparl = NULL;
     Brinfo bp, bpl = brbeg, obpl, bsl = brend, obsl;
+    Heap oldheap;
 
     if (!*argv) {
-	SWITCHHEAPS(compheap) {
+	SWITCHHEAPS(oldheap, compheap) {
 	    /* Select the group in which to store the matches. */
 	    gflags = (((dat->aflags & CAF_NOSORT ) ? CGF_NOSORT  : 0) |
 		      ((dat->aflags & CAF_UNIQALL) ? CGF_UNIQALL : 0) |
@@ -1602,7 +1606,7 @@ addmatches(Cadata dat, char **argv)
 	    }
 	    if (dat->mesg)
 		addmesg(dat->mesg);
-	} SWITCHBACKHEAPS;
+	} SWITCHBACKHEAPS(oldheap);
 
 	return 1;
     }
@@ -1638,7 +1642,7 @@ addmatches(Cadata dat, char **argv)
 
     /* Switch back to the heap that was used when the completion widget
      * was invoked. */
-    SWITCHHEAPS(compheap) {
+    SWITCHHEAPS(oldheap, compheap) {
 	if ((doadd = (!dat->apar && !dat->opar && !dat->dpar))) {
 	    if (dat->aflags & CAF_MATCH)
 		hasmatched = 1;
@@ -1887,17 +1891,22 @@ addmatches(Cadata dat, char **argv)
 	obpl = bpl;
 	obsl = bsl;
 	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))
+	    Heap oldheap2;
+
+	    SWITCHHEAPS(oldheap2, oldheap) {
+		arrays = argv;
+		argv = NULL;
+		while (*arrays &&
+		       (!(argv = get_data_arr(*arrays,
+					      (dat->aflags & CAF_KEYS))) ||
+			!*argv))
+		    arrays++;
 		arrays++;
-	    arrays++;
-	    if (!argv) {
-		ms = NULL;
-		argv = &ms;
-	    }
+		if (!argv) {
+		    ms = NULL;
+		    argv = &ms;
+		}
+	    } SWITCHBACKHEAPS(oldheap2);
 	}
 	if (dat->ppre)
 	    ppl = strlen(dat->ppre);
@@ -1994,17 +2003,22 @@ 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))
+		Heap oldheap2;
+
+		SWITCHHEAPS(oldheap2, oldheap) {
+		    argv = NULL;
+		    while (*arrays &&
+			   (!(argv = get_data_arr(*arrays,
+						  (dat->aflags & CAF_KEYS))) ||
+			    !*argv))
+			arrays++;
 		    arrays++;
-		arrays++;
-		if (!argv) {
-		    ms = NULL;
-		    argv = &ms;
-		}
-		argv--;
+		    if (!argv) {
+			ms = NULL;
+			argv = &ms;
+		    }
+		    argv--;
+		} SWITCHBACKHEAPS(oldheap2);
 	    }
 	}
 	if (dat->apar)
@@ -2015,7 +2029,7 @@ addmatches(Cadata dat, char **argv)
 	    set_list_array(dat->dpar, dparl);
 	if (dat->exp)
 	    addexpl();
-    } SWITCHBACKHEAPS;
+    } SWITCHBACKHEAPS(oldheap);
 
     /* We switched back to the current heap, now restore the stack of
      * matchers. */
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index c7356b69f..052209ee3 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -2268,13 +2268,14 @@ static int cdepth = 0;
 static int
 makecomplistctl(int flags)
 {
+    Heap oldheap;
     int ret;
 
     if (cdepth == MAX_CDEPTH)
 	return 0;
 
     cdepth++;
-    SWITCHHEAPS(compheap) {
+    SWITCHHEAPS(oldheap, compheap) {
 	int ooffs = offs, lip, lp;
 	char *str = comp_str(&lip, &lp, 0), *t;
 	char *os = cmdstr, **ow = clwords, **p, **q, qc;
@@ -2333,7 +2334,7 @@ makecomplistctl(int flags)
 	clwords = ow;
 	clwnum = on;
 	clwpos = op;
-    } SWITCHBACKHEAPS;
+    } SWITCHBACKHEAPS(oldheap);
     cdepth--;
 
     return ret;
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 445c89bb7..75a23f0e5 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -1750,8 +1750,6 @@ domenuselect(Hookdef dummy, Chdata dat)
 	}
 	setwish = wasnext = 0;
 
-    getk:
-
 	if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
 	    zbeep();
 	    break;
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index da72a6902..a329d34d0 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -3200,7 +3200,7 @@ cfp_matcher_pats(char *matcher, char *add)
 		    }
 	}
 	if (*add) {
-	    char *ret = "", buf[259], *oadd = add;
+	    char *ret = "", buf[259];
 
 	    for (mp = ms; *add; add++, mp++) {
 		if (!(m = *mp)) {
@@ -3661,6 +3661,32 @@ bin_compfiles(char *nam, char **args, char *ops, int func)
     return 1;
 }
 
+static int
+bin_compgroups(char *nam, char **args, char *ops, int func)
+{
+    Heap oldheap;
+    char *n;
+
+    SWITCHHEAPS(oldheap, compheap) {
+	while ((n = *args++)) {
+	    endcmgroup(NULL);
+	    begcmgroup(n, 0);
+	    endcmgroup(NULL);
+	    begcmgroup(n, CGF_NOSORT);
+	    endcmgroup(NULL);
+	    begcmgroup(n, CGF_UNIQALL);
+	    endcmgroup(NULL);
+	    begcmgroup(n, CGF_NOSORT|CGF_UNIQCON);
+	    endcmgroup(NULL);
+	    begcmgroup(n, CGF_UNIQALL);
+	    endcmgroup(NULL);
+	    begcmgroup(n, CGF_NOSORT|CGF_UNIQCON);
+	}
+    } SWITCHBACKHEAPS(oldheap);
+
+    return 0;
+}
+
 static struct builtin bintab[] = {
     BUILTIN("compdescribe", 0, bin_compdescribe, 3, -1, 0, NULL, NULL),
     BUILTIN("comparguments", 0, bin_comparguments, 1, -1, 0, NULL, NULL),
@@ -3670,6 +3696,7 @@ static struct builtin bintab[] = {
     BUILTIN("comptry", 0, bin_comptry, 0, -1, 0, NULL, NULL),
     BUILTIN("compfmt", 0, bin_compfmt, 2, -1, 0, NULL, NULL),
     BUILTIN("compfiles", 0, bin_compfiles, 1, -1, 0, NULL, NULL),
+    BUILTIN("compgroups", 0, bin_compgroups, 1, -1, 0, NULL, NULL),
 };
 
 
diff --git a/Src/zsh.h b/Src/zsh.h
index 293947463..49acf129c 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1629,8 +1629,8 @@ struct heap {
 # define NEWHEAPS(h)    do { Heap _switch_oldheaps = h = new_heaps(); do
 # define OLDHEAPS       while (0); old_heaps(_switch_oldheaps); } while (0);
 
-# define SWITCHHEAPS(h)  do { Heap _switch_oldheaps = switch_heaps(h); do
-# define SWITCHBACKHEAPS while (0); switch_heaps(_switch_oldheaps); } while (0);
+# define SWITCHHEAPS(o, h)  do { o = switch_heaps(h); do
+# define SWITCHBACKHEAPS(o) while (0); switch_heaps(o); } while (0);
 
 /****************/
 /* Debug macros */