From 346825df86466cf151be61b9429ef2c1734e66ea Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Sun, 27 Jun 1999 05:33:04 +0000 Subject: zsh-3.1.5-pws-24 --- Src/Zle/.distfiles | 1 + Src/Zle/comp.h | 25 ++ Src/Zle/compctl.c | 14 +- Src/Zle/complist.c | 918 ++++++++++++++++++++++++++++++++++++++++++++++++++ Src/Zle/complist.mdd | 3 + Src/Zle/deltochar.c | 7 +- Src/Zle/iwidgets.list | 1 + Src/Zle/zle.export | 34 ++ Src/Zle/zle.h | 25 +- Src/Zle/zle_hist.c | 467 ++++++++++++++----------- Src/Zle/zle_keymap.c | 65 ++-- Src/Zle/zle_main.c | 79 +++-- Src/Zle/zle_misc.c | 241 +++++++------ Src/Zle/zle_move.c | 248 +++++++------- Src/Zle/zle_params.c | 22 +- Src/Zle/zle_refresh.c | 10 +- Src/Zle/zle_thingy.c | 111 ++++-- Src/Zle/zle_tricky.c | 602 +++++++++++++++++++-------------- Src/Zle/zle_utils.c | 45 +-- Src/Zle/zle_vi.c | 371 ++++++++++---------- Src/Zle/zle_word.c | 194 ++++++----- 21 files changed, 2409 insertions(+), 1074 deletions(-) create mode 100644 Src/Zle/complist.c create mode 100644 Src/Zle/complist.mdd (limited to 'Src/Zle') diff --git a/Src/Zle/.distfiles b/Src/Zle/.distfiles index 9dbf27758..add8f8466 100644 --- a/Src/Zle/.distfiles +++ b/Src/Zle/.distfiles @@ -2,6 +2,7 @@ DISTFILES_SRC=' .cvsignore .distfiles .exrc comp1.mdd comp.h comp1.c comp1.export compctl.mdd compctl.c + complist.mdd complist.c deltochar.mdd deltochar.c zle.mdd iwidgets.list zle.h zle_bindings.c zle_hist.c zle_keymap.c zle_main.c zle_misc.c zle_move.c zle_params.c diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h index bf3ea816f..8264890df 100644 --- a/Src/Zle/comp.h +++ b/Src/Zle/comp.h @@ -36,6 +36,7 @@ typedef struct patcomp *Patcomp; typedef struct cmatcher *Cmatcher; typedef struct cmlist *Cmlist; typedef struct cpattern *Cpattern; +typedef struct menuinfo *Menuinfo; /* node for compctl hash table (compctltab) */ @@ -266,6 +267,19 @@ struct cpattern { #define CFN_FIRST 1 #define CFN_DEFAULT 2 +/* Information about menucompletion stuff. */ + +struct menuinfo { + Cmgroup group; /* position in the group list */ + Cmatch *cur; /* match currently inserted */ + int pos; /* begin on line */ + int len; /* length of inserted string */ + int end; /* end on the line */ + int we; /* non-zero if the cursor was at the end */ + int insc; /* length of suffix inserted */ + int asked; /* we asked if the list should be shown */ +}; + /* Flags for compadd and addmatches(). */ #define CAF_QUOTE 1 @@ -286,6 +300,7 @@ struct cadata { char *pre; /* prefix to insert (-P) */ char *suf; /* suffix to insert (-S) */ char *group; /* name of the group (-[JV]) */ + char *ylist; /* display list (-y) */ char *rems; /* remove suffix on chars... (-r) */ char *remf; /* function to remove suffix (-R) */ char *ign; /* ignored suffixes (-F) */ @@ -298,6 +313,16 @@ struct cadata { char *dpar; /* array to delete non-matches in (-D) */ }; +/* Data given to hooks. */ + +typedef struct chdata *Chdata; + +struct chdata { + Cmgroup matches; /* the matches generated */ + int num; /* the number of matches */ + Cmatch cur; /* current match or NULL */ +}; + /* Flags for special parameters. */ #define CPN_WORDS 0 diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c index c5b24714e..2b426492e 100644 --- a/Src/Zle/compctl.c +++ b/Src/Zle/compctl.c @@ -1727,7 +1727,7 @@ bin_compadd(char *name, char **argv, char *ops, int func) } 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.ign = dat.exp = dat.apar = dat.opar = dat.dpar = dat.ylist = NULL; dat.match = NULL; dat.flags = 0; dat.aflags = CAF_MATCH; @@ -1779,6 +1779,10 @@ bin_compadd(char *name, char **argv, char *ops, int func) sp = &(dat.group); e = "group name expected after -%c"; break; + case 'y': + sp = &(dat.ylist); + e = "string expected after -%c"; + break; case 'i': sp = &(dat.ipre); e = "string expected after -%c"; @@ -2217,13 +2221,14 @@ static void addcompparams(struct compparam *cp, Param *pp) { for (; cp->name; cp++, pp++) { - Param pm = createparam(cp->name, cp->type | PM_SPECIAL | PM_REMOVABLE); + Param pm = createparam(cp->name, + cp->type |PM_SPECIAL|PM_REMOVABLE|PM_LOCAL); if (!pm) pm = (Param) paramtab->getnode(paramtab, cp->name); DPUTS(!pm, "param not set in addcompparams"); *pp = pm; - pm->level = locallevel; + pm->level = locallevel + 1; if ((pm->u.data = cp->var)) { switch(PM_TYPE(cp->type)) { case PM_SCALAR: @@ -2257,7 +2262,8 @@ makecompparams(void) addcompparams(comprparams, comprpms); - if (!(cpm = createparam(COMPSTATENAME, PM_SPECIAL|PM_REMOVABLE|PM_HASHED))) + if (!(cpm = createparam(COMPSTATENAME, + PM_SPECIAL|PM_REMOVABLE|PM_LOCAL|PM_HASHED))) cpm = (Param) paramtab->getnode(paramtab, COMPSTATENAME); DPUTS(!cpm, "param not set in makecompparams"); diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c new file mode 100644 index 000000000..63bc4c6e3 --- /dev/null +++ b/Src/Zle/complist.c @@ -0,0 +1,918 @@ +/* + * complist.c - completion listing enhancements + * + * This file is part of zsh, the Z shell. + * + * Copyright (c) 1999 Sven Wischnowsky + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Sven Wischnowsky or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Sven Wischnowsky and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Sven Wischnowsky and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Sven Wischnowsky and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + +#include "complist.mdh" +#include "complist.pro" + + +/* We use the parameters ZLS_COLORS and ZLS_COLOURS in the same way as + * the color ls does. It's just that we don't support the `or' file + * type. */ + + +static Widget w_menuselect; +static Keymap mskeymap; + +/* Indixes into the terminal string arrays. */ + +#define COL_NO 0 +#define COL_FI 1 +#define COL_DI 2 +#define COL_LN 3 +#define COL_PI 4 +#define COL_SO 5 +#define COL_BD 6 +#define COL_CD 7 +#define COL_EX 8 +#define COL_MI 9 +#define COL_LC 10 +#define COL_RC 11 +#define COL_EC 12 +#define COL_MA 13 + +#define NUM_COLS 14 + +/* Names of the terminal strings. */ + +static char *colnames[] = { + "no", "fi", "di", "ln", "pi", "so", "bd", "cd", "ex", "mi", + "lc", "rc", "ec", "ma", NULL +}; + +/* Default values. */ + +static char *defcols[] = { + "0", "0", "1;34", "1;36", "33", "1;35", "1;33", "1;33", "1;32", NULL, + "\033[", "m", NULL, "7" +}; + +/* This describes a terminal string for a filename extension. */ + +typedef struct extcol *Extcol; + +struct extcol { + char *ext; /* the extension */ + char *col; /* the terminal color string */ + Extcol next; /* the next one in the list */ +}; + +/* This holds all terminal strings. */ + +typedef struct listcols *Listcols; + +struct listcols { + char *cols[NUM_COLS]; /* strings for file types */ + Extcol exts; /* strings for extensions */ +}; + +/* This parses the value of a definition (the part after the `='). + * The return value is a pointer to the character after it. */ + +static char * +getcolval(char *s) +{ + char *p; + + for (p = s; *s && *s != ':'; p++, s++) { + if (*s == '\\' && s[1]) { + switch (*++s) { + case 'a': *p = '\007'; break; + case 'n': *p = '\n'; break; + case 'b': *p = '\b'; break; + case 't': *p = '\t'; break; + case 'v': *p = '\v'; break; + case 'f': *p = '\f'; break; + case 'r': *p = '\r'; break; + case 'e': *p = '\033'; break; + case '_': *p = ' '; break; + case '?': *p = '\177'; break; + default: + if (*s >= '0' && *s <= '7') { + int i = STOUC(*s); + + if (*++s >= '0' && *s <= '7') { + i = (i * 8) + STOUC(*s); + if (*++s >= '0' && *s <= '7') + i = (i * 8) + STOUC(*s); + } + *p = (char) i; + } else + *p = *s; + } + } else if (*s == '^') { + if ((s[1] >= '@' && s[1] <= '_') || + (s[1] >= 'a' && s[1] <= 'z')) + *p = (char) (STOUC(*s) & ~0x60); + else if (s[1] == '?') + *p = '\177'; + else { + *p++ = *s; + *p = s[1]; + } + s++; + } else + *p = *s; + } + if (p != s) + *p = '\0'; + return s; +} + +/* This parses one definition. Return value is a pointer to the + * character after it. */ + +static char * +getcoldef(Listcols c, char *s) +{ + if (*s == '*') { + Extcol ec; + char *n, *p; + + /* This is for an extension. */ + + n = ++s; + while (*s && *s != '=') + s++; + if (!*s ) + return s; + *s++ = '\0'; + p = getcolval(s); + if (*n) { + ec = (Extcol) zhalloc(sizeof(*ec)); + ec->ext = n; + ec->col = s; + ec->next = c->exts; + c->exts = ec; + } + if (*p) + *p++ = '\0'; + return p; + } else { + char *n = s, *p, **nn; + int i; + + /* This is for a file type. */ + + while (*s && *s != '=') + s++; + if (!*s) + return s; + *s++ = '\0'; + for (i = 0, nn = colnames; *nn; i++, nn++) + if (!strcmp(n ,*nn)) + break; + p = getcolval(s); + if (*nn) + c->cols[i] = s; + if (*p) + *p++ = '\0'; + return p; + } +} + +/* This initializes the given terminal color structure. */ + +static int +getcols(Listcols c) +{ + char *s; + int i; + + if (!(s = getsparam("ZLS_COLORS")) && + !(s = getsparam("ZLS_COLOURS"))) { + if (!c) + return 1; + for (i = 0; i < NUM_COLS; i++) + c->cols[i] = ""; + + c->exts = NULL; + return 1; + } + if (!c) + return 0; + /* We have one of the parameters, use it. */ + memset(c, 0, sizeof(*c)); + s = dupstring(s); + while (*s) + s = getcoldef(c, s); + + /* Use default values for those that aren't set explicitly. */ + for (i = 0; i < NUM_COLS; i++) + if (!c->cols[i]) + c->cols[i] = defcols[i]; + /* Default for missing files. */ + if (!c->cols[COL_MI]) + c->cols[COL_MI] = c->cols[COL_FI]; + + if (!c->cols[COL_EC]) { + char *e = (char *) zhalloc(strlen(c->cols[COL_LC]) + + strlen(c->cols[COL_NO]) + + strlen(c->cols[COL_RC]) + 1); + + /* If no `ec' was given, we is `' as the default. */ + strcpy(e, c->cols[COL_LC]); + strcat(e, c->cols[COL_NO]); + strcat(e, c->cols[COL_RC]); + c->cols[COL_EC] = e; + } + return 0; +} + +/* Get the terminal color string for the file with the given name and + * file modes. */ + +static char * +getcolstr(Listcols c, char *n, mode_t m) +{ + Extcol e; + + for (e = c->exts; e; e = e->next) + if (strsfx(e->ext, n)) + return e->col; + + if (S_ISDIR(m)) + return c->cols[COL_DI]; + else if (S_ISLNK(m)) + return c->cols[COL_LN]; + else if (S_ISFIFO(m)) + return c->cols[COL_PI]; + else if (S_ISSOCK(m)) + return c->cols[COL_SO]; + else if (S_ISBLK(m)) + return c->cols[COL_BD]; + else if (S_ISCHR(m)) + return c->cols[COL_CD]; + else if (S_ISREG(m) && (m & S_IXUGO)) + return c->cols[COL_EX]; + + return c->cols[COL_FI]; +} + +/* Information about the list shown. */ + +static int noselect, mselect, inselect, mcol, mline, mcols, mlines; +static Cmatch *mmatch, **mtab; +static Cmgroup mgroup, *mgtab; + +/* List the matches. Most of this is just taken from ilistmatches(), + * of course. */ + +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); + int mc, ml = 0, cc, hasm = 0; + struct listcols col; + + if (minfo.asked == 2) { + showinglist = 0; + return (noselect = 1); + } + getcols(&col); + + /* Set the cursor below the prompt. */ + if (inselect) + clearflag = 0; + trashzle(); + showinglist = listshown = 0; + + clearflag = (isset(USEZLE) && !termflags && + complastprompt && *complastprompt); + + for (g = amatches; g; g = g->next) { + char **pp = g->ylist; + int nl = 0, l; + + if (pp) { + /* We have an ylist, lets see, if it contains newlines. */ + while (!nl && *pp) + nl = !!strchr(*pp++, '\n'); + + pp = g->ylist; + if (nl) { + /* 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->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); + e++; + } + } + } + longest += 2 + of; + if ((ncols = (columns + 1) / longest)) { + for (g = amatches; g; g = g->next) + nlines += (g->lcount + 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->flags & CMF_NOLIST)) + nlines += 1 + ((1 + niceztrlen(m->str)) / columns); + } + } + + /* 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); + 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 (mselect >= 0) { + int i; + + i = ncols * 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 = nlines; + } + /* Now print the matches. */ + g = amatches; + while (g) { + char **pp = g->ylist; + + if ((e = g->expls)) { + while (*e) { + if ((*e)->count) { + if (pnl) { + putc('\n', shout); + pnl = 0; + ml++; + } + ml += printfmt((*e)->str, (*e)->count, 1); + pnl = 1; + } + e++; + } + } + if (pp && *pp) { + if (pnl) { + putc('\n', shout); + pnl = 0; + ml++; + } + 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++; + } + pp++; + } + } + } else if (g->lcount) { + int n = g->lcount, nl = (n + ncols - 1) / ncols, nc = nl, i, j, a = 0; + int zt; + Cmatch *q; + + if (n && pnl) { + putc('\n', shout); + pnl = 0; + ml++; + } + for (p = skipnolist(g->matches); n && nl--;) { + i = ncols; + mc = 0; + q = p; + while (n && i--) { + fputs(col.cols[COL_LC], shout); + if (!(m = *q)) { + fputs(col.cols[COL_MI], shout); + fputs(col.cols[COL_RC], shout); + a = longest - 2; + while (a--) + putc(' ', shout); + fputs(col.cols[COL_EC], shout); + 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->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) + fputs(col.cols[cc], shout); + else if (zt) + fputs(col.cols[COL_NO], shout); + else + fputs(getcolstr(&col, pb, buf.st_mode), shout); + fputs(col.cols[COL_RC], shout); + nicezputs(m->str, shout); + if (zt) + putc(' ', shout); + else + putc(file_type(buf.st_mode), shout); + } else { + fputs(col.cols[cc >= 0 ? cc : COL_NO], shout); + fputs(col.cols[COL_RC], shout); + nicezputs(m->str, shout); + if (of) + putc(' ', shout); + } + a = longest - niceztrlen(m->str) - 2 - of; + while (a--) + putc(' ', shout); + fputs(col.cols[COL_EC], shout); + if (i) { + fputs(col.cols[COL_LC], shout); + fputs(col.cols[COL_NO], shout); + fputs(col.cols[COL_RC], shout); + fputs(" ", shout); + fputs(col.cols[COL_EC], shout); + } + if (--n) + for (j = nc; j && *q; j--) + q = skipnolist(q + 1); + mc++; + } + if (i > 0) { + fputs(col.cols[COL_LC], shout); + fputs(col.cols[COL_MI], shout); + fputs(col.cols[COL_RC], shout); + a = longest - 2; + while (a--) + putc(' ', shout); + fputs(col.cols[COL_EC], shout); + } + if (n) { + putc('\n', shout); + ml++; + 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; + listshown = 1; + } else + clearflag = 0, putc('\n', shout); + } else + putc('\n', shout); + if (!hasm || nlines >= lines) + noselect = 1; + return noselect; +} + +typedef struct menustack *Menustack; + +struct menustack { + Menustack prev; + char *line; + int cs; + struct menuinfo info; +}; + +static int +domenuselect(Hookdef dummy, Chdata dat) +{ + Cmatch **p; + Cmgroup *pg; + Thingy cmd; + Menustack u = NULL; + int i = 0; + char *s; + + if (getcols(NULL) || (dummy && (!(s = getsparam("SELECTMIN")) || + (dat && dat->num < atoi(s))))) + return 1; + + selectlocalmap(mskeymap); + noselect = 0; + mselect = (*(minfo.cur))->gnum; + for (;;) { + showinglist = -2; + zrefresh(); + inselect = 1; + if (noselect) + break; + if (!i) { + i = mcols * mlines; + while (i--) + if (mtab[i]) + break; + if (!i) + break; + i = 1; + } + p = mtab + mcol + (mline * mcols); + pg = mgtab + mcol + (mline * mcols); + minfo.cur = *p; + minfo.group = *pg; + + getk: + + if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak) || + cmd == Th(z_acceptline)) + break; + else if (cmd == Th(z_acceptandhold) || + cmd == Th(z_acceptandmenucomplete)) { + Menustack s = (Menustack) zhalloc(sizeof(*s)); + + s->prev = u; + u = s; + s->line = dupstring((char *) line); + s->cs = cs; + memcpy(&(s->info), &minfo, sizeof(struct menuinfo)); + acceptlast(); + do_menucmp(0); + mselect = (*(minfo.cur))->gnum; + continue; + } else if (cmd == Th(z_undo)) { + int l; + + if (!u) + goto getk; + + cs = 0; + foredel(ll); + spaceinline(l = strlen(u->line)); + strncpy((char *) line, u->line, l); + cs = u->cs; + memcpy(&minfo, &(u->info), sizeof(struct menuinfo)); + p = &(minfo.cur); + u = u->prev; + } else if (cmd == Th(z_redisplay)) { + redisplay(zlenoargs); + continue; + } else if (cmd == Th(z_clearscreen)) { + clearscreen(zlenoargs); + continue; + } else if (cmd == Th(z_downhistory) || + cmd == Th(z_downlineorhistory) || + cmd == Th(z_downlineorsearch) || + cmd == Th(z_vidownlineorhistory)) { + do { + if (mline == mlines - 1) { + p -= mline * mcols; + mline = 0; + } else { + mline++; + p += mcols; + } + } while (!*p); + } else if (cmd == Th(z_uphistory) || + cmd == Th(z_uplineorhistory) || + cmd == Th(z_uplineorsearch) || + cmd == Th(z_viuplineorhistory)) { + do { + if (!mline) { + mline = mlines - 1; + p += mline * mcols; + } else { + mline--; + p -= mcols; + } + } while (!*p); + } else if (cmd == Th(z_forwardchar) || cmd == Th(z_viforwardchar)) { + do { + if (mcol == mcols - 1) { + p -= mcol; + mcol = 0; + } else { + mcol++; + p++; + } + } while (!*p); + } else if (cmd == Th(z_backwardchar) || cmd == Th(z_vibackwardchar)) { + do { + if (!mcol) { + mcol = mcols - 1; + p += mcol; + } else { + mcol--; + p--; + } + } while (!*p); + } else if (cmd == Th(z_beginningofbufferorhistory) || + cmd == Th(z_beginningofline) || + cmd == Th(z_beginningoflinehist) || + cmd == Th(z_vibeginningofline)) { + p -= mcol; + mcol = 0; + while (!*p) { + mcol++; + p++; + } + } else if (cmd == Th(z_endofbufferorhistory) || + cmd == Th(z_endofline) || + cmd == Th(z_endoflinehist) || + cmd == Th(z_viendofline)) { + p += mcols - mcol - 1; + mcol = mcols - 1; + while (!*p) { + mcol--; + p--; + } + } else if (cmd == Th(z_forwardword) || + cmd == Th(z_emacsforwardword) || + cmd == Th(z_viforwardword) || + cmd == Th(z_viforwardwordend)) { + Cmgroup g = *pg; + int ol = mline; + + do { + if (mline == mlines - 1) { + p -= mline * mcols; + pg -= mline * mcols; + mline = 0; + } else { + mline++; + p += mcols; + pg += mcols; + } + } while (ol != mline && (*pg == g || !*pg)); + } else if (cmd == Th(z_backwardword) || + cmd == Th(z_emacsbackwardword) || + cmd == Th(z_vibackwardword)) { + Cmgroup g = *pg; + int ol = mline; + + do { + if (!mline) { + mline = mlines - 1; + p += mline * mcols; + pg += mline * mcols; + } else { + mline--; + p -= mcols; + pg -= mcols; + } + } while (ol != mline && (*pg == g || !*pg)); + } else if (cmd == Th(z_completeword) || + cmd == Th(z_expandorcomplete) || + cmd == Th(z_expandorcompleteprefix) || + cmd == Th(z_menucomplete) || + cmd == Th(z_menuexpandorcomplete) || + !strcmp(cmd->nam, "menu-select") || + !strcmp(cmd->nam, "complete-word") || + !strcmp(cmd->nam, "expand-or-complete") || + !strcmp(cmd->nam, "expand-or-complete-prefix") || + !strcmp(cmd->nam, "menu-complete") || + !strcmp(cmd->nam, "menu-expand-or-complete")) { + do_menucmp(0); + mselect = (*(minfo.cur))->gnum; + continue; + } else if (cmd == Th(z_reversemenucomplete) || + !strcmp(cmd->nam, "reverse-menu-complete")) { + reversemenucomplete(zlenoargs); + mselect = (*(minfo.cur))->gnum; + continue; + } else { + ungetkeycmd(); + break; + } + do_single(**p); + mselect = (**p)->gnum; + } + selectlocalmap(NULL); + mselect = -1; + inselect = 0; + if (!noselect) { + showinglist = -2; + zrefresh(); + } + return noselect; +} + +/* The widget function. */ + +static int +menuselect(char **args) +{ + int d = 0; + + if (!minfo.cur) { + menucomplete(args); + if ((minfo.cur && minfo.asked == 2) || getsparam("ZLS_SELECT")) + return 0; + d = 1; + } + if (minfo.cur && (minfo.asked == 2 || domenuselect(NULL, NULL)) && !d) + menucomplete(args); + + return 0; +} + +/**/ +int +setup_complist(Module m) +{ + return 0; +} + +/**/ +int +boot_complist(Module m) +{ + mtab = NULL; + mgtab = NULL; + mselect = -1; + inselect = 0; + + w_menuselect = addzlefunction("menu-select", menuselect, + ZLE_MENUCMP|ZLE_KEEPSUFFIX|ZLE_ISCOMP); + if (!w_menuselect) { + zwarnnam(m->nam, "name clash when adding ZLE function `menu-select'", + NULL, 0); + return -1; + } + addhookfunc("list_matches", (Hookfn) complistmatches); + addhookfunc("menu_start", (Hookfn) domenuselect); + mskeymap = newkeymap(NULL, "menuselect"); + linkkeymap(mskeymap, "menuselect", 1); + bindkey(mskeymap, "\t", refthingy(t_completeword), NULL); + bindkey(mskeymap, "\n", refthingy(t_acceptline), NULL); + bindkey(mskeymap, "\r", refthingy(t_acceptline), NULL); + bindkey(mskeymap, "\33[A", refthingy(t_uplineorhistory), NULL); + bindkey(mskeymap, "\33[B", refthingy(t_downlineorhistory), NULL); + bindkey(mskeymap, "\33[C", refthingy(t_forwardchar), NULL); + bindkey(mskeymap, "\33[D", refthingy(t_backwardchar), NULL); + bindkey(mskeymap, "\33OA", refthingy(t_uplineorhistory), NULL); + bindkey(mskeymap, "\33OB", refthingy(t_downlineorhistory), NULL); + bindkey(mskeymap, "\33OC", refthingy(t_forwardchar), NULL); + bindkey(mskeymap, "\33OD", refthingy(t_backwardchar), NULL); + return 0; +} + +#ifdef MODULE + +/**/ +int +cleanup_complist(Module m) +{ + free(mtab); + free(mgtab); + + deletezlefunction(w_menuselect); + deletehookfunc("list_matches", (Hookfn) complistmatches); + deletehookfunc("menu_start", (Hookfn) domenuselect); + unlinkkeymap("menuselect", 1); + return 0; +} + +/**/ +int +finish_complist(Module m) +{ + return 0; +} + +#endif diff --git a/Src/Zle/complist.mdd b/Src/Zle/complist.mdd new file mode 100644 index 000000000..8ea60b0a8 --- /dev/null +++ b/Src/Zle/complist.mdd @@ -0,0 +1,3 @@ +moddeps="comp1 zle" + +objects="complist.o" diff --git a/Src/Zle/deltochar.c b/Src/Zle/deltochar.c index 66a301119..f0df33f95 100644 --- a/Src/Zle/deltochar.c +++ b/Src/Zle/deltochar.c @@ -33,8 +33,8 @@ static Widget w_deletetochar; /**/ -static void -deltochar(void) +static int +deltochar(char **args) { int c = getkey(0), dest = cs, ok = 0, n = zmult; @@ -67,8 +67,7 @@ deltochar(void) } } } - if (!ok) - feep(); + return !ok; } /**/ diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index e0c93bd03..c28acb438 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -19,6 +19,7 @@ "backward-kill-line", backwardkillline, ZLE_KILL | ZLE_KEEPSUFFIX "backward-kill-word", backwardkillword, ZLE_KILL | ZLE_KEEPSUFFIX "backward-word", backwardword, 0 +"beep", handlefeep, 0 "beginning-of-buffer-or-history", beginningofbufferorhistory, 0 "beginning-of-history", beginningofhistory, 0 "beginning-of-line", beginningofline, 0 diff --git a/Src/Zle/zle.export b/Src/Zle/zle.export index ccd5df98a..e0b88cd5c 100644 --- a/Src/Zle/zle.export +++ b/Src/Zle/zle.export @@ -1,10 +1,44 @@ #! +acceptlast addzlefunction backdel backkill +bindkey +clearflag +clearscreen deletezlefunction +do_menucmp +do_single feep foredel forekill getkey +getkeycmd +getzlequery +linkkeymap +listshown +menucomplete +menucur +menugrp +minfo +newkeymap +nlnct +printfmt +redisplay +refthingy +reversemenucomplete +selectlocalmap +showinglist +skipnolist +spaceinline +tcmultout +tcout +thingies +trashzle +ungetkeycmd +unlinkkeymap +zlenoargs zmod +zrefresh +zsetterm +ztat diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index d5e0ee89c..ff515e7c4 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -38,7 +38,7 @@ typedef struct thingy *Thingy; /* widgets (ZLE functions) */ -typedef void (*ZleIntFunc) _((void)); +typedef int (*ZleIntFunc) _((char **)); struct widget { int flags; /* flags (see below) */ @@ -54,16 +54,17 @@ struct widget { } u; }; -#define WIDGET_INT (1<<0) /* widget is internally implemented */ -#define WIDGET_NCOMP (1<<1) /* new style completion widget */ -#define ZLE_MENUCMP (1<<2) /* DON'T invalidate completion list */ +#define WIDGET_INT (1<<0) /* widget is internally implemented */ +#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_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 */ +#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 { @@ -142,3 +143,9 @@ typedef struct cutbuffer *Cutbuffer; #define CUTBUFFER_LINE 1 /* for vi: buffer contains whole lines of data */ #define KRINGCT 8 /* number of buffers in the kill ring */ + +/* Convenience macros for the hooks */ + +#define LISTMATCHESHOOK (zlehooks + 0) +#define INSERTMATCHHOOK (zlehooks + 1) +#define MENUSTARTHOOK (zlehooks + 2) diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index 2fc55e98c..f85fa00a6 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -73,12 +73,13 @@ forget_edits(void) } /**/ -void -uphistory(void) +int +uphistory(char **args) { int nodups = isset(HISTIGNOREDUPS); if (!zle_goto_hist(histline, -zmult, nodups) && isset(HISTBEEP)) - feep(); + return 1; + return 0; } /**/ @@ -116,53 +117,53 @@ upline(void) } /**/ -void -uplineorhistory(void) +int +uplineorhistory(char **args) { int ocs = cs; int n = upline(); if (n) { - int m = zmult; + int m = zmult, ret; cs = ocs; - if (virangeflag || !histallowed) { - feep(); - return; - } + if (virangeflag || !histallowed) + return 1; zmult = n; - uphistory(); + ret = uphistory(args); zmult = m; + return ret; } + return 0; } /**/ -void -viuplineorhistory(void) +int +viuplineorhistory(char **args) { int col = lastcol; - uplineorhistory(); + uplineorhistory(args); lastcol = col; - vifirstnonblank(); + return vifirstnonblank(args); } /**/ -void -uplineorsearch(void) +int +uplineorsearch(char **args) { int ocs = cs; int n = upline(); if (n) { - int m = zmult; + int m = zmult, ret; cs = ocs; - if (virangeflag || !histallowed) { - feep(); - return; - } + if (virangeflag || !histallowed) + return 1; zmult = n; - historysearchbackward(); + ret = historysearchbackward(args); zmult = m; + return ret; } + return 0; } /**/ @@ -200,202 +201,220 @@ downline(void) } /**/ -void -downlineorhistory(void) +int +downlineorhistory(char **args) { int ocs = cs; int n = downline(); if (n) { - int m = zmult; + int m = zmult, ret; cs = ocs; - if (virangeflag || !histallowed) { - feep(); - return; - } + if (virangeflag || !histallowed) + return 1; zmult = n; - downhistory(); + ret = downhistory(args); zmult = m; + return ret; } + return 0; } /**/ -void -vidownlineorhistory(void) +int +vidownlineorhistory(char **args) { int col = lastcol; - downlineorhistory(); + downlineorhistory(args); lastcol = col; - vifirstnonblank(); + return vifirstnonblank(zlenoargs); } /**/ -void -downlineorsearch(void) +int +downlineorsearch(char **args) { int ocs = cs; int n = downline(); if (n) { - int m = zmult; + int m = zmult, ret; cs = ocs; - if (virangeflag || !histallowed) { - feep(); - return; - } + if (virangeflag || !histallowed) + return 1; zmult = n; - historysearchforward(); + ret = historysearchforward(args); zmult = m; + return ret; } + return 0; } /**/ -void -acceptlineanddownhistory(void) +int +acceptlineanddownhistory(char **args) { Histent he; - if (!(he = movehistent(quietgethist(histline), 1, HIST_FOREIGN))) { - feep(); - return; - } + if (!(he = movehistent(quietgethist(histline), 1, HIST_FOREIGN))) + return 1; pushnode(bufstack, ztrdup(ZLETEXT(he))); done = 1; stackhist = he->histnum; + return 0; } /**/ -void -downhistory(void) +int +downhistory(char **args) { int nodups = isset(HISTIGNOREDUPS); if (!zle_goto_hist(histline, zmult, nodups) && isset(HISTBEEP)) - feep(); + return 1; + return 0; } static int histpos, srch_hl, srch_cs = -1; static char *srch_str; /**/ -void -historysearchbackward(void) +int +historysearchbackward(char **args) { Histent he; - int n = zmult; - char *s; + int n = zmult, hp; + char *s, *str; if (zmult < 0) { + int ret; zmult = -n; - historysearchforward(); + ret = historysearchforward(args); zmult = n; - return; + return ret; } - if (histline == curhist || histline != srch_hl || cs != srch_cs || mark != 0 - || memcmp(srch_str, line, histpos) != 0) { - zfree(srch_str, histpos); - for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ; - if (histpos < ll) - histpos++; - srch_str = zalloc(histpos); - memcpy(srch_str, line, histpos); + if ((str = *args)) + hp = strlen(str); + else { + if (histline == curhist || histline != srch_hl || cs != srch_cs || + mark != 0 || memcmp(srch_str, line, histpos) != 0) { + zfree(srch_str, histpos); + for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ; + if (histpos < ll) + histpos++; + srch_str = zalloc(histpos); + memcpy(srch_str, line, histpos); + } + str = srch_str; + hp = histpos; } he = quietgethist(histline); while ((he = movehistent(he, -1, hist_skip_flags))) { if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP) continue; s = ZLETEXT(he); - if (metadiffer(s, srch_str, histpos) < 0 && - metadiffer(s, srch_str, ll)) { + if (metadiffer(s, str, hp) < 0 && + (*args || metadiffer(s, str, ll))) { if (--n <= 0) { zle_setline(he); srch_hl = histline; srch_cs = cs; - return; + return 0; } } } - feep(); + return 1; } /**/ -void -historysearchforward(void) +int +historysearchforward(char **args) { Histent he; - int n = zmult; - char *s; + int n = zmult, hp; + char *s, *str; if (zmult < 0) { + int ret; zmult = -n; - historysearchbackward(); + ret = historysearchbackward(args); zmult = n; - return; + return ret; } - if (histline == curhist || histline != srch_hl || cs != srch_cs || mark != 0 - || memcmp(srch_str, line, histpos) != 0) { - zfree(srch_str, histpos); - for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ; - if (histpos < ll) - histpos++; - srch_str = zalloc(histpos); - memcpy(srch_str, line, histpos); + if ((str = *args)) + hp = strlen(str); + else { + if (histline == curhist || histline != srch_hl || cs != srch_cs || + mark != 0 || memcmp(srch_str, line, histpos) != 0) { + zfree(srch_str, histpos); + for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ; + if (histpos < ll) + histpos++; + srch_str = zalloc(histpos); + memcpy(srch_str, line, histpos); + } + str = srch_str; + hp = histpos; } he = quietgethist(histline); while ((he = movehistent(he, 1, hist_skip_flags))) { if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP) continue; s = ZLETEXT(he); - if (metadiffer(s, srch_str, histpos) < (he->histnum == curhist) && - metadiffer(s, srch_str, ll)) { + if (metadiffer(s, str, hp) < (he->histnum == curhist) && + (*args || metadiffer(s, str, ll))) { if (--n <= 0) { zle_setline(he); srch_hl = histline; srch_cs = cs; - return; + return 0; } } } - feep(); + return 1; } /**/ -void -beginningofbufferorhistory(void) +int +beginningofbufferorhistory(char **args) { if (findbol()) cs = 0; else - beginningofhistory(); + return beginningofhistory(args); + return 0; } /**/ -void -beginningofhistory(void) +int +beginningofhistory(char **args) { if (!zle_goto_hist(firsthist(), 0, 0) && isset(HISTBEEP)) - feep(); + return 1; + return 0; } /**/ -void -endofbufferorhistory(void) +int +endofbufferorhistory(char **args) { if (findeol() != ll) cs = ll; else - endofhistory(); + return endofhistory(args); + return 0; } /**/ -void -endofhistory(void) +int +endofhistory(char **args) { zle_goto_hist(curhist, 0, 0); + return 0; } /**/ -void -insertlastword(void) +int +insertlastword(char **args) { int n; char *s, *t; @@ -420,19 +439,15 @@ insertlastword(void) zsfree(lastinsert); lastinsert = NULL; } - if (!(he = quietgethist(evhist)) || !he->nwords) { - feep(); - return; - } + if (!(he = quietgethist(evhist)) || !he->nwords) + return 1; if (zmult > 0) { n = he->nwords - (zmult - 1); } else { n = 1 - zmult; } - if (n < 1 || n > he->nwords) { - feep(); - return; - } + if (n < 1 || n > he->nwords) + return 1; s = he->text + he->words[2*n-2]; t = he->text + he->words[2*n-1]; save = *t; @@ -446,6 +461,7 @@ insertlastword(void) doinsert(s); zmult = n; *t = save; + return 0; } /**/ @@ -461,15 +477,15 @@ zle_setline(Histent he) } /**/ -void -setlocalhistory(void) +int +setlocalhistory(char **args) { if (zmod.flags & MOD_MULT) { hist_skip_flags = zmult? HIST_FOREIGN : 0; - } - else { + } else { hist_skip_flags ^= HIST_FOREIGN; } + return 0; } /**/ @@ -489,13 +505,13 @@ zle_goto_hist(int ev, int n, int skipdups) } /**/ -void -pushline(void) +int +pushline(char **args) { int n = zmult; if (n < 0) - return; + return 1; pushnode(bufstack, metafy((char *) line, ll, META_DUP)); while (--n) pushnode(bufstack, ztrdup("")); @@ -503,18 +519,19 @@ pushline(void) *line = '\0'; ll = cs = 0; clearlist = 1; + return 0; } /**/ -void -pushlineoredit(void) +int +pushlineoredit(char **args) { - int ics; + int ics, ret; unsigned char *s; char *hline = hgetline(); if (zmult < 0) - return; + return 1; if (hline && *hline) { ics = ztrlen(hline); sizeline(ics + ll + 1); @@ -524,34 +541,36 @@ pushlineoredit(void) ll += ics; cs += ics; } - pushline(); + ret = pushline(args); if (!isfirstln) errflag = done = 1; clearlist = 1; + return ret; } /**/ -void -pushinput(void) +int +pushinput(char **args) { - int i; + int i, ret; if (zmult < 0) - return; + return 1; zmult += i = !isfirstln; - pushlineoredit(); + ret = pushlineoredit(args); zmult -= i; + return ret; } /**/ -void -getline(void) +int +getline(char **args) { char *s = (char *)getlinknode(bufstack); - if (!s) - feep(); - else { + if (!s) { + return 1; + } else { int cc; unmetafy(s, &cc); @@ -561,20 +580,23 @@ getline(void) free(s); clearlist = 1; } + return 0; } /**/ -void -historyincrementalsearchbackward(void) +int +historyincrementalsearchbackward(char **args) { - doisearch(-1); + doisearch(args, -1); + return 0; } /**/ -void -historyincrementalsearchforward(void) +int +historyincrementalsearchforward(char **args) { - doisearch(1); + doisearch(args, 1); + return 0; } static struct isrch_spot { @@ -642,13 +664,13 @@ get_isrch_spot(int num, int *hlp, int *posp, int *csp, int *lenp, int *dirp, int /**/ static void -doisearch(int dir) +doisearch(char **args, int dir) { char *s, *ibuf = zhalloc(80), *sbuf = ibuf + FIRST_SEARCH_CHAR; int sbptr = 0, top_spot = 0, pos, sibuf = 80; int nomatch = 0, skip_line = 0, skip_pos = 0; int odir = dir, sens = zmult == 1 ? 3 : 1; - int hl = histline; + int hl = histline, savekeys = -1, feep = 0; Thingy cmd; char *okeymap = curkeymapname; static char *previous_search = NULL; @@ -657,6 +679,14 @@ doisearch(int dir) clearlist = 1; + if (*args) { + int len; + char *arg; + savekeys = kungetct; + arg = getkeystring(*args, &len, 2, NULL); + ungetkeys(arg, len); + } + strcpy(ibuf, ISEARCH_PROMPT); memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3); remember_edits(); @@ -709,7 +739,7 @@ doisearch(int dir) get_isrch_spot(top_spot, &hl, &pos, &cs, &sbptr, &dir, &nomatch); if (!nomatch) { - feep(); + feep = 1; nomatch = 1; } he = quietgethist(hl); @@ -743,14 +773,14 @@ doisearch(int dir) break; } if(cmd == Th(z_clearscreen)) { - clearscreen(); + clearscreen(zlenoargs); goto ref; } else if(cmd == Th(z_redisplay)) { - redisplay(); + redisplay(zlenoargs); goto ref; } else if(cmd == Th(z_vicmdmode)) { if(selectkeymap(invicmdmode() ? "main" : "vicmd", 0)) - feep(); + feep = 1; goto ref; } else if(cmd == Th(z_vibackwarddeletechar) || cmd == Th(z_backwarddeletechar)) { @@ -758,7 +788,7 @@ doisearch(int dir) get_isrch_spot(--top_spot, &hl, &pos, &cs, &sbptr, &dir, &nomatch); else - feep(); + feep = 1; if (nomatch) { statusline = ibuf; skip_pos = 1; @@ -773,16 +803,16 @@ doisearch(int dir) memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3); continue; } else if(cmd == Th(z_acceptandhold)) { - acceptandhold(); + acceptandhold(zlenoargs); break; } else if(cmd == Th(z_acceptandinfernexthistory)) { - acceptandinfernexthistory(); + acceptandinfernexthistory(zlenoargs); break; } else if(cmd == Th(z_acceptlineanddownhistory)) { - acceptlineanddownhistory(); + acceptlineanddownhistory(zlenoargs); break; } else if(cmd == Th(z_acceptline)) { - acceptline(); + acceptline(zlenoargs); break; } else if(cmd == Th(z_historyincrementalsearchbackward)) { set_isrch_spot(top_spot++, hl, pos, cs, sbptr, dir, nomatch); @@ -825,7 +855,7 @@ doisearch(int dir) zrefresh(); } if ((c = getkey(0)) == EOF) - feep(); + feep = 1; else goto ins; } else { @@ -843,7 +873,7 @@ doisearch(int dir) } ins: if (sbptr == PATH_MAX) { - feep(); + feep = 1; continue; } set_isrch_spot(top_spot++, hl, pos, cs, sbptr, dir, nomatch); @@ -854,7 +884,9 @@ doisearch(int dir) } sbuf[sbptr++] = c; } - handlefeep(); + if (feep) + handlefeep(zlenoargs); + feep = 0; } if (sbptr) { zfree(previous_search, previous_search_len); @@ -863,11 +895,17 @@ doisearch(int dir) } statusline = NULL; selectkeymap(okeymap, 1); + /* + * Don't allow unused characters provided as a string to the + * widget to overflow and be used as separated commands. + */ + if (savekeys >= 0 && kungetct > savekeys) + kungetct = savekeys; } /**/ -void -acceptandinfernexthistory(void) +int +acceptandinfernexthistory(char **args) { Histent he; @@ -878,14 +916,15 @@ acceptandinfernexthistory(void) he = movehistent(he, 1, HIST_FOREIGN); pushnode(bufstack, ztrdup(ZLETEXT(he))); stackhist = he->histnum; - return; + return 0; } } + return 1; } /**/ -void -infernexthistory(void) +int +infernexthistory(char **args) { Histent he; @@ -894,28 +933,30 @@ infernexthistory(void) if (!metadiffer(ZLETEXT(he), (char *) line, ll)) { he = movehistent(he, 1, HIST_FOREIGN); zle_setline(he); - return; + return 0; } } - feep(); + return 1; } /**/ -void -vifetchhistory(void) +int +vifetchhistory(char **args) { if (zmult < 0) - return; + return 1; if (histline == curhist) { if (!(zmod.flags & MOD_MULT)) { cs = ll; cs = findbol(); - return; + return 0; } } if (!zle_goto_hist((zmod.flags & MOD_MULT) ? zmult : curhist, 0, 0) && - isset(HISTBEEP)) - feep(); + isset(HISTBEEP)) { + return 1; + } + return 0; } /* the last vi search */ @@ -928,7 +969,7 @@ static int getvisrchstr(void) { char *sbuf = zhalloc(80); - int sptr = 1, ret = 0, ssbuf = 80; + int sptr = 1, ret = 0, ssbuf = 80, feep = 0; Thingy cmd; char *okeymap = curkeymapname; @@ -953,9 +994,9 @@ getvisrchstr(void) cmd = Th(z_selfinsert); } if(cmd == Th(z_redisplay)) { - redisplay(); + redisplay(zlenoargs); } else if(cmd == Th(z_clearscreen)) { - clearscreen(); + clearscreen(zlenoargs); } else if(cmd == Th(z_acceptline) || cmd == Th(z_vicmdmode)) { sbuf[sptr] = 0; @@ -981,7 +1022,7 @@ getvisrchstr(void) zrefresh(); } if ((c = getkey(0)) == EOF) - feep(); + feep = 1; else goto ins; } else if(cmd == Th(z_selfinsertunmeta) || cmd == Th(z_selfinsert)) { @@ -998,9 +1039,11 @@ getvisrchstr(void) } sbuf[sptr++] = c; } else { - feep(); + feep = 1; } - handlefeep(); + if (feep) + handlefeep(zlenoargs); + feep = 0; } statusline = NULL; selectkeymap(okeymap, 1); @@ -1008,36 +1051,58 @@ getvisrchstr(void) } /**/ -void -vihistorysearchforward(void) +int +vihistorysearchforward(char **args) { + if (*args) { + int ose = visrchsense, ret; + char *ost = visrchstr; + + visrchsense = 1; + visrchstr = *args; + ret = virepeatsearch(zlenoargs); + visrchsense = ose; + visrchstr = ost; + return ret; + } visrchsense = 1; if (getvisrchstr()) - virepeatsearch(); + return virepeatsearch(zlenoargs); + return 1; } /**/ -void -vihistorysearchbackward(void) +int +vihistorysearchbackward(char **args) { + if (*args) { + int ose = visrchsense, ret; + char *ost = visrchstr; + + visrchsense = -1; + visrchstr = *args; + ret = virepeatsearch(zlenoargs); + visrchsense = ose; + visrchstr = ost; + return ret; + } visrchsense = -1; if (getvisrchstr()) - virepeatsearch(); + return virepeatsearch(zlenoargs); + return 1; } /**/ -void -virepeatsearch(void) +int +virepeatsearch(char **args) { Histent he; int t0; int n = zmult; char *s; - if (!visrchstr) { - feep(); - return; - } + if (!visrchstr) + return 1; if (zmult < 0) { n = -n; visrchsense = -visrchsense; @@ -1053,20 +1118,22 @@ virepeatsearch(void) : hstrnstr(s, 0, visrchstr, t0, 1, 1) != 0)) { if (--n <= 0) { zle_setline(he); - return; + return 0; } } } - feep(); + return 1; } /**/ -void -virevrepeatsearch(void) +int +virevrepeatsearch(char **args) { + int ret; visrchsense = -visrchsense; - virepeatsearch(); + ret = virepeatsearch(args); visrchsense = -visrchsense; + return ret; } /* Extra function added by A.R. Iano-Fletcher. */ @@ -1074,8 +1141,8 @@ virevrepeatsearch(void) /* history-beginning-search-backward */ /**/ -void -historybeginningsearchbackward(void) +int +historybeginningsearchbackward(char **args) { Histent he; int cpos = cs; /* save cursor position */ @@ -1083,10 +1150,11 @@ historybeginningsearchbackward(void) char *s; if (zmult < 0) { + int ret; zmult = -n; - historybeginningsearchforward(); + ret = historybeginningsearchforward(args); zmult = n; - return; + return ret; } he = quietgethist(histline); while ((he = movehistent(he, -1, hist_skip_flags))) { @@ -1098,19 +1166,19 @@ historybeginningsearchbackward(void) if (--n <= 0) { zle_setline(he); cs = cpos; - return; + return 0; } } } - feep(); + return 1; } /* Extra function added by A.R. Iano-Fletcher. */ /* history-beginning-search-forward */ /**/ -void -historybeginningsearchforward(void) +int +historybeginningsearchforward(char **args) { Histent he; int cpos = cs; /* save cursor position */ @@ -1118,10 +1186,11 @@ historybeginningsearchforward(void) char *s; if (zmult < 0) { + int ret; zmult = -n; - historybeginningsearchbackward(); + ret = historybeginningsearchbackward(args); zmult = n; - return; + return ret; } he = quietgethist(histline); while ((he = movehistent(he, 1, hist_skip_flags))) { @@ -1133,9 +1202,9 @@ historybeginningsearchforward(void) if (--n <= 0) { zle_setline(he); cs = cpos; - return; + return 0; } } } - feep(); + return 1; } diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 7504ed809..28bc96b64 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -98,7 +98,7 @@ struct bindstate { /* currently selected keymap, and its name */ /**/ -Keymap curkeymap; +Keymap curkeymap, localkeymap; /**/ char *curkeymapname; @@ -216,7 +216,7 @@ freekeynode(HashNode hn) static HashTable copyto; /**/ -static Keymap +Keymap newkeymap(Keymap tocopy, char *kmname) { Keymap km = zcalloc(sizeof(*km)); @@ -250,7 +250,7 @@ scancopykeys(HashNode hn, int flags) } /**/ -static void +void deletekeymap(Keymap km) { int i; @@ -322,21 +322,21 @@ openkeymap(char *name) } /**/ -static int -unlinkkeymap(char *name) +int +unlinkkeymap(char *name, int ignm) { KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name); if(!n) return 2; - if(n->flags & KMN_IMMORTAL) + if(!ignm && (n->flags & KMN_IMMORTAL)) return 1; keymapnamtab->freenode(keymapnamtab->removenode(keymapnamtab, name)); return 0; } /**/ -static int -linkkeymap(Keymap km, char *name) +int +linkkeymap(Keymap km, char *name, int imm) { KeymapName n = (KeymapName) keymapnamtab->getnode(keymapnamtab, name); if(n) { @@ -347,9 +347,12 @@ linkkeymap(Keymap km, char *name) if(!--n->keymap->rc) deletekeymap(n->keymap); n->keymap = km; - } else - keymapnamtab->addnode(keymapnamtab, ztrdup(name), - makekeymapnamnode(km)); + } else { + n = makekeymapnamnode(km); + if (imm) + n->flags |= KMN_IMMORTAL; + keymapnamtab->addnode(keymapnamtab, ztrdup(name), n); + } km->rc++; return 0; } @@ -379,6 +382,15 @@ selectkeymap(char *name, int fb) return 0; } +/* Select a local key map. */ + +/**/ +void +selectlocalmap(Keymap m) +{ + localkeymap = m; +} + /* Reopen the currently selected keymap, in case it got deleted. This * * should be called after doing anything that might have run an * * arbitrary user-specified command. */ @@ -642,7 +654,7 @@ bin_bindkey(char *name, char **argv, char *ops, int func) return 1; } if(ops['e'] || ops['v']) - linkkeymap(km, "main"); + linkkeymap(km, "main", 0); } else { kmname = NULL; km = NULL; @@ -715,7 +727,7 @@ bin_bindkey_del(char *name, char *kmname, Keymap km, char **argv, char *ops, cha int ret = 0; do { - int r = unlinkkeymap(*argv); + int r = unlinkkeymap(*argv, 0); if(r == 1) zwarnnam(name, "keymap name `%s' is protected", *argv, 0); else if(r == 2) @@ -735,7 +747,7 @@ bin_bindkey_link(char *name, char *kmname, Keymap km, char **argv, char *ops, ch if(!km) { zwarnnam(name, "no such keymap `%s'", argv[0], 0); return 1; - } else if(linkkeymap(km, argv[1])) { + } else if(linkkeymap(km, argv[1], 0)) { zwarnnam(name, "keymap name `%s' is protected", argv[1], 0); return 1; } @@ -762,7 +774,7 @@ bin_bindkey_new(char *name, char *kmname, Keymap km, char **argv, char *ops, cha } } else km = NULL; - linkkeymap(newkeymap(km, argv[0]), argv[0]); + linkkeymap(newkeymap(km, argv[0]), argv[0], 0); return 0; } @@ -1108,20 +1120,18 @@ default_bindings(void) * will be linked to the "emacs" keymap, except that if VISUAL * * or EDITOR contain the string "vi" then it will be linked to * * the "viins" keymap. */ - linkkeymap(vmap, "viins"); - linkkeymap(emap, "emacs"); - linkkeymap(amap, "vicmd"); - linkkeymap(smap, ".safe"); + linkkeymap(vmap, "viins", 0); + linkkeymap(emap, "emacs", 0); + linkkeymap(amap, "vicmd", 0); + linkkeymap(smap, ".safe", 1); if (((ed = zgetenv("VISUAL")) && strstr(ed, "vi")) || ((ed = zgetenv("EDITOR")) && strstr(ed, "vi"))) - linkkeymap(vmap, "main"); + linkkeymap(vmap, "main", 0); else - linkkeymap(emap, "main"); + linkkeymap(emap, "main", 0); /* the .safe map cannot be modified or deleted */ smap->flags |= KM_IMMUTABLE; - ((KeymapName) keymapnamtab->getnode(keymapnamtab, ".safe"))->flags - |= KMN_IMMORTAL; } /*************************/ @@ -1142,7 +1152,12 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) keybuf[0] = 0; while((c = getkeybuf(!!lastlen)) != EOF) { char *s; - Thingy f = keybind(km, keybuf, &s); + Thingy f; + int loc = 1; + + if (!localkeymap || + (f = keybind(localkeymap, keybuf, &s)) == t_undefinedkey) + loc = 0, f = keybind(km, keybuf, &s); if(f != t_undefinedkey) { lastlen = keybuflen; @@ -1150,7 +1165,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) str = s; lastc = c; } - if(!keyisprefix(km, keybuf)) + if(!keyisprefix((loc ? localkeymap : km), keybuf)) break; } if(!lastlen && keybuflen) diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 13f3cc402..8f6dfdf75 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -106,10 +106,12 @@ struct modifier zmod; /**/ int prefixflag; -/* != 0 if there is a pending beep (usually indicating an error) */ +/* Number of characters waiting to be read by the ungetkeys mechanism */ +/**/ +int kungetct; /**/ -int feepflag; +char *zlenoargs[1] = { NULL }; #ifdef FIONREAD static int delayzsetterm; @@ -262,7 +264,7 @@ zsetterm(void) } static char *kungetbuf; -static int kungetct, kungetsz; +static int kungetsz; /**/ void @@ -499,6 +501,7 @@ zleread(char *lp, char *rp, int flags) viinsbegin = 0; statusline = NULL; selectkeymap("main", 1); + selectlocalmap(NULL); fixsuffix(); if ((s = (unsigned char *)getlinknode(bufstack))) { setline((char *)s); @@ -527,20 +530,21 @@ zleread(char *lp, char *rp, int flags) lastcol = -1; initmodifier(&zmod); prefixflag = 0; - feepflag = 0; zrefresh(); while (!done && !errflag) { statusline = NULL; vilinerange = 0; reselectkeymap(); + selectlocalmap(NULL); bindk = getkeycmd(); if (!ll && isfirstln && c == eofchar) { eofsent = 1; break; } if (bindk) { - execzlefunc(bindk); + if (execzlefunc(bindk, zlenoargs)) + handlefeep(zlenoargs); handleprefixes(); /* for vi mode, make sure the cursor isn't somewhere illegal */ if (invicmdmode() && cs > findbol() && @@ -565,7 +569,6 @@ zleread(char *lp, char *rp, int flags) #endif if (!kungetct) zrefresh(); - handlefeep(); } statusline = NULL; invalidatelist(); @@ -591,10 +594,10 @@ zleread(char *lp, char *rp, int flags) /* execute a widget */ /**/ -void -execzlefunc(Thingy func) +int +execzlefunc(Thingy func, char **args) { - int r = 0; + int r = 0, ret = 0; Widget w; if(func->flags & DISABLED) { @@ -605,7 +608,7 @@ execzlefunc(Thingy func) zsfree(nm); showmsg(msg); zsfree(msg); - feep(); + ret = 1; } else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_NCOMP)) { int wflags = w->flags; @@ -621,9 +624,9 @@ execzlefunc(Thingy func) lastcol = -1; if (wflags & WIDGET_NCOMP) { compwidget = w; - completecall(); + ret = completecall(args); } else - w->u.fn(); + ret = w->u.fn(args); if (!(wflags & ZLE_NOTCOMMAND)) lastcmd = wflags; r = 1; @@ -638,14 +641,23 @@ execzlefunc(Thingy func) zsfree(nm); showmsg(msg); zsfree(msg); - feep(); + ret = 1; } else { - int osc = sfcontext, osi = movefd(0); - + int osc = sfcontext, osi = movefd(0), olv = lastval; + LinkList largs = NULL; + + if (*args) { + largs = newlinklist(); + addlinknode(largs, dupstring(w->u.fnnam)); + while (*args) + addlinknode(largs, dupstring(*args++)); + } startparamscope(); makezleparams(0); sfcontext = SFC_WIDGET; - doshfunc(w->u.fnnam, l, NULL, 0, 1); + doshfunc(w->u.fnnam, l, largs, 0, 0); + ret = lastval; + lastval = olv; sfcontext = osc; endparamscope(); lastcmd = 0; @@ -658,6 +670,7 @@ execzlefunc(Thingy func) refthingy(func); lbindk = func; } + return ret; } /* initialise command modifiers */ @@ -826,14 +839,14 @@ bin_vared(char *name, char **args, char *ops, int func) } /**/ -void -describekeybriefly(void) +int +describekeybriefly(char **args) { char *seq, *str, *msg, *is; Thingy func; if (statusline) - return; + return 1; clearlist = 1; statusline = "Describe key briefly: _"; statusll = strlen(statusline); @@ -841,7 +854,7 @@ describekeybriefly(void) seq = getkeymapcmd(curkeymap, &func, &str); statusline = NULL; if(!*seq) - return; + return 1; msg = bindztrdup(seq); msg = appstr(msg, " is "); if (!func) @@ -852,6 +865,7 @@ describekeybriefly(void) zsfree(is); showmsg(msg); zsfree(msg); + return 0; } #define MAXFOUND 4 @@ -882,13 +896,13 @@ scanfindfunc(char *seq, Thingy func, char *str, void *magic) } /**/ -void -whereis(void) +int +whereis(char **args) { struct findfunc ff; if (!(ff.func = executenamedcommand("Where is: "))) - return; + return 1; ff.found = 0; ff.msg = niceztrdup(ff.func->nam); scankeymap(curkeymap, 1, scanfindfunc, &ff); @@ -898,6 +912,7 @@ whereis(void) ff.msg = appstr(ff.msg, " et al"); showmsg(ff.msg); zsfree(ff.msg); + return 0; } /**/ @@ -933,7 +948,17 @@ trashzle(void) static struct builtin bintab[] = { BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL), BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL), - BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGc", NULL), + BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRa", NULL), +}; + +/* The order of the entries in this table has to match the *HOOK + * macros in zle.h */ + +/**/ +struct hookdef zlehooks[] = { + HOOKDEF("list_matches", ilistmatches, 0), + HOOKDEF("insert_match", NULL, HOOKF_ALL), + HOOKDEF("menu_start", NULL, HOOKF_ALL), }; /**/ @@ -955,6 +980,8 @@ setup_zle(Module m) unambig_dataptr = unambig_data; set_comp_sepptr = set_comp_sep; + getkeyptr = getkey; + /* initialise the thingies */ init_thingies(); lbindk = NULL; @@ -977,6 +1004,7 @@ int boot_zle(Module m) { addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); + addhookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks)); return 0; } @@ -992,6 +1020,7 @@ cleanup_zle(Module m) return 1; } deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); + deletehookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks)); return 0; } @@ -1031,6 +1060,8 @@ finish_zle(Module m) unambig_dataptr = NULL; set_comp_sepptr = NULL; + getkeyptr = NULL; + return 0; } diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index e2ccfbc46..a51cdf92e 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -57,8 +57,8 @@ doinsert(char *str) } /**/ -void -selfinsert(void) +int +selfinsert(char **args) { char s[3], *p = s; @@ -69,56 +69,61 @@ selfinsert(void) *p++ = c; *p = 0; doinsert(s); + return 0; } /**/ -void -selfinsertunmeta(void) +int +selfinsertunmeta(char **args) { c &= 0x7f; if (c == '\r') c = '\n'; - selfinsert(); + return selfinsert(args); } /**/ -void -deletechar(void) +int +deletechar(char **args) { if (zmult < 0) { + int ret; zmult = -zmult; - backwarddeletechar(); + ret = backwarddeletechar(args); zmult = -zmult; - return; + return ret; } if (cs + zmult <= ll) { cs += zmult; backdel(zmult); - } else - feep(); + return 0; + } + return 1; } /**/ -void -backwarddeletechar(void) +int +backwarddeletechar(char **args) { if (zmult < 0) { + int ret; zmult = -zmult; - deletechar(); + ret = deletechar(args); zmult = -zmult; - return; + return ret; } backdel(zmult > cs ? cs : zmult); + return 0; } /**/ -void -killwholeline(void) +int +killwholeline(char **args) { int i, fg, n = zmult; if (n < 0) - return; + return 1; while (n--) { if ((fg = (cs && cs == ll))) cs--; @@ -128,28 +133,31 @@ killwholeline(void) forekill(i - cs + (i != ll), fg); } clearlist = 1; + return 0; } /**/ -void -killbuffer(void) +int +killbuffer(char **args) { cs = 0; forekill(ll, 0); clearlist = 1; + return 0; } /**/ -void -backwardkillline(void) +int +backwardkillline(char **args) { int i = 0, n = zmult; if (n < 0) { + int ret; zmult = -n; - killline(); + ret = killline(args); zmult = n; - return; + return ret; } while (n--) { if (cs && line[cs - 1] == '\n') @@ -160,11 +168,12 @@ backwardkillline(void) } forekill(i, 1); clearlist = 1; + return 0; } /**/ -void -gosmacstransposechars(void) +int +gosmacstransposechars(char **args) { int cc; @@ -172,19 +181,19 @@ gosmacstransposechars(void) if (cs == ll || line[cs] == '\n' || ((cs + 1 == ll || line[cs + 1] == '\n') && (!cs || line[cs - 1] == '\n'))) { - feep(); - return; + return 1; } cs += (cs == 0 || line[cs - 1] == '\n') ? 2 : 1; } cc = line[cs - 2]; line[cs - 2] = line[cs - 1]; line[cs - 1] = cc; + return 0; } /**/ -void -transposechars(void) +int +transposechars(char **args) { int cc, ct; int n = zmult; @@ -194,10 +203,8 @@ transposechars(void) n = -n; while (n--) { if (!(ct = cs) || line[cs - 1] == '\n') { - if (ll == cs || line[cs] == '\n') { - feep(); - return; - } + if (ll == cs || line[cs] == '\n') + return 1; if (!neg) cs++; ct++; @@ -214,29 +221,28 @@ transposechars(void) } if (ct == ll || line[ct] == '\n') ct--; - if (ct < 1 || line[ct - 1] == '\n') { - feep(); - return; - } + if (ct < 1 || line[ct - 1] == '\n') + return 1; cc = line[ct - 1]; line[ct - 1] = line[ct]; line[ct] = cc; } + return 0; } /**/ -void -poundinsert(void) +int +poundinsert(char **args) { cs = 0; - vifirstnonblank(); + vifirstnonblank(zlenoargs); if (line[cs] != '#') { spaceinline(1); line[cs] = '#'; cs = findeol(); while(cs != ll) { cs++; - vifirstnonblank(); + vifirstnonblank(zlenoargs); spaceinline(1); line[cs] = '#'; cs = findeol(); @@ -246,42 +252,46 @@ poundinsert(void) cs = findeol(); while(cs != ll) { cs++; - vifirstnonblank(); + vifirstnonblank(zlenoargs); if(line[cs] == '#') foredel(1); cs = findeol(); } } done = 1; + return 0; } /**/ -void -acceptline(void) +int +acceptline(char **args) { done = 1; + return 0; } /**/ -void -acceptandhold(void) +int +acceptandhold(char **args) { pushnode(bufstack, metafy((char *)line, ll, META_DUP)); stackcs = cs; done = 1; + return 0; } /**/ -void -killline(void) +int +killline(char **args) { int i = 0, n = zmult; if (n < 0) { + int ret; zmult = -n; - backwardkillline(); + ret = backwardkillline(args); zmult = n; - return; + return ret; } while (n--) { if (line[cs] == '\n') @@ -292,11 +302,12 @@ killline(void) } backkill(i, 0); clearlist = 1; + return 0; } /**/ -void -killregion(void) +int +killregion(char **args) { if (mark > ll) mark = ll; @@ -304,11 +315,12 @@ killregion(void) forekill(mark - cs, 0); else backkill(cs - mark, 1); + return 0; } /**/ -void -copyregionaskill(void) +int +copyregionaskill(char **args) { if (mark > ll) mark = ll; @@ -316,25 +328,24 @@ copyregionaskill(void) cut(cs, mark - cs, 0); else cut(mark, cs - mark, 1); + return 0; } static int kct, yankb, yanke; /**/ -void -yank(void) +int +yank(char **args) { Cutbuffer buf = &cutbuf; int n = zmult; if (n < 0) - return; + return 1; if (zmod.flags & MOD_VIBUF) buf = &vibuf[zmod.vibuf]; - if (!buf->buf) { - feep(); - return; - } + if (!buf->buf) + return 1; mark = cs; yankb = cs; while (n--) { @@ -344,18 +355,17 @@ yank(void) cs += buf->len; yanke = cs; } + return 0; } /**/ -void -yankpop(void) +int +yankpop(char **args) { int cc; - if (!(lastcmd & ZLE_YANK) || !kring[kct].buf) { - feep(); - return; - } + if (!(lastcmd & ZLE_YANK) || !kring[kct].buf) + return 1; cs = yankb; foredel(yanke - yankb); cc = kring[kct].len; @@ -364,17 +374,20 @@ yankpop(void) cs += cc; yanke = cs; kct = (kct + KRINGCT - 1) % KRINGCT; + return 0; } /**/ -void -overwritemode(void) +int +overwritemode(char **args) { insmode ^= 1; + return 0; } + /**/ -void -whatcursorposition(void) +int +whatcursorposition(char **args) { char msg[100]; char *s = msg; @@ -408,18 +421,19 @@ whatcursorposition(void) sprintf(s, " point %d of %d(%d%%) column %d", cs+1, ll+1, ll ? 100 * cs / ll : 0, cs - bol); showmsg(msg); + return 0; } /**/ -void -undefinedkey(void) +int +undefinedkey(char **args) { - feep(); + return 1; } /**/ -void -quotedinsert(void) +int +quotedinsert(char **args) { #ifndef HAS_TIO struct sgttyb sob; @@ -433,17 +447,20 @@ quotedinsert(void) zsetterm(); #endif if (c < 0) - feep(); + return 1; else - selfinsert(); + return selfinsert(args); } /**/ -void -digitargument(void) +int +digitargument(char **args) { int sign = (zmult < 0) ? -1 : 1; + if (c < '0' || c > '9') + return 1; + if (!(zmod.flags & MOD_TMULT)) zmod.tmult = 0; if (zmod.flags & MOD_NEG) { @@ -455,26 +472,31 @@ digitargument(void) zmod.tmult = zmod.tmult * 10 + sign * (c & 0xf); zmod.flags |= MOD_TMULT; prefixflag = 1; + return 0; } /**/ -void -negargument(void) +int +negargument(char **args) { - if(zmod.flags & MOD_TMULT) { - feep(); - return; - } + if (zmod.flags & MOD_TMULT) + return 1; zmod.tmult = -1; zmod.flags |= MOD_TMULT|MOD_NEG; prefixflag = 1; + return 0; } /**/ -void -universalargument(void) +int +universalargument(char **args) { int digcnt = 0, pref = 0, minus = 1, gotk; + if (*args) { + zmod.mult = atoi(*args); + zmod.flags |= MOD_MULT; + return 0; + } while ((gotk = getkey(0)) != EOF) { if (gotk == '-' && !digcnt) { minus = -1; @@ -493,11 +515,12 @@ universalargument(void) zmod.tmult *= 4; zmod.flags |= MOD_TMULT; prefixflag = 1; + return 0; } /**/ -void -copyprevword(void) +int +copyprevword(char **args) { int len, t0; @@ -513,18 +536,20 @@ copyprevword(void) spaceinline(len); memcpy((char *)&line[cs], (char *)&line[t0], len); cs += len; + return 0; } /**/ -void -sendbreak(void) +int +sendbreak(char **args) { errflag = 1; + return 1; } /**/ -void -quoteregion(void) +int +quoteregion(char **args) { char *str; size_t len; @@ -544,11 +569,12 @@ quoteregion(void) memcpy((char *)&line[cs], str, len); mark = cs; cs += len; + return 0; } /**/ -void -quoteline(void) +int +quoteline(char **args) { char *str; size_t len = ll; @@ -557,6 +583,7 @@ quoteline(void) sizeline(len); memcpy(line, str, len); cs = ll = len; + return 0; } /**/ @@ -612,7 +639,7 @@ Thingy executenamedcommand(char *prmt) { Thingy cmd; - int len, l = strlen(prmt), ols = listshown; + int len, l = strlen(prmt), ols = listshown, feep = 0; char *ptr; char *okeymap = curkeymapname; @@ -637,20 +664,20 @@ executenamedcommand(char *prmt) return NULL; } if(cmd == Th(z_clearscreen)) { - clearscreen(); + clearscreen(zlenoargs); } else if(cmd == Th(z_redisplay)) { - redisplay(); + redisplay(zlenoargs); } else if(cmd == Th(z_viquotedinsert)) { *ptr = '^'; zrefresh(); c = getkey(0); if(c == EOF || !c || len == NAMLEN) - feep(); + feep = 1; else *ptr++ = c, len++; } else if(cmd == Th(z_quotedinsert)) { if((c = getkey(0)) == EOF || !c || len == NAMLEN) - feep(); + feep = 1; else *ptr++ = c, len++; } else if(cmd == Th(z_backwarddeletechar) || @@ -701,7 +728,7 @@ executenamedcommand(char *prmt) scanhashtable(thingytab, 1, 0, DISABLED, scancompcmd, 0); } LASTALLOC; if (empty(cmdll)) - feep(); + feep = 1; else if (cmd == Th(z_listchoices) || cmd == Th(z_deletecharorlist)) { int zmultsav = zmult; @@ -723,7 +750,7 @@ executenamedcommand(char *prmt) !(isset(LISTAMBIGUOUS) && cmdambig > len)) { int zmultsav = zmult; if (isset(LISTBEEP)) - feep(); + feep = 1; statusll = l + cmdambig + 1; zmult = 1; listlist(cmdll); @@ -733,12 +760,14 @@ executenamedcommand(char *prmt) } } else { if (len == NAMLEN || icntrl(c) || cmd != Th(z_selfinsert)) - feep(); + feep = 1; else *ptr++ = c, len++; } } - handlefeep(); + if (feep) + handlefeep(zlenoargs); + feep = 0; } } diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c index aec1c1767..9189218f1 100644 --- a/Src/Zle/zle_move.c +++ b/Src/Zle/zle_move.c @@ -33,64 +33,69 @@ static int vimarkcs[27], vimarkline[27]; /**/ -void -beginningofline(void) +int +beginningofline(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - endofline(); + ret = endofline(args); zmult = n; - return; + return ret; } while (n--) { if (cs == 0) - return; + return 0; if (line[cs - 1] == '\n') if (!--cs) - return; + return 0; while (cs && line[cs - 1] != '\n') cs--; } + return 0; } /**/ -void -endofline(void) +int +endofline(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - beginningofline(); + ret = beginningofline(args); zmult = n; - return; + return ret; } while (n--) { if (cs >= ll) { cs = ll; - return; + return 0; } if (line[cs] == '\n') if (++cs == ll) - return; + return 0; while (cs != ll && line[cs] != '\n') cs++; } + return 0; } /**/ -void -beginningoflinehist(void) +int +beginningoflinehist(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - endoflinehist(); + ret = endoflinehist(args); zmult = n; - return; + return ret; } while (n) { if (cs == 0) @@ -103,26 +108,29 @@ beginningoflinehist(void) n--; } if (n) { - int m = zmult; + int m = zmult, ret; zmult = n; - uphistory(); + ret = uphistory(args); zmult = m; cs = 0; + return ret; } + return 0; } /**/ -void -endoflinehist(void) +int +endoflinehist(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - beginningoflinehist(); + ret = beginningoflinehist(args); zmult = n; - return; + return ret; } while (n) { if (cs >= ll) { @@ -137,46 +145,51 @@ endoflinehist(void) n--; } if (n) { - int m = zmult; + int m = zmult, ret; zmult = n; - downhistory(); + ret = downhistory(args); zmult = m; + return ret; } + return 0; } /**/ -void -forwardchar(void) +int +forwardchar(char **args) { cs += zmult; if (cs > ll) cs = ll; if (cs < 0) cs = 0; + return 0; } /**/ -void -backwardchar(void) +int +backwardchar(char **args) { cs -= zmult; if (cs > ll) cs = ll; if (cs < 0) cs = 0; + return 0; } /**/ -void -setmarkcommand(void) +int +setmarkcommand(char **args) { mark = cs; + return 0; } /**/ -void -exchangepointandmark(void) +int +exchangepointandmark(char **args) { int x; @@ -185,11 +198,12 @@ exchangepointandmark(void) cs = x; if (cs > ll) cs = ll; + return 0; } /**/ -void -vigotocolumn(void) +int +vigotocolumn(char **args) { int x, y; @@ -202,20 +216,20 @@ vigotocolumn(void) cs = y; if (cs < x) cs = x; + return 0; } /**/ -void -vimatchbracket(void) +int +vimatchbracket(char **args) { int ocs = cs, dir, ct; unsigned char oth, me; otog: if (cs == ll || line[cs] == '\n') { - feep(); cs = ocs; - return; + return 1; } switch (me = line[cs]) { case '{': @@ -258,49 +272,49 @@ vimatchbracket(void) ct++; } if (cs < 0 || cs >= ll) { - feep(); cs = ocs; + return 1; } else if(dir > 0 && virangeflag) cs++; + return 0; } /**/ -void -viforwardchar(void) +int +viforwardchar(char **args) { int lim = findeol() - invicmdmode(); int n = zmult; if (n < 0) { + int ret; zmult = -n; - vibackwardchar(); + ret = vibackwardchar(args); zmult = n; - return; - } - if (cs >= lim) { - feep(); - return; + return ret; } + if (cs >= lim) + return 1; while (n-- && cs < lim) cs++; + return 0; } /**/ -void -vibackwardchar(void) +int +vibackwardchar(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - viforwardchar(); + ret = viforwardchar(args); zmult = n; - return; - } - if (cs == findbol()) { - feep(); - return; + return ret; } + if (cs == findbol()) + return 1; while (n--) { cs--; if (cs < 0 || line[cs] == '\n') { @@ -308,157 +322,163 @@ vibackwardchar(void) break; } } + return 0; } /**/ -void -viendofline(void) +int +viendofline(char **args) { int oldcs = cs, n = zmult; - if (n < 1) { - feep(); - return; - } + if (n < 1) + return 1; while(n--) { if (cs > ll) { cs = oldcs; - feep(); - return; + return 1; } cs = findeol() + 1; } cs--; lastcol = 1<<30; + return 0; } /**/ -void -vibeginningofline(void) +int +vibeginningofline(char **args) { cs = findbol(); + return 0; } static int vfindchar, vfinddir, tailadd; /**/ -void -vifindnextchar(void) +int +vifindnextchar(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = 1; tailadd = 0; - virepeatfind(); + return virepeatfind(args); } + return 1; } /**/ -void -vifindprevchar(void) +int +vifindprevchar(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = -1; tailadd = 0; - virepeatfind(); + return virepeatfind(args); } + return 1; } /**/ -void -vifindnextcharskip(void) +int +vifindnextcharskip(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = 1; tailadd = -1; - virepeatfind(); + return virepeatfind(args); } + return 1; } /**/ -void -vifindprevcharskip(void) +int +vifindprevcharskip(char **args) { if ((vfindchar = vigetkey()) != -1) { vfinddir = -1; tailadd = 1; - virepeatfind(); + return virepeatfind(args); } + return 1; } /**/ -void -virepeatfind(void) +int +virepeatfind(char **args) { int ocs = cs, n = zmult; - if (!vfinddir) { - feep(); - return; - } + if (!vfinddir) + return 1; if (n < 0) { + int ret; zmult = -n; - virevrepeatfind(); + ret = virevrepeatfind(args); zmult = n; - return; + return ret; } while (n--) { do cs += vfinddir; while (cs >= 0 && cs < ll && line[cs] != vfindchar && line[cs] != '\n'); if (cs < 0 || cs >= ll || line[cs] == '\n') { - feep(); cs = ocs; - return; + return 1; } } cs += tailadd; if (vfinddir == 1 && virangeflag) cs++; + return 0; } /**/ -void -virevrepeatfind(void) +int +virevrepeatfind(char **args) { + int ret; + if (zmult < 0) { zmult = -zmult; - virepeatfind(); + ret = virepeatfind(args); zmult = -zmult; - return; + return ret; } vfinddir = -vfinddir; - virepeatfind(); + ret = virepeatfind(args); vfinddir = -vfinddir; + return ret; } /**/ -void -vifirstnonblank(void) +int +vifirstnonblank(char **args) { cs = findbol(); while (cs != ll && iblank(line[cs])) cs++; + return 0; } /**/ -void -visetmark(void) +int +visetmark(char **args) { int ch; ch = getkey(0); - if (ch < 'a' || ch > 'z') { - feep(); - return; - } + if (ch < 'a' || ch > 'z') + return 1; ch -= 'a'; vimarkcs[ch] = cs; vimarkline[ch] = histline; + return 0; } /**/ -void -vigotomark(void) +int +vigotomark(char **args) { int ch; @@ -466,30 +486,26 @@ vigotomark(void) if (ch == c) ch = 26; else { - if (ch < 'a' || ch > 'z') { - feep(); - return; - } + if (ch < 'a' || ch > 'z') + return 1; ch -= 'a'; } - if (!vimarkline[ch]) { - feep(); - return; - } + if (!vimarkline[ch]) + return 1; if (curhist != vimarkline[ch] && !zle_goto_hist(vimarkline[ch], 0, 0)) { vimarkline[ch] = 0; - feep(); - return; + return 1; } cs = vimarkcs[ch]; if (cs > ll) cs = ll; + return 0; } /**/ -void -vigotomarkline(void) +int +vigotomarkline(char **args) { - vigotomark(); - vifirstnonblank(); + vigotomark(args); + return vifirstnonblank(zlenoargs); } diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index 5c4feef50..bac399e7d 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -69,8 +69,8 @@ static struct zleparam { zleunsetfn, NULL }, { "keys", PM_ARRAY | PM_READONLY, NULL, FN(get_keys), zleunsetfn, NULL }, - { "NUMERIC", PM_INTEGER, FN(set_numeric), FN(get_numeric), - zleunsetfn, NULL }, + { "NUMERIC", PM_INTEGER | PM_UNSET, FN(set_numeric), FN(get_numeric), + unset_numeric, NULL }, { "HISTNO", PM_INTEGER | PM_READONLY, NULL, FN(get_histno), zleunsetfn, NULL }, { NULL, 0, NULL, NULL, NULL, NULL } @@ -84,12 +84,12 @@ makezleparams(int ro) for(zp = zleparams; zp->name; zp++) { Param pm = createparam(zp->name, (zp->type |PM_SPECIAL|PM_REMOVABLE| - (ro ? PM_READONLY : 0))); + PM_LOCAL|(ro ? PM_READONLY : 0))); if (!pm) pm = (Param) paramtab->getnode(paramtab, zp->name); DPUTS(!pm, "param not set in makezleparams"); - pm->level = locallevel; + pm->level = locallevel + 1; pm->u.data = zp->data; switch(PM_TYPE(zp->type)) { case PM_SCALAR: @@ -107,6 +107,8 @@ makezleparams(int ro) break; } pm->unsetfn = zp->unsetfn; + if ((zp->type & PM_UNSET) && (zmod.flags & MOD_MULT)) + pm->flags &= ~PM_UNSET; } } @@ -267,6 +269,7 @@ static void set_numeric(Param pm, zlong x) { zmult = x; + zmod.flags = MOD_MULT; } /**/ @@ -276,6 +279,17 @@ get_numeric(Param pm) return zmult; } +/**/ +static void +unset_numeric(Param pm, int exp) +{ + if (exp) { + stdunsetfn(pm, exp); + zmod.flags = 0; + zmult = 1; + } +} + /**/ static zlong get_histno(Param pm) diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index ac18f52f0..da0b38bfe 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -1004,23 +1004,25 @@ tcoutarg(int cap, int arg) } /**/ -void -clearscreen(void) +int +clearscreen(char **args) { tcout(TCCLEARSCREEN); resetneeded = 1; clearflag = 0; + return 0; } /**/ -void -redisplay(void) +int +redisplay(char **args) { moveto(0, 0); zputc('\r', shout); /* extra care */ tc_upcurs(lprompth - 1); resetneeded = 1; clearflag = 0; + return 0; } /**/ diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index dbf982899..cf01f2fc1 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -318,9 +318,10 @@ deletezlefunction(Widget w) /* * The available operations are: * - * -l list user-defined widgets (no arguments) + * -l list widgets/test for existence * -D delete widget names * -A link the two named widgets (2 arguments) + * -C create completion widget (3 arguments) * -N create new user-defined widget (1 or 2 arguments) * invoke a widget (1 argument) */ @@ -334,12 +335,12 @@ bin_zle(char *name, char **args, char *ops, int func) int (*func) _((char *, char **, char *, char)); int min, max; } const opns[] = { - { 'l', bin_zle_list, 0, 0 }, + { 'l', bin_zle_list, 0, -1 }, { 'D', bin_zle_del, 1, -1 }, { 'A', bin_zle_link, 2, 2 }, { 'N', bin_zle_new, 1, 2 }, { 'C', bin_zle_complete, 3, 3 }, - { 'c', bin_zle_complete, 3, 3 }, + { 'R', bin_zle_refresh, 0, 1 }, { 0, bin_zle_call, 0, -1 }, }; struct opn const *op, *opp; @@ -357,10 +358,6 @@ bin_zle(char *name, char **args, char *ops, int func) /* check number of arguments */ for(n = 0; args[n]; n++) ; - if(!op->o && n != 1 && n != 2) { - zerrnam(name, "wrong number of arguments", NULL, 0); - return 1; - } if(n < op->min) { zerrnam(name, "not enough arguments for -%c", NULL, op->o); return 1; @@ -377,7 +374,41 @@ bin_zle(char *name, char **args, char *ops, int func) static int bin_zle_list(char *name, char **args, char *ops, char func) { - scanhashtable(thingytab, 1, 0, DISABLED, scanlistwidgets, ops['L']); + if (!*args) { + scanhashtable(thingytab, 1, 0, DISABLED, scanlistwidgets, + (ops['a'] ? -1 : ops['L'])); + return 0; + } else { + int ret = 0; + Thingy t; + + for (; *args && !ret; args++) { + if (!(t = (Thingy) thingytab->getnode2(thingytab, *args)) || + (!ops['a'] && (t->widget->flags & WIDGET_INT))) + ret = 1; + } + return ret; + } +} + +/**/ +static int +bin_zle_refresh(char *name, char **args, char *ops, char func) +{ + char *s = statusline; + int sl = statusll; + + if (*args) { + statusline = *args; + statusll = strlen(statusline); + } else { + statusline = NULL; + statusll = 0; + } + zrefresh(); + + statusline = s; + statusll = sl; return 0; } @@ -388,6 +419,10 @@ scanlistwidgets(HashNode hn, int list) Thingy t = (Thingy) hn; Widget w = t->widget; + if(list < 0) { + printf("%s\n", hn->nam); + return; + } if(w->flags & WIDGET_INT) return; if(list) { @@ -490,7 +525,8 @@ bin_zle_complete(char *name, char **args, char *ops, char func) return 1; } #endif - t = rthingy(args[1]); + + t = rthingy((args[1][0] == '.') ? args[1] : dyncat(".", args[1])); cw = t->widget; unrefthingy(t); if (!cw || !(cw->flags & ZLE_ISCOMP)) { @@ -517,31 +553,64 @@ bin_zle_call(char *name, char **args, char *ops, char func) { Thingy t; struct modifier modsave; + int ret, saveflag = 0; + char *wname = *args++; if(!zleactive || incompctlfunc || incompfunc) { zerrnam(name, "widgets can only be called when ZLE is active", NULL, 0); return 1; } - if (args[1]) { - modsave = zmod; - if (isdigit(*args[1])) { - zmod.mult = atoi(args[1]); - zmod.flags |= MOD_MULT; + + if (!wname) { + zwarnnam(name, "wrong number of arguments", NULL, 0); + if (saveflag) + zmod = modsave; + return 1; + } + while (*args && **args == '-') { + char *num; + if (!args[0][1] || args[0][1] == '-') { + args++; + break; } - else { - zmod.mult = 1; - zmod.flags &= ~MOD_MULT; + while (*++(*args)) { + switch (**args) { + case 'n': + num = args[0][1] ? args[0]+1 : args[1]; + if (!num) { + zwarnnam(name, "number expected after -%c", NULL, **args); + return 1; + } + if (!args[0][1]) + args++; + modsave = zmod; + saveflag = 1; + zmod.mult = atoi(num); + zmod.flags |= MOD_MULT; + break; + case 'N': + modsave = zmod; + saveflag = 1; + zmod.mult = 1; + zmod.flags &= ~MOD_MULT; + break; + default: + zwarnnam(name, "unknown option: %s", *args, 0); + return 1; + } } + args++; } - t = rthingy(args[0]); + + t = rthingy(wname); PERMALLOC { - execzlefunc(t); + ret = execzlefunc(t, args); } LASTALLOC; unrefthingy(t); - if (args[1]) + if (saveflag) zmod = modsave; - return 0; + return ret; } /*******************/ diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 8c2ae7bb6..65e1aeae9 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -110,20 +110,10 @@ static int movetoend; static int menucmp; -/* Pointers to the current position in the groups list and in the menu- * - * completion array (the one that was put in the command line last). */ +/* Information about menucompletion. */ -static Cmgroup menugrp; -static Cmatch *menucur; - -/* menupos is the point (in the command line) where the menu-completion * - * strings are inserted. menulen is the length of the string that was * - * inserted last. menuend is the end position of this string in the * - * command line. menuwe is non-zero if the cursor was at the end of the * - * word (meaning that suffixes should go before the cursor). menuinsc is * - * the length of any suffix that has been temporarily added. */ - -static int menupos, menulen, menuend, menuwe, menuinsc; +/**/ +struct menuinfo minfo; /* This is for completion inside a brace expansion. brbeg and brend hold * * strings that were temporarily removed from the string to complete. * @@ -376,157 +366,174 @@ static int lastend; #define FC_LINE 1 #define FC_INWORD 2 +/* Arguments for and return value of completion widget. */ + +static char **cfargs; +static int cfret; + /**/ -void -completecall(void) +int +completecall(char **args) { + cfargs = args; + cfret = 0; compfunc = compwidget->u.comp.func; - compwidget->u.comp.fn(); + if (compwidget->u.comp.fn(zlenoargs) && !cfret) + cfret = 1; compfunc = NULL; + + return cfret; } /**/ -void -completeword(void) +int +completeword(char **args) { usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); if (c == '\t' && usetab()) - selfinsert(); + return selfinsert(args); else { + int ret; if (lastambig == 1 && isset(BASHAUTOLIST) && !usemenu && !menucmp) { - docomplete(COMP_LIST_COMPLETE); + ret = docomplete(COMP_LIST_COMPLETE); lastambig = 2; } else - docomplete(COMP_COMPLETE); + ret = docomplete(COMP_COMPLETE); + return ret; } } /**/ -void -menucomplete(void) +int +menucomplete(char **args) { usemenu = 1; useglob = isset(GLOBCOMPLETE); if (c == '\t' && usetab()) - selfinsert(); + return selfinsert(args); else - docomplete(COMP_COMPLETE); + return docomplete(COMP_COMPLETE); } /**/ -void -listchoices(void) +int +listchoices(char **args) { usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); - docomplete(COMP_LIST_COMPLETE); + return docomplete(COMP_LIST_COMPLETE); } /**/ -void -spellword(void) +int +spellword(char **args) { usemenu = useglob = 0; - docomplete(COMP_SPELL); + return docomplete(COMP_SPELL); } /**/ -void -deletecharorlist(void) +int +deletecharorlist(char **args) { - Cmgroup mg = menugrp; - Cmatch *mc = menucur; + Cmgroup mg = minfo.group; + Cmatch *mc = minfo.cur; + int ret; usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); if (cs != ll) { fixsuffix(); - deletechar(); + ret = deletechar(args); } else - docomplete(COMP_LIST_COMPLETE); + ret = docomplete(COMP_LIST_COMPLETE); - menucur = mc; - menugrp = mg; + minfo.cur = mc; + minfo.group = mg; + return ret; } /**/ -void -expandword(void) +int +expandword(char **args) { usemenu = useglob = 0; if (c == '\t' && usetab()) - selfinsert(); + return selfinsert(args); else - docomplete(COMP_EXPAND); + return docomplete(COMP_EXPAND); } /**/ -void -expandorcomplete(void) +int +expandorcomplete(char **args) { usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); if (c == '\t' && usetab()) - selfinsert(); + return selfinsert(args); else { + int ret; if (lastambig == 1 && isset(BASHAUTOLIST) && !usemenu && !menucmp) { - docomplete(COMP_LIST_COMPLETE); + ret = docomplete(COMP_LIST_COMPLETE); lastambig = 2; } else - docomplete(COMP_EXPAND_COMPLETE); + ret = docomplete(COMP_EXPAND_COMPLETE); + return ret; } } /**/ -void -menuexpandorcomplete(void) +int +menuexpandorcomplete(char **args) { usemenu = 1; useglob = isset(GLOBCOMPLETE); if (c == '\t' && usetab()) - selfinsert(); + return selfinsert(args); else - docomplete(COMP_EXPAND_COMPLETE); + return docomplete(COMP_EXPAND_COMPLETE); } /**/ -void -listexpand(void) +int +listexpand(char **args) { usemenu = !!isset(MENUCOMPLETE); useglob = isset(GLOBCOMPLETE); - docomplete(COMP_LIST_EXPAND); + return docomplete(COMP_LIST_EXPAND); } /**/ -void -reversemenucomplete(void) +int +reversemenucomplete(char **args) { - if (!menucmp) { - menucomplete(); - return; - } + if (!menucmp) + return menucomplete(args); + HEAPALLOC { - if (menucur == menugrp->matches) { + if (minfo.cur == (minfo.group)->matches) { do { - if (!(menugrp = menugrp->prev)) - menugrp = lmatches; - } while (!menugrp->mcount); - menucur = menugrp->matches + menugrp->mcount - 1; + if (!(minfo.group = (minfo.group)->prev)) + minfo.group = lmatches; + } while (!(minfo.group)->mcount); + minfo.cur = (minfo.group)->matches + (minfo.group)->mcount - 1; } else - menucur--; + minfo.cur--; metafy_line(); - do_single(*menucur); + do_single(*(minfo.cur)); unmetafy_line(); } LASTALLOC; + return 0; } /* Accepts the current completion and starts a new arg, * * with the next completions. This gives you a way to * * accept several selections from the list of matches. */ -static void +/**/ +void acceptlast(void) { if (brbeg && *brbeg) { @@ -542,26 +549,24 @@ acceptlast(void) brbeg[l] = ','; brbeg[l + 1] = '\0'; } else { - cs = menupos + menulen + menuinsc; + cs = minfo.pos + minfo.len + minfo.insc; iremovesuffix(' ', 1); inststrlen(" ", 1, 1); - menuinsc = menulen = 0; - menupos = cs; - menuwe = 1; + minfo.insc = minfo.len = 0; + minfo.pos = cs; + minfo.we = 1; } } /**/ -void -acceptandmenucomplete(void) +int +acceptandmenucomplete(char **args) { - if (!menucmp) { - feep(); - return; - } + if (!menucmp) + return 1; acceptlast(); - menucomplete(); + return menucomplete(args); } /* These are flags saying if we are completing in the command * @@ -788,11 +793,11 @@ check_param(char *s, int set, int test) /* The main entry point for completion. */ /**/ -static void +static int docomplete(int lst) { char *s, *ol; - int olst = lst, chl = 0, ne = noerrs, ocs; + int olst = lst, chl = 0, ne = noerrs, ocs, ret = 0, omc = menucmp; if (showagain && validlist) showinglist = -2; @@ -803,7 +808,7 @@ docomplete(int lst) if (menucmp && lst != COMP_LIST_EXPAND && (!compwidget || compwidget == lastcompwidget)) { do_menucmp(lst); - return; + return 0; } lastcompwidget = compwidget; @@ -823,7 +828,7 @@ docomplete(int lst) * changed, do no more. */ if (doexpandhist()) - return; + return 0; metafy_line(); @@ -874,8 +879,7 @@ docomplete(int lst) ll = strlen((char *) line); cs = ocs; unmetafy_line(); - feep(); - return; + return 1; } ocs = cs; cs = 0; @@ -985,7 +989,7 @@ docomplete(int lst) inwhat = IN_CMD; if (lst == COMP_SPELL) { - char *x, *q; + char *x, *q, *ox; for (q = s; *q; q++) if (INULL(*q)) @@ -993,10 +997,11 @@ docomplete(int lst) cs = wb; foredel(we - wb); HEAPALLOC { - untokenize(x = dupstring(s)); + untokenize(x = ox = dupstring(s)); if (*s == Tilde || *s == Equals || *s == String) *x = *s; spckword(&x, 0, lincmd, 0); + ret = !strcmp(x, ox); } LASTALLOC; untokenize(x); inststr(x); @@ -1032,18 +1037,30 @@ docomplete(int lst) p++, skipparens(Inbrace, Outbrace, &p); } } - docompletion(s, lst, lincmd); - } + ret = docompletion(s, lst, lincmd); + } else + ret = !strcmp(ol, (char *) line); } else /* Just do completion. */ - docompletion(s, lst, lincmd); + ret = docompletion(s, lst, lincmd); zsfree(s); - } + } else + ret = 1; /* Reset the lexer state, pop the heap. */ lexrestore(); popheap(); zsfree(qword); unmetafy_line(); + + if (menucmp && !omc) { + struct chdata dat; + + dat.matches = amatches; + dat.num = nmatches; + dat.cur = NULL; + runhookdef(MENUSTARTHOOK, (void *) &dat); + } + return ret; } /* Do completion, given that we are in the middle of a menu completion. We * @@ -1052,7 +1069,7 @@ docomplete(int lst) * insert the next completion. */ /**/ -static void +void do_menucmp(int lst) { /* Just list the matches if the list was requested. */ @@ -1062,16 +1079,16 @@ do_menucmp(int lst) } /* Otherwise go to the next match in the array... */ HEAPALLOC { - if (!*++menucur) { + if (!*++(minfo.cur)) { do { - if (!(menugrp = menugrp->next)) - menugrp = amatches; - } while (!menugrp->mcount); - menucur = menugrp->matches; + if (!(minfo.group = (minfo.group)->next)) + minfo.group = amatches; + } while (!(minfo.group)->mcount); + minfo.cur = minfo.group->matches; } /* ... and insert it into the command line. */ metafy_line(); - do_single(*menucur); + do_single(*(minfo.cur)); unmetafy_line(); } LASTALLOC; } @@ -1425,7 +1442,6 @@ get_comp_string(void) lexrestore(); goto start; } - feep(); noaliases = 0; lexrestore(); LASTALLOC_RETURN NULL; @@ -1484,11 +1500,14 @@ get_comp_string(void) if (lev) lev--; } - wb++; p = (char *) line + wb; + wb++; if (wb && (*p == '[' || *p == '(') && - !skipparens(*p, (*p == '[' ? ']' : ')'), &p)) - we = p - (char *) line; + !skipparens(*p, (*p == '[' ? ']' : ')'), &p)) { + we = (p - (char *) line) - 1; + if (insubscr == 2) + insubscr = 3; + } } else { /* In mathematical expression, we complete parameter names * * (even if they don't have a `$' in front of them). So we * @@ -1513,9 +1532,10 @@ get_comp_string(void) varname = ztrdup((char *) line + i + 1); line[wb - 1] = sav; if ((keypm = (Param) paramtab->getnode(paramtab, varname)) && - (keypm->flags & PM_HASHED)) - insubscr = 2; - else + (keypm->flags & PM_HASHED)) { + if (insubscr != 3) + insubscr = 2; + } else insubscr = 1; } } @@ -1734,11 +1754,8 @@ doexpansion(char *s, int lst, int olst, int explincmd) } if (errflag) goto end; - if (empty(vl) || !*(char *)peekfirst(vl)) { - if (!noerrs) - feep(); + if (empty(vl) || !*(char *)peekfirst(vl)) goto end; - } if (peekfirst(vl) == (void *) ss || (olst == COMP_EXPAND_COMPLETE && !nextnode(firstnode(vl)) && *s == Tilde && @@ -1748,8 +1765,6 @@ doexpansion(char *s, int lst, int olst, int explincmd) * expandorcomplete was called, otherwise, just beep. */ if (lst == COMP_EXPAND_COMPLETE) docompletion(s, COMP_COMPLETE, explincmd); - else - feep(); goto end; } if (lst == COMP_LIST_EXPAND) { @@ -3776,9 +3791,10 @@ addmatches(Cadata dat, char **argv) } else dat->prpre = dupstring(dat->prpre); /* Select the group in which to store the matches. */ - if (dat->group) { + if (dat->group || dat->ylist) { endcmgroup(NULL); - begcmgroup(dat->group, (dat->aflags & CAF_NOSORT)); + begcmgroup((dat->ylist ? NULL : dat->group), + (dat->aflags & CAF_NOSORT)); if (dat->aflags & CAF_NOSORT) mgroup->flags |= CGF_NOSORT; } else { @@ -3800,6 +3816,10 @@ addmatches(Cadata dat, char **argv) lpre = quotename(lpre, NULL); lsuf = quotename(lsuf, NULL); } + if (dat->ppre) + dat->ppre = quotename(dat->ppre, NULL); + if (dat->psuf) + dat->psuf = quotename(dat->psuf, NULL); } /* Walk through the matches given. */ for (; (s = *argv); argv++) { @@ -3825,8 +3845,10 @@ addmatches(Cadata dat, char **argv) } } if (!(dat->aflags & CAF_MATCH)) { - ms = ((dat->aflags & CAF_QUOTE) ? dupstring(s) : - quotename(s, NULL)); + if (dat->aflags & CAF_QUOTE) + ms = dupstring(s); + else + sl = strlen(ms = quotename(s, NULL)); lc = bld_parts(ms, sl, -1, NULL); isexact = 0; } else if (!(ms = comp_match(lpre, lsuf, s, cp, &lc, @@ -3865,6 +3887,10 @@ addmatches(Cadata dat, char **argv) set_param(dat->opar, oparl); if (dat->dpar) set_param(dat->dpar, dparl); + if (dat->ylist) { + endcmgroup(get_user_var(dat->ylist)); + begcmgroup("default", 0); + } } LASTALLOC; } SWITCHBACKHEAPS; @@ -4288,9 +4314,11 @@ gen_matches_files(int dirs, int execs, int all) } /**/ -static void +static int docompletion(char *s, int lst, int incmd) { + int ret = 0; + HEAPALLOC { char *opm; LinkNode n; @@ -4328,8 +4356,8 @@ docompletion(char *s, int lst, int incmd) foredel(ll); inststr(origline); cs = origcs; - feep(); clearlist = 1; + ret = 1; goto compend; } if (comppatmatch && *comppatmatch && comppatmatch != opm) @@ -4339,17 +4367,17 @@ docompletion(char *s, int lst, int incmd) showinglist = -2; else if (useline) { /* We have matches. */ - if (nmatches > 1) + if (nmatches > 1) { /* There is more than one match. */ - do_ambiguous(); - - else if (nmatches == 1) { + ret = do_ambiguous(); + } else if (nmatches == 1) { /* Only one match. */ Cmgroup m = amatches; while (!m->mcount) m = m->next; - menucur = NULL; + minfo.cur = NULL; + minfo.asked = 0; do_single(m->matches[0]); invalidatelist(); } @@ -4363,7 +4391,7 @@ docompletion(char *s, int lst, int incmd) int up = 0, tr = 1, nn = 0; if (!nmatches) - feep(); + ret = 1; while (g) { if ((e = g->expls)) @@ -4404,6 +4432,7 @@ docompletion(char *s, int lst, int incmd) cs = ll; popheap(); } LASTALLOC; + return ret; } /* This calls the given function for new style completion. */ @@ -4604,8 +4633,8 @@ callcompfunc(char *s, char *fn) else compoldlist = "yes"; kset |= CP_OLDLIST; - if (menucur) { - sprintf(buf, "%d", (*menucur)->gnum); + if (minfo.cur) { + sprintf(buf, "%d", (*(minfo.cur))->gnum); compoldins = buf; kset |= CP_OLDINS; } else @@ -4623,7 +4652,20 @@ callcompfunc(char *s, char *fn) makezleparams(1); sfcontext = SFC_CWIDGET; NEWHEAPS(compheap) { - doshfunc(fn, list, NULL, 0, 1); + LinkList largs = NULL; + int olv = lastval; + + if (*cfargs) { + char **p = cfargs; + + largs = newlinklist(); + addlinknode(largs, dupstring(fn)); + while (*p) + addlinknode(largs, dupstring(*p++)); + } + doshfunc(fn, list, largs, 0, 0); + cfret = lastval; + lastval = olv; } OLDHEAPS; sfcontext = osc; endparamscope(); @@ -4673,7 +4715,7 @@ callcompfunc(char *s, char *fn) movetoend = 2; oldlist = (hasperm && compoldlist && !strcmp(compoldlist, "keep")); - oldins = (hasperm && menucur && + oldins = (hasperm && minfo.cur && compoldins && !strcmp(compoldins, "keep")); zfree(comprpms, CP_REALPARAMS * sizeof(Param)); @@ -4710,7 +4752,7 @@ makecomplist(char *s, int incmd, int lst) int onm = nmatches, osi = movefd(0); /* Inside $... ? */ - if (compfunc && (p = check_param(s, 0, NULL))) + if (compfunc && (p = check_param(s, 0, 0))) os = s = p; /* We build a copy of the list of matchers to use to make sure that this @@ -5281,10 +5323,10 @@ makecomplistglobal(char *os, int incmd, int lst, int flags) cc = &cc_default; keypm = NULL; } else if (linwhat == IN_MATH) { - if (insubscr == 2) { + if (insubscr >= 2) { /* Inside subscript of assoc array, complete keys. */ cc_dummy.mask = 0; - cc_dummy.suffix = "]"; + cc_dummy.suffix = (insubscr == 2 ? "]" : ""); } else { /* Other math environment, complete paramete names. */ keypm = NULL; @@ -5590,7 +5632,7 @@ makecomplistext(Compctl occ, char *os, int incmd) case CCT_RANGEPAT: if (cc->type == CCT_RANGEPAT) tokenize(sc = dupstring(cc->u.l.a[i])); - for (j = clwpos; j; j--) { + for (j = clwpos - 1; j > 0; j--) { untokenize(s = ztrdup(clwords[j])); if (cc->type == CCT_RANGESTR) sc = rembslash(cc->u.l.a[i]); @@ -5791,7 +5833,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) ic = 0; /* Check if we have to complete a parameter name... */ - if (!incompfunc && (p = check_param(s, 1, NULL))) { + if (!incompfunc && (p = check_param(s, 1, 0))) { s = p; /* And now make sure that we complete parameter names. */ cc = &cc_dummy; @@ -6267,8 +6309,15 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) maketildelist(); addwhat = oaw; } - if (cc->widget) + if (cc->widget) { + char **ocfa = cfargs; + int ocfr = cfret; + + cfargs = zlenoargs; callcompfunc(os, cc->widget); + cfargs = ocfa; + cfret = ocfr; + } if (cc->func) { /* This handles the compctl -K flag. */ List list; @@ -6313,20 +6362,14 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (cc->mask & (CC_JOBS | CC_RUNNING | CC_STOPPED)) { /* Get job names. */ int i; - char *j, *jj; + char *j; for (i = 0; i < MAXJOB; i++) if ((jobtab[i].stat & STAT_INUSE) && jobtab[i].procs && jobtab[i].procs->text) { int stopped = jobtab[i].stat & STAT_STOPPED; - j = jj = dupstring(jobtab[i].procs->text); - /* Find the first word. */ - for (; *jj; jj++) - if (*jj == ' ') { - *jj = '\0'; - break; - } + j = dupstring(jobtab[i].procs->text); if ((cc->mask & CC_JOBS) || (stopped && (cc->mask & CC_STOPPED)) || (!stopped && (cc->mask & CC_RUNNING))) @@ -6507,7 +6550,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if (cc->subcmd) { /* Handle -l sub-completion. */ char **ow = clwords, *os = cmdstr, *ops = NULL; - int oldn = clwnum, oldp = clwpos; + int oldn = clwnum, oldp = clwpos, br; unsigned long occ = ccont; ccont = CC_CCCONT; @@ -6523,21 +6566,22 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) erange = 1; clwnum = erange - brange + 1; clwpos = clwpos - brange; - + br = brange; + if (cc->subcmd[0]) { /* And probably put the command name given to the flag * * in the array. */ clwpos++; clwnum++; incmd = 0; - ops = clwords[brange - 1]; - clwords[brange - 1] = cc->subcmd; + ops = clwords[br - 1]; + clwords[br - 1] = ztrdup(cc->subcmd); cmdstr = ztrdup(cc->subcmd); - clwords += brange - 1; + clwords += br - 1; } else { - cmdstr = ztrdup(clwords[brange]); + cmdstr = ztrdup(clwords[br]); incmd = !clwpos; - clwords += brange; + clwords += br; } /* Produce the matches. */ makecomplistcmd(s, incmd, CFN_FIRST); @@ -6548,8 +6592,10 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) cmdstr = os; clwnum = oldn; clwpos = oldp; - if (ops) - clwords[brange - 1] = ops; + if (ops) { + zsfree(clwords[br - 1]); + clwords[br - 1] = ops; + } ccont = occ; } if (cc->substr) @@ -6570,7 +6616,8 @@ invalidatelist(void) if (validlist) freematches(); lastambig = menucmp = validlist = showinglist = fromcomp = 0; - menucur = NULL; + minfo.cur = NULL; + minfo.asked = 0; compwidget = NULL; } @@ -7337,19 +7384,20 @@ instmatch(Cmatch m, int *scs) /* Handle the case were we found more than one match. */ /**/ -static void +static int do_ambiguous(void) { + int ret = 0; menucmp = 0; /* If we have to insert the first match, call do_single(). This is * * how REC_EXACT takes effect. We effectively turn the ambiguous * * completion into an unambiguous one. */ if (ainfo && ainfo->exact == 1 && useexact && !(fromcomp & FC_LINE)) { - menucur = NULL; + minfo.cur = NULL; do_single(ainfo->exactm); invalidatelist(); - return; + return ret; } /* Setting lastambig here means that the completion is ambiguous and * * AUTO_MENU might want to start a menu completion next time round, * @@ -7369,7 +7417,8 @@ do_ambiguous(void) int atend = (cs == we), oll = ll, la, eq, tcs; VARARR(char, oline, ll); - menucur = NULL; + minfo.cur = NULL; + minfo.asked = 0; /* Copy the line buffer to be able to easily test if it changed. */ memcpy(oline, line, ll); @@ -7418,19 +7467,21 @@ do_ambiguous(void) fromcomp = fc; lastambig = 0; clearlist = 1; - return; + return ret; } } else - return; + return ret; /* At this point, we might want a completion listing. Show the listing * * if it is needed. */ if (isset(LISTBEEP)) - feep(); - if (uselist && usemenu != 2 && - (!showinglist || (usemenu == 3 && !oldlist)) && + ret = 1; + if (uselist && (usemenu != 2 || (!showinglist && !oldlist)) && + ((!showinglist && (!listshown || !oldlist)) || + (usemenu == 3 && !oldlist)) && (smatches >= 2 || (compforcelist && *compforcelist))) showinglist = -2; + return ret; } /* This is a stat that ignores backslashes in the filename. The `ls' * @@ -7440,7 +7491,7 @@ do_ambiguous(void) * (l)stat(). */ /**/ -static int +int ztat(char *nam, struct stat *buf, int ls) { char b[PATH_MAX], *p; @@ -7458,7 +7509,7 @@ ztat(char *nam, struct stat *buf, int ls) /* Insert a single match in the command line. */ /**/ -static void +void do_single(Cmatch m) { int l, sr = 0, scs; @@ -7471,39 +7522,39 @@ do_single(Cmatch m) fixsuffix(); - if (!menucur) { + if (!minfo.cur) { /* We are currently not in a menu-completion, * * so set the position variables. */ - menupos = wb; - menuwe = (movetoend >= 2 || (movetoend == 1 && !menucmp)); - menuend = we; + minfo.pos = wb; + minfo.we = (movetoend >= 2 || (movetoend == 1 && !menucmp)); + minfo.end = we; } /* If we are already in a menu-completion or if we have done a * * glob completion, we have to delete some of the stuff on the * * command line. */ - if (menucur) - l = menulen + menuinsc; + if (minfo.cur) + l = minfo.len + minfo.insc; else l = we - wb; - menuinsc = 0; - cs = menupos; + minfo.insc = 0; + cs = minfo.pos; foredel(l); /* And then we insert the new string. */ - menulen = instmatch(m, &scs); - menuend = cs; - cs = menupos + menulen; + minfo.len = instmatch(m, &scs); + minfo.end = cs; + cs = minfo.pos + minfo.len; if (m->suf) { havesuff = 1; - menuinsc = ztrlen(m->suf); - menulen -= menuinsc; - if (menuwe) { - menuend += menuinsc; + minfo.insc = ztrlen(m->suf); + minfo.len -= minfo.insc; + if (minfo.we) { + minfo.end += minfo.insc; if (m->flags & CMF_REMOVE) { - makesuffixstr(m->remf, m->rems, menuinsc); - if (menuinsc == 1) + makesuffixstr(m->remf, m->rems, minfo.insc); + if (minfo.insc == 1) suffixlen[STOUC(m->suf[0])] = 1; } } @@ -7519,11 +7570,11 @@ do_single(Cmatch m) cs += eparq; for (pq = parq; pq; pq--) inststrlen("\"", 1, 1); - menuinsc += parq; + minfo.insc += parq; inststrlen("}", 1, 1); - menuinsc++; - if (menuwe) - menuend += menuinsc; + minfo.insc++; + if (minfo.we) + minfo.end += minfo.insc; } if ((m->flags & CMF_FILE) || (m->ripre && isset(AUTOPARAMSLASH))) { /* If we have a filename or we completed a parameter name * @@ -7559,10 +7610,10 @@ do_single(Cmatch m) /* It is a directory, so add the slash. */ havesuff = 1; inststrlen("/", 1, 1); - menuinsc++; - if (menuwe) - menuend++; - if (!menucmp || menuwe) { + minfo.insc++; + if (minfo.we) + minfo.end++; + if (!menucmp || minfo.we) { if (m->remf || m->rems) makesuffixstr(m->remf, m->rems, 1); else if (isset(AUTOREMOVESLASH)) { @@ -7572,8 +7623,8 @@ do_single(Cmatch m) } } } - if (!menuinsc) - cs = menupos + menulen; + if (!minfo.insc) + cs = minfo.pos + minfo.len; } /* If completing in a brace expansion... */ if (brbeg) { @@ -7589,9 +7640,9 @@ do_single(Cmatch m) cs = scs; havesuff = 1; inststrlen(",", 1, 1); - menuinsc++; + minfo.insc++; makesuffix(1); - if ((!menucmp || menuwe) && isset(AUTOPARAMKEYS)) + if ((!menucmp || minfo.we) && isset(AUTOPARAMKEYS)) suffixlen[','] = suffixlen['}'] = 1; } } else if (!havesuff && (!(m->flags & CMF_FILE) || !sr)) { @@ -7600,20 +7651,33 @@ do_single(Cmatch m) * the string doesn't name an existing file. */ if (m->autoq && (!m->isuf || m->isuf[0] != m->autoq)) { inststrlen(&(m->autoq), 1, 1); - menuinsc++; + minfo.insc++; } - if (!menucmp) { + if (!menucmp && usemenu != 3) { inststrlen(" ", 1, 1); - menuinsc++; - if (menuwe) + minfo.insc++; + if (minfo.we) makesuffix(1); } } - if (menuwe && m->ripre && isset(AUTOPARAMKEYS)) - makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), menuinsc - parq); + if (minfo.we && m->ripre && isset(AUTOPARAMKEYS)) + makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq); - if ((menucmp && !menuwe) || !movetoend) - cs = menuend; + if ((menucmp && !minfo.we) || !movetoend) + cs = minfo.end; + { + Cmatch *om = minfo.cur; + struct chdata dat; + + dat.matches = amatches; + dat.num = nmatches; + dat.cur = m; + + if (menucmp) + minfo.cur = &m; + runhookdef(INSERTMATCHHOOK, (void *) &dat); + minfo.cur = om; + } } /* This maps the value in v into the range [0,m-1], decrementing v @@ -7643,40 +7707,42 @@ do_ambig_menu(void) if (usemenu != 3) { menucmp = 1; - menucur = NULL; + minfo.cur = NULL; } else { if (oldlist) { if (oldins) acceptlast(); } else - menucur = NULL; + minfo.cur = NULL; } if (insgroup) { insgnum = comp_mod(insgnum, permgnum); - for (menugrp = amatches; - menugrp && menugrp->num != insgnum + 1; - menugrp = menugrp->next); - if (!menugrp || !menugrp->mcount) { - menucur = NULL; + for (minfo.group = amatches; + minfo.group && (minfo.group)->num != insgnum + 1; + minfo.group = (minfo.group)->next); + if (!minfo.group || !(minfo.group)->mcount) { + minfo.cur = NULL; + minfo.asked = 0; return; } - insmnum = comp_mod(insmnum, menugrp->mcount); + insmnum = comp_mod(insmnum, (minfo.group)->mcount); } else { int c = 0; insmnum = comp_mod(insmnum, permmnum); - for (menugrp = amatches; - menugrp && (c += menugrp->mcount) <= insmnum; - menugrp = menugrp->next) - insmnum -= menugrp->mcount; - if (!menugrp) { - menucur = NULL; + for (minfo.group = amatches; + minfo.group && (c += (minfo.group)->mcount) <= insmnum; + minfo.group = (minfo.group)->next) + insmnum -= (minfo.group)->mcount; + if (!minfo.group) { + minfo.cur = NULL; + minfo.asked = 0; return; } } - mc = menugrp->matches + insmnum; + mc = (minfo.group)->matches + insmnum; do_single(*mc); - menucur = mc; + minfo.cur = mc; } /* Return the length of the common prefix of s and t. */ @@ -7715,7 +7781,7 @@ sfxlen(char *s, char *t) * It returns the number of lines printed. */ /**/ -static int +int printfmt(char *fmt, int n, int dopr) { char *p = fmt, nc[DIGBUFSIZE]; @@ -7798,7 +7864,8 @@ printfmt(char *fmt, int n, int dopr) /* This skips over matches that are not to be listed. */ -static Cmatch * +/**/ +Cmatch * skipnolist(Cmatch *p) { while (*p && ((*p)->flags & CMF_NOLIST)) @@ -7813,11 +7880,7 @@ skipnolist(Cmatch *p) void listmatches(void) { - Cmgroup g; - Cmatch *p, m; - Cexpl *e; - int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0; - int of = isset(LISTTYPES), opl = 0; + struct chdata dat; #ifdef DEBUG /* Sanity check */ @@ -7827,6 +7890,22 @@ listmatches(void) } #endif + dat.matches = amatches; + dat.num = nmatches; + dat.cur = NULL; + runhookdef(LISTMATCHESHOOK, (void *) &dat); +} + +/**/ +int +ilistmatches(Hookdef dummy, Chdata dat) +{ + Cmgroup g; + Cmatch *p, m; + Cexpl *e; + int nlines = 0, ncols, nlist = 0, longest = 1, pnl = 0; + int of = isset(LISTTYPES), opl = 0; + /* Set the cursor below the prompt. */ trashzle(); showinglist = listshown = 0; @@ -7911,8 +7990,9 @@ listmatches(void) } /* Maybe we have to ask if the user wants to see the list. */ - if ((complistmax && nlist > complistmax) || - (!complistmax && nlines >= lines)) { + 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); @@ -7926,7 +8006,9 @@ listmatches(void) tcmultout(TCUP, TCMULTUP, nlnct); } else putc('\n', shout); - return; + if (minfo.cur) + minfo.asked = 2; + return 0; } if (clearflag) { putc('\r', shout); @@ -7936,6 +8018,8 @@ listmatches(void) } else putc('\n', shout); settyinfo(&shttyinfo); + if (minfo.cur) + minfo.asked = 1; } /* Now print the matches. */ @@ -7956,7 +8040,7 @@ listmatches(void) e++; } } - if (pp) { + if (pp && *pp) { if (pnl) { putc('\n', shout); pnl = 0; @@ -8055,6 +8139,7 @@ listmatches(void) clearflag = 0, putc('\n', shout); } else putc('\n', shout); + return 0; } /* This is used to print expansions. */ @@ -8064,9 +8149,9 @@ void listlist(LinkList l) { struct cmgroup dg; - Cmgroup am = amatches; int vl = validlist, sm = smatches; char *oclp = complastprompt; + Cmgroup am = amatches; if (listshown) showagain = 1; @@ -8074,12 +8159,12 @@ listlist(LinkList l) complastprompt = ((zmult == 1) == !!isset(ALWAYSLASTPROMPT) ? "yes" : NULL); smatches = 1; validlist = 1; - amatches = &dg; memset(&dg, 0, sizeof(struct cmgroup)); dg.ylist = (char **) makearray(l, 1, &(dg.lcount), NULL); - listmatches(); - + amatches = &dg; + ilistmatches(NULL, NULL); amatches = am; + validlist = vl; smatches = sm; complastprompt = oclp; @@ -8153,20 +8238,22 @@ doexpandhist(void) } /**/ -void -magicspace(void) +int +magicspace(char **args) { + int ret; c = ' '; - selfinsert(); - doexpandhist(); + ret = selfinsert(args); + return !doexpandhist(); } /**/ -void -expandhistory(void) +int +expandhistory(char **args) { if (!doexpandhist()) - feep(); + return 1; + return 0; } static int cmdwb, cmdwe; @@ -8210,19 +8297,17 @@ getcurcmd(void) } /**/ -void -processcmd(void) +int +processcmd(char **args) { char *s; int m = zmult; s = getcurcmd(); - if (!s) { - feep(); - return; - } + if (!s) + return 1; zmult = 1; - pushline(); + pushline(zlenoargs); zmult = m; inststr(bindk->nam); inststr(" "); @@ -8232,11 +8317,12 @@ processcmd(void) } LASTALLOC; zsfree(s); done = 1; + return 0; } /**/ -void -expandcmdpath(void) +int +expandcmdpath(char **args) { int oldcs = cs, na = noaliases; char *s, *str; @@ -8244,16 +8330,12 @@ expandcmdpath(void) noaliases = 1; s = getcurcmd(); noaliases = na; - if (!s || cmdwb < 0 || cmdwe < cmdwb) { - feep(); - return; - } + if (!s || cmdwb < 0 || cmdwe < cmdwb) + return 1; str = findcmd(s, 1); zsfree(s); - if (!str) { - feep(); - return; - } + if (!str) + return 1; cs = cmdwb; foredel(cmdwe - cmdwb); spaceinline(strlen(str)); @@ -8263,16 +8345,20 @@ expandcmdpath(void) cs += cmdwe - cmdwb + strlen(str); if (cs > ll) cs = ll; + return 0; } /* Extra function added by AR Iano-Fletcher. */ /* This is a expand/complete in the vein of wash. */ /**/ -void -expandorcompleteprefix(void) +int +expandorcompleteprefix(char **args) { + int ret; + comppref = 1; - expandorcomplete(); + ret = expandorcomplete(args); comppref = 0; + return ret; } diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 8524fd21e..bd2f39a06 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -409,19 +409,11 @@ showmsg(char const *msg) /* handle the error flag */ /**/ -void -feep(void) -{ - feepflag = 1; -} - -/**/ -void -handlefeep(void) +int +handlefeep(char **args) { - if(feepflag) - zbeep(); - feepflag = 0; + zbeep(); + return 0; } /***************/ @@ -554,18 +546,17 @@ setlastline(void) /* move backwards through the change list */ /**/ -void -undo(void) +int +undo(char **args) { handleundo(); do { - if(!curchange->prev) { - feep(); - return; - } + if(!curchange->prev) + return 1; unapplychange(curchange = curchange->prev); } while(curchange->flags & CH_PREV); setlastline(); + return 0; } /**/ @@ -592,19 +583,18 @@ unapplychange(struct change *ch) /* move forwards through the change list */ /**/ -void -redo(void) +int +redo(char **args) { handleundo(); do { - if(!curchange->next) { - feep(); - return; - } + if(!curchange->next) + return 1; applychange(curchange); curchange = curchange->next; } while(curchange->prev->flags & CH_NEXT); setlastline(); + return 0; } /**/ @@ -631,8 +621,8 @@ applychange(struct change *ch) /* vi undo: toggle between the end of the undo list and the preceding point */ /**/ -void -viundochange(void) +int +viundochange(char **args) { handleundo(); if(curchange->next) { @@ -641,6 +631,7 @@ viundochange(void) curchange = curchange->next; } while(curchange->next); setlastline(); + return 0; } else - undo(); + return undo(args); } diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 5b1548e25..71f766739 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -102,10 +102,8 @@ vigetkey(void) char m[3], *str; Thingy cmd; - if((c = getkey(0)) == EOF) { - feep(); + if((c = getkey(0)) == EOF) return -1; - } m[0] = c; metafy(m, 1, META_NOALLOC); @@ -115,13 +113,10 @@ vigetkey(void) cmd = t_undefinedkey; if (!cmd || cmd == Th(z_sendbreak)) { - feep(); return -1; } else if (cmd == Th(z_quotedinsert)) { - if ((c = getkey(0)) == EOF) { - feep(); + if ((c = getkey(0)) == EOF) return -1; - } } else if(cmd == Th(z_viquotedinsert)) { char sav = line[cs]; @@ -129,10 +124,8 @@ vigetkey(void) zrefresh(); c = getkey(0); line[cs] = sav; - if(c == EOF) { - feep(); + if(c == EOF) return -1; - } } else if (cmd == Th(z_vicmdmode)) return -1; return c; @@ -142,7 +135,7 @@ vigetkey(void) static int getvirange(int wf) { - int pos = cs; + int pos = cs, ret = 0; int mult1 = zmult, hist1 = histline; Thingy k2; @@ -168,39 +161,37 @@ getvirange(int wf) k2 == Th(z_sendbreak)) { wordflag = 0; virangeflag = 0; - feep(); return -1; } - if(k2 == bindk) - /* The command key is repeated: a number of lines is used. */ - dovilinerange(); - else - execzlefunc(k2); + /* + * With k2 == bindk, the command key is repeated: + * a number of lines is used. If the function used + * returns 1, we fail. + */ + if ((k2 == bindk) ? dovilinerange() : execzlefunc(k2, zlenoargs)) + ret = -1; if(vichgrepeat) zmult = mult1; else zmult = mult1 * zmod.tmult; - } while(prefixflag); + } while(prefixflag && !ret); wordflag = 0; virangeflag = 0; /* It is an error to use a non-movement command to delimit the * * range. We here reject the case where the command modified * * the line, or selected a different history line. */ - if(histline != hist1 || ll != lastll || memcmp(line, lastline, ll)) { + if (histline != hist1 || ll != lastll || memcmp(line, lastline, ll)) { histline = hist1; memcpy(line, lastline, ll = lastll); cs = pos; - feep(); return -1; } /* Can't handle an empty file. Also, if the movement command * * failed, or didn't move, it is an error. */ - if (!ll || (cs == pos && virangeflag != 2)) { - feep(); + if (!ll || (cs == pos && virangeflag != 2) || ret == -1) return -1; - } /* vi-match-bracket changes the value of virangeflag when * * moving to the opening bracket, meaning that we need to * @@ -233,7 +224,7 @@ getvirange(int wf) } /**/ -static void +static int dovilinerange(void) { int pos = cs, n = zmult; @@ -243,17 +234,14 @@ dovilinerange(void) * downward, otherwise upward. The repeat count gives the * * number of lines. */ vilinerange = 1; - if (!n) { - feep(); - return; - } + if (!n) + return 1; if (n > 0) { while(n-- && cs <= ll) cs = findeol() + 1; if (n != -1) { cs = pos; - feep(); - return; + return 1; } cs--; } else { @@ -261,123 +249,127 @@ dovilinerange(void) cs = findbol() - 1; if (n != 1) { cs = pos; - feep(); - return; + return 1; } cs++; } virangeflag = 2; + return 0; } /**/ -void -viaddnext(void) +int +viaddnext(char **args) { if (cs != findeol()) cs++; startvitext(1); + return 0; } /**/ -void -viaddeol(void) +int +viaddeol(char **args) { cs = findeol(); startvitext(1); + return 0; } /**/ -void -viinsert(void) +int +viinsert(char **args) { startvitext(1); + return 0; } /**/ -void -viinsertbol(void) +int +viinsertbol(char **args) { - vifirstnonblank(); + vifirstnonblank(zlenoargs); startvitext(1); + return 0; } /**/ -void -videlete(void) +int +videlete(char **args) { - int c2; + int c2, ret = 1; startvichange(1); if ((c2 = getvirange(0)) != -1) { forekill(c2 - cs, 0); + ret = 0; if (vilinerange && ll) { if (cs == ll) cs--; foredel(1); - vifirstnonblank(); + vifirstnonblank(zlenoargs); } } vichgflag = 0; + return ret; } /**/ -void -videletechar(void) +int +videletechar(char **args) { int n = zmult; startvichange(-1); /* handle negative argument */ if (n < 0) { + int ret; zmult = -n; - vibackwarddeletechar(); + ret = vibackwarddeletechar(args); zmult = n; - return; + return ret; } /* it is an error to be on the end of line */ - if (cs == ll || line[cs] == '\n') { - feep(); - return; - } + if (cs == ll || line[cs] == '\n') + return 1; /* Put argument into the acceptable range -- it is not an error to * * specify a greater count than the number of available characters. */ if (n > findeol() - cs) n = findeol() - cs; /* do the deletion */ forekill(n, 0); + return 0; } /**/ -void -vichange(void) +int +vichange(char **args) { - int c2; + int c2, ret = 1; startvichange(1); if ((c2 = getvirange(1)) != -1) { + ret = 0; forekill(c2 - cs, 0); selectkeymap("main", 1); viinsbegin = cs; undoing = 0; } + return ret; } /**/ -void -visubstitute(void) +int +visubstitute(char **args) { int n = zmult; startvichange(1); - if (n < 0) { - feep(); - return; - } + if (n < 0) + return 1; /* it is an error to be on the end of line */ - if (cs == ll || line[cs] == '\n') { - feep(); - return; - } + if (cs == ll || line[cs] == '\n') + return 1; /* Put argument into the acceptable range -- it is not an error to * * specify a greater count than the number of available characters. */ if (n > findeol() - cs) @@ -385,79 +377,84 @@ visubstitute(void) /* do the substitution */ forekill(n, 0); startvitext(1); + return 0; } /**/ -void -vichangeeol(void) +int +vichangeeol(char **args) { forekill(findeol() - cs, 0); startvitext(1); + return 0; } /**/ -void -vichangewholeline(void) +int +vichangewholeline(char **args) { - vifirstnonblank(); - vichangeeol(); + vifirstnonblank(args); + return vichangeeol(zlenoargs); } /**/ -void -viyank(void) +int +viyank(char **args) { - int oldcs = cs, c2; + int oldcs = cs, c2, ret = 1; startvichange(1); - if ((c2 = getvirange(0)) != -1) + if ((c2 = getvirange(0)) != -1) { cut(cs, c2 - cs, 0); + ret = 0; + } vichgflag = 0; cs = oldcs; + return ret; } /**/ -void -viyankeol(void) +int +viyankeol(char **args) { int x = findeol(); startvichange(-1); - if (x == cs) { - feep(); - return; - } + if (x == cs) + return 1; cut(cs, x - cs, 0); + return 0; } /**/ -void -viyankwholeline(void) +int +viyankwholeline(char **args) { int bol = findbol(), oldcs = cs; int n = zmult; startvichange(-1); if (n < 1) - return; + return 1; while(n--) { if (cs > ll) { - feep(); cs = oldcs; - return; + return 1; } cs = findeol() + 1; } vilinerange = 1; cut(bol, cs - bol - 1, 0); cs = oldcs; + return 0; } /**/ -void -vireplace(void) +int +vireplace(char **args) { startvitext(0); + return 0; } /* vi-replace-chars has some oddities relating to vi-repeat-change. In * @@ -474,32 +471,27 @@ vireplace(void) * without a rewrite of the repeat code. */ /**/ -void -vireplacechars(void) +int +vireplacechars(char **args) { int ch, n = zmult; startvichange(1); /* check argument range */ if (n < 1 || n + cs > findeol()) { - if(vichgrepeat) { - int ofeep = feepflag; + if(vichgrepeat) vigetkey(); - feepflag = ofeep; - } if(vichgflag) { free(vichgbuf); vichgbuf = NULL; vichgflag = 0; } - feep(); - return; + return 1; } /* get key */ if((ch = vigetkey()) == -1) { vichgflag = 0; - feep(); - return; + return 1; } /* do change */ if (ch == '\r' || ch == '\n') { @@ -513,47 +505,51 @@ vireplacechars(void) cs--; } vichgflag = 0; + return 0; } /**/ -void -vicmdmode(void) +int +vicmdmode(char **args) { if (invicmdmode() || selectkeymap("vicmd", 0)) - feep(); + return 1; undoing = 1; vichgflag = 0; if (cs != findbol()) cs--; + return 0; } /**/ -void -viopenlinebelow(void) +int +viopenlinebelow(char **args) { cs = findeol(); spaceinline(1); line[cs++] = '\n'; startvitext(1); clearlist = 1; + return 0; } /**/ -void -viopenlineabove(void) +int +viopenlineabove(char **args) { cs = findbol(); spaceinline(1); line[cs] = '\n'; startvitext(1); clearlist = 1; + return 0; } /**/ -void -vioperswapcase(void) +int +vioperswapcase(char **args) { - int oldcs, c2; + int oldcs, c2, ret = 1; /* get the range */ startvichange(1); @@ -569,22 +565,22 @@ vioperswapcase(void) } /* go back to the first line of the range */ cs = oldcs; + ret = 0; #if 0 vifirstnonblank(); #endif } vichgflag = 0; + return ret; } /**/ -void -virepeatchange(void) +int +virepeatchange(char **args) { /* make sure we have a change to repeat */ - if (!vichgbuf || vichgflag) { - feep(); - return; - } + if (!vichgbuf || vichgflag) + return 1; /* restore or update the saved count and buffer */ if (zmod.flags & MOD_MULT) { lastmod.mult = zmod.mult; @@ -598,11 +594,12 @@ virepeatchange(void) /* repeat the command */ inrepeat = 1; ungetkeys(vichgbuf, vichgbufptr); + return 0; } /**/ -void -viindent(void) +int +viindent(char **args) { int oldcs = cs, c2; @@ -610,14 +607,13 @@ viindent(void) startvichange(1); if ((c2 = getvirange(0)) == -1) { vichgflag = 0; - return; + return 1; } vichgflag = 0; /* must be a line range */ if (!vilinerange) { - feep(); cs = oldcs; - return; + return 1; } oldcs = cs; /* add a tab to the beginning of each line within range */ @@ -628,12 +624,13 @@ viindent(void) } /* go back to the first line of the range */ cs = oldcs; - vifirstnonblank(); + vifirstnonblank(zlenoargs); + return 0; } /**/ -void -viunindent(void) +int +viunindent(char **args) { int oldcs = cs, c2; @@ -641,14 +638,13 @@ viunindent(void) startvichange(1); if ((c2 = getvirange(0)) == -1) { vichgflag = 0; - return; + return 1; } vichgflag = 0; /* must be a line range */ if (!vilinerange) { - feep(); cs = oldcs; - return; + return 1; } oldcs = cs; /* remove a tab from the beginning of each line within range */ @@ -659,12 +655,13 @@ viunindent(void) } /* go back to the first line of the range */ cs = oldcs; - vifirstnonblank(); + vifirstnonblank(zlenoargs); + return 0; } /**/ -void -vibackwarddeletechar(void) +int +vibackwarddeletechar(char **args) { int n = zmult; @@ -672,16 +669,16 @@ vibackwarddeletechar(void) startvichange(-1); /* handle negative argument */ if (n < 0) { + int ret; zmult = -n; - videletechar(); + ret = videletechar(args); zmult = n; - return; + return ret; } /* It is an error to be at the beginning of the line, or (in * * insert mode) to delete past the beginning of insertion. */ if ((!invicmdmode() && cs - n < viinsbegin) || cs == findbol()) { - feep(); - return; + return 1; } /* Put argument into the acceptable range -- it is not an error to * * specify a greater count than the number of available characters. */ @@ -689,41 +686,39 @@ vibackwarddeletechar(void) n = cs - findbol(); /* do the deletion */ backkill(n, 1); + return 0; } /**/ -void -vikillline(void) +int +vikillline(char **args) { - if (viinsbegin > cs) { - feep(); - return; - } + if (viinsbegin > cs) + return 1; backdel(cs - viinsbegin); + return 0; } /**/ -void -viputbefore(void) +int +viputbefore(char **args) { Cutbuffer buf = &cutbuf; int n = zmult; startvichange(-1); if (n < 0) - return; + return 1; if (zmod.flags & MOD_VIBUF) buf = &vibuf[zmod.vibuf]; - if (!buf->buf) { - feep(); - return; - } + if (!buf->buf) + return 1; if(buf->flags & CUTBUFFER_LINE) { cs = findbol(); spaceinline(buf->len + 1); memcpy((char *)line + cs, buf->buf, buf->len); line[cs + buf->len] = '\n'; - vifirstnonblank(); + vifirstnonblank(zlenoargs); } else { while (n--) { spaceinline(buf->len); @@ -733,30 +728,29 @@ viputbefore(void) if (cs) cs--; } + return 0; } /**/ -void -viputafter(void) +int +viputafter(char **args) { Cutbuffer buf = &cutbuf; int n = zmult; startvichange(-1); if (n < 0) - return; + return 1; if (zmod.flags & MOD_VIBUF) buf = &vibuf[zmod.vibuf]; - if (!buf->buf) { - feep(); - return; - } + if (!buf->buf) + return 1; if(buf->flags & CUTBUFFER_LINE) { cs = findeol(); spaceinline(buf->len + 1); line[cs++] = '\n'; memcpy((char *)line + cs, buf->buf, buf->len); - vifirstnonblank(); + vifirstnonblank(zlenoargs); } else { if (cs != findeol()) cs++; @@ -768,20 +762,18 @@ viputafter(void) if (cs) cs--; } - + return 0; } /**/ -void -vijoin(void) +int +vijoin(char **args) { int x; startvichange(-1); - if ((x = findeol()) == ll) { - feep(); - return; - } + if ((x = findeol()) == ll) + return 1; cs = x + 1; for (x = 1; cs != ll && iblank(line[cs]); cs++, x++); backdel(x); @@ -791,17 +783,18 @@ vijoin(void) spaceinline(1); line[cs] = ' '; } + return 0; } /**/ -void -viswapcase(void) +int +viswapcase(char **args) { int eol, n = zmult; startvichange(-1); if (n < 1) - return; + return 1; eol = findeol(); while (cs < eol && n--) { if (islower(line[cs])) @@ -812,11 +805,12 @@ viswapcase(void) } if (cs && cs == eol) cs--; + return 0; } /**/ -void -vicapslockpanic(void) +int +vicapslockpanic(char **args) { clearlist = 1; zbeep(); @@ -825,20 +819,19 @@ vicapslockpanic(void) zrefresh(); while (!islower(getkey(0))); statusline = NULL; + return 0; } /**/ -void -visetbuffer(void) +int +visetbuffer(char **args) { int ch; if ((zmod.flags & MOD_VIBUF) || (((ch = getkey(0)) < '1' || ch > '9') && - (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))) { - feep(); - return; - } + (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))) + return 1; if (ch >= 'A' && ch <= 'Z') /* needed in cut() */ zmod.flags |= MOD_VIAPP; else @@ -846,32 +839,33 @@ visetbuffer(void) zmod.vibuf = tulower(ch) + (idigit(ch) ? -'1' + 26 : -'a'); zmod.flags |= MOD_VIBUF; prefixflag = 1; + return 0; } /**/ -void -vikilleol(void) +int +vikilleol(char **args) { int n = findeol() - cs; startvichange(-1); if (!n) { /* error -- line already empty */ - feep(); - return; + return 1; } /* delete to end of line */ forekill(findeol() - cs, 0); + return 0; } /**/ -void -vipoundinsert(void) +int +vipoundinsert(char **args) { int oldcs = cs; startvichange(-1); - vifirstnonblank(); + vifirstnonblank(zlenoargs); if(line[cs] != '#') { spaceinline(1); line[cs] = '#'; @@ -884,11 +878,12 @@ vipoundinsert(void) viinsbegin--; cs = oldcs - (cs < oldcs); } + return 0; } /**/ -void -viquotedinsert(void) +int +viquotedinsert(char **args) { #ifndef HAS_TIO struct sgttyb sob; @@ -908,23 +903,23 @@ viquotedinsert(void) #endif foredel(1); if(c < 0) - feep(); + return 1; else - selfinsert(); + return selfinsert(args); } /* the 0 key in vi: continue a repeat count in the manner of * * digit-argument if possible, otherwise do vi-beginning-of-line. */ /**/ -void -vidigitorbeginningofline(void) +int +vidigitorbeginningofline(char **args) { if(zmod.flags & MOD_TMULT) - digitargument(); + return digitargument(args); else { removesuffix(); invalidatelist(); - vibeginningofline(); + return vibeginningofline(args); } } diff --git a/Src/Zle/zle_word.c b/Src/Zle/zle_word.c index f446d1769..31f83a2df 100644 --- a/Src/Zle/zle_word.c +++ b/Src/Zle/zle_word.c @@ -31,38 +31,41 @@ #include "zle_word.pro" /**/ -void -forwardword(void) +int +forwardword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - backwardword(); + ret = backwardword(args); zmult = n; - return; + return ret; } while (n--) { while (cs != ll && iword(line[cs])) cs++; if (wordflag && !n) - return; + return 0; while (cs != ll && !iword(line[cs])) cs++; } + return 0; } /**/ -void -viforwardword(void) +int +viforwardword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - backwardword(); + ret = backwardword(args); zmult = n; - return; + return ret; } while (n--) { if (iident(line[cs])) @@ -72,64 +75,69 @@ viforwardword(void) while (cs != ll && !iident(line[cs]) && !iblank(line[cs])) cs++; if (wordflag && !n) - return; + return 0; while (cs != ll && (iblank(line[cs]) || line[cs] == '\n')) cs++; } + return 0; } /**/ -void -viforwardblankword(void) +int +viforwardblankword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - vibackwardblankword(); + ret = vibackwardblankword(args); zmult = n; - return; + return ret; } while (n--) { while (cs != ll && !iblank(line[cs])) cs++; if (wordflag && !n) - return; + return 0; while (cs != ll && iblank(line[cs])) cs++; } + return 0; } /**/ -void -emacsforwardword(void) +int +emacsforwardword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - emacsbackwardword(); + ret = emacsbackwardword(args); zmult = n; - return; + return ret; } while (n--) { while (cs != ll && !iword(line[cs])) cs++; if (wordflag && !n) - return; + return 0; while (cs != ll && iword(line[cs])) cs++; } + return 0; } /**/ -void -viforwardblankwordend(void) +int +viforwardblankwordend(char **args) { int n = zmult; if (n < 0) - return; + return 1; while (n--) { while (cs != ll && iblank(line[cs + 1])) cs++; @@ -138,19 +146,21 @@ viforwardblankwordend(void) } if (cs != ll && virangeflag) cs++; + return 0; } /**/ -void -viforwardwordend(void) +int +viforwardwordend(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - backwardword(); + ret = backwardword(args); zmult = n; - return; + return ret; } while (n--) { if (iblank(line[cs + 1])) @@ -165,19 +175,21 @@ viforwardwordend(void) } if (cs != ll && virangeflag) cs++; + return 0; } /**/ -void -backwardword(void) +int +backwardword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - forwardword(); + ret = forwardword(args); zmult = n; - return; + return ret; } while (n--) { while (cs && !iword(line[cs - 1])) @@ -185,19 +197,21 @@ backwardword(void) while (cs && iword(line[cs - 1])) cs--; } + return 0; } /**/ -void -vibackwardword(void) +int +vibackwardword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - backwardword(); + ret = backwardword(args); zmult = n; - return; + return ret; } while (n--) { while (cs && iblank(line[cs - 1])) @@ -209,19 +223,21 @@ vibackwardword(void) while (cs && !iident(line[cs - 1]) && !iblank(line[cs - 1])) cs--; } + return 0; } /**/ -void -vibackwardblankword(void) +int +vibackwardblankword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - viforwardblankword(); + ret = viforwardblankword(args); zmult = n; - return; + return ret; } while (n--) { while (cs && iblank(line[cs - 1])) @@ -229,19 +245,21 @@ vibackwardblankword(void) while (cs && !iblank(line[cs - 1])) cs--; } + return 0; } /**/ -void -emacsbackwardword(void) +int +emacsbackwardword(char **args) { int n = zmult; if (n < 0) { + int ret; zmult = -n; - emacsforwardword(); + ret = emacsforwardword(args); zmult = n; - return; + return ret; } while (n--) { while (cs && !iword(line[cs - 1])) @@ -249,19 +267,21 @@ emacsbackwardword(void) while (cs && iword(line[cs - 1])) cs--; } + return 0; } /**/ -void -backwarddeleteword(void) +int +backwarddeleteword(char **args) { int x = cs, n = zmult; if (n < 0) { + int ret; zmult = -n; - deleteword(); + ret = deleteword(args); zmult = n; - return; + return ret; } while (n--) { while (x && !iword(line[x - 1])) @@ -270,19 +290,18 @@ backwarddeleteword(void) x--; } backdel(cs - x); + return 0; } /**/ -void -vibackwardkillword(void) +int +vibackwardkillword(char **args) { int x = cs, lim = (viinsbegin > findbol()) ? viinsbegin : findbol(); int n = zmult; - if (n < 0) { - feep(); - return; - } + if (n < 0) + return 1; /* this taken from "vibackwardword" */ while (n--) { while ((x > lim) && iblank(line[x - 1])) @@ -295,20 +314,22 @@ vibackwardkillword(void) x--; } backkill(cs - x, 1); + return 0; } /**/ -void -backwardkillword(void) +int +backwardkillword(char **args) { int x = cs; int n = zmult; if (n < 0) { + int ret; zmult = -n; - killword(); + ret = killword(args); zmult = n; - return; + return ret; } while (n--) { while (x && !iword(line[x - 1])) @@ -317,11 +338,12 @@ backwardkillword(void) x--; } backkill(cs - x, 1); + return 0; } /**/ -void -upcaseword(void) +int +upcaseword(char **args) { int n = zmult; int neg = n < 0, ocs = cs; @@ -338,11 +360,12 @@ upcaseword(void) } if (neg) cs = ocs; + return 0; } /**/ -void -downcaseword(void) +int +downcaseword(char **args) { int n = zmult; int neg = n < 0, ocs = cs; @@ -359,11 +382,12 @@ downcaseword(void) } if (neg) cs = ocs; + return 0; } /**/ -void -capitalizeword(void) +int +capitalizeword(char **args) { int first, n = zmult; int neg = n < 0, ocs = cs; @@ -384,20 +408,22 @@ capitalizeword(void) } if (neg) cs = ocs; + return 0; } /**/ -void -deleteword(void) +int +deleteword(char **args) { int x = cs; int n = zmult; if (n < 0) { + int ret; zmult = -n; - backwarddeleteword(); + ret = backwarddeleteword(args); zmult = n; - return; + return ret; } while (n--) { while (x != ll && !iword(line[x])) @@ -406,20 +432,22 @@ deleteword(void) x++; } foredel(x - cs); + return 0; } /**/ -void -killword(void) +int +killword(char **args) { int x = cs; int n = zmult; if (n < 0) { + int ret; zmult = -n; - backwardkillword(); + ret = backwardkillword(args); zmult = n; - return; + return ret; } while (n--) { while (x != ll && !iword(line[x])) @@ -428,11 +456,12 @@ killword(void) x++; } forekill(x - cs, 0); + return 0; } /**/ -void -transposewords(void) +int +transposewords(char **args) { int p1, p2, p3, p4, x = cs; char *temp, *pp; @@ -448,22 +477,16 @@ transposewords(void) x = cs; while (x && line[x - 1] != '\n' && !iword(line[x])) x--; - if (!x || line[x - 1] == '\n') { - feep(); - return; - } + if (!x || line[x - 1] == '\n') + return 1; } for (p4 = x; p4 != ll && iword(line[p4]); p4++); for (p3 = p4; p3 && iword(line[p3 - 1]); p3--); - if (!p3) { - feep(); - return; - } + if (!p3) + return 1; for (p2 = p3; p2 && !iword(line[p2 - 1]); p2--); - if (!p2) { - feep(); - return; - } + if (!p2) + return 1; for (p1 = p2; p1 && iword(line[p1 - 1]); p1--); pp = temp = (char *)zhalloc(p4 - p1 + 1); struncpy(&pp, (char *) line + p3, p4 - p3); @@ -474,4 +497,5 @@ transposewords(void) } if (neg) cs = ocs; + return 0; } -- cgit 1.4.1