From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26276 invoked from network); 15 Jul 1999 14:01:45 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 15 Jul 1999 14:01:45 -0000 Received: (qmail 10382 invoked by alias); 15 Jul 1999 14:01:29 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 7161 Received: (qmail 10362 invoked from network); 15 Jul 1999 14:01:28 -0000 Date: Thu, 15 Jul 1999 16:01:26 +0200 (MET DST) Message-Id: <199907151401.QAA16962@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: Peter Stephenson's message of Wed, 14 Jul 1999 16:17:59 +0200 Subject: Re: Completing subcommand strings Peter Stephenson wrote: > I managed to get into trouble completing after > > sh -c 'tar xvf > > when it seems to like to insert another copy of `tar xvf' along with any > file it's inserting; the bug could be in a lot of different places. I'm > certainly not expecting every little thing like that to be fixed before > 3.1.6. Irony? Sarcasm? Must have been something like that... Oh dear. I guess the problem Peter meant was the one showing up when trying the above with menu-completion. The path-prefix/suffix also contained the quote-prefix/suffix. But before I saw this I remembered that I had completely forgotten about accept-and-menu-complete when I implemented the completion-in- quotes stuff. There we have to treat such quote-prefixes and -suffixes completely different. I've made it so that they will only appear once in the command line, surrounding all matches inserted. But of course I had to treat parameter expansions specially -- a prefix like `${' should of course be stuck in front of every accepted match. While hacking this I found a buglet in _brace_parameters: the automatically inserted closing quote (as in ${"foo) was backslashed. Then I had to tell complist about all this new stuff and adapt it to the list-change from 7154. Uff. Bye Sven diff -u os/Zle/comp.h Src/Zle/comp.h --- os/Zle/comp.h Thu Jul 15 10:52:03 1999 +++ Src/Zle/comp.h Thu Jul 15 13:54:03 1999 @@ -218,6 +218,8 @@ int brsl; /* ...and the suffix */ char *rems; /* when to remove the suffix */ char *remf; /* shell function to call for suffix-removal */ + int qipl; /* length of quote-prefix */ + int qisl; /* length of quote-suffix */ int rnum; /* group relative number */ int gnum; /* global number */ }; diff -u os/Zle/complist.c Src/Zle/complist.c --- os/Zle/complist.c Thu Jul 15 10:52:04 1999 +++ Src/Zle/complist.c Thu Jul 15 15:44:28 1999 @@ -680,7 +680,7 @@ struct menustack { Menustack prev; char *line; - int cs; + int cs, acc; struct menuinfo info; Cmgroup amatches, pmatches, lmatches; }; @@ -746,19 +746,19 @@ s->amatches = amatches; s->pmatches = pmatches; s->lmatches = lmatches; - menucmp = 0; + s->acc = menuacc; + menucmp = menuacc = 0; fixsuffix(); validlist = 0; pmatches = NULL; invalidatelist(); menucomplete(zlenoargs); if (dat->num < 2 || !minfo.cur || !*(minfo.cur)) { - noselect = 1; - clearlist = 1; + noselect = clearlist = listshown = 1; zrefresh(); break; } - clearlist = 1; + clearlist = listshown = 1; mselect = (*(minfo.cur))->gnum; continue; } else if (cmd == Th(z_acceptandhold) || @@ -771,6 +771,7 @@ s->cs = cs; memcpy(&(s->info), &minfo, sizeof(struct menuinfo)); s->amatches = s->pmatches = s->lmatches = NULL; + s->acc = menuacc; acceptlast(); do_menucmp(0); mselect = (*(minfo.cur))->gnum; @@ -786,6 +787,7 @@ spaceinline(l = strlen(u->line)); strncpy((char *) line, u->line, l); cs = u->cs; + menuacc = u->acc; memcpy(&minfo, &(u->info), sizeof(struct menuinfo)); p = &(minfo.cur); if (u->pmatches && pmatches != u->pmatches) { diff -u os/Zle/zle_tricky.c Src/Zle/zle_tricky.c --- os/Zle/zle_tricky.c Thu Jul 15 10:52:06 1999 +++ Src/Zle/zle_tricky.c Thu Jul 15 15:40:49 1999 @@ -106,10 +106,11 @@ static int movetoend; -/* != 0 if we are in the middle of a menu completion */ +/* != 0 if we are in the middle of a menu completion and number of matches +* accepted with accept-and-menu-complete */ /**/ -int menucmp; +int menucmp, menuacc; /* Information about menucompletion. */ @@ -192,6 +193,10 @@ static int lpl, lsl, rpl, rsl, fpl, fsl, lppl, lpsl; static int noreal; +/* A parameter expansion prefix (like ${). */ + +static char *parpre; + /* This is either zero or equal to the special character the word we are * * trying to complete starts with (e.g. Tilde or Equals). */ @@ -540,6 +545,8 @@ void acceptlast(void) { + menuacc++; + if (brbeg && *brbeg) { int l; @@ -553,10 +560,16 @@ brbeg[l] = ','; brbeg[l + 1] = '\0'; } else { + int l; + cs = minfo.pos + minfo.len + minfo.insc; iremovesuffix(' ', 1); - + l = cs; + cs = minfo.pos + minfo.len - (*(minfo.cur))->qisl; + foredel(l - cs); inststrlen(" ", 1, 1); + if (parpre) + inststr(parpre); minfo.insc = minfo.len = 0; minfo.pos = cs; minfo.we = 1; @@ -694,6 +707,9 @@ { char *p; + zsfree(parpre); + parpre = NULL; + if (!test) ispar = parq = eparq = 0; /* Try to find a `$'. */ @@ -755,6 +771,8 @@ /* Now make sure that the cursor is inside the name. */ if (offs <= e - s && offs >= b - s && n <= 0) { + char sav; + if (br) { p = e; while (*p == (test ? Dnull : '"')) @@ -782,6 +800,12 @@ else parq = eparq = 0; + /* Save the prefix. */ + sav = *b; + *b = '\0'; + untokenize(parpre = ztrdup(s)); + *b = sav; + /* And adjust wb, we, and offs again. */ offs -= b - s; wb = cs - offs; @@ -1064,7 +1088,7 @@ dat.num = nmatches; dat.cur = NULL; if (runhookdef(MENUSTARTHOOK, (void *) &dat)) - menucmp = 0; + menucmp = menuacc = 0; } return ret; } @@ -3575,6 +3599,8 @@ cm->flags = flags; cm->brpl = bpl; cm->brsl = bsl; + cm->qipl = qipl; + cm->qisl = qisl; cm->autoq = (autoq ? autoq : (inbackt ? '`' : '\0')); cm->rems = cm->remf = NULL; addlinknode((alt ? fmatches : matches), cm); @@ -4847,7 +4873,7 @@ insmnum = insgnum = 1; insgroup = oldlist = oldins = 0; begcmgroup("default", 0); - menucmp = 0; + menucmp = menuacc = 0; ccused = newlinklist(); ccstack = newlinklist(); @@ -5000,6 +5026,8 @@ memcpy(tmp + sl + 1, s, noffs); tmp[(scs = cs = sl + 1 + noffs)] = 'x'; strcpy(tmp + sl + 2 + noffs, s + noffs); + if (incompfunc) + tmp = rembslash(tmp); inpush(dupstrspace(tmp), 0, NULL); line = (unsigned char *) tmp; ll = tl - 1; @@ -5029,6 +5057,7 @@ p = NULL; if (!got && !zleparse) { DPUTS(!p, "no current word in substr"); + got = 1; cur = i; swb = wb - 1; swe = we - 1; @@ -5093,7 +5122,7 @@ } sav = s[(i = swb - sl - 1)]; s[i] = '\0'; - qp = tricat(qipre, s, ""); + qp = tricat(qipre, (incompfunc ? rembslash(s) : s), ""); s[i] = sav; if (swe < swb) swe = swb; @@ -5101,7 +5130,7 @@ sl = strlen(s); if (swe > sl) swe = sl, ns[swe - swb + 1] = '\0'; - qs = tricat(s + swe, qisuf, ""); + qs = tricat((incompfunc ? rembslash(s + swe) : s + swe), qisuf, ""); sl = strlen(ns); if (soffs > sl) soffs = sl; @@ -5998,7 +6027,10 @@ char save = line[cs]; line[cs] = 0; - lppre = dupstring((char *) (line + wb)); + lppre = dupstring((char *) line + wb + + (qipre && *qipre ? + (strlen(qipre) - + (*qipre == '\'' || *qipre == '\"')) : 0)); line[cs] = save; if (brbeg && *brbeg) strcpy(lppre + qbrpl, lppre + qbrpl + strlen(brbeg)); @@ -6017,11 +6049,17 @@ lppl = 0; } if (cs != we) { - char save = line[we]; + int end = we; + char save = line[end]; - line[we] = 0; + if (qisuf && *qisuf) { + int ql = strlen(qisuf); + + end -= ql - (qisuf[ql-1] == '\'' || qisuf[ql-1] == '"'); + } + line[end] = 0; lpsuf = dupstring((char *) (line + cs)); - line[we] = save; + line[end] = save; if (brend && *brend) { char *p = lpsuf + qbrsl - (cs - wb); @@ -6659,7 +6697,8 @@ listmatches(); if (validlist) freematches(); - lastambig = menucmp = validlist = showinglist = fromcomp = 0; + lastambig = menucmp = menuacc = validlist = showinglist = + fromcomp = listshown = 0; minfo.cur = NULL; minfo.asked = 0; compwidget = NULL; @@ -6936,6 +6975,8 @@ r->rems = ztrdup(m->rems); r->remf = ztrdup(m->remf); r->autoq = m->autoq; + r->qipl = m->qipl; + r->qisl = m->qisl; return r; } @@ -7365,7 +7406,9 @@ /* Ignored prefix. */ if (m->ipre) { - inststrlen(m->ipre, 1, (l = strlen(m->ipre))); + char *p = m->ipre + (menuacc ? m->qipl : 0); + + inststrlen(p, 1, (l = strlen(p))); r += l; } /* -P prefix. */ @@ -7432,7 +7475,8 @@ do_ambiguous(void) { int ret = 0; - menucmp = 0; + + menucmp = menuacc = 0; /* If we have to insert the first match, call do_single(). This is * * how REC_EXACT takes effect. We effectively turn the ambiguous * @@ -7670,7 +7714,7 @@ } } if (!minfo.insc) - cs = minfo.pos + minfo.len; + cs = minfo.pos + minfo.len - m->qisl; } /* If completing in a brace expansion... */ if (brbeg) { @@ -7709,8 +7753,11 @@ if (minfo.we && m->ripre && isset(AUTOPARAMKEYS)) makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq); - if ((menucmp && !minfo.we) || !movetoend) + if ((menucmp && !minfo.we) || !movetoend) { cs = minfo.end; + if (cs + m->qisl == lastend) + cs += minfo.insc; + } { Cmatch *om = minfo.cur; struct chdata dat; @@ -7753,6 +7800,7 @@ if (usemenu != 3) { menucmp = 1; + menuacc = 0; minfo.cur = NULL; } else { if (oldlist) { diff -u oc/Base/_brace_parameter Completion/Base/_brace_parameter --- oc/Base/_brace_parameter Wed Jul 14 14:46:58 1999 +++ Completion/Base/_brace_parameter Thu Jul 15 11:40:02 1999 @@ -18,4 +18,4 @@ [[ n -gt 0 ]] && suf='' -_parameters -s "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/' +_parameters -Qs "${q[1,-n-1]}" -S "$suf" -r '-:?#%+=[/' -- Sven Wischnowsky wischnow@informatik.hu-berlin.de