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

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<TAB>) 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@xxxxxxxxxxxxxxxxxxxxxxx



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