diff options
author | Sven Wischnowsky <wischnow@users.sourceforge.net> | 2001-07-11 08:22:02 +0000 |
---|---|---|
committer | Sven Wischnowsky <wischnow@users.sourceforge.net> | 2001-07-11 08:22:02 +0000 |
commit | 027604400ba98f4c947784fc691dc7c93b9bf366 (patch) | |
tree | 96072e9c3b307111e1aaf8ca92c2c75570aa78f3 | |
parent | 1f62b5acbe4a6e5c2c1f704ab1dcfd207afe9919 (diff) | |
download | zsh-027604400ba98f4c947784fc691dc7c93b9bf366.tar.gz zsh-027604400ba98f4c947784fc691dc7c93b9bf366.tar.xz zsh-027604400ba98f4c947784fc691dc7c93b9bf366.zip |
15352,15357
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | Completion/Base/Completer/_prefix | 59 | ||||
-rw-r--r-- | Completion/Unix/Command/_man | 61 | ||||
-rw-r--r-- | Src/Zle/compcore.c | 576 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 2 |
5 files changed, 540 insertions, 170 deletions
diff --git a/ChangeLog b/ChangeLog index 008d2c5b9..5aac4ac5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2001-07-10 Sven Wischnowsky <wischnow@zsh.org> + + * 15357: Completion/Base/Completer/_prefix, Src/Zle/compcore.c, + Src/Zle/zle_tricky.c: prefix completion: make e-o-c-p leave a + space before the cursor, make _prefix leave the cursor after + the inserted match even if only a single match; and make the + C-code not show explanation strings if the completion function + it doesn't want a list + + * 15352: Completion/Unix/Command/_man: remove not only numeric + suffixes, but also `.n' and the like + 2001-07-09 Bart Schaefer <schaefer@zsh.org> * 15321: Src/exec.c: Fix line numbers in an error message; unwind diff --git a/Completion/Base/Completer/_prefix b/Completion/Base/Completer/_prefix new file mode 100644 index 000000000..3ec153245 --- /dev/null +++ b/Completion/Base/Completer/_prefix @@ -0,0 +1,59 @@ +#autoload + +# Try to ignore the suffix. A bit like e-o-c-prefix. + +[[ _matcher_num -gt 1 || -z "$SUFFIX" ]] && return 1 + +local comp curcontext="$curcontext" tmp suf="$SUFFIX" \ + _completer _completer_num \ + _matcher _c_matcher _matchers _matcher_num + +zstyle -a ":completion:${curcontext}:" completer comp || + comp=( "${(@)_completers[1,_completer_num-1][(R)_prefix(|:*),-1]}" ) + +if zstyle -t ":completion:${curcontext}:" add-space; then + ISUFFIX=" $SUFFIX" +else + ISUFFIX="$SUFFIX" +fi +SUFFIX='' + +_completer_num=1 + +for tmp in "$comp[@]"; do + if [[ "$tmp" = *:-* ]]; then + _completer="${${tmp%:*}[2,-1]//_/-}${tmp#*:}" + tmp="${tmp%:*}" + elif [[ $tmp = *:* ]]; then + _completer="${tmp#*:}" + tmp="${tmp%:*}" + else + _completer="${tmp[2,-1]//_/-}" + fi + curcontext="${curcontext/:[^:]#:/:${_completer}:}" + + zstyle -a ":completion:${curcontext}:" matcher-list _matchers || + _matchers=( '' ) + + _matcher_num=1 + _matcher='' + for _c_matcher in "$_matchers[@]"; do + if [[ "$_c_matcher" == +* ]]; then + _matcher="$_matcher $_c_matcher[2,-1]" + else + _matcher="$_c_matcher" + fi + + if [[ "$tmp" != _prefix ]] && "$tmp"; then + [[ compstate[nmatches] -gt 1 ]] && return 0 + compadd -U -i "$IPREFIX" -I "$ISUFFIX" - "${compstate[unambiguous]%$suf}x" + compstate[list]= + compstate[insert]=unambiguous + return 0 + fi + (( _matcher_num++ )) + done + (( _completer_num++ )) +done + +return 1 diff --git a/Completion/Unix/Command/_man b/Completion/Unix/Command/_man new file mode 100644 index 000000000..0bdd8db8b --- /dev/null +++ b/Completion/Unix/Command/_man @@ -0,0 +1,61 @@ +#compdef man apropos whatis + +_man() { + local dirs expl mrd awk + + if [[ $service == man ]] && (( $words[(I)-l] + $words[(I)--local-file] )); then + _files || return 0 + fi + + if (( ! $#manpath )); then + local mp + mp=($(manpath 2>/dev/null)) + [[ "$mp" == *:* ]] && mp=( ${(s.:.)mp} ) + manpath=( $mp ) + fi + + (( $#manpath )) || manpath=( ${(s.:.)$(manpath 2>/dev/null)} ) || + manpath=( /usr/man(-/) /(opt|usr)/(dt|share|X11R6|local)/(cat|)man(-/) ) + + # `sman' is the SGML manual directory for Solaris 7. + # 1M is system administrator commands on SVR4 + + mrd=(${^manpath/\%L/${LANG:-En_US.ASCII}}/mandb(N)) + + if [[ $words[2] = (<->*|1M|l|n) ]]; then + dirs=( $^manpath/(sman|man|cat)${words[2]}/ ) + awk="\$2 == \"$words[2]\" {print \$1}" + else + dirs=( $^manpath/(sman|man|cat)*/ ) + awk='{print $1}' + fi + + _wanted manuals expl 'manual page' _man_pages +} + +_man_pages() { + local matcher pages dummy + + zparseopts -E M+:=matcher + + if (( $#matcher )); then + matcher=( ${matcher:#-M} ) + matcher="$matcher" + else + matcher= + fi + + pages=( $dirs ) + compfiles -p pages '' '' "$matcher" '' dummy '*' + pages=( ${^~pages}(N:t:r) ) + + (($#mrd)) && pages[$#pages+1]=($(awk $awk $mrd)) + + # Remove any compression suffix, then remove the minimum possible string + # beginning with .<->: that handles problem cases like files called + # `POSIX.1.5'. + + compadd "$@" - ${pages%.(?|<->*)} +} + +_man "$@" diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 48189ab31..97ed6d58f 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -39,16 +39,23 @@ static Widget lastcompwidget; /**/ int useexact, useline, uselist, forcelist, startauto; +/**/ +mod_export int iforcemenu; + /* Non-zero if we should go back to the last prompt. */ /**/ -int dolastprompt; +mod_export int dolastprompt; /* Non-zero if we should keep an old list. */ /**/ -mod_export -int oldlist, oldins; +mod_export int oldlist, oldins; + +/* Original prefix/suffix lengths. Flag saying if they changed. */ + +/**/ +int origlpre, origlsuf, lenchanged; /* This is used to decide when the cursor should be moved to the end of * * the inserted word: 0 - never, 1 - only when a single match is inserted, * @@ -60,7 +67,12 @@ int movetoend; /* The match and group number to insert when starting menucompletion. */ /**/ -mod_export int insmnum, insgnum, insgroup, insspace; +mod_export int insmnum, insspace; + +#if 0 +/* group-numbers in compstate[insert] */ +int insgnum, insgroup; /* mod_export */ +#endif /* Information about menucompletion. */ @@ -131,6 +143,11 @@ mod_export Cmgroup lastmatches, pmatches, amatches, lmatches, lastlmatches; /**/ mod_export int hasoldlist, hasperm; +/* Non-zero if we have a match representing all other matches. */ + +/**/ +int hasallmatch; + /* Non-zero if we have newly added matches. */ /**/ @@ -148,6 +165,16 @@ mod_export int nmatches; /**/ mod_export int smatches; +/* != 0 if more than one match and at least two different matches */ + +/**/ +mod_export int diffmatches; + +/* The number of messages. */ + +/**/ +mod_export int nmessages; + /* != 0 if only explanation strings should be printed */ /**/ @@ -260,7 +287,7 @@ int lastend; int do_completion(Hookdef dummy, Compldat dat) { - int ret = 0, lst = dat->lst, incmd = dat->incmd; + int ret = 0, lst = dat->lst, incmd = dat->incmd, osl = showinglist; char *s = dat->s; char *opm; LinkNode n; @@ -278,7 +305,7 @@ do_completion(Hookdef dummy, Compldat dat) compqstack[0] = '\''; hasunqu = 0; - useline = (lst != COMP_LIST_COMPLETE); + useline = (wouldinstab ? -1 : (lst != COMP_LIST_COMPLETE)); useexact = isset(RECEXACT); zsfree(compexactstr); compexactstr = ztrdup(""); @@ -307,6 +334,9 @@ do_completion(Hookdef dummy, Compldat dat) hasmatched = hasunmatched = 0; minmlen = 1000000; maxmlen = -1; + compignored = 0; + nmessages = 0; + hasallmatch = 0; /* Make sure we have the completion list and compctl. */ if (makecomplist(s, incmd, lst)) { @@ -318,6 +348,8 @@ do_completion(Hookdef dummy, Compldat dat) clearlist = 1; ret = 1; minfo.cur = NULL; + if (useline < 0) + ret = selfinsert(zlenoargs); goto compend; } zsfree(lastprebr); @@ -326,7 +358,13 @@ do_completion(Hookdef dummy, Compldat dat) if (comppatmatch && *comppatmatch && comppatmatch != opm) haspattern = 1; - if (!useline && uselist) { + if (iforcemenu) { + if (nmatches) + do_ambig_menu(); + ret = !nmatches; + } else if (useline < 0) + ret = selfinsert(zlenoargs); + else if (!useline && uselist) { /* All this and the guy only wants to see the list, sigh. */ cs = 0; foredel(ll); @@ -334,41 +372,8 @@ do_completion(Hookdef dummy, Compldat dat) cs = origcs; showinglist = -2; } else if (useline == 2 && nmatches > 1) { - int first = 1, nm = nmatches; - Cmatch *mc; - - menucmp = 1; - menuacc = 0; - - for (minfo.group = amatches; - minfo.group && !(minfo.group)->mcount; - minfo.group = (minfo.group)->next); - - mc = (minfo.group)->matches; - - while (1) { - if (!first) - accept_last(); - first = 0; + do_allmatches(1); - if (!--nm) - menucmp = 0; - - do_single(*mc); - minfo.cur = mc; - - if (!*++(minfo.cur)) { - do { - if (!(minfo.group = (minfo.group)->next)) - break; - } while (!(minfo.group)->mcount); - if (!minfo.group) - break; - minfo.cur = minfo.group->matches; - } - mc = minfo.cur; - } - menucmp = 0; minfo.cur = NULL; if (forcelist) @@ -377,10 +382,13 @@ do_completion(Hookdef dummy, Compldat dat) invalidatelist(); } else if (useline) { /* We have matches. */ - if (nmatches > 1) { + if (nmatches > 1 && diffmatches) { /* There is more than one match. */ ret = do_ambiguous(); - } else if (nmatches == 1) { + + if (!showinglist && uselist && listshown && (usemenu == 2 || oldlist)) + showinglist = osl; + } else if (nmatches == 1 || (nmatches > 1 && !diffmatches)) { /* Only one match. */ Cmgroup m = amatches; @@ -396,6 +404,11 @@ do_completion(Hookdef dummy, Compldat dat) clearlist = 1; } else invalidatelist(); + } else if (nmessages && forcelist) { + if (uselist) + showinglist = -2; + else + clearlist = 1; } } else { invalidatelist(); @@ -407,9 +420,10 @@ do_completion(Hookdef dummy, Compldat dat) cs = origcs; } /* Print the explanation strings if needed. */ - if (!showinglist && validlist && usemenu != 2 && nmatches != 1 && - useline != 2 && (!oldlist || !listshown)) { - onlyexpl = 1; + if (!showinglist && validlist && usemenu != 2 && uselist && + (nmatches != 1 || diffmatches) && + useline >= 0 && useline != 2 && (!oldlist || !listshown)) { + onlyexpl = 3; showinglist = -2; } compend: @@ -469,22 +483,40 @@ before_complete(Hookdef dummy, int *lst) /**/ int -after_complete(Hookdef dummy, Compldat dat) +after_complete(Hookdef dummy, int *dat) { if (menucmp && !oldmenucmp) { - struct chdata dat; - - dat.matches = amatches; - dat.num = nmatches; - dat.cur = NULL; - if (runhookdef(MENUSTARTHOOK, (void *) &dat)) + struct chdata cdat; + int ret; + + cdat.matches = amatches; + cdat.num = nmatches; + cdat.nmesg = nmessages; + cdat.cur = NULL; + if ((ret = runhookdef(MENUSTARTHOOK, (void *) &cdat))) { + dat[1] = 0; menucmp = menuacc = 0; + minfo.cur = NULL; + if (ret >= 2) { + fixsuffix(); + cs = 0; + foredel(ll); + inststr(origline); + cs = origcs; + if (ret == 2) { + clearlist = 1; + invalidatelist(); + } + } + } } return 0; } /* This calls the given completion widget function. */ +static int parwb, parwe, paroffs; + /**/ static void callcompfunc(char *s, char *fn) @@ -610,7 +642,7 @@ callcompfunc(char *s, char *fn) zsfree(compprefix); zsfree(compsuffix); if (unset(COMPLETEINWORD)) { - tmp = multiquote(s, 0); + tmp = (linwhat == IN_MATH ? dupstring(s) : multiquote(s, 0)); untokenize(tmp); compprefix = ztrdup(tmp); compsuffix = ztrdup(""); @@ -621,22 +653,42 @@ callcompfunc(char *s, char *fn) sav = *ss; *ss = '\0'; - tmp = multiquote(s, 0); + tmp = (linwhat == IN_MATH ? dupstring(s) : multiquote(s, 0)); untokenize(tmp); compprefix = ztrdup(tmp); *ss = sav; - ss = multiquote(ss, 0); + ss = (linwhat == IN_MATH ? dupstring(ss) : multiquote(ss, 0)); untokenize(ss); compsuffix = ztrdup(ss); } zsfree(compiprefix); - compiprefix = ztrdup(""); zsfree(compisuffix); - compisuffix = ztrdup(""); + if (parwb < 0) { + compiprefix = ztrdup(""); + compisuffix = ztrdup(""); + } else { + int l; + + compiprefix = (char *) zalloc((l = wb - parwb) + 1); + memcpy(compiprefix, line + parwb, l); + compiprefix[l] = '\0'; + compisuffix = (char *) zalloc((l = parwe - we) + 1); + memcpy(compisuffix, line + we, l); + compisuffix[l] = '\0'; + + wb = parwb; + we = parwe; + offs = paroffs; + } zsfree(compqiprefix); compqiprefix = ztrdup(qipre ? qipre : ""); zsfree(compqisuffix); compqisuffix = ztrdup(qisuf ? qisuf : ""); + origlpre = (strlen(compqiprefix) + strlen(compiprefix) + + strlen(compprefix)); + origlsuf = (strlen(compqisuffix) + strlen(compisuffix) + + strlen(compsuffix)); + lenchanged = 0; compcurrent = (usea ? (clwpos + 1 - aadd) : 0); zsfree(complist); @@ -667,7 +719,9 @@ callcompfunc(char *s, char *fn) compinsert = ""; kset &= ~CP_INSERT; } - compinsert = ztrdup(compinsert); + compinsert = (useline < 0 ? tricat("tab ", "", compinsert) : + ztrdup(compinsert)); + zsfree(compexact); if (useexact) compexact = ztrdup("accept"); else { @@ -737,35 +791,58 @@ callcompfunc(char *s, char *fn) else uselist = 0; forcelist = (complist && strstr(complist, "force")); - onlyexpl = (complist && strstr(complist, "expl")); + onlyexpl = (complist ? ((strstr(complist, "expl") ? 1 : 0) | + (strstr(complist, "messages") ? 2 : 0)) : 0); if (!compinsert) useline = 0; + else if (strstr(compinsert, "tab")) + useline = -1; else if (!strcmp(compinsert, "unambig") || !strcmp(compinsert, "unambiguous") || !strcmp(compinsert, "automenu-unambiguous")) useline = 1, usemenu = 0; - else if (!strcmp(compinsert, "menu")) - useline = 1, usemenu = 1; - else if (!strcmp(compinsert, "auto") || - !strcmp(compinsert, "automenu")) - useline = 1, usemenu = 2; else if (!strcmp(compinsert, "all")) useline = 2, usemenu = 0; else if (idigit(*compinsert)) { +#if 0 + /* group-numbers in compstate[insert] */ char *m; - +#endif useline = 1; usemenu = 3; insmnum = atoi(compinsert); +#if 0 + /* group-numbers in compstate[insert] */ if ((m = strchr(compinsert, ':'))) { insgroup = 1; insgnum = atoi(m + 1); } +#endif insspace = (compinsert[strlen(compinsert) - 1] == ' '); - } else - useline = usemenu = 0; - startauto = (compinsert && - !strcmp(compinsert, "automenu-unambiguous")); + } else { + char *p; + + if (strpfx("menu", compinsert)) + useline = 1, usemenu = 1; + else if (strpfx("auto", compinsert)) + useline = 1, usemenu = 2; + else + useline = usemenu = 0; + + if (useline && (p = strchr(compinsert, ':'))) { + insmnum = atoi(++p); +#if 0 + /* group-numbers in compstate[insert] */ + if ((p = strchr(p, ':'))) { + insgroup = 1; + insgnum = atoi(p + 1); + } +#endif + } + } + startauto = ((compinsert && + !strcmp(compinsert, "automenu-unambiguous")) || + (bashlistfirst && (!compinsert || !*compinsert))); useexact = (compexact && !strcmp(compexact, "accept")); if (!comptoend || !*comptoend) @@ -802,16 +879,22 @@ static int makecomplist(char *s, int incmd, int lst) { char *p; + int owb = wb, owe = we, ooffs = offs; /* Inside $... ? */ - if (compfunc && (p = check_param(s, 0, 0))) + if (compfunc && (p = check_param(s, 0, 0))) { s = p; + parwb = owb; + parwe = owe; + paroffs = ooffs; + } else + parwb = -1; linwhat = inwhat; if (compfunc) { char *os = s; - int onm = nmatches, osi = movefd(0); + int onm = nmatches, odm = diffmatches, osi = movefd(0); bmatchers = NULL; mstack = NULL; @@ -827,8 +910,13 @@ makecomplist(char *s, int incmd, int lst) mnum = 0; unambig_mnum = -1; isuf = NULL; - insmnum = insgnum = 1; - insgroup = oldlist = oldins = 0; + insmnum = 1; +#if 0 + /* group-numbers in compstate[insert] */ + insgnum = 1; + insgroup = 0; +#endif + oldlist = oldins = 0; begcmgroup("default", 0); menucmp = menuacc = newmatches = onlyexpl = 0; @@ -841,11 +929,12 @@ makecomplist(char *s, int incmd, int lst) if (oldlist) { nmatches = onm; + diffmatches = odm; validlist = 1; amatches = lastmatches; lmatches = lastlmatches; if (pmatches) { - freematches(pmatches); + freematches(pmatches, 1); pmatches = NULL; hasperm = 0; } @@ -854,7 +943,7 @@ makecomplist(char *s, int incmd, int lst) return 0; } if (lastmatches) { - freematches(lastmatches); + freematches(lastmatches, 1); lastmatches = NULL; } permmatches(1); @@ -868,7 +957,7 @@ makecomplist(char *s, int incmd, int lst) hasperm = 0; hasoldlist = 1; - if (nmatches && !errflag) { + if ((nmatches || nmessages) && !errflag) { validlist = 1; redup(osi, 0); @@ -1041,7 +1130,7 @@ check_param(char *s, int set, int test) } /* Save the prefix. */ if (compfunc) { - parflags = (br >= 2 ? CMF_PARBR : 0); + parflags = (br >= 2 ? CMF_PARBR | (nest ? CMF_PARNEST : 0) : 0); sav = *b; *b = '\0'; untokenize(parpre = ztrdup(s)); @@ -1148,7 +1237,7 @@ set_comp_sep(void) LinkNode n; int owe = we, owb = wb, ocs = cs, swb, swe, scs, soffs, ne = noerrs; int tl, got = 0, i = 0, cur = -1, oll = ll, sl, remq; - int ois = instring, oib = inbackt, noffs = lp; + int ois = instring, oib = inbackt, noffs = lp, ona = noaliases; char *tmp, *p, *ns, *ol = (char *) line, sav, *qp, *qs, *ts, qc = '\0'; s += lip; @@ -1210,7 +1299,7 @@ set_comp_sep(void) } i++; } while (tok != ENDINPUT && tok != LEXERR); - noaliases = 0; + noaliases = ona; strinend(); inpop(); errflag = zleparse = 0; @@ -1437,18 +1526,38 @@ get_user_var(char *nam) /* Otherwise it should be a parameter name. */ char **arr = NULL, *val; + queue_signals(); if ((arr = getaparam(nam)) || (arr = gethparam(nam))) - return (incompfunc ? arrdup(arr) : arr); - - if ((val = getsparam(nam))) { + arr = (incompfunc ? arrdup(arr) : arr); + else if ((val = getsparam(nam))) { arr = (char **) zhalloc(2*sizeof(char *)); arr[0] = (incompfunc ? dupstring(val) : val); arr[1] = NULL; } + unqueue_signals(); return arr; } } +static char ** +get_data_arr(char *name, int keys) +{ + struct value vbuf; + char **ret; + Value v; + + queue_signals(); + if (!(v = fetchvalue(&vbuf, &name, 1, + (keys ? SCANPM_WANTKEYS : SCANPM_WANTVALS) | + SCANPM_MATCHMANY))) + ret = NULL; + else + ret = getarrvalue(v); + unqueue_signals(); + + return ret; +} + /* This is used by compadd to add a couple of matches. The arguments are * the strings given via options. The last argument is the array with * the matches. */ @@ -1460,10 +1569,11 @@ addmatches(Cadata dat, char **argv) char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL; char **aign = NULL, **dparr = NULL, *oaq = autoq, *oppre = dat->ppre; char *oqp = qipre, *oqs = qisuf, qc, **disp = NULL, *ibuf = NULL; + char **arrays = NULL; int lpl, lsl, pl, sl, bcp = 0, bcs = 0, bpadd = 0, bsadd = 0; - int ppl = 0, psl = 0; + int ppl = 0, psl = 0, ilen = 0; int llpl = 0, llsl = 0, nm = mnum, gflags = 0, ohp = haspattern; - int oisalt = 0, isalt, isexact, doadd, ois = instring, oib = inbackt; + int isexact, doadd, ois = instring, oib = inbackt; Cline lc = NULL, pline = NULL, sline = NULL; Cmatch cm; struct cmlist mst; @@ -1471,9 +1581,10 @@ addmatches(Cadata dat, char **argv) Patprog cp = NULL, *pign = NULL; LinkList aparl = NULL, oparl = NULL, dparl = NULL; Brinfo bp, bpl = brbeg, obpl, bsl = brend, obsl; + Heap oldheap; - if (!*argv) { - SWITCHHEAPS(compheap) { + if (!*argv && !(dat->aflags & CAF_ALL)) { + SWITCHHEAPS(oldheap, compheap) { /* Select the group in which to store the matches. */ gflags = (((dat->aflags & CAF_NOSORT ) ? CGF_NOSORT : 0) | ((dat->aflags & CAF_UNIQALL) ? CGF_UNIQALL : 0) | @@ -1485,7 +1596,9 @@ addmatches(Cadata dat, char **argv) endcmgroup(NULL); begcmgroup("default", 0); } - } SWITCHBACKHEAPS; + if (dat->mesg) + addmesg(dat->mesg); + } SWITCHBACKHEAPS(oldheap); return 1; } @@ -1521,7 +1634,7 @@ addmatches(Cadata dat, char **argv) /* Switch back to the heap that was used when the completion widget * was invoked. */ - SWITCHHEAPS(compheap) { + SWITCHHEAPS(oldheap, compheap) { if ((doadd = (!dat->apar && !dat->opar && !dat->dpar))) { if (dat->aflags & CAF_MATCH) hasmatched = 1; @@ -1597,6 +1710,11 @@ addmatches(Cadata dat, char **argv) lsuf = dupstring(compsuffix); llpl = strlen(lpre); llsl = strlen(lsuf); + + if (llpl + strlen(compqiprefix) + strlen(lipre) != origlpre || + llsl + strlen(compqisuffix) + strlen(lisuf) != origlsuf) + lenchanged = 1; + /* Test if there is an existing -P prefix. */ if (dat->pre && *dat->pre) { pl = pfxlen(dat->pre, lpre); @@ -1649,55 +1767,57 @@ addmatches(Cadata dat, char **argv) llpl -= gfl; } } - s = dat->ppre ? dat->ppre : ""; - if ((ml = match_str(lpre, s, &bpl, 0, NULL, 0, 0, 1)) >= 0) { - if (matchsubs) { - Cline tmp = get_cline(NULL, 0, NULL, 0, NULL, 0, 0); - - tmp->prefix = matchsubs; - if (matchlastpart) - matchlastpart->next = tmp; + if ((s = dat->ppre)) { + if ((ml = match_str(lpre, s, &bpl, 0, NULL, 0, 0, 1)) >= 0) { + if (matchsubs) { + Cline tmp = get_cline(NULL, 0, NULL, 0, NULL, 0, 0); + + tmp->prefix = matchsubs; + if (matchlastpart) + matchlastpart->next = tmp; + else + matchparts = tmp; + } + pline = matchparts; + lpre += ml; + llpl -= ml; + bcp = ml; + bpadd = strlen(s) - ml; + } else { + if (llpl <= lpl && strpfx(lpre, s)) + lpre = dupstring(""); + else if (llpl > lpl && strpfx(s, lpre)) + lpre += lpl; else - matchparts = tmp; + *argv = NULL; + bcp = lpl; } - pline = matchparts; - lpre += ml; - llpl -= ml; - bcp = ml; - bpadd = strlen(s) - ml; - } else { - if (llpl <= lpl && strpfx(lpre, s)) - lpre = ""; - else if (llpl > lpl && strpfx(s, lpre)) - lpre += lpl; - else - *argv = NULL; - bcp = lpl; } - s = dat->psuf ? dat->psuf : ""; - if ((ml = match_str(lsuf, s, &bsl, 0, NULL, 1, 0, 1)) >= 0) { - if (matchsubs) { - Cline tmp = get_cline(NULL, 0, NULL, 0, NULL, 0, CLF_SUF); - - tmp->suffix = matchsubs; - if (matchlastpart) - matchlastpart->next = tmp; + if ((s = dat->psuf)) { + if ((ml = match_str(lsuf, s, &bsl, 0, NULL, 1, 0, 1)) >= 0) { + if (matchsubs) { + Cline tmp = get_cline(NULL, 0, NULL, 0, NULL, 0, CLF_SUF); + + tmp->suffix = matchsubs; + if (matchlastpart) + matchlastpart->next = tmp; + else + matchparts = tmp; + } + sline = revert_cline(matchparts); + lsuf[llsl - ml] = '\0'; + llsl -= ml; + bcs = ml; + bsadd = strlen(s) - ml; + } else { + if (llsl <= lsl && strsfx(lsuf, s)) + lsuf = dupstring(""); + else if (llsl > lsl && strsfx(s, lsuf)) + lsuf[llsl - lsl] = '\0'; else - matchparts = tmp; + *argv = NULL; + bcs = lsl; } - sline = revert_cline(matchparts); - lsuf[llsl - ml] = '\0'; - llsl -= ml; - bcs = ml; - bsadd = strlen(s) - ml; - } else { - if (llsl <= lsl && strsfx(lsuf, s)) - lsuf = ""; - else if (llsl > lsl && strsfx(s, lsuf)) - lsuf[llsl - lsl] = '\0'; - else - *argv = NULL; - bcs = lsl; } if (comppatmatch && *comppatmatch) { int is = (*comppatmatch == '*'); @@ -1732,6 +1852,8 @@ addmatches(Cadata dat, char **argv) endcmgroup(NULL); begcmgroup("default", 0); } + if (dat->mesg) + addmesg(dat->mesg); if (*argv) { if (dat->pre) dat->pre = dupstring(dat->pre); @@ -1743,7 +1865,6 @@ addmatches(Cadata dat, char **argv) } else dat->prpre = dupstring(dat->prpre); /* Select the set of matches. */ - oisalt = (dat->aflags & CAF_ALT); if (dat->remf) { dat->remf = dupstring(dat->remf); @@ -1761,17 +1882,28 @@ addmatches(Cadata dat, char **argv) /* Walk through the matches given. */ obpl = bpl; obsl = bsl; - if (!oisalt && (aign || pign)) { - int max = 0; - char **ap = argv; - - ppl = (dat->ppre ? strlen(dat->ppre) : 0); - while ((s = *ap++)) - if ((sl = strlen(s)) > max) - max = sl; - psl = (dat->psuf ? strlen(dat->psuf) : 0); - ibuf = (char *) zhalloc(1 + ppl + max + psl); + if (dat->aflags & CAF_ARRAYS) { + Heap oldheap2; + + SWITCHHEAPS(oldheap2, oldheap) { + arrays = argv; + argv = NULL; + while (*arrays && + (!(argv = get_data_arr(*arrays, + (dat->aflags & CAF_KEYS))) || + !*argv)) + arrays++; + arrays++; + if (!argv) { + ms = NULL; + argv = &ms; + } + } SWITCHBACKHEAPS(oldheap2); } + if (dat->ppre) + ppl = strlen(dat->ppre); + if (dat->psuf) + psl = strlen(dat->psuf); for (; (s = *argv); argv++) { bpl = obpl; bsl = obsl; @@ -1780,9 +1912,11 @@ addmatches(Cadata dat, char **argv) disp = NULL; } sl = strlen(s); - isalt = oisalt; - if (!isalt && (aign || pign)) { - int il = ppl + sl + psl; + if (aign || pign) { + int il = ppl + sl + psl, addit = 1; + + if (il + 1> ilen) + ibuf = (char *) zhalloc((ilen = il) + 2); if (ppl) memcpy(ibuf, dat->ppre, ppl); @@ -1796,15 +1930,21 @@ addmatches(Cadata dat, char **argv) char **pt = aign; int filell; - for (isalt = 0; !isalt && *pt; pt++) - isalt = ((filell = strlen(*pt)) < il && - !strcmp(*pt, ibuf + il - filell)); + for (; addit && *pt; pt++) + addit = !((filell = strlen(*pt)) < il && + !strcmp(*pt, ibuf + il - filell)); } - if (!isalt && pign) { + if (addit && pign) { Patprog *pt = pign; - for (isalt = 0; !isalt && *pt; pt++) - isalt = pattry(*pt, ibuf); + for (; addit && *pt; pt++) + addit = !pattry(*pt, ibuf); + } + if (!addit) { + compignored++; + if (dparr && !*++dparr) + dparr = NULL; + continue; } } if (!(dat->aflags & CAF_MATCH)) { @@ -1832,7 +1972,7 @@ addmatches(Cadata dat, char **argv) for (bp = obsl; bp; bp = bp->next) bp->curpos += bsadd; - if ((cm = add_match_data(isalt, ms, lc, dat->ipre, NULL, + if ((cm = add_match_data(0, ms, lc, dat->ipre, NULL, dat->isuf, dat->pre, dat->prpre, dat->ppre, pline, dat->psuf, sline, @@ -1854,6 +1994,24 @@ addmatches(Cadata dat, char **argv) } free_cline(lc); } + if ((dat->aflags & CAF_ARRAYS) && !argv[1]) { + Heap oldheap2; + + SWITCHHEAPS(oldheap2, oldheap) { + argv = NULL; + while (*arrays && + (!(argv = get_data_arr(*arrays, + (dat->aflags & CAF_KEYS))) || + !*argv)) + arrays++; + arrays++; + if (!argv) { + ms = NULL; + argv = &ms; + } + argv--; + } SWITCHBACKHEAPS(oldheap2); + } } if (dat->apar) set_list_array(dat->apar, aparl); @@ -1863,7 +2021,37 @@ addmatches(Cadata dat, char **argv) set_list_array(dat->dpar, dparl); if (dat->exp) addexpl(); - } SWITCHBACKHEAPS; + if (!hasallmatch && (dat->aflags & CAF_ALL)) { + Cmatch cm = (Cmatch) zhalloc(sizeof(struct cmatch)); + + memset(cm, 0, sizeof(struct cmatch)); + cm->str = dupstring("<all>"); + cm->flags = (dat->flags | CMF_ALL | + (complist ? + ((strstr(complist, "packed") ? CMF_PACKED : 0) | + (strstr(complist, "rows") ? CMF_ROWS : 0)) : 0)); + if (disp) { + if (!*++disp) + disp = NULL; + if (disp) + cm->disp = dupstring(*disp); + } else { + cm->disp = dupstring(""); + cm->flags |= CMF_DISPLINE; + } + mnum++; + ainfo->count++; + if (curexpl) + curexpl->count++; + + addlinknode(matches, cm); + + newmatches = 1; + mgroup->new = 1; + + hasallmatch = 1; + } + } SWITCHBACKHEAPS(oldheap); /* We switched back to the current heap, now restore the stack of * matchers. */ @@ -1977,7 +2165,7 @@ add_match_data(int alt, char *str, Cline line, sl = tsl; } if (qisl) { - Cline qsl = bld_parts(qisuf, qisl, qisl, NULL); + Cline qsl = bld_parts(dupstring(qisuf), qisl, qisl, NULL); qsl->flags |= CLF_SUF; qsl->suffix = qsl->prefix; @@ -2060,7 +2248,7 @@ add_match_data(int alt, char *str, Cline line, line = p; } if (qipl) { - Cline lp, p = bld_parts(qipre, qipl, qipl, &lp); + Cline lp, p = bld_parts(dupstring(qipre), qipl, qipl, &lp); lp->next = line; line = p; @@ -2175,6 +2363,8 @@ add_match_data(int alt, char *str, Cline line, newmatches = 1; mgroup->new = 1; + if (alt) + compignored++; if (!complastprompt || !*complastprompt) dolastprompt = 0; @@ -2221,7 +2411,7 @@ add_match_data(int alt, char *str, Cline line, comp_setunset(0, 0, CP_EXACTSTR, 0); } ai->exactm = cm; - } else if (useexact) { + } else if (useexact && !matcheq(cm, ai->exactm)) { ai->exact = 2; ai->exactm = NULL; if (incompfunc) @@ -2258,13 +2448,14 @@ begcmgroup(char *n, int flags) } mgroup = (Cmgroup) zhalloc(sizeof(struct cmgroup)); mgroup->name = dupstring(n); - mgroup->lcount = mgroup->llcount = mgroup->mcount = 0; + mgroup->lcount = mgroup->llcount = mgroup->mcount = mgroup->ecount = + mgroup->ccount = 0; mgroup->flags = flags; mgroup->matches = NULL; mgroup->ylist = NULL; mgroup->expls = NULL; mgroup->perm = NULL; - mgroup->new = 0; + mgroup->new = mgroup->num = mgroup->nbrbeg = mgroup->nbrend = 0; mgroup->lexpls = expls = newlinklist(); mgroup->lmatches = matches = newlinklist(); @@ -2272,7 +2463,9 @@ begcmgroup(char *n, int flags) mgroup->lallccs = allccs = ((flags & CGF_NOSORT) ? NULL : newlinklist()); - mgroup->next = amatches; + if ((mgroup->next = amatches)) + amatches->prev = mgroup; + mgroup->prev = NULL; amatches = mgroup; } @@ -2296,7 +2489,7 @@ addexpl(void) for (n = firstnode(expls); n; incnode(n)) { e = (Cexpl) getdata(n); - if (!strcmp(curexpl->str, e->str)) { + if (e->count >= 0 && !strcmp(curexpl->str, e->str)) { e->count += curexpl->count; e->fcount += curexpl->fcount; @@ -2307,6 +2500,29 @@ addexpl(void) newmatches = 1; } +/* Add a message to the current group. Make sure it is shown. */ + +/**/ +mod_export void +addmesg(char *mesg) +{ + LinkNode n; + Cexpl e; + + for (n = firstnode(expls); n; incnode(n)) { + e = (Cexpl) getdata(n); + if (e->count < 0 && !strcmp(mesg, e->str)) + return; + } + e = (Cexpl) zhalloc(sizeof(*e)); + e->count = e->fcount = -1; + e->str = dupstring(mesg); + addlinknode(expls, e); + newmatches = 1; + mgroup->new = 1; + nmessages++; +} + /* The comparison function for matches (used for sorting). */ /**/ @@ -2488,7 +2704,7 @@ dupmatch(Cmatch m, int nbeg, int nend) r->pre = ztrdup(m->pre); r->suf = ztrdup(m->suf); r->flags = m->flags; - if (nbeg) { + if (m->brpl) { int *p, *q, i; r->brpl = (int *) zalloc(nbeg * sizeof(int)); @@ -2497,7 +2713,7 @@ dupmatch(Cmatch m, int nbeg, int nend) *p = *q; } else r->brpl = NULL; - if (nend) { + if (m->brsl) { int *p, *q, i; r->brsl = (int *) zalloc(nend * sizeof(int)); @@ -2538,7 +2754,7 @@ permmatches(int last) opm = pmatches; pmatches = lmatches = NULL; - nmatches = smatches = 0; + nmatches = smatches = diffmatches = 0; if (!ainfo->count) { if (last) @@ -2570,11 +2786,14 @@ permmatches(int last) nmatches += g->mcount; smatches += g->lcount; + if (g->mcount > 1) + diffmatches = 1; + n = (Cmgroup) zcalloc(sizeof(struct cmgroup)); if (g->perm) { g->perm->next = NULL; - freematches(g->perm); + freematches(g->perm, 0); } g->perm = n; @@ -2606,6 +2825,7 @@ permmatches(int last) for (eq = g->expls; (o = *eq); eq++, ep++) { *ep = e = (Cexpl) zcalloc(sizeof(struct cexpl)); e->count = (fi ? o->fcount : o->count); + e->fcount = 0; e->str = ztrdup(o->str); } *ep = NULL; @@ -2624,18 +2844,29 @@ permmatches(int last) nmatches += g->mcount; smatches += g->lcount; + + if (g->mcount > 1) + diffmatches = 1; + g->num = gn++; } g->new = 0; g = g->next; } - for (g = pmatches; g; g = g->next) { + for (g = pmatches, p = NULL; g; g = g->next) { g->nbrbeg = nbrbeg; g->nbrend = nbrend; for (rn = 1, q = g->matches; *q; q++) { (*q)->rnum = rn++; (*q)->gnum = mn++; } + if (!diffmatches && *g->matches) { + if (p) { + if (!matcheq(*g->matches, *p)) + diffmatches = 1; + } else + p = g->matches; + } } hasperm = 1; permmnum = mn - 1; @@ -2666,8 +2897,10 @@ freematch(Cmatch m, int nbeg, int nend) zsfree(m->remf); zsfree(m->disp); zsfree(m->autoq); - zfree(m->brpl, nbeg * sizeof(int)); - zfree(m->brsl, nend * sizeof(int)); + if (m->brpl) + zfree(m->brpl, nbeg * sizeof(int)); + if (m->brsl) + zfree(m->brsl, nend * sizeof(int)); zfree(m, sizeof(m)); } @@ -2676,7 +2909,7 @@ freematch(Cmatch m, int nbeg, int nend) /**/ mod_export void -freematches(Cmgroup g) +freematches(Cmgroup g, int cm) { Cmgroup n; Cmatch *m; @@ -2687,6 +2920,7 @@ freematches(Cmgroup g) for (m = g->matches; *m; m++) freematch(*m, g->nbrbeg, g->nbrend); + free(g->matches); if (g->ylist) freearray(g->ylist); @@ -2704,4 +2938,6 @@ freematches(Cmgroup g) g = n; } + if (cm) + minfo.cur = NULL; } diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 9de491a4a..e6b8cfff7 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -2359,6 +2359,8 @@ expandorcompleteprefix(char **args) comppref = 1; ret = expandorcomplete(args); + if (cs && line[cs - 1] == ' ') + makesuffixstr(NULL, "\\-", 0); comppref = 0; return ret; } |