From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20320 invoked from network); 14 Sep 1999 09:50:31 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 14 Sep 1999 09:50:31 -0000 Received: (qmail 29917 invoked by alias); 14 Sep 1999 09:50:14 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 7823 Received: (qmail 29910 invoked from network); 14 Sep 1999 09:50:14 -0000 Date: Tue, 14 Sep 1999 11:50:07 +0200 (MET DST) Message-Id: <199909140950.LAA27294@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: Sven Wischnowsky's message of Mon, 13 Sep 1999 15:30:59 +0200 (MET DST) Subject: Re: Problem with _arguments and _normal as action if nolistambiguous is set. I wrote: > Andrej Borsenkow wrote: > > > itsrm2% sudo -TAB > > itsrm2% sudo <=cursor here > > This is a really ugly bug. It comes from the fact that the options are > added with a `r:|-=*' match spec and commands are not. The completion > code currently can't merge the unambiguous string information if the > equal substrings are in an anchor for some matches and in a normal > string-part for other matches. This should do it by turning sequences of cline structs for anchrs (and their prefixes) into a prefix and then trying to join the two lists again. Bye Sven diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c --- os/Zle/zle_tricky.c Tue Sep 14 09:08:46 1999 +++ Src/Zle/zle_tricky.c Tue Sep 14 11:46:44 1999 @@ -1946,7 +1946,7 @@ { Cline r; - /* Preverably take it from the buffer list (freecl), if there + /* Prefer to take it from the buffer list (freecl), if there * is none, allocate a new one. */ if ((r = freecl)) @@ -1981,6 +1981,28 @@ } } +/* Copy a cline list. */ + +static Cline +cp_cline(Cline l) +{ + Cline r = NULL, *p = &r, t; + + while (l) { + if ((t = freecl)) + freecl = t->next; + else + t = (Cline) zhalloc(sizeof(*t)); + memcpy(t, l, sizeof(*t)); + *p = t; + p = &(t->next); + l = l->next; + } + *p = NULL; + + return r; +} + /* This reverts the order of the elements of the given cline list and * returns a pointer to the new head. */ @@ -3365,6 +3387,50 @@ n->suffix = NULL; } +/* This turns the sequence of anchor cline structs from b to e into a + * prefix sequence, puts it before the prefix of e and then tries to + * join that with the prefix of a. + * This is needed if some matches had a anchor match spec and others + * didn't. */ + +static void +sub_join(Cline a, Cline b, Cline e, int anew) +{ + if (!e->suffix && a->prefix) { + Cline op = e->prefix, n = NULL, *p = &n, t, ca; + + for (; b != e; b = b->next) { + if ((*p = t = b->prefix)) { + while (t->next) + t = t->next; + p = &(t->next); + } + b->suffix = b->prefix = NULL; + b->flags &= ~CLF_SUF; + *p = b; + p = &(b->next); + } + *p = e->prefix; + ca = a->prefix; + + while (n != op) { + e->prefix = cp_cline(n); + a->prefix = cp_cline(ca); + + if (anew) { + join_psfx(e, a, NULL, NULL, 0); + if (e->prefix) + break; + } else { + join_psfx(e, a, NULL, NULL, 0); + if (a->prefix) + break; + } + n = n->next; + } + } +} + /* This simplifies the cline list given as the first argument so that * it also matches the second list. */ @@ -3388,11 +3454,7 @@ for (t = o; (tn = t->next) && (tn->flags & CLF_NEW); t = tn); if (tn && cmp_anchors(tn, n, 0)) { - Cline tmp; - - tmp = o->prefix; - o->prefix = tn->prefix; - tn->prefix = tmp; + sub_join(n, o, tn, 1); if (po) po->next = tn; @@ -3410,11 +3472,7 @@ for (t = n; (tn = t->next) && (tn->flags & CLF_NEW); t = tn); if (tn && cmp_anchors(o, tn, 0)) { - Cline tmp; - - tmp = n->prefix; - n->prefix = tn->prefix; - tn->prefix = tmp; + sub_join(o, n, tn, 0); n = tn; o->flags |= CLF_MISS; @@ -3433,10 +3491,8 @@ (o->flags & (CLF_SUF | CLF_MID)); t = tn); if (tn && cmp_anchors(o, tn, 1)) { - Cline t; + sub_join(o, n, tn, 0); - t = tn->prefix; tn->prefix = n->prefix; n->prefix = t; - t = tn->suffix; tn->suffix = n->suffix; n->suffix = t; n = tn; continue; } @@ -3446,6 +3502,7 @@ (n->flags & (CLF_SUF | CLF_MID)); t = tn); if (tn && cmp_anchors(tn, n, 1)) { + sub_join(n, o, tn, 1); if (po) po->next = tn; else @@ -3474,8 +3531,8 @@ for (t = n; (tn = t->next) && !cmp_anchors(o, tn, 1); t = tn); if (tn) { - t = tn->prefix; tn->prefix = n->prefix; n->prefix = t; - t = tn->suffix; tn->suffix = n->suffix; n->suffix = t; + sub_join(o, n, tn, 0); + n = tn; o->flags |= CLF_MISS; continue; @@ -3484,8 +3541,8 @@ t = tn); if (tn) { - t = tn->prefix; tn->prefix = o->prefix; o->prefix = t; - t = tn->suffix; tn->suffix = o->suffix; o->suffix = t; + sub_join(n, o, tn, 1); + if (po) po->next = tn; else -- Sven Wischnowsky wischnow@informatik.hu-berlin.de