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

Re: simulation of dabbrev-expand



Adam Spiers wrote:

> [ removing duplicates in completion lists ]
> 
> I think it should be optional.  I also think you should have the
> choice of whether to remove all duplicates or just consecutive ones.
> What about -1 and -2, or some other funny option characters?

Ok. This makes `-1' keep the completion system from removing all
duplicates and `-2' keep it from removing consecutive duplicates. Yes, 
the sense is reversed so that `-J' still gives the normal behaviour.

In other words:

-J   -- sorted list without duplicates
-J1  -- sorted list with duplicates (which are all consecutive due to
        the sorting)
-J2  -- same as -J1
-V   -- unsorted list without duplicates
-V1  -- unsorted list with only non-consecutive duplicates
-V2  -- unsorted list with all duplicates

Ok?

I took the opportunity to clean up begcmgroup() and makearray().

This also changes `_description' to accept any `-[JV]*' option as its
first argument.

Bye
 Sven

diff -u os/Zle/comp.h Src/Zle/comp.h
--- os/Zle/comp.h	Wed Sep 22 13:33:18 1999
+++ Src/Zle/comp.h	Wed Sep 22 15:20:46 1999
@@ -161,6 +161,8 @@
 #define CC_CCCONT	(1<<2)
 #define CC_PATCONT	(1<<3)
 #define CC_DEFCONT	(1<<4)
+#define CC_UNIQCON      (1<<5)
+#define CC_UNIQALL      (1<<6)
 
 typedef struct cexpl *Cexpl;
 typedef struct cmgroup *Cmgroup;
@@ -206,9 +208,11 @@
 };
 
 
-#define CGF_NOSORT  1		/* don't sort this group */
-#define CGF_LINES   2		/* these are to be printed on different lines */
-#define CGF_HASDL   4		/* has disply strings printed on sseparate lines */
+#define CGF_NOSORT   1		/* don't sort this group */
+#define CGF_LINES    2		/* these are to be printed on different lines */
+#define CGF_HASDL    4		/* has display strings printed on separate lines */
+#define CGF_UNIQALL  8		/* remove all duplicates */
+#define CGF_UNIQCON 16		/* remove consecutive duplicates */
 
 /* This is the struct used to hold matches. */
 
@@ -301,6 +305,8 @@
 #define CAF_NOSORT   2
 #define CAF_ALT      4
 #define CAF_MATCH    8
+#define CAF_UNIQCON 16
+#define CAF_UNIQALL 32
 
 /* Data for compadd and addmatches() */
 
diff -u os/Zle/compctl.c Src/Zle/compctl.c
--- os/Zle/compctl.c	Wed Sep 22 13:33:18 1999
+++ Src/Zle/compctl.c	Wed Sep 22 15:39:01 1999
@@ -750,6 +750,14 @@
 		}
 		cct.mask2 |= CC_NOSORT;
 		break;
+	    case '1':
+		cct.mask2 |= CC_UNIQALL;
+		cct.mask2 &= ~CC_UNIQCON;
+		break;
+	    case '2':
+		cct.mask2 |= CC_UNIQCON;
+		cct.mask2 &= ~CC_UNIQALL;
+		break;
 	    case 'M':
 		if (cclist & COMP_LIST) {
 		    cclist |= COMP_LISTMATCH;
@@ -1439,7 +1447,7 @@
     }
 
     /* loop through flags w/o args that are set, printing them if so */
-    if (flags & t) {
+    if ((flags & t) || (flags2 & (CC_UNIQALL | CC_UNIQCON))) {
 	printf(" -");
 	if ((flags & (CC_ALREG | CC_ALGLOB)) == (CC_ALREG | CC_ALGLOB))
 	    putchar('a'), flags &= ~(CC_ALREG | CC_ALGLOB);
@@ -1450,6 +1458,10 @@
 	    flags >>= 1;
 	    t >>= 1;
 	}
+	if (flags2 & CC_UNIQALL)
+	    putchar('1');
+	else if (flags2 & CC_UNIQCON)
+	    putchar('2');
     }
     if (flags2 & (CC_XORCONT | CC_PATCONT | CC_DEFCONT)) {
 	printf(" -t");
@@ -1787,6 +1799,14 @@
 		    dat.aflags |= CAF_NOSORT;
 		sp = &(dat.group);
 		e = "group name expected after -%c";
+		break;
+	    case '1':
+		if (!(dat.aflags & CAF_UNIQCON))
+		    dat.aflags |= CAF_UNIQALL;
+		break;
+	    case '2':
+		if (!(dat.aflags & CAF_UNIQALL))
+		    dat.aflags |= CAF_UNIQCON;
 		break;
 	    case 'y':
 		sp = &(dat.ylist);
diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c
--- os/Zle/zle_tricky.c	Wed Sep 22 13:33:20 1999
+++ Src/Zle/zle_tricky.c	Wed Sep 22 15:58:39 1999
@@ -3963,7 +3963,7 @@
     char **aign = NULL, **dparr = NULL, oaq = autoq, *oppre = dat->ppre;
     char *oqp = qipre, *oqs = qisuf, qc, **disp = NULL;
     int lpl, lsl, pl, sl, bpl, bsl, bppl = -1, bssl = -1;
-    int llpl = 0, llsl = 0, nm = mnum;
+    int llpl = 0, llsl = 0, nm = mnum, gflags;
     int oisalt = 0, isalt, isexact, doadd, ois = instring, oib = inbackt;
     Cline lc = NULL;
     Cmatch cm;
@@ -4145,20 +4145,19 @@
 		} else
 		    dat->prpre = dupstring(dat->prpre);
 		/* Select the group in which to store the matches. */
+		gflags = (((dat->aflags & CAF_NOSORT ) ? CGF_NOSORT  : 0) |
+			  ((dat->aflags & CAF_UNIQALL) ? CGF_UNIQALL : 0) |
+			  ((dat->aflags & CAF_UNIQCON) ? CGF_UNIQCON : 0));
 		if (dat->group) {
 		    endcmgroup(NULL);
-		    begcmgroup(dat->group, (dat->aflags & CAF_NOSORT));
-		    if (dat->aflags & CAF_NOSORT)
-			mgroup->flags |= CGF_NOSORT;
+		    begcmgroup(dat->group, gflags);
 		} else {
 		    endcmgroup(NULL);
 		    begcmgroup("default", 0);
 		}
 		if (dat->ylist) {
 		    endcmgroup(NULL);
-		    begcmgroup(NULL, (dat->aflags & CAF_NOSORT));
-		    if (dat->aflags & CAF_NOSORT)
-			mgroup->flags |= CGF_NOSORT;
+		    begcmgroup(NULL, gflags);
 		}
 		/* Select the set of matches. */
 		oisalt = (dat->aflags & CAF_ALT);
@@ -4247,7 +4246,7 @@
 	    if (dat->ylist) {
 		if (dat->group) {
 		    endcmgroup(get_user_var(dat->ylist));
-		    begcmgroup(dat->group, (dat->aflags & CAF_NOSORT));
+		    begcmgroup(dat->group, gflags);
 		    if (dat->exp)
 			addexpl();
 		} else {
@@ -6164,7 +6163,7 @@
 static void
 makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
 {
-    int t, sf1, sf2, ooffs, um = usemenu, delit, oaw;
+    int t, sf1, sf2, ooffs, um = usemenu, delit, oaw, gflags;
     char *p, *sd = NULL, *tt, *s1, *s2, *os =  dupstring(s);
     struct cmlist ms;
 
@@ -6199,18 +6198,19 @@
     curcc = cc;
 
     mflags = 0;
+    gflags = (((cc->mask2 & CC_NOSORT ) ? CGF_NOSORT  : 0) |
+	      ((cc->mask2 & CC_UNIQALL) ? CGF_UNIQALL : 0) |
+	      ((cc->mask2 & CC_UNIQCON) ? CGF_UNIQCON : 0));
     if (cc->gname) {
 	endcmgroup(NULL);
-	begcmgroup(cc->gname, cc->mask2 & CC_NOSORT);
+	begcmgroup(cc->gname, gflags);
     }
     if (cc->ylist) {
 	endcmgroup(NULL);
-	begcmgroup(NULL, cc->mask2 & CC_NOSORT);
+	begcmgroup(NULL, gflags);
     }
     if (cc->mask & CC_REMOVE)
 	mflags |= CMF_REMOVE;
-    if (cc->mask2 & CC_NOSORT)
-	mgroup->flags |= CGF_NOSORT;
     if (cc->explain) {
 	expl = (Cexpl) zhalloc(sizeof(struct cexpl));
 	expl->count = expl->fcount = 0;
@@ -7006,7 +7006,7 @@
 	    expl->str = tt;
 	    if (cc->gname) {
 		endcmgroup(yaptr);
-		begcmgroup(cc->gname, cc->mask2 & CC_NOSORT);
+		begcmgroup(cc->gname, gflags);
 		addexpl();
 	    } else {
 		addexpl();
@@ -7227,7 +7227,7 @@
 
 /**/
 static Cmatch *
-makearray(LinkList l, int s, int u, int *np, int *nlp, int *llp)
+makearray(LinkList l, int type, int flags, int *np, int *nlp, int *llp)
 {
     Cmatch *ap, *bp, *cp, *rp;
     LinkNode nod;
@@ -7242,57 +7242,75 @@
 	*ap++ = (Cmatch) getdata(nod);
     *ap = NULL;
 
-    if (s == 1) {
-	char **ap, **bp, **cp;
-
-	/* Now sort the array (it contains strings). */
-	qsort((void *) rp, n, sizeof(char *),
-	      (int (*) _((const void *, const void *)))strbpcmp);
-
-	/* And delete the ones that occur more than once. */
-	for (ap = cp = (char **) rp; *ap; ap++) {
-	    *cp++ = *ap;
-	    for (bp = ap; bp[1] && !strcmp(*ap, bp[1]); bp++, n--);
-	    ap = bp;
-	}
-	*cp = NULL;
-    } else if (s) {
-	/* Now sort the array (it contains matches). */
-	qsort((void *) rp, n, sizeof(Cmatch),
-	      (int (*) _((const void *, const void *)))matchcmp);
-
-	/* And delete the ones that occur more than once. */
-	for (ap = cp = rp; *ap; ap++) {
-	    *cp++ = *ap;
-	    for (bp = ap; bp[1] && matcheq(*ap, bp[1]); bp++, n--);
-	    ap = bp;
-	    /* Mark those, that would show the same string in the list. */
-	    for (; bp[1] && !(*ap)->disp && !(bp[1])->disp &&
-		     !strcmp((*ap)->str, (bp[1])->str); bp++)
-		(bp[1])->flags |= CMF_NOLIST;
-	}
-	for (ap = rp; *ap; ap++) {
-	    if ((*ap)->disp && ((*ap)->flags & CMF_DISPLINE))
-		ll++;
-	    if ((*ap)->flags & CMF_NOLIST)
-		nl++;
-	}
-	*cp = NULL;
-    } else if (u) {
-	for (ap = rp; *ap; ap++) {
-	    for (bp = cp = ap + 1; *bp; bp++) {
-		if (!matcheq(*ap, *bp))
-		    *cp++ = *bp;
-		else
-		    n--;
+    if (!type) {
+	if (flags) {
+	    char **ap, **bp, **cp;
+
+	    /* Now sort the array (it contains strings). */
+	    qsort((void *) rp, n, sizeof(char *),
+		  (int (*) _((const void *, const void *)))strbpcmp);
+
+	    /* And delete the ones that occur more than once. */
+	    for (ap = cp = (char **) rp; *ap; ap++) {
+		*cp++ = *ap;
+		for (bp = ap; bp[1] && !strcmp(*ap, bp[1]); bp++, n--);
+		ap = bp;
 	    }
 	    *cp = NULL;
 	}
-	for (ap = rp; *ap; ap++) {
-	    if ((*ap)->disp && ((*ap)->flags & CMF_DISPLINE))
-		ll++;
-	    if ((*ap)->flags & CMF_NOLIST)
-		nl++;
+    } else {
+	if (!(flags & CGF_NOSORT)) {
+	    /* Now sort the array (it contains matches). */
+	    qsort((void *) rp, n, sizeof(Cmatch),
+		  (int (*) _((const void *, const void *)))matchcmp);
+
+	    if (!(flags & (CGF_UNIQALL | CGF_UNIQCON))) {
+		/* And delete the ones that occur more than once. */
+		for (ap = cp = rp; *ap; ap++) {
+		    *cp++ = *ap;
+		    for (bp = ap; bp[1] && matcheq(*ap, bp[1]); bp++, n--);
+		    ap = bp;
+		    /* Mark those, that would show the same string in the list. */
+		    for (; bp[1] && !(*ap)->disp && !(bp[1])->disp &&
+			     !strcmp((*ap)->str, (bp[1])->str); bp++)
+			(bp[1])->flags |= CMF_NOLIST;
+		}
+		*cp = NULL;
+	    }
+	    for (ap = rp; *ap; ap++) {
+		if ((*ap)->disp && ((*ap)->flags & CMF_DISPLINE))
+		    ll++;
+		if ((*ap)->flags & CMF_NOLIST)
+		    nl++;
+	    }
+	} else {
+	    if (!(flags & CGF_UNIQALL) && !(flags & CGF_UNIQCON)) {
+		for (ap = rp; *ap; ap++) {
+		    for (bp = cp = ap + 1; *bp; bp++) {
+			if (!matcheq(*ap, *bp))
+			    *cp++ = *bp;
+			else
+			    n--;
+		    }
+		    *cp = NULL;
+		}
+	    } else if (!(flags & CGF_UNIQCON)) {
+		for (ap = cp = rp; *ap; ap++) {
+		    *cp++ = *ap;
+		    for (bp = ap; bp[1] && matcheq(*ap, bp[1]); bp++, n--);
+		    ap = bp;
+		    for (; bp[1] && !(*ap)->disp && !(bp[1])->disp &&
+			     !strcmp((*ap)->str, (bp[1])->str); bp++)
+			(bp[1])->flags |= CMF_NOLIST;
+		}
+		*cp = NULL;
+	    }
+	    for (ap = rp; *ap; ap++) {
+		if ((*ap)->disp && ((*ap)->flags & CMF_DISPLINE))
+		    ll++;
+		if ((*ap)->flags & CMF_NOLIST)
+		    nl++;
+	    }
 	}
     }
     if (np)
@@ -7308,13 +7326,14 @@
 
 /**/
 static void
-begcmgroup(char *n, int nu)
+begcmgroup(char *n, int flags)
 {
     if (n) {
 	Cmgroup p = amatches;
 
 	while (p) {
-	    if (p->name && ((nu && !p->lallccs) || (!nu && p->lallccs)) &&
+	    if (p->name &&
+		flags == (p->flags & (CGF_NOSORT|CGF_UNIQALL|CGF_UNIQCON)) &&
 		!strcmp(n, p->name)) {
 		mgroup = p;
 
@@ -7330,7 +7349,8 @@
     }
     mgroup = (Cmgroup) zhalloc(sizeof(struct cmgroup));
     mgroup->name = dupstring(n);
-    mgroup->flags = mgroup->lcount = mgroup->llcount = mgroup->mcount = 0;
+    mgroup->lcount = mgroup->llcount = mgroup->mcount = 0;
+    mgroup->flags = flags;
     mgroup->matches = NULL;
     mgroup->ylist = NULL;
     mgroup->expls = NULL;
@@ -7339,7 +7359,7 @@
     mgroup->lmatches = matches = newlinklist();
     mgroup->lfmatches = fmatches = newlinklist();
 
-    mgroup->lallccs = allccs = (nu ? NULL : newlinklist());
+    mgroup->lallccs = allccs = ((flags & CGF_NOSORT) ? NULL : newlinklist());
 
     mgroup->next = amatches;
     amatches = mgroup;
@@ -7435,9 +7455,7 @@
 		/* We have no matches, try ignoring fignore. */
 		g->lmatches = g->lfmatches;
 
-	    g->matches = makearray(g->lmatches,
-				   ((g->flags & CGF_NOSORT) ? 0 : 2), 1,
-				   &nn, &nl, &ll);
+	    g->matches = makearray(g->lmatches, 1, g->flags, &nn, &nl, &ll);
 	    g->mcount = nn;
 	    if ((g->lcount = nn - nl) < 0)
 		g->lcount = 0;
@@ -9172,7 +9190,7 @@
     smatches = 1;
     validlist = 1;
     memset(&dg, 0, sizeof(struct cmgroup));
-    dg.ylist = (char **) makearray(l, 1, 0, &(dg.lcount), NULL, NULL);
+    dg.ylist = (char **) makearray(l, 0, 1, &(dg.lcount), NULL, NULL);
     amatches = &dg;
     ilistmatches(NULL, NULL);
     amatches = am;
diff -u od/Zsh/compctl.yo Doc/Zsh/compctl.yo
--- od/Zsh/compctl.yo	Wed Sep 22 13:33:04 1999
+++ Doc/Zsh/compctl.yo	Wed Sep 22 16:00:48 1999
@@ -137,7 +137,7 @@
 texinode(Option Flags)(Alternative Completion)(Command Flags)(Programmable Completion Using compctl)
 sect(Option Flags)
 startlist()
-list([ tt(-fcFBdeaRGovNAIOPZEnbjrzu/) ])
+list([ tt(-fcFBdeaRGovNAIOPZEnbjrzu/12) ])
 list([ tt(-k) var(array) ] [ tt(-g) var(globstring) ] \
   [ tt(-s) var(subststring) ])
 list([ tt(-K) var(function) ] [ tt(-i) var(function) ])
@@ -515,6 +515,18 @@
 nor in menucompletion. These unsorted groups are in a different name
 space from the sorted ones, so groups defined as tt(-J files) and tt(-V
 files) are distinct.
+)
+item(tt(-1))(
+If given together with the tt(-J) option, makes duplicate matches in
+the group be kept. If given together with the tt(-V) option, makes
+only consecutive duplicates in the group be removed. Note that groups
+with and without this flag are in different name spaces.
+)
+item(tt(-2))(
+If given together with the tt(-J) option, behaves the same as
+tt(-J). If given together with the tt(-V) option, keep all duplicate
+matches. Again, groups with and without this flag are in different
+name spaces.
 )
 item(tt(-M) var(match-spec))(
 This defines additional matching control specifications that should be used
diff -u od/Zsh/compsys.yo Doc/Zsh/compsys.yo
--- od/Zsh/compsys.yo	Wed Sep 22 13:33:04 1999
+++ Doc/Zsh/compsys.yo	Wed Sep 22 16:05:57 1999
@@ -566,8 +566,10 @@
 matches are placed in a separate group (the second argument is used as 
 the name of the group) if the configuration key tt(group_matches) is
 set to a non-empty string. Normally a sorted group will be used for this
-(with the `tt(-J)' option), but if the option `tt(-V)' is given, a
-unsorted group will be used instead.
+(with the `tt(-J)' option), but if a option starting with `tt(-V)' or
+`tt(-J)' is given, that option will be included in the array, so that
+it is possible to make the group unsorted by given the option
+`tt(-V)', `tt(-V1)', or `tt(-V2)'.
 
 In most cases, this function will be used like this:
 
diff -u od/Zsh/compwid.yo Doc/Zsh/compwid.yo
--- od/Zsh/compwid.yo	Wed Sep 22 13:33:04 1999
+++ Doc/Zsh/compwid.yo	Wed Sep 22 16:01:05 1999
@@ -369,7 +369,7 @@
 )
 findex(compadd)
 cindex(completion widgets, adding specified matches)
-xitem(tt(compadd) [ tt(-qQfenUaml) ] [ tt(-F) var(array) ])
+xitem(tt(compadd) [ tt(-qQfenUaml12) ] [ 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) ])
@@ -462,6 +462,18 @@
 )
 item(tt(-V) var(name))(
 Like tt(-J) but naming a unsorted group.
+)
+item(tt(-1))(
+If given together with the tt(-J) option, makes duplicate matches in
+the group be kept. If given together with the tt(-V) option, makes
+only consecutive duplicates in the group be removed. Note that groups
+with and without this flag are in different name spaces.
+)
+item(tt(-2))(
+If given together with the tt(-J) option, behaves the same as
+tt(-J). If given together with the tt(-V) option, keep all duplicate
+matches. Again, groups with and without this flag are in different
+name spaces.
 )
 item(tt(-X) var(explanation))(
 As for tt(compctl) and tt(compgen), the var(explanation) string will be
diff -u oldcompletion/Core/_description Completion/Core/_description
--- oldcompletion/Core/_description	Tue Sep 21 10:26:40 1999
+++ Completion/Core/_description	Wed Sep 22 16:06:15 1999
@@ -2,8 +2,8 @@
 
 local gropt=-J
 
-if [[ "$1" = -V ]]; then
-  gropt=-V
+if [[ "$1" = -[VJ]* ]]; then
+  gropt="$1"
   shift
 fi
 

--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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