diff options
author | Tanaka Akira <akr@users.sourceforge.net> | 1999-09-22 13:22:05 +0000 |
---|---|---|
committer | Tanaka Akira <akr@users.sourceforge.net> | 1999-09-22 13:22:05 +0000 |
commit | 5b061d74c20e153e166086f5c22ea62ef4f5a475 (patch) | |
tree | c62d76bda037df99c54e20e4936a49c1c57c52cd /Src/Zle/complist.c | |
parent | 6276757fe911f692e5a6fdd192ae3ea768d8e359 (diff) | |
download | zsh-5b061d74c20e153e166086f5c22ea62ef4f5a475.tar.gz zsh-5b061d74c20e153e166086f5c22ea62ef4f5a475.tar.xz zsh-5b061d74c20e153e166086f5c22ea62ef4f5a475.zip |
zsh-workers/7998
Diffstat (limited to 'Src/Zle/complist.c')
-rw-r--r-- | Src/Zle/complist.c | 560 |
1 files changed, 166 insertions, 394 deletions
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c index 55e78c0cb..25fea68e1 100644 --- a/Src/Zle/complist.c +++ b/Src/Zle/complist.c @@ -317,434 +317,198 @@ putcolstr(Listcols c, char *n, mode_t m) static int noselect, mselect, inselect, mcol, mline, mcols, mlines; static Cmatch *mmatch, **mtab; static Cmgroup mgroup, *mgtab; +static struct listcols mcolors; -/* List the matches. Most of this is just taken from ilistmatches(), - * of course. */ + +static void +clprintm(Cmgroup g, Cmatch *mp, int mc, int ml, int lastc, int width, + char *path, struct stat *buf) +{ + Cmatch m; + int len, cc; + + if (!mp) { + zcputs(&mcolors, COL_MI); + len = width - 2; + while (len-- > 0) + putc(' ', shout); + if (mcolors.cols[COL_EC]) + tputs(mcolors.cols[COL_EC], 1, putshout); + else + zcputs(&mcolors, COL_NO); + + return; + } + m = *mp; + if (m->disp && (m->flags & CMF_DISPLINE)) { + if (mselect >= 0) { + int mm = (mcols * ml) + (mcols >> 1); + + mtab[mm] = mp; + mgtab[mm] = g; + } + if (m->gnum == mselect) { + mline = ml; + mmatch = mp; + mgroup = g; + cc = COL_MA; + } else + cc = COL_NO; + zcputs(&mcolors, cc); + printfmt(m->disp, 0, 1, 0); + if (mcolors.cols[COL_EC]) + tputs(mcolors.cols[COL_EC], 1, putshout); + else + zcputs(&mcolors, COL_NO); + } else { + int mx; + + if (g->widths) { + int i; + + for (i = mx = 0; i < mc; i++) + mx += g->widths[i]; + } else + mx = mc * g->width; + mx += (width >> 1); + + if (mselect >= 0) { + int mm = mcols * ml; + + mtab[mx + mm] = mp; + mgtab[mx + mm] = g; + } + if (m->gnum == mselect) { + mcol = mx; + mline = ml; + mmatch = mp; + mgroup = g; + zcputs(&mcolors, COL_MA); + } else if (buf) + putcolstr(&mcolors, path, buf->st_mode); + else + zcputs(&mcolors, COL_NO); + + nicezputs((m->disp ? m->disp : m->str), shout); + len = niceztrlen(m->disp ? m->disp : m->str); + + if (isset(LISTTYPES)) { + if (buf) + putc(file_type(buf->st_mode), shout); + else + putc(' ', shout); + len++; + } + len = width - len - 2; + + while (len-- > 0) + putc(' ', shout); + + if (mcolors.cols[COL_EC]) + tputs(mcolors.cols[COL_EC], 1, putshout); + else + zcputs(&mcolors, COL_NO); + if (!lastc) { + zcputs(&mcolors, COL_NO); + fputs(" ", shout); + if (mcolors.cols[COL_EC]) + tputs(mcolors.cols[COL_EC], 1, putshout); + else + zcputs(&mcolors, COL_NO); + } + } +} static int complistmatches(Hookdef dummy, Chdata dat) { - Cmgroup amatches = dat->matches, g; - Cmatch *p, m; - Cexpl *e; - int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0, opl = 0; - int of = isset(LISTTYPES), cf; - int mc, ml = 0, cc, hasm = 0, cl = -1; - struct listcols col; + Cmgroup oamatches = amatches; + + amatches = dat->matches; if (minfo.asked == 2) { showinglist = 0; + amatches = oamatches; return (noselect = 1); } - getcols(&col); - - for (g = amatches; g; g = g->next) { - char **pp = g->ylist; - int nl = 0, l; - - if (pp) { - /* We have an ylist, lets see, if it contains newlines. */ - while (!nl && *pp) - nl = !!strchr(*pp++, '\n'); - - pp = g->ylist; - if (nl || !pp[1]) { - /* Yup, there are newlines, count lines. */ - char *nlptr, *sptr; - - g->flags |= CGF_LINES; - noselect = 1; - while ((sptr = *pp)) { - while (sptr && *sptr) { - nlines += (nlptr = strchr(sptr, '\n')) - ? 1 + (nlptr-sptr)/columns - : strlen(sptr)/columns; - sptr = nlptr ? nlptr+1 : NULL; - } - nlines++; - pp++; - } - nlines--; - } else { - while (*pp) { - if ((l = strlen(*pp)) > longest) - longest = l; - nlist++; - pp++; - } - } - } else { - for (p = g->matches; (m = *p); p++) { - if (m->disp) { - if (m->flags & CMF_DISPLINE) { - nlines += 1 + printfmt(m->disp, 0, 0, 0); - g->flags |= CGF_HASDL; - } else if ((l = niceztrlen(m->disp)) > longest) - longest = l; - nlist++; - } else if (!(m->flags & CMF_NOLIST)) { - if ((l = niceztrlen(m->str)) > longest) - longest = l; - nlist++; - } else - noselect = 1; - } - } - if ((e = g->expls)) { - while (*e) { - if ((*e)->count) - nlines += 1 + printfmt((*e)->str, (*e)->count, 0, 1); - e++; - } - } - } - longest += 2 + of; - if ((ncols = columns / longest)) { - for (g = amatches; g; g = g->next) - nlines += (g->lcount - g->llcount + ncols - 1) / ncols; - } else { - ncols = 1; - opl = 1; - for (g = amatches; g; g = g->next) { - char **pp = g->ylist; - - if (pp) { - if (!(g->flags & CGF_LINES)) { - while (*pp) { - nlines += 1 + (strlen(*pp) / columns); - pp++; - } - } - } else - for (p = g->matches; (m = *p); p++) - if (m->disp) { - if (m->flags & CMF_DISPLINE) - nlines += 1 + printfmt(m->disp, 0, 0, 0); - else - nlines += 1 + (niceztrlen(m->disp) / columns); - } else if (!(m->flags & CMF_NOLIST)) - nlines += 1 + ((1 + niceztrlen(m->str)) / columns); - } - } - cf = (isset(USEZLE) && !termflags && complastprompt && *complastprompt); - if (!nlines || (mselect >= 0 && (!cf || (nlines + nlnct - 1) >= lines))) { + getcols(&mcolors); + + calclist(); + + if (!listdat.nlines || (mselect >= 0 && + (!(isset(USEZLE) && !termflags && + complastprompt && *complastprompt) || + (listdat.nlines + nlnct - 1) >= lines))) { showinglist = listshown = 0; noselect = 1; + amatches = oamatches; return 1; } - /* Set the cursor below the prompt. */ + if (listdat.hidden) { + noselect = 1; + mselect = -1; + } if (inselect) clearflag = 0; - trashzle(); - showinglist = listshown = 0; - - clearflag = cf; - - /* Maybe we have to ask if the user wants to see the list. */ - if ((!minfo.cur || !minfo.asked) && - ((complistmax && nlist > complistmax) || - (!complistmax && nlines >= lines))) { - int qup; - zsetterm(); - qup = printfmt("zsh: do you wish to see all %n possibilities? ", nlist, 1, 1); - fflush(shout); - if (getzlequery() != 'y') { - if (clearflag) { - putc('\r', shout); - tcmultout(TCUP, TCMULTUP, qup); - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - tcmultout(TCUP, TCMULTUP, nlnct); - } else - putc('\n', shout); - noselect = 1; - if (minfo.cur) - minfo.asked = 2; - return 1; - } - if (clearflag) { - putc('\r', shout); - tcmultout(TCUP, TCMULTUP, qup); - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } else - putc('\n', shout); - settyinfo(&shttyinfo); - if (minfo.cur) - minfo.asked = 1; + + if (asklist()) { + amatches = oamatches; + return 1; } if (mselect >= 0) { int i; - i = ncols * nlines; + i = columns * listdat.nlines; free(mtab); mtab = (Cmatch **) zalloc(i * sizeof(Cmatch **)); memset(mtab, 0, i * sizeof(Cmatch **)); free(mgtab); mgtab = (Cmgroup *) zalloc(i * sizeof(Cmgroup)); memset(mgtab, 0, i * sizeof(Cmgroup)); - mcols = ncols; - mlines = cl = nlines; - if (cl < 2) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } + mcols = columns; + mlines = listdat.nlines; } - /* Now print the matches. */ last_col = COL_NO - 1; - g = amatches; - while (g) { - char **pp = g->ylist; - if ((e = g->expls)) { - int l; - - while (*e) { - if ((*e)->count) { - if (pnl) { - putc('\n', shout); - pnl = 0; - ml++; - if (cl >= 0 && --cl <= 1) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } - } - l = printfmt((*e)->str, (*e)->count, 1, 1); - ml += l; - if (cl >= 0 && (cl -= l) <= 1) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } - pnl = 1; - } - e++; - } - } - if (pp && *pp) { - if (pnl) { - putc('\n', shout); - pnl = 0; - ml++; - if (cl >= 0 && --cl <= 1) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } - } - if (g->flags & CGF_LINES) { - while (*pp) { - zputs(*pp, shout); - if (*++pp) - putc('\n', shout); - } - } else { - int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, a; - char **pq; - - while (n && nl--) { - i = ncols; - mc = 0; - pq = pp; - while (n && i--) { - if (pq - g->ylist >= g->lcount) - break; - zputs(*pq, shout); - if (i) { - a = longest - strlen(*pq); - while (a--) - putc(' ', shout); - } - pq += nc; - n--; - } - if (n) { - putc('\n', shout); - ml++; - if (cl >= 0 && --cl <= 1) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } - } - pp++; - } - } - } else if (g->lcount) { - int n = g->lcount - g->llcount, nl = (n + ncols - 1) / ncols; - int nc = nl, i, j, a = 0; - int zt; - Cmatch *q; - - if (g->flags & CGF_HASDL) { - for (p = g->matches; (m = *p); p++) - if (m->disp && (m->flags & CMF_DISPLINE)) { - if (pnl) { - putc('\n', shout); - pnl = 0; - ml++; - if (cl >= 0 && --cl <= 1) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } - } - hasm = 1; - if (mselect >= 0) { - for (i = 0; i < ncols; i++) { - mtab[i + (ncols * ml)] = p; - mgtab[i + (ncols * ml)] = g; - } - } - if (m->gnum == mselect) { - mline = ml; - mmatch = p; - mgroup = g; - cc = COL_MA; - } else - cc = COL_NO; - zcputs(&col, cc); - printfmt(m->disp, 0, 1, 0); - if (col.cols[COL_EC]) - tputs(col.cols[COL_EC], 1, putshout); - else - zcputs(&col, COL_NO); - pnl = 1; - } - } - if (n && pnl) { - putc('\n', shout); - pnl = 0; - ml++; - if (cl >= 0 && --cl <= 1) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } - } - for (p = skipnolist(g->matches); n && nl--;) { - i = ncols; - mc = 0; - q = p; - while (n && i--) { - if (!(m = *q)) { - zcputs(&col, COL_MI); - a = longest - 2; - while (a--) - putc(' ', shout); - if (col.cols[COL_EC]) - tputs(col.cols[COL_EC], 1, putshout); - else - zcputs(&col, COL_NO); - break; - } - hasm = 1; - if (mselect >= 0) { - mtab[mc + (ncols * ml)] = q; - mgtab[mc + (ncols * ml)] = g; - } - if (m->gnum == mselect) { - mcol = mc; - mline = ml; - mmatch = q; - mgroup = g; - cc = COL_MA; - } else - cc = -1; - if (!m->disp && m->flags & CMF_FILE) { - struct stat buf; - char *pb; - - pb = (char *) zhalloc((m->prpre ? strlen(m->prpre) : 0) + - 3 + strlen(m->str)); - sprintf(pb, "%s%s", (m->prpre ? m->prpre : "./"), - m->str); - - zt = ztat(pb, &buf, 1); - if (cc >= 0) - zcputs(&col, cc); - else if (zt) - zcputs(&col, COL_NO); - else - putcolstr(&col, pb, buf.st_mode); - nicezputs(m->str, shout); - if (zt) - putc(' ', shout); - else - putc(file_type(buf.st_mode), shout); - } else { - zcputs(&col, cc >= 0 ? cc : COL_NO); - nicezputs((m->disp ? m->disp : m->str), shout); - if (of) - putc(' ', shout); - } - a = longest - niceztrlen(m->disp ? m->disp : m->str) - 2 - of; - while (a-- > 0) - putc(' ', shout); - if (col.cols[COL_EC]) - tputs(col.cols[COL_EC], 1, putshout); - else - zcputs(&col, COL_NO); - if (i) { - zcputs(&col, COL_NO); - fputs(" ", shout); - if (col.cols[COL_EC]) - tputs(col.cols[COL_EC], 1, putshout); - else - zcputs(&col, COL_NO); - } - if (--n) - for (j = nc; j && *q; j--) - q = skipnolist(q + 1); - mc++; - } - if (i > 0) { - zcputs(&col, COL_MI); - a = longest - 2; - while (a--) - putc(' ', shout); - if (col.cols[COL_EC]) - tputs(col.cols[COL_EC], 1, putshout); - else - zcputs(&col, COL_NO); - } - if (n) { - putc('\n', shout); - ml++; - if (cl >= 0 && --cl <= 1) { - cl = -1; - if (tccan(TCCLEAREOD)) - tcout(TCCLEAREOD); - } - if (n && nl) - p = skipnolist(p + 1); - } - } - } - if (g->lcount) - pnl = 1; - g = g->next; - } - if (clearflag) { - /* Move the cursor up to the prompt, if always_last_prompt * - * is set and all that... */ - if ((nlines += nlnct - 1) < lines) { - tcmultout(TCUP, TCMULTUP, nlines); - showinglist = -1; - } else - clearflag = 0, putc('\n', shout); - } else - putc('\n', shout); - listshown = (clearflag ? 1 : -1); - if (!hasm || nlines >= lines) + if (!printlist(1, clprintm) || listdat.nlines >= lines) noselect = 1; + amatches = oamatches; + return noselect; } +static int +adjust_mcol(Cmatch ***tabp, Cmgroup **grp) +{ + Cmatch **tab = *tabp; + int p, n, c; + + tab -= mcol; + + for (p = mcol; p >= 0 && !tab[p]; p--); + for (n = mcol; n < mcols && !tab[n]; n++); + if (n == mcols) + n = -1; + + if (p < 0) { + if (n < 0) + return 1; + c = n; + } else if (n < 0) + c = p; + else + c = ((mcol - p) < (n - mcol) ? p : n); + + *tabp = tab + c; + if (grp) + *grp = *grp + c - mcol; + + mcol = c; + + return 0; +} + typedef struct menustack *Menustack; struct menustack { @@ -887,6 +651,8 @@ domenuselect(Hookdef dummy, Chdata dat) mline++; p += mcols; } + if (adjust_mcol(&p, NULL)) + continue; } while (!*p); } else if (cmd == Th(z_uphistory) || cmd == Th(z_uplineorhistory) || @@ -900,6 +666,8 @@ domenuselect(Hookdef dummy, Chdata dat) mline--; p -= mcols; } + if (adjust_mcol(&p, NULL)) + continue; } while (!*p); } else if (cmd == Th(z_forwardchar) || cmd == Th(z_viforwardchar)) { do { @@ -958,6 +726,8 @@ domenuselect(Hookdef dummy, Chdata dat) p += mcols; pg += mcols; } + if (adjust_mcol(&p, &pg)) + continue; } while (ol != mline && (*pg == g || !*pg)); } else if (cmd == Th(z_backwardword) || cmd == Th(z_emacsbackwardword) || @@ -975,6 +745,8 @@ domenuselect(Hookdef dummy, Chdata dat) p -= mcols; pg -= mcols; } + if (adjust_mcol(&p, &pg)) + continue; } while (ol != mline && (*pg == g || !*pg)); } else if (cmd == Th(z_completeword) || cmd == Th(z_expandorcomplete) || |