diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-07-19 14:26:14 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-07-19 14:26:14 +0000 |
commit | d6d4a3abfc84f0940e663cd69537789a039a7056 (patch) | |
tree | 5f5f40ae248c17c34fccbcadef85dddd4136b781 /Src/Zle/zle_tricky.c | |
parent | 1f6786ef7ae24ff858f52c6d4ac2bc23d529c0c1 (diff) | |
download | zsh-d6d4a3abfc84f0940e663cd69537789a039a7056.tar.gz zsh-d6d4a3abfc84f0940e663cd69537789a039a7056.tar.xz zsh-d6d4a3abfc84f0940e663cd69537789a039a7056.zip |
zsh-3.1.6-test-2 zsh-3.1.6-test-2
Diffstat (limited to 'Src/Zle/zle_tricky.c')
-rw-r--r-- | Src/Zle/zle_tricky.c | 162 |
1 files changed, 118 insertions, 44 deletions
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 5461079cb..b678a5cad 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -106,10 +106,11 @@ static int insmnum, insgnum, insgroup, insspace; 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 char *qipre, *qisuf, autoq; 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). */ @@ -209,9 +214,9 @@ static char *qword; static Cmgroup mgroup; -/* A match counter. */ +/* Match counters: all matches, normal matches (not alternate set). */ -static int mnum; +static int mnum, nmnum; /* The match counter when unambig_data() was called. */ @@ -540,6 +545,8 @@ reversemenucomplete(char **args) void acceptlast(void) { + menuacc++; + if (brbeg && *brbeg) { int l; @@ -553,10 +560,16 @@ acceptlast(void) 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 @@ check_param(char *s, int set, int test) { char *p; + zsfree(parpre); + parpre = NULL; + if (!test) ispar = parq = eparq = 0; /* Try to find a `$'. */ @@ -755,6 +771,8 @@ check_param(char *s, int set, int test) /* 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 @@ check_param(char *s, int set, int test) 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; @@ -1017,7 +1041,7 @@ docomplete(int lst) int ocs = cs, ne = noerrs; noerrs = 1; - doexpansion(s, lst, olst, lincmd); + ret = doexpansion(s, lst, olst, lincmd); lastambig = 0; noerrs = ne; @@ -1043,8 +1067,8 @@ docomplete(int lst) } } ret = docompletion(s, lst, lincmd); - } else - ret = !strcmp(ol, (char *) line); + } else if (ret) + clearlist = 1; } else /* Just do completion. */ ret = docompletion(s, lst, lincmd); @@ -1064,7 +1088,7 @@ docomplete(int lst) dat.num = nmatches; dat.cur = NULL; if (runhookdef(MENUSTARTHOOK, (void *) &dat)) - menucmp = 0; + menucmp = menuacc = 0; } return ret; } @@ -1736,9 +1760,10 @@ get_comp_string(void) /* Expand the current word. */ /**/ -static void +static int doexpansion(char *s, int lst, int olst, int explincmd) { + int ret = 1; LinkList vl; char *ss; @@ -1775,7 +1800,7 @@ doexpansion(char *s, int lst, int olst, int explincmd) } if (lst == COMP_LIST_EXPAND) { /* Only the list of expansions was requested. */ - listlist(vl); + ret = listlist(vl); showinglist = 0; goto end; } @@ -1783,6 +1808,7 @@ doexpansion(char *s, int lst, int olst, int explincmd) cs = wb; foredel(we - wb); while ((ss = (char *)ugetnode(vl))) { + ret = 0; untokenize(ss); ss = quotename(ss, NULL); inststr(ss); @@ -1801,6 +1827,8 @@ doexpansion(char *s, int lst, int olst, int explincmd) end: popheap(); } LASTALLOC; + + return ret; } /* This is called from the lexer to give us word positions. */ @@ -3547,6 +3575,8 @@ add_match_data(int alt, char *str, Cline line, ai->line = join_clines(ai->line, line); mnum++; + if (!alt) + nmnum++; ai->count++; /* Allocate and fill the match structure. */ @@ -3569,6 +3599,8 @@ add_match_data(int alt, char *str, Cline line, 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); @@ -3896,6 +3928,7 @@ addmatches(Cadata dat, char **argv) } } compnmatches = mnum; + compnnmatches = nmnum; if (dat->exp) addexpl(); if (dat->apar) @@ -4380,10 +4413,14 @@ docompletion(char *s, int lst, int incmd) } if (comppatmatch && *comppatmatch && comppatmatch != opm) haspattern = 1; - if (!useline && uselist) + if (!useline && uselist) { /* All this and the guy only wants to see the list, sigh. */ + cs = 0; + foredel(ll); + inststr(origline); + cs = origcs; showinglist = -2; - else if (useline) { + } else if (useline) { /* We have matches. */ if (nmatches > 1) { /* There is more than one match. */ @@ -4399,9 +4436,13 @@ docompletion(char *s, int lst, int incmd) do_single(m->matches[0]); invalidatelist(); } - } else + } else { invalidatelist(); - + cs = 0; + foredel(ll); + inststr(origline); + cs = origcs; + } /* Print the explanation strings if needed. */ if (!showinglist && validlist && usemenu != 2 && nmatches != 1) { Cmgroup g = amatches; @@ -4582,22 +4623,22 @@ callcompfunc(char *s, char *fn) zsfree(compprefix); zsfree(compsuffix); if (unset(COMPLETEINWORD)) { - /* Maybe we'll have to do quoting here some time. */ - tmp = dupstring(s); + tmp = quotename(s, NULL); untokenize(tmp); compprefix = ztrdup(tmp); compsuffix = ztrdup(""); } else { char *ss, sav; - tmp = dupstring(s); - ss = tmp + offs; + ss = s + offs; sav = *ss; *ss = '\0'; + tmp = quotename(s, NULL); untokenize(tmp); compprefix = ztrdup(tmp); *ss = sav; + ss = quotename(ss, NULL); untokenize(ss); compsuffix = ztrdup(ss); } @@ -4611,6 +4652,7 @@ callcompfunc(char *s, char *fn) compqisuffix = ztrdup(qisuf ? qisuf : ""); compcurrent = (usea ? (clwpos + 1 - aadd) : 0); compnmatches = mnum; + compnnmatches = nmnum; zsfree(complist); switch (uselist) { @@ -4825,13 +4867,13 @@ makecomplist(char *s, int incmd, int lst) if (!validlist) lastambig = 0; amatches = NULL; - mnum = 0; + mnum = nmnum = 0; unambig_mnum = -1; isuf = NULL; insmnum = insgnum = 1; insgroup = oldlist = oldins = 0; begcmgroup("default", 0); - menucmp = 0; + menucmp = menuacc = 0; ccused = newlinklist(); ccstack = newlinklist(); @@ -4984,6 +5026,8 @@ sep_comp_string(char *ss, char *s, int noffs, int rec) 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; @@ -5013,6 +5057,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec) p = NULL; if (!got && !zleparse) { DPUTS(!p, "no current word in substr"); + got = 1; cur = i; swb = wb - 1; swe = we - 1; @@ -5077,7 +5122,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec) } 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; @@ -5085,7 +5130,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec) 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; @@ -5172,7 +5217,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec) compisuffix = ztrdup(""); zsfree(compqiprefix); zsfree(compqisuffix); - if (instring) { + if (ois) { compqiprefix = qp; compqisuffix = qs; } else { @@ -5188,6 +5233,7 @@ sep_comp_string(char *ss, char *s, int noffs, int rec) p = compwords[i] = (char *) getdata(n); untokenize(p); } + compcurrent = cur + 1; compwords[i] = NULL; } autoq = oaq; @@ -5242,6 +5288,7 @@ makecomplistcall(Compctl cc) inbackt = oib; autoq = oaq; compnmatches = mnum; + compnnmatches = nmnum; } LASTALLOC; } SWITCHBACKHEAPS; @@ -5317,6 +5364,7 @@ makecomplistctl(int flags) autoq = oaq; offs = ooffs; compnmatches = mnum; + compnnmatches = nmnum; zsfree(cmdstr); freearray(clwords); cmdstr = os; @@ -5979,7 +6027,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) 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)); @@ -5998,11 +6049,17 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) lppl = 0; } if (cs != we) { - char save = line[we]; + int end = we; + char save = line[end]; + + if (qisuf && *qisuf) { + int ql = strlen(qisuf); - line[we] = 0; + 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); @@ -6640,7 +6697,8 @@ invalidatelist(void) 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; @@ -6917,6 +6975,8 @@ dupmatch(Cmatch m) r->rems = ztrdup(m->rems); r->remf = ztrdup(m->remf); r->autoq = m->autoq; + r->qipl = m->qipl; + r->qisl = m->qisl; return r; } @@ -7346,7 +7406,9 @@ instmatch(Cmatch m, int *scs) /* 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. */ @@ -7413,7 +7475,8 @@ static int 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 * @@ -7501,11 +7564,13 @@ do_ambiguous(void) * if it is needed. */ if (isset(LISTBEEP)) ret = 1; - if (uselist && (usemenu != 2 || (!showinglist && !oldlist)) && + + if (uselist && (usemenu != 2 || (!listshown && !oldlist)) && ((!showinglist && (!listshown || !oldlist)) || (usemenu == 3 && !oldlist)) && (smatches >= 2 || (compforcelist && *compforcelist))) showinglist = -2; + return ret; } @@ -7649,7 +7714,7 @@ do_single(Cmatch m) } } if (!minfo.insc) - cs = minfo.pos + minfo.len; + cs = minfo.pos + minfo.len - m->qisl; } /* If completing in a brace expansion... */ if (brbeg) { @@ -7688,8 +7753,11 @@ do_single(Cmatch m) 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; @@ -7732,6 +7800,7 @@ do_ambig_menu(void) if (usemenu != 3) { menucmp = 1; + menuacc = 0; minfo.cur = NULL; } else { if (oldlist) { @@ -7931,13 +8000,6 @@ ilistmatches(Hookdef dummy, Chdata dat) int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0; int of = isset(LISTTYPES), opl = 0; - /* Set the cursor below the prompt. */ - trashzle(); - showinglist = listshown = 0; - - clearflag = (isset(USEZLE) && !termflags && - complastprompt && *complastprompt); - for (g = amatches; g; g = g->next) { char **pp = g->ylist; int nl = 0, l; @@ -8013,6 +8075,16 @@ ilistmatches(Hookdef dummy, Chdata dat) nlines += 1 + ((1 + niceztrlen(m->str)) / columns); } } + if (!nlines) { + showinglist = listshown = 0; + return 1; + } + /* Set the cursor below the prompt. */ + trashzle(); + showinglist = listshown = 0; + + clearflag = (isset(USEZLE) && !termflags && + complastprompt && *complastprompt); /* Maybe we have to ask if the user wants to see the list. */ if ((!minfo.cur || !minfo.asked) && @@ -8152,25 +8224,25 @@ ilistmatches(Hookdef dummy, Chdata dat) pnl = 1; g = g->next; } - if (clearflag) { /* Move the cursor up to the prompt, if always_last_prompt * * is set and all that... */ if ((nlines += nlnct - 1) < lines) { tcmultout(TCUP, TCMULTUP, nlines); showinglist = -1; - listshown = 1; } else clearflag = 0, putc('\n', shout); } else putc('\n', shout); + listshown = (clearflag ? 1 : -1); + return 0; } /* This is used to print expansions. */ /**/ -void +int listlist(LinkList l) { struct cmgroup dg; @@ -8193,6 +8265,8 @@ listlist(LinkList l) validlist = vl; smatches = sm; complastprompt = oclp; + + return !dg.lcount; } /* Expand the history references. */ |