From 7a40d6c258ad87d147ee5d6839e746c33ebc0ac7 Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Thu, 15 Apr 1999 18:12:56 +0000 Subject: zsh-3.1.5-pws-6 --- Src/Zle/comp.h | 5 + Src/Zle/comp1.c | 8 +- Src/Zle/comp1.export | 3 +- Src/Zle/compctl.c | 67 ++-- Src/Zle/iwidgets.list | 2 +- Src/Zle/zle.h | 24 +- Src/Zle/zle_main.c | 29 +- Src/Zle/zle_params.c | 23 +- Src/Zle/zle_thingy.c | 57 +--- Src/Zle/zle_tricky.c | 847 +++++++++++++++++++++++++++----------------------- 10 files changed, 544 insertions(+), 521 deletions(-) (limited to 'Src/Zle') diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index afd55b7f1..20e3d2cce 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -267,3 +267,8 @@ struct cline { #define CLF_MISS 4 #define CLF_DIFF 8 #define CLF_SUF 16 + +/* Flags for makecomplist*(). Things not to do. */ + +#define CFN_FIRST 1 +#define CFN_DEFAULT 2 diff --git a/Src/Zle/comp1.c b/Src/Zle/comp1.c index 42bc92bb2..36588a385 100644 --- a/Src/Zle/comp1.c +++ b/Src/Zle/comp1.c @@ -43,12 +43,6 @@ Cmlist cmatcher; /* pointers to functions required by zle and defined by compctl */ -/**/ -void (*printcompctlptr) _((char *, Compctl, int, int)); - -/**/ -Compctl (*compctl_widgetptr) _((char *, char **)); - /**/ void (*makecompparamsptr) _((void)); @@ -66,6 +60,8 @@ int (*getcpatptr) _((char *, int, char *, int)); /**/ void (*makecomplistcallptr) _((Compctl)); +/**/ +void (*makecomplistctlptr) _((int)); /* Hash table for completion info for commands */ diff --git a/Src/Zle/comp1.export b/Src/Zle/comp1.export index c90161740..72581173b 100644 --- a/Src/Zle/comp1.export +++ b/Src/Zle/comp1.export @@ -11,7 +11,6 @@ clwsize cmatcher compcommand compcontext -compctl_widgetptr compctltab compcurrent compiprefix @@ -28,8 +27,8 @@ incompctlfunc incompfunc instring makecomplistcallptr +makecomplistctlptr makecompparamsptr patcomps -printcompctlptr quotename rembslash diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 1913d3828..879042cf3 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -1638,38 +1638,6 @@ bin_compctl(char *name, char **argv, char *ops, int func) return ret; } -/* Externally callable version of get_compctl. Used for completion widgets */ - -/**/ -static Compctl -compctl_widget(char *name, char **argv) -{ - Compctl cc = (Compctl) zcalloc(sizeof(*cc)); - cclist = 0; - showmask = 0; - - if (get_compctl(name, &argv, cc, 1, 0, 0)) { - freecompctl(cc); - return NULL; - } - - if (cclist & COMP_REMOVE) { - zwarnnam(name, "use -D to delete widget", NULL, 0); - return NULL; - } else if (cclist) { - zwarnnam(name, "special options illegal in widget", NULL, 0); - freecompctl(cc); - return NULL; - } else if (*argv) { - zwarnnam(name, "command names illegal in widget", NULL, 0); - freecompctl(cc); - return NULL; - } - cc->refc++; - - return cc; -} - /**/ static int bin_complist(char *name, char **argv, char *ops, int func) @@ -1677,7 +1645,7 @@ bin_complist(char *name, char **argv, char *ops, int func) Compctl cc; int ret = 0; - if (!incompfunc) { + if (incompfunc != 1) { zerrnam(name, "can only be called from completion function", NULL, 0); return 1; } @@ -1706,7 +1674,7 @@ bin_compadd(char *name, char **argv, char *ops, int func) char *pre = NULL, *suf = NULL, *group = NULL; int f = 0, q = 0, m = 0, ns = 0, a = 0; - if (!incompfunc) { + if (incompfunc != 1) { zerrnam(name, "can only be called from completion function", NULL, 0); return 1; } @@ -1792,15 +1760,27 @@ bin_compadd(char *name, char **argv, char *ops, int func) } } ca_args: - if (!*argv) { - zerrnam(name, "missing completions", NULL, 0); + if (!*argv) return 1; - } + addmatchesptr(ipre, ppre, psuf, prpre, pre, suf, group, f, q, m, ns, a, argv); return 0; } +/**/ +static int +bin_compcall(char *name, char **argv, char *ops, int func) +{ + if (incompfunc != 1) { + zerrnam(name, "can only be called from completion function", NULL, 0); + return 1; + } + makecomplistctlptr((ops['T'] ? 0 : CFN_FIRST) | + (ops['D'] ? 0 : CFN_DEFAULT)); + return 0; +} + #define VAR(X) ((void *) (&(X))) static struct compparam { char *name; @@ -1823,7 +1803,7 @@ void makecompparams(void) struct compparam *cp; for (cp = compparams; cp->name; cp++) { - Param pm = createparam(cp->name, cp->type | PM_SPECIAL); + Param pm = createparam(cp->name, cp->type | PM_SPECIAL|PM_REMOVABLE); if (!pm) pm = (Param) paramtab->getnode(paramtab, cp->name); DPUTS(!pm, "param not set in makecompparams"); @@ -1856,7 +1836,7 @@ compunsetfn(Param pm, int exp) static int comp_wrapper(List list, FuncWrap w, char *name) { - if (!incompfunc) + if (incompfunc != 1) return 1; else { char *octxt, *ocmd, *opre, *osuf, *oipre; @@ -1907,7 +1887,7 @@ ignore_prefix(int l) static int comp_check(void) { - if (!incompfunc) { + if (incompfunc != 1) { zerr("condition can only be used in completion function", NULL, 0); return 0; } @@ -2119,7 +2099,8 @@ cond_nmatches(char **a, int id) static struct builtin bintab[] = { BUILTIN("compctl", 0, bin_compctl, 0, -1, 0, NULL, NULL), BUILTIN("complist", 0, bin_complist, 1, -1, 0, NULL, NULL), - BUILTIN("compadd", 0, bin_compadd, 1, -1, 0, NULL, NULL), + BUILTIN("compadd", 0, bin_compadd, 0, -1, 0, NULL, NULL), + BUILTIN("compcall", 0, bin_compcall, 0, 0, 0, "TD", NULL), }; static struct conddef cotab[] = { @@ -2149,8 +2130,6 @@ int setup_compctl(Module m) { compctltab->printnode = printcompctlp; - printcompctlptr = printcompctl; - compctl_widgetptr = compctl_widget; makecompparamsptr = makecompparams; return 0; } @@ -2183,8 +2162,6 @@ int finish_compctl(Module m) { compctltab->printnode = NULL; - printcompctlptr = NULL; - compctl_widgetptr = NULL; makecompparamsptr = NULL; return 0; } diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index 12425d872..61ad0e24a 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -26,7 +26,7 @@ "capitalize-word", capitalizeword, 0 "clear-screen", clearscreen, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND "complete-word", completeword, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP -"copy-prev-word", copyprevword, 0 +"copy-prev-word", copyprevword, ZLE_KEEPSUFFIX "copy-region-as-kill", copyregionaskill, ZLE_KEEPSUFFIX "delete-char", deletechar, ZLE_KEEPSUFFIX "delete-char-or-list", deletecharorlist, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index f12505bd3..144bb1996 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -46,7 +46,6 @@ struct widget { union { ZleIntFunc fn; /* pointer to internally implemented widget */ char *fnnam; /* name of the shell function for user-defined widget */ - Compctl cc; /* for use with a WIDGET_COMP widget */ struct { ZleIntFunc fn; /* internal widget function to call */ char *wid; /* name of widget to call */ @@ -56,20 +55,15 @@ struct widget { }; #define WIDGET_INT (1<<0) /* widget is internally implemented */ -#define WIDGET_COMP (1<<1) /* Special completion widget */ -#define WIDGET_NCOMP (1<<2) /* new style completion widget */ -#define ZLE_MENUCMP (1<<3) /* DON'T invalidate completion list */ -#define ZLE_YANK (1<<4) -#define ZLE_LINEMOVE (1<<5) /* command is a line-oriented movement */ -#define ZLE_LASTCOL (1<<6) /* command maintains lastcol correctly */ -#define ZLE_KILL (1<<7) -#define ZLE_KEEPSUFFIX (1<<9) /* DON'T remove added suffix */ -#define ZLE_USEMENU (1<<10) /* Do ) use menu completion for */ -#define ZLE_NOMENU (1<<11) /* Don't ) widget, else use default */ -#define ZLE_USEGLOB (1<<12) /* Do ) use glob completion for */ -#define ZLE_NOGLOB (1<<13) /* Don't ) widget, else use default */ -#define ZLE_NOTCOMMAND (1<<14) /* widget should not alter lastcmd */ -#define ZLE_ISCOMP (1<<15) /* usable for new style completion */ +#define WIDGET_NCOMP (1<<1) /* new style completion widget */ +#define ZLE_MENUCMP (1<<2) /* DON'T invalidate completion list */ +#define ZLE_YANK (1<<3) +#define ZLE_LINEMOVE (1<<4) /* command is a line-oriented movement */ +#define ZLE_LASTCOL (1<<5) /* command maintains lastcol correctly */ +#define ZLE_KILL (1<<6) +#define ZLE_KEEPSUFFIX (1<<7) /* DON'T remove added suffix */ +#define ZLE_NOTCOMMAND (1<<8) /* widget should not alter lastcmd */ +#define ZLE_ISCOMP (1<<9) /* usable for new style completion */ /* thingies */ struct thingy { diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 2c0d3655e..03549b5d0 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -45,10 +45,10 @@ int mark; /**/ int c; -/* the binding for this key */ +/* the bindings for the previous and for this key */ /**/ -Thingy bindk; +Thingy lbindk, bindk; /* insert mode/overwrite mode flag */ @@ -554,6 +554,7 @@ zleread(char *lp, char *rp, int ha) void execzlefunc(Thingy func) { + int r = 0; Widget w; if(func->flags & DISABLED) { @@ -565,14 +566,13 @@ execzlefunc(Thingy func) showmsg(msg); zsfree(msg); feep(); - } else if((w = func->widget)->flags & - (WIDGET_INT|WIDGET_COMP | WIDGET_NCOMP)) { + } else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_NCOMP)) { int wflags = w->flags; if(!(wflags & ZLE_KEEPSUFFIX)) removesuffix(); if(!(wflags & ZLE_MENUCMP) || - ((wflags & (WIDGET_COMP|WIDGET_NCOMP)) && compwidget != w)) { + ((wflags & WIDGET_NCOMP) && compwidget != w)) { /* If we are doing a special completion, and the widget * is not the one currently in use for special completion, * we are starting a new completion. @@ -584,16 +584,14 @@ execzlefunc(Thingy func) vilinerange = 1; if(!(wflags & ZLE_LASTCOL)) lastcol = -1; - if (wflags & WIDGET_COMP) { - compwidget = w; - completespecial(); - } else if (wflags & WIDGET_NCOMP) { + if (wflags & WIDGET_NCOMP) { compwidget = w; completecall(); } else w->u.fn(); if (!(wflags & ZLE_NOTCOMMAND)) lastcmd = wflags; + r = 1; } else { List l = getshfunc(w->u.fnnam); @@ -610,14 +608,20 @@ execzlefunc(Thingy func) int osc = sfcontext; startparamscope(); - makezleparams(); + makezleparams(0); sfcontext = SFC_WIDGET; doshfunc(w->u.fnnam, l, NULL, 0, 1); sfcontext = osc; endparamscope(); lastcmd = 0; + r = 1; } } + if (r) { + unrefthingy(lbindk); + refthingy(func); + lbindk = func; + } } /* initialise command modifiers */ @@ -877,9 +881,11 @@ setup_zle(Module m) comp_strptr = comp_str; getcpatptr = getcpat; makecomplistcallptr = makecomplistcall; + makecomplistctlptr = makecomplistctl; /* initialise the thingies */ init_thingies(); + lbindk = NULL; /* miscellaneous initialisations */ stackhist = stackcs = -1; @@ -920,6 +926,8 @@ finish_zle(Module m) { int i; + unrefthingy(lbindk); + cleanup_keymaps(); deletehashtable(thingytab); @@ -944,6 +952,7 @@ finish_zle(Module m) comp_strptr = NULL; getcpatptr = NULL; makecomplistcallptr = NULL; + makecomplistctlptr = NULL; return 0; } diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index e0c4e94ec..74f905ef4 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -61,17 +61,22 @@ static struct zleparam { zleunsetfn, NULL }, { "RBUFFER", PM_SCALAR, FN(set_rbuffer), FN(get_rbuffer), zleunsetfn, NULL }, + { "WIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_widget), + zleunsetfn, NULL }, + { "LASTWIDGET", PM_SCALAR | PM_READONLY, NULL, FN(get_lwidget), + zleunsetfn, NULL }, { NULL, 0, NULL, NULL, NULL, NULL } }; /**/ void -makezleparams(void) +makezleparams(int ro) { struct zleparam *zp; for(zp = zleparams; zp->name; zp++) { - Param pm = createparam(zp->name, zp->type | PM_SPECIAL); + Param pm = createparam(zp->name, (zp->type |PM_SPECIAL|PM_REMOVABLE| + (ro ? PM_READONLY : 0))); if (!pm) pm = (Param) paramtab->getnode(paramtab, zp->name); DPUTS(!pm, "param not set in makezleparams"); @@ -197,3 +202,17 @@ get_rbuffer(Param pm) { return metafy((char *)line + cs, ll - cs, META_HEAPDUP); } + +/**/ +static char * +get_widget(Param pm) +{ + return bindk->nam; +} + +/**/ +static char * +get_lwidget(Param pm) +{ + return (lbindk ? lbindk->nam : ""); +} diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index 2e21b5add..629d5a84e 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -244,9 +244,7 @@ unbindwidget(Thingy t, int override) static void freewidget(Widget w) { - if ((w->flags & WIDGET_COMP) && w->u.cc) - freecompctl(w->u.cc); - else if (w->flags & WIDGET_NCOMP) { + if (w->flags & WIDGET_NCOMP) { zsfree(w->u.comp.wid); zsfree(w->u.comp.func); } else if(!(w->flags & WIDGET_INT)) @@ -339,7 +337,7 @@ bin_zle(char *name, char **args, char *ops, int func) { 'D', bin_zle_del, 1, -1 }, { 'A', bin_zle_link, 2, 2 }, { 'N', bin_zle_new, 1, 2 }, - { 'C', bin_zle_compctl, 1, -1}, + { 'C', bin_zle_complete, 3, 3 }, { 'c', bin_zle_complete, 3, 3 }, { 0, bin_zle_call, 0, -1 }, }; @@ -392,14 +390,11 @@ scanlistwidgets(HashNode hn, int list) if(w->flags & WIDGET_INT) return; if(list) { - fputs((w->flags & WIDGET_COMP) ? "zle -C " : "zle -N ", stdout); + fputs("zle -N ", stdout); if(t->nam[0] == '-') fputs("-- ", stdout); quotedzputs(t->nam, stdout); - if (w->flags & WIDGET_COMP) { - if (printcompctlptr && w->u.cc) - printcompctlptr(NULL, w->u.cc, PRINT_LIST, 0); - } else if (w->flags & WIDGET_NCOMP) { + if (w->flags & WIDGET_NCOMP) { fputc(' ', stdout); quotedzputs(w->u.comp.wid, stdout); fputc(' ', stdout); @@ -410,11 +405,7 @@ scanlistwidgets(HashNode hn, int list) } } else { nicezputs(t->nam, stdout); - if (w->flags & WIDGET_COMP) { - fputs(" -C", stdout); - if (printcompctlptr && w->u.cc) - printcompctlptr(NULL, w->u.cc, PRINT_TYPE, 0); - } else if (w->flags & WIDGET_NCOMP) { + if (w->flags & WIDGET_NCOMP) { fputs(" -c ", stdout); nicezputs(w->u.comp.wid, stdout); fputc(' ', stdout); @@ -480,44 +471,6 @@ bin_zle_new(char *name, char **args, char *ops, char func) return 1; } -/**/ -static int -bin_zle_compctl(char *name, char **args, char *ops, char func) -{ - Compctl cc = NULL; - Widget w; - char *wname = args[0]; - - if (!compctl_widgetptr) { - zwarnnam(name, "compctl module is not loaded", NULL, 0); - return 1; - } - - args++; - - if (*args && !(cc = compctl_widgetptr(name, args))) - return 1; - - w = zalloc(sizeof(*w)); - w->flags = WIDGET_COMP|ZLE_MENUCMP|ZLE_KEEPSUFFIX; - w->first = NULL; - w->u.cc = cc; - if(bindwidget(w, rthingy(wname))) { - freewidget(w); - zerrnam(name, "widget name `%s' is protected", wname, 0); - return 1; - } - if (ops['m']) - w->flags |= ZLE_USEMENU; - else if (ops['M']) - w->flags |= ZLE_NOMENU; - if (ops['g']) - w->flags |= ZLE_USEGLOB; - else if (ops['G']) - w->flags |= ZLE_NOGLOB; - return 0; -} - /**/ static int bin_zle_complete(char *name, char **args, char *ops, char func) diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index a958752ca..df3e11f46 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -98,10 +98,12 @@ static int menupos, menulen, menuend, menuwe, menuinsc; /* This is for completion inside a brace expansion. brbeg and brend hold * * strings that were temporarily removed from the string to complete. * - * brpl and brsl hold the offset of these strings. */ + * brpl and brsl hold the offset of these strings. * + * brpcs and brscs hold the positions of the re-inserted string in the * + * line. */ static char *brbeg = NULL, *brend = NULL; -static int brpl, brsl; +static int brpl, brsl, brpcs, brscs; /* The list of matches. fmatches contains the matches we first ignore * * because of fignore. */ @@ -261,7 +263,6 @@ usetab(void) } enum { COMP_COMPLETE, - COMP_WIDGET, COMP_LIST_COMPLETE, COMP_SPELL, COMP_EXPAND, @@ -269,18 +270,6 @@ enum { COMP_COMPLETE, COMP_LIST_EXPAND }; #define COMP_ISEXPAND(X) ((X) >= COMP_EXPAND) -/**/ -void -completespecial(void) -{ - int flags = compwidget->flags; - usemenu = (flags & ZLE_USEMENU) ? 1 : (flags & ZLE_NOMENU) ? 0 - : isset(MENUCOMPLETE); - useglob = (flags & ZLE_USEGLOB) ? 1 : (flags & ZLE_NOGLOB) ? 0 - : isset(GLOBCOMPLETE); - docomplete(compwidget->u.cc ? COMP_WIDGET : COMP_COMPLETE); -} - /**/ void completecall(void) @@ -426,19 +415,30 @@ reversemenucomplete(void) void acceptandmenucomplete(void) { - int sl = suffixlen[' ']; - if (!menucmp) { feep(); return; } - cs = menupos + menulen + menuinsc; - if (sl) - backdel(sl); - inststrlen(" ", 1, 1); - menuinsc = menulen = 0; - menupos = cs; - menuwe = 1; + if (brbeg && *brbeg) { + int l = (brscs >= 0 ? brscs : cs) - brpcs; + + zsfree(brbeg); + brbeg = (char *) zalloc(l + 2); + memcpy(brbeg, line + brpcs, l); + brbeg[l] = ','; + brbeg[l + 1] = '\0'; + } else { + int sl = suffixlen[' ']; + + cs = menupos + menulen + menuinsc; + if (sl) + backdel(sl); + + inststrlen(" ", 1, 1); + menuinsc = menulen = 0; + menupos = cs; + menuwe = 1; + } menucomplete(); } @@ -447,6 +447,10 @@ acceptandmenucomplete(void) static int lincmd, linredir; +/* The string for the redirection operator. */ + +static char *rdstr; + /* Non-zero if the last completion done was ambiguous (used to find * * out if AUTOMENU should start). More precisely, it's nonzero after * * successfully doing any completion, unless the completion was * @@ -998,6 +1002,8 @@ get_comp_string(void) oins = ins; /* Get the next token. */ ctxtlex(); + if (inredir) + rdstr = tokstrings[tok]; if (tok == DINPAR) tokstr = NULL; @@ -1859,7 +1865,8 @@ pattern_match(Cpattern p, char *s, unsigned char *in, unsigned char *out) /* Do the matching for a prefix. */ static char * -match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp) +match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp, + Cmatcher nm) { static unsigned char *ea; static int ealen = 0; @@ -1867,61 +1874,27 @@ match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp) static int rwlen; int ll = strlen(l), lw = strlen(w), mlw; - int il = 0, iw = 0, t, stil, stiw, std, bc = brpl; - char *nw = rw, *stl = NULL, *stw; + int il = 0, iw = 0, t, bc = brpl; + char *nw = rw; Cmlist ms; - Cmatcher mp, stm; + Cmatcher mp, lm = NULL; Cline lr = NULL; - *nlp = NULL; + if (nlp) { + *nlp = NULL; - if (ll > ealen) { - /* This is the `in'/`out' string for pattern matching. */ - if (ealen) - zfree(ea, ealen); - ea = (unsigned char *) zalloc(ealen = ll + 20); + if (ll > ealen) { + /* This is the `in'/`out' string for pattern matching. */ + if (ealen) + zfree(ea, ealen); + ea = (unsigned char *) zalloc(ealen = ll + 20); + } } while (ll && lw) { - if (*l == *w) { - /* Same character, take it. */ - - if (stl) { - /* But first check, if we were collecting characters * - * for a `*'. */ - int sl = iw - stiw; - - nw = addtoword(&rw, &rwlen, nw, stm, stl, stw, sl, 0); - - addtocline(nlp, &lr, stl, stm->llen, - stw, sl, stm, (std ? CLF_SUF : 0)); - - stl = NULL; - - if (bc <= 0 && bplp) { - *bplp = nw - rw; - bplp = NULL; - } - } - nw = addtoword(&rw, &rwlen, nw, NULL, NULL, l, 1, 0); - - addtocline(nlp, &lr, l, 1, NULL, 0, NULL, 0); - - l++; - w++; - il++; - iw++; - ll--; - lw--; - bc--; - - if (bc <= 0 && bplp) { - *bplp = nw - rw; - bplp = NULL; - } - continue; - } for (ms = mstack; ms; ms = ms->next) { for (mp = ms->matcher; mp; mp = mp->next) { + if (nm == mp || lm == mp) + continue; t = 1; /* Try to match the prefix, if any. */ if (mp->flags & CMF_LEFT) { @@ -1947,22 +1920,42 @@ match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp) else t = 0; } - if (t && !stl) { - /* We simply keep the current position * - * and start collecting characters until * - * another matcher matches. */ - std = (mp->flags & CMF_LEFT); - stl = l; - stil = il; - stw = w; - stiw = iw; - stm = mp; - t = 0; - l += mp->llen; - il += mp->llen; - ll -= mp->llen; - - break; + if (t) { + int i = 0, j = iw, k = lw; + int jj = il + mp->llen, kk = ll - mp->llen; + char *p = l + mp->llen, *q = w; + + for (; k; i++, j++, k--, q++) { + if (match_pfx(p, q, NULL, NULL, + NULL, NULL, mp)) + break; + } + if (k) { + if (nlp) { + nw = addtoword(&rw, &rwlen, nw, mp, + l, w, i, 0); + addtocline(nlp, &lr, l, mp->llen, + w, i, mp, + ((mp->flags & CMF_LEFT) ? + CLF_SUF : 0)); + } + w = q; + iw = j; + lw = k; + l = p; + il = jj; + ll = kk; + bc -= i; + + if (bc <= 0 && bplp) { + *bplp = nw - rw; + bplp = NULL; + } + lm = mp; + break; + } + else + t = 0; } else t = 0; @@ -1988,26 +1981,10 @@ match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp) if (t) { /* If it matched, build a new chunk on the Cline list * * and add the string to the built match. */ - if (stl) { - int sl = iw - stiw; - - nw = addtoword(&rw, &rwlen, nw, stm, stl, stw, sl, 0); - - addtocline(nlp, &lr, - stl, stm->llen, stw, sl, stm, - (std ? CLF_SUF : 0)); - - stl = NULL; - - if (bc <= 0 && bplp) { - *bplp = nw - rw; - bplp = NULL; - } + if (nlp) { + nw = addtoword(&rw, &rwlen, nw, mp, l, w, mlw, 0); + addtocline(nlp, &lr, l, mp->llen, w, mlw, mp, 0); } - nw = addtoword(&rw, &rwlen, nw, mp, l, w, mlw, 0); - - addtocline(nlp, &lr, l, mp->llen, w, mlw, mp, 0); - l += mp->llen; w += mlw; ll -= mp->llen; @@ -2023,62 +2000,84 @@ match_pfx(char *l, char *w, Cline *nlp, int *lp, Cline *rlp, int *bplp) break; } } - if (mp) + if (mp) { + if (mp != lm) + lm = NULL; break; + } } - if (!stl && !t) { - if (*nlp) { + if (t) + continue; + if (*l == *w) { + /* Same character, take it. */ + if (nlp) { + nw = addtoword(&rw, &rwlen, nw, NULL, NULL, l, 1, 0); + addtocline(nlp, &lr, l, 1, NULL, 0, NULL, 0); + } + l++; + w++; + il++; + iw++; + ll--; + lw--; + bc--; + + if (bc <= 0 && bplp) { + *bplp = nw - rw; + bplp = NULL; + } + lm = NULL; + } else { + if (nlp && *nlp) { lr->next = freecl; freecl = *nlp; } return NULL; } - if (stl) { - /* We are collecting characters, just skip over. */ - w++; - lw--; - iw++; - } } - *lp = iw; + if (lp) + *lp = iw; if (lw) { - /* There is a unmatched portion in the word, keep it. */ - if (rlp) { - w = dupstring(w); - addtocline(nlp, &lr, w, lw, w, -1, NULL, CLF_MID); - - *rlp = lr; - } else { - addtocline(nlp, &lr, l, 0, dupstring(w), lw, NULL, CLF_END); + if (nlp) { + /* There is a unmatched portion in the word, keep it. */ + if (rlp) { + w = dupstring(w); + addtocline(nlp, &lr, w, lw, w, -1, NULL, CLF_MID); - nw = addtoword(&rw, &rwlen, nw, NULL, NULL, w, lw, 0); + *rlp = lr; + } else { + addtocline(nlp, &lr, l, 0, dupstring(w), lw, NULL, CLF_END); + nw = addtoword(&rw, &rwlen, nw, NULL, NULL, w, lw, 0); + } } - } - else if (rlp) { - if (lr) { + } else if (rlp) { + if (nlp && lr) { lr->next = freecl; freecl = *nlp; } return NULL; } - if (nw) + if (nlp && nw) *nw = '\0'; if (ll) { - if (*nlp) { + if (nlp && *nlp) { lr->next = freecl; freecl = *nlp; } - return 0; + return NULL; } - /* Finally, return the built match string. */ - return dupstring(rw); + if (nlp) + /* Finally, return the built match string. */ + return dupstring(rw); + + return ((char *) 1); } /* Do the matching for a suffix. */ static char * -match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp) +match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp, Cmatcher nm) { static unsigned char *ea; static int ealen = 0; @@ -2086,60 +2085,29 @@ match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp) static int rwlen; int ll = strlen(l), lw = strlen(w), mlw; - int il = 0, iw = 0, t, stil, stiw, std, bc = brsl; - char *nw = rw, *stl = NULL, *stw; + int il = 0, iw = 0, t, bc = brsl; + char *nw = rw; Cmlist ms; - Cmatcher mp, stm; + Cmatcher mp, lm = NULL; Cline lr = NULL; l += ll; w += lw; - *nlp = NULL; + if (nlp) { + *nlp = NULL; - if (ll > ealen) { - if (ealen) - zfree(ea, ealen); - ea = (unsigned char *) zalloc(ealen = ll + 20); + if (ll > ealen) { + if (ealen) + zfree(ea, ealen); + ea = (unsigned char *) zalloc(ealen = ll + 20); + } } while (ll && lw) { - if (l[-1] == w[-1]) { - if (stl) { - int sl = iw - stiw; - - stl -= stm->llen; - stw -= sl; - nw = addtoword(&rw, &rwlen, nw, stm, stl, stw, sl, 1); - - addtocline(nlp, &lr, stl, stm->llen, - stw, sl, stm, (std ? CLF_SUF : 0)); - - stl = NULL; - - if (bc <= 0 && bslp) { - *bslp = nw - rw; - bslp = NULL; - } - } - nw = addtoword(&rw, &rwlen, nw, NULL, NULL, l - 1, 1, 1); - - addtocline(nlp, &lr, l - 1, 1, NULL, 0, NULL, 0); - - l--; - w--; - il++; - iw++; - ll--; - lw--; - bc--; - if (bc <= 0 && bslp) { - *bslp = nw - rw; - bslp = NULL; - } - continue; - } for (ms = mstack; ms; ms = ms->next) { for (mp = ms->matcher; mp; mp = mp->next) { + if (nm == mp || lm == mp) + continue; t = 1; if (mp->flags & CMF_RIGHT) { if (il < mp->ralen || iw < mp->ralen) @@ -2164,22 +2132,43 @@ match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp) else t = 0; } - if (t && !stl) { - std = (mp->flags & CMF_LEFT); - stl = l; - stil = il; - stw = w; - stiw = iw; - stm = mp; - t = 0; - l -= mp->llen; - il += mp->llen; - ll -= mp->llen; - - break; + if (t) { + int i = 0, j = iw, k = lw; + int jj = il + mp->llen, kk = ll - mp->llen; + char *p = l - mp->llen, *q = w; + + for (; k; i++, j++, k--, q--) + if (match_sfx(p, q, NULL, NULL, + NULL, mp)) + break; + if (k) { + if (nlp) { + nw = addtoword(&rw, &rwlen, nw, mp, + l - mp->llen, w - i, + i, 1); + addtocline(nlp, &lr, l - mp->llen, + mp->llen, w - i, i, mp, + ((mp->flags & CMF_LEFT) ? + CLF_SUF : 0)); + } + w = q; + iw = j; + lw = k; + l = p; + il = jj; + ll = kk; + bc -= i; + + if (bc <= 0 && bslp) { + *bslp = nw - rw; + bslp = NULL; + } + lm = mp; + break; + } + else + t = 0; } - else - t = 0; } } else { t = pattern_match(mp->line, l - mp->llen, NULL, ea) && @@ -2199,30 +2188,11 @@ match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp) t = 0; } if (t) { - if (stl) { - int sl = iw - stiw; - - stl -= stm->llen; - stw -= sl; - - nw = addtoword(&rw, &rwlen, nw, stm, stl, stw, sl, 1); - - addtocline(nlp, &lr, - stl, stm->llen, stw, sl, stm, - (std ? CLF_SUF : 0)); - - stl = NULL; - - if (bc <= 0 && bslp) { - *bslp = nw - rw; - bslp = NULL; - } + if (nlp) { + nw = addtoword(&rw, &rwlen, nw, mp, l, w, mlw, 1); + addtocline(nlp, &lr, l - mp->llen, mp->llen, + w - mlw, mlw, mp, 0); } - nw = addtoword(&rw, &rwlen, nw, mp, l, w, mlw, 1); - - addtocline(nlp, &lr, l - mp->llen, mp->llen, - w - mlw, mlw, mp, 0); - l -= mp->llen; w -= mlw; ll -= mp->llen; @@ -2237,34 +2207,55 @@ match_sfx(char *l, char *w, Cline *nlp, int *lp, int *bslp) break; } } - if (mp) + if (mp) { + if (mp != lm) + lm = NULL; break; + } } - if (!stl && !t) { - if (*nlp) { + if (t) + continue; + if (l[-1] == w[-1]) { + if (nlp) { + nw = addtoword(&rw, &rwlen, nw, NULL, NULL, l - 1, 1, 1); + addtocline(nlp, &lr, l - 1, 1, NULL, 0, NULL, 0); + } + l--; + w--; + il++; + iw++; + ll--; + lw--; + bc--; + if (bc <= 0 && bslp) { + *bslp = nw - rw; + bslp = NULL; + } + lm = NULL; + } else { + if (nlp && *nlp) { lr->next = freecl; freecl = *nlp; } return NULL; } - if (stl) { - w--; - lw--; - iw++; - } } - *lp = iw; - if (nw) + if (lp) + *lp = iw; + if (nlp && nw) *nw = '\0'; if (ll) { - if (*nlp) { + if (nlp && *nlp) { lr->next = freecl; freecl = *nlp; } - return 0; + return NULL; } - return dupstring(rw); + if (nlp) + return dupstring(rw); + + return ((char *) 1); } /* Check if the word `w' matches. */ @@ -2283,8 +2274,8 @@ comp_match(char *pfx, char *sfx, char *w, Cline *clp, int qu, int *bpl, int *bsl int sl; Cline sli, last; - if ((p = match_pfx(pfx, w, &pli, &pl, &last, bpl))) { - if ((s = match_sfx(sfx, w + pl, &sli, &sl, bsl))) { + if ((p = match_pfx(pfx, w, &pli, &pl, &last, bpl, NULL))) { + if ((s = match_sfx(sfx, w + pl, &sli, &sl, bsl, NULL))) { int pml, sml; last->llen -= sl; @@ -2305,7 +2296,7 @@ comp_match(char *pfx, char *sfx, char *w, Cline *clp, int qu, int *bpl, int *bsl } else return NULL; - } else if (!(r = match_pfx(pfx, w, &pli, &pl, NULL, bpl))) + } else if (!(r = match_pfx(pfx, w, &pli, &pl, NULL, bpl, NULL))) return NULL; if (lppre && *lppre) { @@ -2373,6 +2364,7 @@ instmatch(Cmatch m) if (brbeg && *brbeg) { cs = a + m->brpl + (m->pre ? strlen(m->pre) : 0); l = strlen(brbeg); + brpcs = cs; inststrlen(brbeg, 1, l); r += l; ocs += l; @@ -2385,12 +2377,13 @@ instmatch(Cmatch m) if (brend && *brend) { a = cs; cs -= m->brsl; - ocs = cs; + ocs = brscs = cs; l = strlen(brend); inststrlen(brend, 1, l); r += l; cs = a + l; - } + } else + brscs = -1; if (m->suf) { inststrlen(m->suf, 1, (l = strlen(m->suf))); r += l; @@ -2509,6 +2502,7 @@ addmatches(char *ipre, char *ppre, char *psuf, char *prpre, char *pre, if (!ai->firstm) ai->firstm = cm; } + compnmatches = mnum; } LASTALLOC; } SWITCHBACKHEAPS; } @@ -3180,6 +3174,108 @@ docompletion(char *s, int lst, int incmd) } LASTALLOC; } +/* This calls the given function for new style completion. */ + +/**/ +static void +callcompfunc(char *s, char *fn) +{ + List list; + int lv = lastval; + + if ((list = getshfunc(fn)) != &dummy_list) { + LinkList args = newlinklist(); + char **p, *tmp; + int aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext; + + addlinknode(args, fn); + + zsfree(compcontext); + zsfree(compcommand); + compcommand = ""; + if (inwhat == IN_MATH) { + if (insubscr) { + compcontext = "subscript"; + compcommand = varname ? varname : ""; + } else + compcontext = "math"; + usea = 0; + } else if (lincmd) + compcontext = (insubscr ? "subscript" : "command"); + else if (linredir) { + compcontext = "redirect"; + if (rdstr) + compcommand = rdstr; + } else + switch (inwhat) { + case IN_ENV: + compcontext = "value"; + compcommand = varname; + usea = 0; + break; + case IN_COND: + compcontext = "condition"; + break; + default: + if (cmdstr) { + compcontext = "argument"; + compcommand = cmdstr; + } else { + compcontext = "value"; + if (clwords[0]) + compcommand = clwords[0]; + } + aadd = 1; + } + compcontext = ztrdup(compcontext); + tmp = quotename(compcommand, NULL, NULL, NULL); + untokenize(tmp); + compcommand = ztrdup(tmp); + if (usea && (!aadd || clwords[0])) + for (p = clwords + aadd; *p; p++) { + tmp = dupstring(*p); + untokenize(tmp); + addlinknode(args, tmp); + } + zsfree(compprefix); + zsfree(compsuffix); + if (unset(COMPLETEINWORD)) { + tmp = quotename(s, NULL, NULL, NULL); + untokenize(tmp); + compprefix = ztrdup(tmp); + compsuffix = ztrdup(""); + } else { + char *ss = s + offs, sav; + + tmp = quotename(s, &ss, NULL, NULL); + sav = *ss; + *ss = '\0'; + untokenize(tmp); + compprefix = ztrdup(tmp); + *ss = sav; + untokenize(ss); + compsuffix = ztrdup(ss); + } + zsfree(compiprefix); + compiprefix = ztrdup(""); + compcurrent = (usea ? (clwpos + 1 - aadd) : 1); + compnmatches = mnum; + incompfunc = 1; + startparamscope(); + makecompparamsptr(); + makezleparams(1); + sfcontext = SFC_CWIDGET; + NEWHEAPS(compheap) { + doshfunc(fn, list, args, 0, 1); + } OLDHEAPS; + sfcontext = osc; + endparamscope(); + lastcmd = 0; + incompfunc = icf; + } + lastval = lv; +} + /* The beginning and end of a word range to be used by -l. */ static int brange, erange; @@ -3232,98 +3328,10 @@ makecomplist(char *s, int incmd, int lst) ccused = newlinklist(); ccstack = newlinklist(); - if (compfunc) { - List list; - int lv = lastval; - - if ((list = getshfunc(compfunc)) != &dummy_list) { - LinkList args = newlinklist(); - char **p, *tmp; - int aadd = 0, usea = 1; - - addlinknode(args, compfunc); - - zsfree(compcontext); - zsfree(compcommand); - compcommand = ""; - if (inwhat == IN_MATH) { - if (insubscr) { - compcontext = "subscript"; - compcommand = varname ? varname : ""; - } else - compcontext = "math"; - usea = 0; - } else if (lincmd) - compcontext = (insubscr ? "subscript" : "command"); - else if (linredir) - compcontext = "redirect"; - else - switch (inwhat) { - case IN_ENV: - compcontext = "value"; - compcommand = varname; - usea = 0; - break; - case IN_COND: - compcontext = "condition"; - break; - default: - if (cmdstr) { - compcontext = "argument"; - compcommand = cmdstr; - } else { - compcontext = "value"; - if (clwords[0]) - compcommand = clwords[0]; - } - aadd = 1; - } - compcontext = ztrdup(compcontext); - tmp = quotename(compcommand, NULL, NULL, NULL); - untokenize(tmp); - compcommand = ztrdup(tmp); - if (usea && (!aadd || clwords[0])) - for (p = clwords + aadd; *p; p++) { - tmp = dupstring(*p); - untokenize(tmp); - addlinknode(args, tmp); - } - zsfree(compprefix); - zsfree(compsuffix); - if (unset(COMPLETEINWORD)) { - tmp = quotename(s, NULL, NULL, NULL); - untokenize(tmp); - compprefix = ztrdup(tmp); - compsuffix = ztrdup(""); - } else { - char *ss = s + offs, sav; - - tmp = quotename(s, &ss, NULL, NULL); - sav = *ss; - *ss = '\0'; - untokenize(tmp); - compprefix = ztrdup(tmp); - *ss = sav; - untokenize(ss); - compsuffix = ztrdup(ss); - } - zsfree(compiprefix); - compiprefix = ztrdup(""); - compcurrent = (usea ? (clwpos + 1 - aadd) : 1); - compnmatches = mnum; - incompfunc = 1; - startparamscope(); - makecompparamsptr(); - NEWHEAPS(compheap) { - doshfunc(compfunc, list, args, 0, 1); - } OLDHEAPS; - endparamscope(); - lastcmd = 9; - incompfunc = 0; - } - lastval = lv; - } else - makecomplistglobal(s, incmd, lst); + if (compfunc) + callcompfunc(s, compfunc); + else + makecomplistglobal(s, incmd, lst, 0); endcmgroup(NULL); @@ -3368,11 +3376,11 @@ ctokenize(char *p) if (*p == '\\') bslash = 1; else { - if (*p == '$') { + if (*p == '$' || *p == '=') { if (bslash) p[-1] = Bnull; else - *p = String; + *p = (*p == '$' ? String : Equals); } bslash = 0; } @@ -3431,22 +3439,75 @@ makecomplistcall(Compctl cc) } SWITCHBACKHEAPS; } +/* A simple counter to avoid endless recursion between old and new style * + * completion. */ + +static int cdepth = 0; + +#define MAX_CDEPTH 16 + +/**/ +void +makecomplistctl(int flags) +{ + if (cdepth == MAX_CDEPTH) + return; + + cdepth++; + SWITCHHEAPS(compheap) { + HEAPALLOC { + int ooffs = offs, lip, lp; + char *str = comp_str(&lip, &lp), *t; + char *os = cmdstr, **ow = clwords, **p, **q; + int on = clwnum, op = clwpos; + + clwnum = arrlen(pparams) + 1; + clwpos = compcurrent - 1; + cmdstr = ztrdup(compcommand); + clwords = (char **) zalloc((clwnum + 1) * sizeof(char *)); + clwords[0] = ztrdup(cmdstr); + for (p = pparams, q = clwords + 1; *p; p++, q++) { + t = dupstring(*p); + ctokenize(t); + remnulargs(t); + *q = ztrdup(t); + } + *q = NULL; + offs = lip + lp; + incompfunc = 2; + makecomplistglobal(str, + (!clwpos && !strcmp(compcontext, "command")), + COMP_COMPLETE, flags); + incompfunc = 1; + offs = ooffs; + compnmatches = mnum; + zsfree(cmdstr); + freearray(clwords); + cmdstr = os; + clwords = ow; + clwnum = on; + clwpos = op; + } LASTALLOC; + } SWITCHBACKHEAPS; + cdepth--; +} + /* This function gets the compctls for the given command line and * * adds all completions for them. */ /**/ static void -makecomplistglobal(char *os, int incmd, int lst) +makecomplistglobal(char *os, int incmd, int lst, int flags) { Compctl cc; char *s; - if (lst == COMP_WIDGET) { - cc = compwidget->u.cc; - } else if (inwhat == IN_ENV) + ccont = CC_CCCONT; + + if (inwhat == IN_ENV) { /* Default completion for parameter values. */ cc = &cc_default; - else if (inwhat == IN_MATH) { + } else if (inwhat == IN_MATH) { /* Parameter names inside mathematical expression. */ cc_dummy.mask = CC_PARAMS; cc = &cc_dummy; @@ -3469,16 +3530,17 @@ makecomplistglobal(char *os, int incmd, int lst) cc = &cc_default; else { /* Otherwise get the matches for the command. */ - makecomplistcmd(os, incmd); + makecomplistcmd(os, incmd, flags); cc = NULL; } if (cc) { /* First, use the -T compctl. */ - makecomplistcc(&cc_first, os, incmd); - - if (!(ccont & CC_CCCONT)) - return; + if (!(flags & CFN_FIRST)) { + makecomplistcc(&cc_first, os, incmd); + if (!(ccont & CC_CCCONT)) + return; + } makecomplistcc(cc, os, incmd); } } @@ -3487,18 +3549,19 @@ makecomplistglobal(char *os, int incmd, int lst) /**/ static void -makecomplistcmd(char *os, int incmd) +makecomplistcmd(char *os, int incmd, int flags) { Compctl cc; Compctlp ccp; char *s; /* First, use the -T compctl. */ - makecomplistcc(&cc_first, os, incmd); - - if (!(ccont & CC_CCCONT)) - return; + if (!(flags & CFN_FIRST)) { + makecomplistcc(&cc_first, os, incmd); + if (!(ccont & CC_CCCONT)) + return; + } /* Then search the pattern compctls, with the command name and the * * full pathname of the command. */ makecomplistpc(os, incmd); @@ -3526,9 +3589,11 @@ makecomplistcmd(char *os, int incmd) (cc = ccp->cc)) || ((s = dupstring(cmdstr)) && remlpaths(&s) && (ccp = (Compctlp) compctltab->getnode(compctltab, s)) && - (cc = ccp->cc))))) + (cc = ccp->cc))))) { + if (flags & CFN_DEFAULT) + return; cc = &cc_default; - + } makecomplistcc(cc, os, incmd); } @@ -3817,12 +3882,12 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) ccont |= (cc->mask2 & (CC_CCCONT | CC_DEFCONT | CC_PATCONT)); - if (!incompfunc && findnode(ccstack, cc)) + if (incompfunc != 1 && findnode(ccstack, cc)) return; addlinknode(ccstack, cc); - if (!incompfunc && allccs) { + if (incompfunc != 1 && allccs) { if (findnode(allccs, cc)) { uremnode(ccstack, firstnode(ccstack)); return; @@ -4430,45 +4495,50 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) /* Add user names. */ maketildelist(); if (cc->func) { - /* This handles the compctl -K flag. */ - List list; - char **r; - int lv = lastval; - - /* Get the function. */ - if ((list = getshfunc(cc->func)) != &dummy_list) { - /* We have it, so build a argument list. */ - LinkList args = newlinklist(); - int osc = sfcontext; - - addlinknode(args, cc->func); - - if (delit) { - p = dupstrpfx(os, ooffs); - untokenize(p); - addlinknode(args, p); - p = dupstring(os + ooffs); - untokenize(p); - addlinknode(args, p); - } else { - addlinknode(args, lpre); - addlinknode(args, lsuf); + if (cc->func[0] == ' ') + /* Temporary hack for access to new style completione. */ + callcompfunc(os, cc->func + 1); + else { + /* This handles the compctl -K flag. */ + List list; + char **r; + int lv = lastval; + + /* Get the function. */ + if ((list = getshfunc(cc->func)) != &dummy_list) { + /* We have it, so build a argument list. */ + LinkList args = newlinklist(); + int osc = sfcontext; + + addlinknode(args, cc->func); + + if (delit) { + p = dupstrpfx(os, ooffs); + untokenize(p); + addlinknode(args, p); + p = dupstring(os + ooffs); + untokenize(p); + addlinknode(args, p); + } else { + addlinknode(args, lpre); + addlinknode(args, lsuf); + } + + /* This flag allows us to use read -l and -c. */ + if (incompfunc != 1) + incompctlfunc = 1; + sfcontext = SFC_COMPLETE; + /* Call the function. */ + doshfunc(cc->func, list, args, 0, 1); + sfcontext = osc; + incompctlfunc = 0; + /* And get the result from the reply parameter. */ + if ((r = get_user_var("reply"))) + while (*r) + addmatch(*r++, NULL); } - - /* This flag allows us to use read -l and -c. */ - if (!incompfunc) - incompctlfunc = 1; - sfcontext = SFC_COMPLETE; - /* Call the function. */ - doshfunc(cc->func, list, args, 0, 1); - sfcontext = osc; - incompctlfunc = 0; - /* And get the result from the reply parameter. */ - if ((r = get_user_var("reply"))) - while (*r) - addmatch(*r++, NULL); + lastval = lv; } - lastval = lv; } if (cc->mask & (CC_JOBS | CC_RUNNING | CC_STOPPED)) { /* Get job names. */ @@ -4625,7 +4695,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) } /* No harm in allowing read -l and -c here, too */ - if (!incompfunc) + if (incompfunc != 1) incompctlfunc = 1; sfcontext = SFC_COMPLETE; doshfunc(cc->ylist, list, args, 0, 1); @@ -4692,7 +4762,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) clwords += brange; } /* Produce the matches. */ - makecomplistcmd(s, incmd); + makecomplistcmd(s, incmd, CFN_FIRST); /* And restore the things we changed. */ clwords = ow; @@ -5021,9 +5091,10 @@ permmatches(void) &nn, &nl); g->mcount = nn; g->lcount = nn - nl; - if (g->ylist) + if (g->ylist) { g->lcount = arrlen(g->ylist); - + smatches = 2; + } g->expls = (Cexpl *) makearray(g->lexpls, 0, &(g->ecount), NULL); g->ccount = 0; -- cgit 1.4.1