diff options
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/comp.h | 30 | ||||
-rw-r--r-- | Src/Zle/comp1.c | 8 | ||||
-rw-r--r-- | Src/Zle/comp1.export | 1 | ||||
-rw-r--r-- | Src/Zle/compctl.c | 86 | ||||
-rw-r--r-- | Src/Zle/compctl.mdd | 2 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 14 | ||||
-rw-r--r-- | Src/Zle/zle_misc.c | 10 | ||||
-rw-r--r-- | Src/Zle/zle_refresh.c | 17 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 306 |
9 files changed, 310 insertions, 164 deletions
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index c9d6aa859..caeb4d6c3 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -270,6 +270,31 @@ struct cpattern { #define CAF_ALT 4 #define CAF_MATCH 8 +/* Data for compadd and addmatches() */ + +typedef struct cadata *Cadata; + +struct cadata { + char *ipre; /* ignored prefix (-i) */ + char *isuf; /* ignored suffix (-I) */ + char *ppre; /* `path' prefix (-p) */ + char *psuf; /* `path' suffix (-s) */ + char *prpre; /* expanded `path' prefix (-W) */ + char *pre; /* prefix to insert (-P) */ + char *suf; /* suffix to insert (-S) */ + char *group; /* name of the group (-[JV]) */ + char *rems; /* remove suffix on chars... (-r) */ + char *remf; /* function to remove suffix (-R) */ + char *ign; /* ignored suffixes (-F) */ + int flags; /* CMF_* flags (-[fqn]) */ + int aflags; /* CAF_* flags (-[QUa]) */ + Cmatcher match; /* match spec (parsed from -M) */ + char *exp; /* explanation (-X) */ + char *apar; /* array to store matches in (-A) */ + char *opar; /* array to store originals in (-O) */ + char *dpar; /* array to delete non-matches in (-D) */ +}; + /* Flags for special parameters. */ #define CP_WORDS (1 << 0) @@ -306,7 +331,8 @@ struct cpattern { #define CP_TOEND (1 << 28) #define CP_OLDLIST (1 << 29) #define CP_OLDINS (1 << 30) +#define CP_VARED (1 << 31) -#define CP_NUM 31 +#define CP_NUM 32 -#define CP_ALLMASK ((int) ((((unsigned int) 1) << CP_NUM) - 1)) +#define CP_ALLMASK ((unsigned int) 0xffffffff) diff --git a/Src/Zle/comp1.c b/Src/Zle/comp1.c index fe21b1dfc..c51aad297 100644 --- a/Src/Zle/comp1.c +++ b/Src/Zle/comp1.c @@ -52,7 +52,7 @@ void (*comp_setunsetptr) _((int, int)); /* pointers to functions required by compctl and defined by zle */ /**/ -int (*addmatchesptr) _((char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, char *, int, int, Cmatcher, char *, char *, char *, char **)); +int (*addmatchesptr) _((Cadata, char **)); /**/ char *(*comp_strptr) _((int *, int *, int)); @@ -129,7 +129,8 @@ char **compwords, *complastprompt, *comptoend, *compoldlist, - *compoldins; + *compoldins, + *compvared; /**/ Param *comppms; @@ -445,7 +446,7 @@ setup_comp1(Module m) compquoting = comprestore = complist = compinsert = compexact = compexactstr = comppatmatch = comppatinsert = compforcelist = complastprompt = comptoend = - compoldlist = compoldins = NULL; + compoldlist = compoldins = compvared = NULL; makecompparamsptr = NULL; comp_setunsetptr = NULL; return 0; @@ -497,6 +498,7 @@ finish_comp1(Module m) zsfree(comptoend); zsfree(compoldlist); zsfree(compoldins); + zsfree(compvared); return 0; } diff --git a/Src/Zle/comp1.export b/Src/Zle/comp1.export index 4f9fb143d..2dc285d3a 100644 --- a/Src/Zle/comp1.export +++ b/Src/Zle/comp1.export @@ -41,6 +41,7 @@ comp_setunsetptr comp_strptr compsuffix comptoend +compvared compwords freecmatcher freecmlist diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index 28c7cb7b7..a06d558e3 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -1691,17 +1691,22 @@ bin_compgen(char *name, char **argv, char *ops, int func) static int bin_compadd(char *name, char **argv, char *ops, int func) { - char *p, **sp, *e; - char *ipre = NULL, *isuf = NULL, *ppre = NULL, *psuf = NULL, *prpre = NULL; - char *pre = NULL, *suf = NULL, *group = NULL, *m = NULL, *rs = NULL; - char *ign = NULL, *rf = NULL, *expl = NULL, *apar = NULL, *opar = NULL; - int f = 0, a = CAF_MATCH, dm; + struct cadata dat; + char *p, **sp, *e, *m = NULL; + int dm; Cmatcher match = NULL; if (incompfunc != 1) { zerrnam(name, "can only be called from completion function", NULL, 0); return 1; } + dat.ipre = dat.isuf = dat.ppre = dat.psuf = dat.prpre = + dat.pre = dat.suf = dat.group = dat.rems = dat.remf = + dat.ign = dat.exp = dat.apar = dat.opar = dat.dpar = NULL; + dat.match = NULL; + dat.flags = 0; + dat.aflags = CAF_MATCH; + for (; *argv && **argv == '-'; argv++) { if (!(*argv)[1]) { argv++; @@ -1713,64 +1718,64 @@ bin_compadd(char *name, char **argv, char *ops, int func) dm = 0; switch (*p) { case 'q': - f |= CMF_REMOVE; + dat.flags |= CMF_REMOVE; break; case 'Q': - a |= CAF_QUOTE; + dat.aflags |= CAF_QUOTE; break; case 'f': - f |= CMF_FILE; + dat.flags |= CMF_FILE; break; case 'F': - sp = &ign; + sp = &(dat.ign); e = "string expected after -%c"; break; case 'n': - f |= CMF_NOLIST; + dat.flags |= CMF_NOLIST; break; case 'U': - a &= ~CAF_MATCH; + dat.aflags &= ~CAF_MATCH; break; case 'P': - sp = ⪯ + sp = &(dat.pre); e = "string expected after -%c"; break; case 'S': - sp = &suf; + sp = &(dat.suf); e = "string expected after -%c"; break; case 'J': - sp = &group; + sp = &(dat.group); e = "group name expected after -%c"; break; case 'V': - if (!group) - a |= CAF_NOSORT; - sp = &group; + if (!dat.group) + dat.aflags |= CAF_NOSORT; + sp = &(dat.group); e = "group name expected after -%c"; break; case 'i': - sp = &ipre; + sp = &(dat.ipre); e = "string expected after -%c"; break; case 'I': - sp = &isuf; + sp = &(dat.isuf); e = "string expected after -%c"; break; case 'p': - sp = &ppre; + sp = &(dat.ppre); e = "string expected after -%c"; break; case 's': - sp = &psuf; + sp = &(dat.psuf); e = "string expected after -%c"; break; case 'W': - sp = &prpre; + sp = &(dat.prpre); e = "string expected after -%c"; break; case 'a': - a |= CAF_ALT; + dat.aflags |= CAF_ALT; break; case 'M': sp = &m; @@ -1778,25 +1783,29 @@ bin_compadd(char *name, char **argv, char *ops, int func) dm = 1; break; case 'X': - sp = &expl; + sp = &(dat.exp); e = "string expected after -%c"; break; case 'r': - f |= CMF_REMOVE; - sp = &rs; + dat.flags |= CMF_REMOVE; + sp = &(dat.rems); e = "string expected after -%c"; break; case 'R': - f |= CMF_REMOVE; - sp = &rf; + dat.flags |= CMF_REMOVE; + sp = &(dat.remf); e = "function name expected after -%c"; break; case 'A': - sp = &apar; + sp = &(dat.apar); e = "parameter name expected after -%c"; break; case 'O': - sp = ⦷ + sp = &(dat.opar); + e = "parameter name expected after -%c"; + break; + case 'D': + sp = &(dat.dpar); e = "parameter name expected after -%c"; break; case '-': @@ -1830,12 +1839,11 @@ bin_compadd(char *name, char **argv, char *ops, int func) if (!*argv) return 1; - match = cpcmatcher(match); - a = addmatchesptr(ipre, isuf, ppre, psuf, prpre, pre, suf, group, - rs, rf, ign, f, a, match, expl, apar, opar, argv); + dat.match = match = cpcmatcher(match); + dm = addmatchesptr(&dat, argv); freecmatcher(match); - return a; + return dm; } #define CVT_RANGENUM 0 @@ -2165,6 +2173,7 @@ static struct compparam { { "to_end", PM_SCALAR, VAL(comptoend), NULL, NULL }, { "old_list", PM_SCALAR, VAL(compoldlist), NULL, NULL }, { "old_insert", PM_SCALAR, VAL(compoldins), NULL, NULL }, + { "vared", PM_SCALAR, VAL(compvared), NULL, NULL }, { NULL, 0, NULL, NULL, NULL } }; @@ -2308,7 +2317,7 @@ compunsetfn(Param pm, int exp) /**/ void -comp_setunset(int set, int unset) +comp_setunset(unsigned int set, unsigned int unset) { Param *p; @@ -2334,11 +2343,11 @@ comp_wrapper(List list, FuncWrap w, char *name) else { char *orest, *opre, *osuf, *oipre, *oisuf, **owords; long ocur; - int unset = 0, m, sm; + unsigned int unset = 0, m, sm; Param *pp; m = CP_WORDS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | - CP_IPREFIX | CP_RESTORE; + CP_IPREFIX | CP_ISUFFIX | CP_RESTORE; for (pp = comppms, sm = 1; m; pp++, m >>= 1, sm <<= 1) { if ((m & 1) && ((*pp)->flags & PM_UNSET)) unset |= sm; @@ -2373,7 +2382,8 @@ comp_wrapper(List list, FuncWrap w, char *name) } LASTALLOC; comp_setunset(CP_COMPSTATE | (~unset & (CP_WORDS | CP_CURRENT | CP_PREFIX | - CP_SUFFIX | CP_IPREFIX | CP_RESTORE)), + CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX | + CP_RESTORE)), unset); } else comp_setunset(CP_COMPSTATE | (~unset & CP_RESTORE), diff --git a/Src/Zle/compctl.mdd b/Src/Zle/compctl.mdd index 113eef27e..e7b2cfb68 100644 --- a/Src/Zle/compctl.mdd +++ b/Src/Zle/compctl.mdd @@ -1,6 +1,6 @@ moddeps="comp1" -autobins="compctl complist compadd compset" +autobins="compctl compgen compadd compset" autoprefixconds="prefix suffix between after" diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 4d9c99f87..a5da84b66 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -413,7 +413,6 @@ zleread(char *lp, char *rp, int flags) baud = getiparam("BAUD"); costmult = (baud) ? 3840000L / baud : 0; - tv.tv_sec = 0; #endif /* ZLE doesn't currently work recursively. This is needed in case a * @@ -523,6 +522,7 @@ zleread(char *lp, char *rp, int flags) #ifdef HAVE_SELECT if (baud && !(lastcmd & ZLE_MENUCMP)) { FD_SET(SHTTY, &foofd); + tv.tv_sec = 0; if ((tv.tv_usec = cost * costmult) > 500000) tv.tv_usec = 500000; if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd, @@ -656,14 +656,18 @@ handleprefixes(void) initmodifier(&zmod); } +/* this exports the argument we are currently vared'iting if != NULL */ + +/**/ +char *varedarg; + /* vared: edit (literally) a parameter value */ /**/ static int bin_vared(char *name, char **args, char *ops, int func) { - char *s; - char *t; + char *s, *t, *ova = varedarg; Value v; Param pm = 0; int create = 0; @@ -753,7 +757,9 @@ bin_vared(char *name, char **args, char *ops, int func) PERMALLOC { pushnode(bufstack, ztrdup(s)); } LASTALLOC; + varedarg = *args; t = (char *) zleread(p1, p2, ops['h'] ? ZLRF_HISTORY : 0); + varedarg = ova; if (!t || errflag) { /* error in editing */ errflag = 0; @@ -927,6 +933,8 @@ setup_zle(Module m) /* initialise the keymap system */ init_keymaps(); + varedarg = NULL; + return 0; } diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index e7f1744d5..30c31c358 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -611,7 +611,7 @@ Thingy executenamedcommand(char *prmt) { Thingy cmd; - int len, l = strlen(prmt); + int len, l = strlen(prmt), ols = listshown; char *ptr; char *okeymap = curkeymapname; @@ -629,6 +629,10 @@ executenamedcommand(char *prmt) if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) { statusline = NULL; selectkeymap(okeymap, 1); + if ((listshown = ols)) + showinglist = -2; + else + clearlist = 1; return NULL; } if(cmd == Th(z_clearscreen)) { @@ -669,6 +673,10 @@ executenamedcommand(char *prmt) unrefthingy(r); statusline = NULL; selectkeymap(okeymap, 1); + if ((listshown = ols)) + showinglist = -2; + else + clearlist = 1; return r; } unrefthingy(r); diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index 6b0239961..2377b70fa 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -96,6 +96,7 @@ static int more_start, /* more text before start of screen? */ olnct, /* previous number of lines */ ovln, /* previous video cursor position line */ lpromptw, rpromptw, /* prompt widths on screen */ + lpromptwof, /* left prompt width with real end position */ lprompth, /* lines taken up by the prompt */ rprompth, /* right prompt height */ vcs, vln, /* video cursor position column & line */ @@ -141,8 +142,14 @@ resetvideo(void) *obuf[ln] = '\0'; } - countprompt(lpromptbuf, &lpromptw, &lprompth); - countprompt(rpromptbuf, &rpromptw, &rprompth); + countprompt(lpromptbuf, &lpromptwof, &lprompth, 1); + countprompt(rpromptbuf, &rpromptw, &rprompth, 0); + if (lpromptwof != winw) + lpromptw = lpromptwof; + else { + lpromptw = 0; + lprompth++; + } if (lpromptw) { memset(nbuf[0], ' ', lpromptw); @@ -271,7 +278,7 @@ zrefresh(void) clearflag = 0; resetneeded = 1; } - listshown = 0; + listshown = showinglist = 0; } clearlist = 0; @@ -327,7 +334,7 @@ zrefresh(void) vcs = 0; else if (!clearflag && lpromptbuf[0]) { zputs(lpromptbuf, shout); - if (lpromptw == 0 && lprompth == 1) + if (lpromptwof == winw) zputs("\n", shout); /* works with both hasam and !hasam */ } if (clearflag) { @@ -947,7 +954,7 @@ tc_rightcurs(int cl) zputc('\r', shout); tc_upcurs(lprompth - 1); zputs(lpromptbuf, shout); - if (lpromptw == 0 && lprompth == 1) + if (lpromptwof == winw) zputs("\n", shout); /* works with both hasam and !hasam */ } i = lpromptw; diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 92b167cfe..8db571d0b 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -87,6 +87,10 @@ static int usemenu, useglob, useexact, useline, uselist; static int oldlist, oldins; +/* Non-zero if we have to redisplay the list of matches. */ + +static int showagain = 0; + /* The match and group number to insert when starting menucompletion. */ static int insmnum, insgnum, insgroup; @@ -555,7 +559,7 @@ acceptandmenucomplete(void) /* These are flags saying if we are completing in the command * * position, in a redirection, or in a parameter expansion. */ -static int lincmd, linredir, ispar, linwhat; +static int lincmd, linredir, ispar, linwhat, linarr; /* The string for the redirection operator. */ @@ -758,10 +762,14 @@ docomplete(int lst) char *s, *ol; int olst = lst, chl = 0, ne = noerrs, ocs; + if (showagain && validlist) + showinglist = -2; + showagain = 0; + /* If we are doing a menu-completion... */ - if (menucmp && lst != COMP_LIST_EXPAND && compwidget && - compwidget == lastcompwidget) { + if (menucmp && lst != COMP_LIST_EXPAND && + (!compwidget || compwidget == lastcompwidget)) { do_menucmp(lst); return; } @@ -872,7 +880,7 @@ docomplete(int lst) } if (lst == COMP_EXPAND_COMPLETE) do { - /* check if there is a parameter expresiion. */ + /* Check if there is a parameter expression. */ for (; *q && *q != String; q++); if (*q == String && q[1] != Inpar && q[1] != Inbrack) { if (*++q == Inbrace) { @@ -1128,7 +1136,7 @@ unmetafy_line(void) static char * get_comp_string(void) { - int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins, inarr, ia, parct; + int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins, ia, parct; char *s = NULL, *linptr, *tmp, *p, *tt = NULL; zsfree(brbeg); @@ -1192,7 +1200,7 @@ get_comp_string(void) inpush(dupstrspace((char *) linptr), 0, NULL); strinbeg(); stophist = 2; - i = tt0 = cp = rd = ins = oins = inarr = parct = ia = 0; + i = tt0 = cp = rd = ins = oins = linarr = parct = ia = 0; /* This loop is possibly the wrong way to do this. It goes through * * the previously massaged command line using the lexer. It stores * @@ -1211,11 +1219,11 @@ get_comp_string(void) linredir = (inredir && !ins); oins = ins; /* Get the next token. */ - if (inarr) + if (linarr) incmdpos = 0; ctxtlex(); if (tok == ENVARRAY) { - inarr = 1; + linarr = 1; zsfree(varname); varname = ztrdup(tokstr); } else if (tok == INPAR) @@ -1224,7 +1232,7 @@ get_comp_string(void) if (parct) parct--; else - inarr = 0; + linarr = 0; } if (inredir) rdstr = tokstrings[tok]; @@ -1267,7 +1275,7 @@ get_comp_string(void) clwpos = i; cp = lincmd; rd = linredir; - ia = inarr; + ia = linarr; if (inwhat == IN_NOTHING && incond) inwhat = IN_COND; } else if (linredir) @@ -1515,12 +1523,53 @@ get_comp_string(void) */ for (i = 0, p = s; *p; p++, i++) { /* careful, ${... is not a brace expansion... - * in fact, if it's got a substitution in it's too - * hard for us anyway. sorry. + * we try to get braces after a parameter expansion right, + * but this may fail sometimes. sorry. */ if (*p == String || *p == Qstring) { - tt = NULL; - break; + if (p[1] == Inbrace || p[1] == Inpar || p[1] == Inbrack) { + char *tp = p + 1; + if (skipparens(*tp, (*tp == Inbrace ? Outbrace : + (*tp == Inpar ? Outpar : Outbrack)), + &tp)) { + tt = NULL; + break; + } + i += tp - p; + p = tp; + } else { + char *tp = p + 1; + + for (; *tp == '^' || *tp == Hat || + *tp == '=' || *tp == Equals || + *tp == '~' || *tp == Tilde || + *tp == '#' || *tp == Pound || *tp == '+'; + tp++); + if (*tp == Quest || *tp == Star || *tp == String || + *tp == Qstring || *tp == '?' || *tp == '*' || + *tp == '$' || *tp == '-' || *tp == '!' || + *tp == '@') + p++, i++; + else { + if (idigit(*tp)) + while (idigit(*tp)) + tp++; + else if (iident(*tp)) + while (iident(*tp)) + tp++; + else { + tt = NULL; + break; + } + if (*tp == Inbrace) { + tt = NULL; + break; + } + tp--; + i += tp - p; + p = tp; + } + } } else if (*p == Inbrace) { if (tt) { /* too many inbraces */ @@ -3472,14 +3521,10 @@ set_param(char *name, LinkList l) /**/ int -addmatches(char *ipre, char *isuf, - char *ppre, char *psuf, char *prpre, char *pre, - char *suf, char *group, char *rems, char *remf, char *ign, - int flags, int aflags, Cmatcher match, char *exp, - char *apar, char *opar, char **argv) +addmatches(Cadata dat, char **argv) { char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL; - char **aign = NULL; + char **aign = NULL, **dparr; int lpl, lsl, pl, sl, bpl, bsl, llpl = 0, llsl = 0, nm = mnum; int oisalt = 0, isalt, isexact, doadd; Cline lc = NULL; @@ -3487,45 +3532,52 @@ addmatches(char *ipre, char *isuf, struct cmlist mst; Cmlist oms = mstack; Comp cp = NULL; - LinkList aparl = NULL, oparl = NULL; + LinkList aparl = NULL, oparl = NULL, dparl = NULL; /* Switch back to the heap that was used when the completion widget * was invoked. */ SWITCHHEAPS(compheap) { HEAPALLOC { - doadd = (!apar && !opar); - if (apar) + doadd = (!dat->apar && !dat->opar && !dat->dpar); + if (dat->apar) aparl = newlinklist(); - if (opar) + if (dat->opar) oparl = newlinklist(); - if (exp) { + if (dat->dpar) { + if (*(dat->dpar) == '(') + dparr = NULL; + else if ((dparr = get_user_var(dat->dpar)) && !*dparr) + dparr = NULL; + dparl = newlinklist(); + } + if (dat->exp) { expl = (Cexpl) zhalloc(sizeof(struct cexpl)); expl->count = expl->fcount = 0; - expl->str = dupstring(exp); + expl->str = dupstring(dat->exp); } else expl = NULL; /* Store the matcher in our stack of matchers. */ - if (match) { + if (dat->match) { mst.next = mstack; - mst.matcher = match; + mst.matcher = dat->match; mstack = &mst; if (!mnum) - add_bmatchers(match); + add_bmatchers(dat->match); - addlinknode(matchers, match); - match->refc++; + addlinknode(matchers, dat->match); + dat->match->refc++; } if (mnum && (mstack || bmatchers)) update_bmatchers(); /* Get the suffixes to ignore. */ - if (ign) - aign = get_user_var(ign); + if (dat->ign) + aign = get_user_var(dat->ign); /* Get the contents of the completion variables if we have * to perform matching. */ - if (aflags & CAF_MATCH) { + if (dat->aflags & CAF_MATCH) { lipre = dupstring(compiprefix); lisuf = dupstring(compisuffix); lpre = dupstring(compprefix); @@ -3533,8 +3585,8 @@ addmatches(char *ipre, char *isuf, llpl = strlen(lpre); llsl = strlen(lsuf); /* Test if there is an existing -P prefix. */ - if (pre && *pre) { - pl = pfxlen(pre, lpre); + if (dat->pre && *dat->pre) { + pl = pfxlen(dat->pre, lpre); llpl -= pl; lpre += pl; } @@ -3557,79 +3609,76 @@ addmatches(char *ipre, char *isuf, } } /* Now duplicate the strings we have from the command line. */ - if (ipre) - ipre = (lipre ? dyncat(lipre, ipre) : dupstring(ipre)); + if (dat->ipre) + dat->ipre = (lipre ? dyncat(lipre, dat->ipre) : + dupstring(dat->ipre)); else if (lipre) - ipre = lipre; - if (isuf) - isuf = (lisuf ? dyncat(lisuf, isuf) : dupstring(isuf)); + dat->ipre = lipre; + if (dat->isuf) + dat->isuf = (lisuf ? dyncat(lisuf, dat->isuf) : + dupstring(dat->isuf)); else if (lisuf) - isuf = lisuf; - if (ppre) { - ppre = dupstring(ppre); - lpl = strlen(ppre); + dat->isuf = lisuf; + if (dat->ppre) { + dat->ppre = dupstring(dat->ppre); + lpl = strlen(dat->ppre); } else lpl = 0; - if (psuf) { - psuf = dupstring(psuf); - lsl = strlen(psuf); + if (dat->psuf) { + dat->psuf = dupstring(dat->psuf); + lsl = strlen(dat->psuf); } else lsl = 0; - if (aflags & CAF_MATCH) { - s = ppre ? ppre : ""; - if (llpl <= lpl && strpfx(lpre, s)) { - llpl = 0; + if (dat->aflags & CAF_MATCH) { + s = dat->ppre ? dat->ppre : ""; + if (llpl <= lpl && strpfx(lpre, s)) lpre = ""; - } else if (llpl > lpl && strpfx(s, lpre)) { - llpl -= lpl; + else if (llpl > lpl && strpfx(s, lpre)) lpre += lpl; - } else + else *argv = NULL; - s = psuf ? psuf : ""; - if (llsl <= lsl && strsfx(lsuf, s)) { - llsl = 0; + s = dat->psuf ? dat->psuf : ""; + if (llsl <= lsl && strsfx(lsuf, s)) lsuf = ""; - } else if (llsl > lsl && strsfx(s, lsuf)) { + else if (llsl > lsl && strsfx(s, lsuf)) lsuf[llsl - lsl] = '\0'; - llsl -= lsl; - } else + else *argv = NULL; } if (*argv) { - if (pre) - pre = dupstring(pre); - if (suf) - suf = dupstring(suf); - if (!prpre && (prpre = ppre)) { - singsub(&prpre); - untokenize(prpre); + if (dat->pre) + dat->pre = dupstring(dat->pre); + if (dat->suf) + dat->suf = dupstring(dat->suf); + if (!dat->prpre && (dat->prpre = dat->ppre)) { + singsub(&(dat->prpre)); + untokenize(dat->prpre); } else - prpre = dupstring(prpre); + dat->prpre = dupstring(dat->prpre); /* Select the group in which to store the matches. */ - if (group) { + if (dat->group) { endcmgroup(NULL); - begcmgroup(group, (aflags & CAF_NOSORT)); - if (aflags & CAF_NOSORT) + begcmgroup(dat->group, (dat->aflags & CAF_NOSORT)); + if (dat->aflags & CAF_NOSORT) mgroup->flags |= CGF_NOSORT; } else { endcmgroup(NULL); begcmgroup("default", 0); } /* Select the set of matches. */ - oisalt = (aflags & CAF_ALT); + oisalt = (dat->aflags & CAF_ALT); - if (remf) { - remf = dupstring(remf); - rems = NULL; - } else if (rems) - rems = dupstring(rems); + if (dat->remf) { + dat->remf = dupstring(dat->remf); + dat->rems = NULL; + } else if (dat->rems) + dat->rems = dupstring(dat->rems); /* Probably quote the prefix and suffix for testing. */ - if (!cp && (aflags & CAF_MATCH) && !(aflags & CAF_QUOTE)) { + if (!cp && (dat->aflags & CAF_MATCH) && + !(dat->aflags & CAF_QUOTE)) { lpre = quotename(lpre, NULL); lsuf = quotename(lsuf, NULL); - llpl = strlen(lpre); - llsl = strlen(lsuf); } } /* Walk through the matches given. */ @@ -3638,7 +3687,7 @@ addmatches(char *ipre, char *isuf, bpl = brpl; bsl = brsl; isalt = oisalt; - if ((!psuf || !*psuf) && aign) { + if ((!dat->psuf || !*(dat->psuf)) && aign) { /* Do the suffix-test. If the match has one of the * suffixes from ign, we put it in the alternate set. */ char **pt = aign; @@ -3649,39 +3698,52 @@ addmatches(char *ipre, char *isuf, && !strcmp(*pt, s + sl - filell)) isalt = 1; - if (isalt && !doadd) + if (isalt && !doadd) { + if (dparr && !*++dparr) + dparr = NULL; continue; + } } - if (!(aflags & CAF_MATCH)) { + if (!(dat->aflags & CAF_MATCH)) { ms = dupstring(s); lc = bld_parts(ms, sl, -1, NULL); isexact = 0; } else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc, - !(aflags & CAF_QUOTE), - &bpl, &bsl, &isexact))) + !(dat->aflags & CAF_QUOTE), + &bpl, &bsl, &isexact))) { + if (dparr && !*++dparr) + dparr = NULL; continue; - + } if (doadd) { - cm = add_match_data(isalt, ms, lc, ipre, ipre, isuf, pre, - prpre, ppre, psuf, suf, bpl, bsl, - flags, isexact); - cm->rems = rems; - cm->remf = remf; + cm = add_match_data(isalt, ms, lc, dat->ipre, dat->ipre, + dat->isuf, dat->pre, dat->prpre, + dat->ppre, dat->psuf, dat->suf, + bpl, bsl, dat->flags, isexact); + cm->rems = dat->rems; + cm->remf = dat->remf; } else { - if (apar) + if (dat->apar) addlinknode(aparl, ms); - if (opar) + if (dat->opar) addlinknode(oparl, s); + if (dat->dpar && dparr) { + addlinknode(dparl, *dparr); + if (!*++dparr) + dparr = NULL; + } free_cline(lc); } } compnmatches = mnum; - if (exp) + if (dat->exp) addexpl(); - if (apar) - set_param(apar, aparl); - if (opar) - set_param(opar, oparl); + if (dat->apar) + set_param(dat->apar, aparl); + if (dat->opar) + set_param(dat->opar, oparl); + if (dat->dpar) + set_param(dat->dpar, dparl); } LASTALLOC; } SWITCHBACKHEAPS; @@ -4128,6 +4190,7 @@ docompletion(char *s, int lst, int incmd) (unset(ALWAYSLASTPROMPT) && zmult != 1)) ? "yes" : ""); movetoend = ((cs == we || isset(ALWAYSTOEND)) ? 2 : 1); + showinglist = 0; /* Make sure we have the completion list and compctl. */ if (makecomplist(s, incmd, lst)) { @@ -4217,14 +4280,22 @@ callcompfunc(char *s, char *fn) if ((list = getshfunc(fn)) != &dummy_list) { char **p, *tmp; - int set, aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext; + int aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext; + unsigned int set; Param *ocpms = comppms; comppms = (Param *) zalloc(CP_NUM * sizeof(Param)); - set = -1 & ~(CP_PARAMETER | CP_REDIRECT | CP_QUOTE | CP_QUOTING | - CP_EXACTSTR | CP_FORCELIST | CP_OLDLIST | CP_OLDINS | - (useglob ? 0 : CP_PATMATCH)); + set = CP_ALLMASK & + ~(CP_PARAMETER | CP_REDIRECT | CP_QUOTE | CP_QUOTING | + CP_EXACTSTR | CP_FORCELIST | CP_OLDLIST | CP_OLDINS | + (useglob ? 0 : CP_PATMATCH)); + zsfree(compvared); + if (varedarg) { + compvared = ztrdup(varedarg); + set |= CP_VARED; + } else + compvared = ztrdup(""); if (!*complastprompt) set &= ~CP_LASTPROMPT; zsfree(compcontext); @@ -4257,7 +4328,7 @@ callcompfunc(char *s, char *fn) } else switch (linwhat) { case IN_ENV: - compcontext = "array_value"; + compcontext = (linarr ? "array_value" : "value"); compparameter = varname; set |= CP_PARAMETER; if (!clwpos) { @@ -4551,6 +4622,7 @@ makecomplist(char *s, int incmd, int lst) insmnum = insgnum = 1; insgroup = oldlist = oldins = 0; begcmgroup("default", 0); + menucmp = 0; ccused = newlinklist(); ccstack = newlinklist(); @@ -6717,11 +6789,13 @@ unambig_data(int *cp) return scache; } -/* Insert the given match. This returns the number of characters inserted.*/ +/* Insert the given match. This returns the number of characters inserted. + * scs is used to return the position where a automatically created suffix + * has to be inserted. */ /**/ static int -instmatch(Cmatch m) +instmatch(Cmatch m, int *scs) { int l, r = 0, ocs, a = cs; @@ -6771,6 +6845,7 @@ instmatch(Cmatch m) } else brscs = -1; /* -S suffix */ + *scs = cs; if (m->suf) { inststrlen(m->suf, 1, (l = strlen(m->suf))); r += l; @@ -6842,13 +6917,13 @@ do_ambiguous(void) /* If REC_EXACT and AUTO_MENU are set and what we inserted is an * * exact match, we want menu completion the next time round * - * so we set fromcomp,to ensure that the word on the line is not * + * so we set fromcomp, to ensure that the word on the line is not * * taken as an exact match. Also we remember if we just moved the * * cursor into the word. */ fromcomp = ((isset(AUTOMENU) ? FC_LINE : 0) | ((atend && cs != lastend) ? FC_INWORD : 0)); - /* Probably move the cursor to then end. */ + /* Probably move the cursor to the end. */ if (movetoend == 3) cs = lastend; @@ -6907,7 +6982,7 @@ ztat(char *nam, struct stat *buf, int ls) static void do_single(Cmatch m) { - int l, sr = 0; + int l, sr = 0, scs; int havesuff = 0; char *str = m->str, *ppre = m->ppre, *psuf = m->psuf, *prpre = m->prpre; @@ -6937,7 +7012,7 @@ do_single(Cmatch m) foredel(l); /* And then we insert the new string. */ - menulen = instmatch(m); + menulen = instmatch(m, &scs); menuend = cs; cs = menupos + menulen; @@ -6956,6 +7031,7 @@ do_single(Cmatch m) } else { /* There is no user-specified suffix, * * so generate one automagically. */ + cs = scs; if (m->ripre && (m->flags & CMF_PARBR)) { /*{{*/ /* Completing a parameter in braces. Add a removable `}' suffix. */ @@ -7006,6 +7082,8 @@ do_single(Cmatch m) } } } + if (!menuinsc) + cs = menupos + menulen; } /* If completing in a brace expansion... */ if (brbeg) { @@ -7018,7 +7096,7 @@ do_single(Cmatch m) } else if (!menucmp) { /*{{*/ /* Otherwise, add a `,' suffix, and let `}' remove it. */ - cs = menuend; + cs = scs; havesuff = 1; inststrlen(",", 1, 1); menuinsc++; @@ -7492,7 +7570,12 @@ listlist(LinkList l) struct cmgroup dg; Cmgroup am = amatches; int vl = validlist, sm = smatches; + char *oclp = complastprompt; + + if (listshown) + showagain = 1; + complastprompt = ((zmult == 1) == !!isset(ALWAYSLASTPROMPT) ? "yes" : NULL); smatches = 1; validlist = 1; amatches = &dg; @@ -7503,6 +7586,7 @@ listlist(LinkList l) amatches = am; validlist = vl; smatches = sm; + complastprompt = oclp; } /* Expand the history references. */ |