aboutsummaryrefslogtreecommitdiff
path: root/Src/Zle
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/compcore.c12
-rw-r--r--Src/Zle/compctl.c30
-rw-r--r--Src/Zle/complete.c4
-rw-r--r--Src/Zle/computil.c2
-rw-r--r--Src/Zle/zle_keymap.c160
-rw-r--r--Src/Zle/zle_main.c160
-rw-r--r--Src/Zle/zle_refresh.c4
-rw-r--r--Src/Zle/zle_thingy.c20
8 files changed, 297 insertions, 95 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 3ea9e8c4c..03e5eafc7 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -616,7 +616,7 @@ callcompfunc(char *s, char *fn)
untokenize(*q = ztrdup(*p));
*q = NULL;
} else
- compwords = (char **) zcalloc(sizeof(char *));
+ compwords = (char **) zshcalloc(sizeof(char *));
compparameter = ztrdup(compparameter);
compredirect = ztrdup(compredirect);
@@ -2706,7 +2706,7 @@ dupmatch(Cmatch m, int nbeg, int nend)
{
Cmatch r;
- r = (Cmatch) zcalloc(sizeof(struct cmatch));
+ r = (Cmatch) zshcalloc(sizeof(struct cmatch));
r->str = ztrdup(m->str);
r->ipre = ztrdup(m->ipre);
@@ -2803,7 +2803,7 @@ permmatches(int last)
if (g->mcount > 1)
diffmatches = 1;
- n = (Cmgroup) zcalloc(sizeof(struct cmgroup));
+ n = (Cmgroup) zshcalloc(sizeof(struct cmgroup));
if (g->perm) {
g->perm->next = NULL;
@@ -2821,7 +2821,7 @@ permmatches(int last)
n->num = gn++;
n->flags = g->flags;
n->mcount = g->mcount;
- n->matches = p = (Cmatch *) zcalloc((n->mcount + 1) * sizeof(Cmatch));
+ n->matches = p = (Cmatch *) zshcalloc((n->mcount + 1) * sizeof(Cmatch));
n->name = ztrdup(g->name);
for (q = g->matches; *q; q++, p++)
*p = dupmatch(*q, nbrbeg, nbrend);
@@ -2835,9 +2835,9 @@ permmatches(int last)
n->ylist = NULL;
if ((n->ecount = g->ecount)) {
- n->expls = ep = (Cexpl *) zcalloc((n->ecount + 1) * sizeof(Cexpl));
+ n->expls = ep = (Cexpl *) zshcalloc((n->ecount + 1) * sizeof(Cexpl));
for (eq = g->expls; (o = *eq); eq++, ep++) {
- *ep = e = (Cexpl) zcalloc(sizeof(struct cexpl));
+ *ep = e = (Cexpl) zshcalloc(sizeof(struct cexpl));
e->count = (fi ? o->fcount : o->count);
e->fcount = 0;
e->str = ztrdup(o->str);
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index b4981a842..d364e09d4 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -242,7 +242,7 @@ compctlread(char *name, char **args, char *ops, char *reply)
if (ops['A'] && !ops['e']) {
/* the -A option means that one array is specified, instead of
many parameters */
- char **p, **b = (char **)zcalloc((clwnum + 1) * sizeof(char *));
+ char **p, **b = (char **)zshcalloc((clwnum + 1) * sizeof(char *));
for (i = 0, p = b; i < clwnum; p++, i++)
*p = ztrdup(clwords[i]);
@@ -893,7 +893,7 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
cc->xor = &cc_default;
} else {
/* more flags follow: prepare to loop again */
- cc->xor = (Compctl) zcalloc(sizeof(*cc));
+ cc->xor = (Compctl) zshcalloc(sizeof(*cc));
cc = cc->xor;
memset((void *)&cct, 0, sizeof(cct));
cct.mask2 = CC_CCCONT;
@@ -930,7 +930,7 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
/* o keeps track of or's, m remembers the starting condition,
* c is the current condition being parsed
*/
- o = m = c = (Compcond) zcalloc(sizeof(*c));
+ o = m = c = (Compcond) zshcalloc(sizeof(*c));
/* Loop over each condition: something like 's[...][...], p[...]' */
for (t = *argv; *t;) {
while (*t == ' ')
@@ -1021,20 +1021,20 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
/* Allocate space for all the arguments of the conditions */
if (c->type == CCT_POS ||
c->type == CCT_NUMWORDS) {
- c->u.r.a = (int *)zcalloc(n * sizeof(int));
- c->u.r.b = (int *)zcalloc(n * sizeof(int));
+ c->u.r.a = (int *)zshcalloc(n * sizeof(int));
+ c->u.r.b = (int *)zshcalloc(n * sizeof(int));
} else if (c->type == CCT_CURSUF ||
c->type == CCT_CURPRE ||
c->type == CCT_QUOTE)
- c->u.s.s = (char **)zcalloc(n * sizeof(char *));
+ c->u.s.s = (char **)zshcalloc(n * sizeof(char *));
else if (c->type == CCT_RANGESTR ||
c->type == CCT_RANGEPAT) {
- c->u.l.a = (char **)zcalloc(n * sizeof(char *));
- c->u.l.b = (char **)zcalloc(n * sizeof(char *));
+ c->u.l.a = (char **)zshcalloc(n * sizeof(char *));
+ c->u.l.b = (char **)zshcalloc(n * sizeof(char *));
} else {
- c->u.s.p = (int *)zcalloc(n * sizeof(int));
- c->u.s.s = (char **)zcalloc(n * sizeof(char *));
+ c->u.s.p = (int *)zshcalloc(n * sizeof(int));
+ c->u.s.s = (char **)zshcalloc(n * sizeof(char *));
}
/* Now loop over the actual arguments */
for (l = 0; *t == '['; l++, t++) {
@@ -1137,17 +1137,17 @@ get_xcompctl(char *name, char ***av, Compctl cc, int isdef)
t++;
if (*t == ',') {
/* Another condition to `or' */
- o->or = c = (Compcond) zcalloc(sizeof(*c));
+ o->or = c = (Compcond) zshcalloc(sizeof(*c));
o = c;
t++;
} else if (*t) {
/* Another condition to `and' */
- c->and = (Compcond) zcalloc(sizeof(*c));
+ c->and = (Compcond) zshcalloc(sizeof(*c));
c = c->and;
}
}
/* Assign condition to current compctl */
- *next = (Compctl) zcalloc(sizeof(*cc));
+ *next = (Compctl) zshcalloc(sizeof(*cc));
(*next)->cond = m;
argv++;
/* End of the condition; get the flags that go with it. */
@@ -1271,7 +1271,7 @@ cc_reassign(Compctl cc)
*/
Compctl c2;
- c2 = (Compctl) zcalloc(sizeof *cc);
+ c2 = (Compctl) zshcalloc(sizeof *cc);
c2->xor = cc->xor;
c2->ext = cc->ext;
c2->refc = 1;
@@ -1587,7 +1587,7 @@ bin_compctl(char *name, char **argv, char *ops, int func)
if ((ret = get_gmatcher(name, argv)))
return ret - 1;
- cc = (Compctl) zcalloc(sizeof(*cc));
+ cc = (Compctl) zshcalloc(sizeof(*cc));
if (get_compctl(name, &argv, cc, 1, 0, 0)) {
freecompctl(cc);
return 1;
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 5f034a4a9..b9dc9f27a 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -686,7 +686,7 @@ restrict_range(int b, int e)
e = wl;
i = e - b + 1;
- p = (char **) zcalloc((i + 1) * sizeof(char *));
+ p = (char **) zshcalloc((i + 1) * sizeof(char *));
for (q = p, pp = compwords + b; i; i--, q++, pp++)
*q = ztrdup(*pp);
@@ -1158,7 +1158,7 @@ compunsetfn(Param pm, int exp)
*((char **) pm->u.data) = ztrdup("");
} else if (PM_TYPE(pm->flags) == PM_ARRAY) {
freearray(*((char ***) pm->u.data));
- *((char ***) pm->u.data) = zcalloc(sizeof(char *));
+ *((char ***) pm->u.data) = zshcalloc(sizeof(char *));
} else if (PM_TYPE(pm->flags) == PM_HASHED) {
deleteparamtable(pm->u.hash);
pm->u.hash = NULL;
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 157a179af..500ad3163 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -124,7 +124,7 @@ cd_init(char *nam, char *sep, char **args, int disp)
cd_state.showd = disp;
while (*args) {
- *setp = set = (Cdset) zcalloc(sizeof(*set));
+ *setp = set = (Cdset) zshcalloc(sizeof(*set));
setp = &(set->next);
if (!(ap = get_user_var(*args))) {
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 28203655e..9ac6dc8ed 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -86,6 +86,16 @@ struct bindstate {
char *lastseq;
Thingy bind;
char *str;
+ char *prefix;
+ int prefixlen;
+};
+
+/* This structure is used when scanning for prefix bindings to remove */
+
+struct remprefstate {
+ Keymap km;
+ char *prefix;
+ int prefixlen;
};
#define BS_LIST (1<<0)
@@ -146,7 +156,7 @@ createkeymapnamtab(void)
static KeymapName
makekeymapnamnode(Keymap keymap)
{
- KeymapName kmn = (KeymapName) zcalloc(sizeof(*kmn));
+ KeymapName kmn = (KeymapName) zshcalloc(sizeof(*kmn));
kmn->keymap = keymap;
return kmn;
@@ -191,7 +201,7 @@ newkeytab(char *kmname)
static Key
makekeynode(Thingy t, char *str)
{
- Key k = (Key) zcalloc(sizeof(*k));
+ Key k = (Key) zshcalloc(sizeof(*k));
k->bind = t;
k->str = str;
@@ -220,7 +230,7 @@ static HashTable copyto;
mod_export Keymap
newkeymap(Keymap tocopy, char *kmname)
{
- Keymap km = zcalloc(sizeof(*km));
+ Keymap km = zshcalloc(sizeof(*km));
int i;
km->rc = 0;
@@ -834,6 +844,19 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
zwarnnam(name, "keymap `%s' is protected", kmname, 0);
return 1;
}
+ if (func == 'r' && ops['p']) {
+ char *useq, *bseq;
+ int len;
+ struct remprefstate rps;
+ rps.km = km;
+ while ((useq = *argv++)) {
+ bseq = getkeystring(useq, &len, 2, NULL);
+ rps.prefix = metafy(bseq, len, META_USEHEAP);
+ rps.prefixlen = strlen(rps.prefix);
+ scankeymap(km, 0, scanremoveprefix, &rps);
+ }
+ return 0;
+ }
do {
char *useq = *argv, *bseq, *seq, *str;
int len;
@@ -878,6 +901,20 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
return ret;
}
+/* Remove bindings for key sequences which have the given (proper) prefix. */
+
+/**/
+static void
+scanremoveprefix(char *seq, Thingy bind, char *str, void *magic)
+{
+ struct remprefstate *rps = magic;
+
+ if (strncmp(seq, rps->prefix, rps->prefixlen) || !seq[rps->prefixlen])
+ return;
+
+ bindkey(rps->km, seq, refthingy(t_undefinedkey), NULL);
+}
+
/* List key bindings. If an argument is given, list just that one *
* binding, otherwise list the entire keymap. If the -L option is *
* given, list in the form of bindkey commands. */
@@ -890,7 +927,7 @@ bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
bs.flags = ops['L'] ? BS_LIST : 0;
bs.kmname = kmname;
- if(argv[0]) {
+ if(argv[0] && !ops['p']) {
int len;
char *seq;
@@ -899,8 +936,23 @@ bin_bindkey_list(char *name, char *kmname, Keymap km, char **argv, char *ops, ch
bs.flags |= BS_ALL;
bs.firstseq = bs.lastseq = seq;
bs.bind = keybind(km, seq, &bs.str);
+ bs.prefix = NULL;
+ bs.prefixlen = 0;
bindlistout(&bs);
} else {
+ /* empty prefix is equivalent to no prefix */
+ if (ops['p'] && (!argv[0] || argv[0][0])) {
+ if (!argv[0]) {
+ zwarnnam(name, "option -p requires a prefix string", NULL, 0);
+ return 1;
+ }
+ bs.prefix = getkeystring(argv[0], &bs.prefixlen, 2, NULL);
+ bs.prefix = metafy(bs.prefix, bs.prefixlen, META_HREALLOC);
+ bs.prefixlen = strlen(bs.prefix);
+ } else {
+ bs.prefix = NULL;
+ bs.prefixlen = 0;
+ }
bs.firstseq = ztrdup("");
bs.lastseq = ztrdup("");
bs.bind = t_undefinedkey;
@@ -919,6 +971,10 @@ scanbindlist(char *seq, Thingy bind, char *str, void *magic)
{
struct bindstate *bs = magic;
+ if (bs->prefixlen &&
+ (strncmp(seq, bs->prefix, bs->prefixlen) || !seq[bs->prefixlen]))
+ return;
+
if(bind == bs->bind && (bind || !strcmp(str, bs->str)) &&
ztrlen(seq) == 1 && ztrlen(bs->lastseq) == 1) {
int l = bs->lastseq[1] ?
@@ -1011,6 +1067,66 @@ cleanup_keymaps(void)
zfree(keybuf, keybufsz);
}
+static char *cursorptr;
+
+/* utility function for termcap output routine to add to string */
+
+static int
+add_cursor_char(int c)
+{
+ *cursorptr++ = c;
+ return 0;
+}
+
+/* interrogate termcap for cursor keys and add bindings to keymap */
+
+/**/
+static void
+add_cursor_key(Keymap km, int tccode, Thingy thingy, int defchar)
+{
+ char buf[2048];
+ int ok = 0;
+
+ /*
+ * Be careful not to try too hard with bindings for dubious or
+ * dysfunctional terminals.
+ */
+ if (tccan(tccode) && !(termflags & (TERM_NOUP|TERM_BAD|TERM_UNKNOWN))) {
+ /*
+ * We can use the real termcap sequence. We need to
+ * persuade termcap to output `move cursor 1 char' and capture it.
+ */
+ cursorptr = buf;
+ tputs(tcstr[tccode], 1, add_cursor_char);
+ *cursorptr = '\0';
+
+ /*
+ * Sanity checking. If the cursor key is zero-length (unlikely,
+ * but this is termcap we're talking about), or it's a single
+ * character, then we don't bind it.
+ */
+ if (buf[0] && buf[1] && (buf[0] != Meta || buf[2]))
+ ok = 1;
+ }
+ if (!ok) {
+ /* Assume the normal VT100-like values. */
+ sprintf(buf, "\33[%c", defchar);
+ }
+ bindkey(km, buf, refthingy(thingy), NULL);
+
+ /*
+ * If the string looked like \e[? or \eO?, bind the other one, too.
+ * This is necessary to make cursor keys work on many xterms with
+ * both normal and application modes.
+ */
+ if (buf[0] == '\33' && (buf[1] == '[' || buf[1] == 'O') &&
+ buf[2] && !buf[3])
+ {
+ buf[1] = (buf[1] == '[') ? 'O' : '[';
+ bindkey(km, buf, refthingy(thingy), NULL);
+ }
+}
+
/* Create the default keymaps. For efficiency reasons, this function *
* assigns directly to the km->first array. It knows that there are no *
* prefix bindings in the way, and that it is using a simple keymap. */
@@ -1023,6 +1139,7 @@ default_bindings(void)
Keymap emap = newkeymap(NULL, "emacs");
Keymap amap = newkeymap(NULL, "vicmd");
Keymap smap = newkeymap(NULL, ".safe");
+ Keymap vimaps[2], kptr;
char buf[3], *ed;
int i;
@@ -1066,25 +1183,22 @@ default_bindings(void)
/* vt100 arrow keys are bound by default, for historical reasons. *
* Both standard and keypad modes are supported. */
- /* vi command mode: arrow keys */
- bindkey(amap, "\33[A", refthingy(t_uplineorhistory), NULL);
- bindkey(amap, "\33[B", refthingy(t_downlineorhistory), NULL);
- bindkey(amap, "\33[C", refthingy(t_viforwardchar), NULL);
- bindkey(amap, "\33[D", refthingy(t_vibackwardchar), NULL);
- bindkey(amap, "\33OA", refthingy(t_uplineorhistory), NULL);
- bindkey(amap, "\33OB", refthingy(t_downlineorhistory), NULL);
- bindkey(amap, "\33OC", refthingy(t_viforwardchar), NULL);
- bindkey(amap, "\33OD", refthingy(t_vibackwardchar), NULL);
-
- /* emacs mode: arrow keys */
- bindkey(emap, "\33[A", refthingy(t_uplineorhistory), NULL);
- bindkey(emap, "\33[B", refthingy(t_downlineorhistory), NULL);
- bindkey(emap, "\33[C", refthingy(t_forwardchar), NULL);
- bindkey(emap, "\33[D", refthingy(t_backwardchar), NULL);
- bindkey(emap, "\33OA", refthingy(t_uplineorhistory), NULL);
- bindkey(emap, "\33OB", refthingy(t_downlineorhistory), NULL);
- bindkey(emap, "\33OC", refthingy(t_forwardchar), NULL);
- bindkey(emap, "\33OD", refthingy(t_backwardchar), NULL);
+ vimaps[0] = vmap;
+ vimaps[1] = amap;
+ for (i = 0; i < 2; i++) {
+ kptr = vimaps[i];
+ /* vi command and insert modes: arrow keys */
+ add_cursor_key(kptr, TCUPCURSOR, t_uplineorhistory, 'A');
+ add_cursor_key(kptr, TCDOWNCURSOR, t_downlineorhistory, 'B');
+ add_cursor_key(kptr, TCLEFTCURSOR, t_vibackwardchar, 'D');
+ add_cursor_key(kptr, TCRIGHTCURSOR, t_viforwardchar, 'C');
+ }
+
+ /* emacs mode: arrow keys */
+ add_cursor_key(emap, TCUPCURSOR, t_uplineorhistory, 'A');
+ add_cursor_key(emap, TCDOWNCURSOR, t_downlineorhistory, 'B');
+ add_cursor_key(emap, TCLEFTCURSOR, t_backwardchar, 'D');
+ add_cursor_key(emap, TCRIGHTCURSOR, t_forwardchar, 'C');
/* emacs mode: ^X sequences */
bindkey(emap, "\30*", refthingy(t_expandword), NULL);
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index aa5086597..6156b40d0 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -76,7 +76,10 @@ mod_export Thingy lbindk, bindk;
/**/
int insmode;
-static int eofchar, eofsent;
+/**/
+mod_export int eofchar;
+
+static int eofsent;
static long keytimeout;
#ifdef HAVE_SELECT
@@ -313,6 +316,7 @@ breakread(int fd, char *buf, int n)
FD_ZERO(&f);
FD_SET(fd, &f);
+
return (select(fd + 1, (SELECT_ARG_2_T) & f, NULL, NULL, NULL) == -1 ?
EOF : read(fd, buf, n));
}
@@ -395,7 +399,13 @@ getkey(int keytmout)
# endif
#endif
}
- while ((r = read(SHTTY, &cc, 1)) != 1) {
+ for (;;) {
+ int q = queue_signal_level();
+ dont_queue_signals();
+ r = read(SHTTY, &cc, 1);
+ restore_queue_signals(q);
+ if (r == 1)
+ break;
if (r == 0) {
/* The test for IGNOREEOF was added to make zsh ignore ^Ds
that were typed while commands are running. Unfortuantely
@@ -556,7 +566,7 @@ zleread(char *lp, char *rp, int flags)
reselectkeymap();
selectlocalmap(NULL);
bindk = getkeycmd();
- if (!ll && isfirstln && c == eofchar) {
+ if (!ll && isfirstln && unset(IGNOREEOF) && c == eofchar) {
eofsent = 1;
break;
}
@@ -630,23 +640,36 @@ execzlefunc(Thingy func, char **args)
} else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_NCOMP)) {
int wflags = w->flags;
- if(!(wflags & ZLE_KEEPSUFFIX))
- removesuffix();
- if(!(wflags & ZLE_MENUCMP)) {
- fixsuffix();
- invalidatelist();
+ if (keybuf[0] == eofchar && !keybuf[1] &&
+ !ll && isfirstln && isset(IGNOREEOF)) {
+ showmsg((!islogin) ? "zsh: use 'exit' to exit." :
+ "zsh: use 'logout' to logout.");
+ ret = 1;
+ } else {
+ if(!(wflags & ZLE_KEEPSUFFIX))
+ removesuffix();
+ if(!(wflags & ZLE_MENUCMP)) {
+ fixsuffix();
+ invalidatelist();
+ }
+ if (wflags & ZLE_LINEMOVE)
+ vilinerange = 1;
+ if(!(wflags & ZLE_LASTCOL))
+ lastcol = -1;
+ if (wflags & WIDGET_NCOMP) {
+ int atcurhist = histline == curhist;
+ compwidget = w;
+ ret = completecall(args);
+ if (atcurhist)
+ histline = curhist;
+ } else {
+ queue_signals();
+ ret = w->u.fn(args);
+ unqueue_signals();
+ }
+ if (!(wflags & ZLE_NOTCOMMAND))
+ lastcmd = wflags;
}
- if (wflags & ZLE_LINEMOVE)
- vilinerange = 1;
- if(!(wflags & ZLE_LASTCOL))
- lastcol = -1;
- if (wflags & WIDGET_NCOMP) {
- compwidget = w;
- ret = completecall(args);
- } else
- ret = w->u.fn(args);
- if (!(wflags & ZLE_NOTCOMMAND))
- lastcmd = wflags;
r = 1;
} else {
Eprog prog = getshfunc(w->u.fnnam);
@@ -735,11 +758,15 @@ bin_vared(char *name, char **args, char *ops, int func)
struct value vbuf;
Value v;
Param pm = 0;
- int create = 0, ifl;
+ int create = 0, ifl, ieof;
int type = PM_SCALAR, obreaks = breaks, haso = 0;
char *p1 = NULL, *p2 = NULL;
FILE *oshout = NULL;
+ if ((interact && unset(USEZLE)) || !strcmp(term, "emacs")) {
+ zwarnnam(name, "ZLE not enabled", NULL, 0);
+ return 1;
+ }
if (zleactive) {
zwarnnam(name, "ZLE cannot be used recursively (yet)", NULL, 0);
return 1;
@@ -810,17 +837,65 @@ bin_vared(char *name, char **args, char *ops, int func)
}
/* handle non-existent parameter */
s = args[0];
+ queue_signals();
v = fetchvalue(&vbuf, &s, (!create || type == PM_SCALAR),
SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY);
if (!v && !create) {
+ unqueue_signals();
zwarnnam(name, "no such variable: %s", args[0], 0);
return 1;
} else if (v) {
- s = getstrvalue(v);
- pm = v->pm;
+ if (v->isarr) {
+ /* Array: check for separators and quote them. */
+ char **arr = getarrvalue(v), **aptr, **tmparr, **tptr;
+ tptr = tmparr = (char **)zhalloc(sizeof(char *)*(arrlen(arr)+1));
+ for (aptr = arr; *aptr; aptr++) {
+ int sepcount = 0;
+ /*
+ * See if this word contains a separator character
+ * or backslash
+ */
+ for (t = *aptr; *t; t++) {
+ if (*t == Meta) {
+ if (isep(t[1] ^ 32))
+ sepcount++;
+ t++;
+ } else if (isep(*t) || *t == '\\')
+ sepcount++;
+ }
+ if (sepcount) {
+ /* Yes, so allocate enough space to quote it. */
+ char *newstr, *nptr;
+ newstr = zhalloc(strlen(*aptr)+sepcount+1);
+ /* Go through string quoting separators */
+ for (t = *aptr, nptr = newstr; *t; ) {
+ if (*t == Meta) {
+ if (isep(t[1] ^ 32))
+ *nptr++ = '\\';
+ *nptr++ = *t++;
+ } else if (isep(*t) || *t == '\\')
+ *nptr++ = '\\';
+ *nptr++ = *t++;
+ }
+ *nptr = '\0';
+ /* Stick this into the array of words to join up */
+ *tptr++ = newstr;
+ } else
+ *tptr++ = *aptr; /* No, keep original array element */
+ }
+ *tptr = NULL;
+ s = sepjoin(tmparr, NULL, 0);
+ } else {
+ s = ztrdup(getstrvalue(v));
+ }
+ unqueue_signals();
} else if (*s) {
+ unqueue_signals();
zwarnnam(name, "invalid parameter name: %s", args[0], 0);
return 1;
+ } else {
+ unqueue_signals();
+ s = ztrdup(s);
}
if (SHTTY == -1) {
@@ -835,22 +910,23 @@ bin_vared(char *name, char **args, char *ops, int func)
haso = 1;
}
/* edit the parameter value */
- zpushnode(bufstack, ztrdup(s));
+ zpushnode(bufstack, s);
varedarg = *args;
ifl = isfirstln;
- if (ops['e'])
- isfirstln = 1;
if (ops['h'])
- hbegin(1);
+ hbegin(2);
+ isfirstln = ops['e'];
+ ieof = opts[IGNOREEOF];
+ opts[IGNOREEOF] = 0;
t = (char *) zleread(p1, p2, ops['h'] ? ZLRF_HISTORY : 0);
+ opts[IGNOREEOF] = ieof;
if (ops['h'])
- hend();
+ hend(NULL);
isfirstln = ifl;
varedarg = ova;
if (haso) {
- close(SHTTY);
- fclose(shout);
+ fclose(shout); /* close(SHTTY) */
shout = oshout;
SHTTY = -1;
}
@@ -864,24 +940,27 @@ bin_vared(char *name, char **args, char *ops, int func)
if (t[strlen(t) - 1] == '\n')
t[strlen(t) - 1] = '\0';
/* final assignment of parameter value */
- if (create && (!pm || (type && PM_TYPE(pm->flags) != type))) {
- if (pm)
- unsetparam(args[0]);
+ if (create) {
+ unsetparam(args[0]);
createparam(args[0], type);
- pm = 0;
}
- if (!pm)
- pm = (Param) paramtab->getnode(paramtab, args[0]);
+ queue_signals();
+ pm = (Param) paramtab->getnode(paramtab, args[0]);
if (pm && (PM_TYPE(pm->flags) & (PM_ARRAY|PM_HASHED))) {
char **a;
- a = spacesplit(t, 1, 0);
+ /*
+ * Use spacesplit with fourth argument 1: identify quoted separators,
+ * unquote but don't split.
+ */
+ a = spacesplit(t, 1, 0, 1);
if (PM_TYPE(pm->flags) == PM_ARRAY)
setaparam(args[0], a);
else
sethparam(args[0], a);
} else
setsparam(args[0], t);
+ unqueue_signals();
return 0;
}
@@ -1015,9 +1094,9 @@ zleaftertrap(Hookdef dummy, void *dat)
}
static struct builtin bintab[] = {
- BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL),
+ BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLRp", NULL),
BUILTIN("vared", 0, bin_vared, 1, 7, 0, NULL, NULL),
- BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRaU", NULL),
+ BUILTIN("zle", 0, bin_zle, 0, -1, 0, "lDANCLmMgGcRaUI", NULL),
};
/* The order of the entries in this table has to match the *HOOK
@@ -1040,7 +1119,6 @@ setup_(Module m)
{
/* Set up editor entry points */
trashzleptr = trashzle;
- gotwordptr = gotword;
refreshptr = zrefresh;
spaceinlineptr = spaceinline;
zlereadptr = zleread;
@@ -1054,6 +1132,7 @@ setup_(Module m)
/* miscellaneous initialisations */
stackhist = stackcs = -1;
kungetbuf = (char *) zalloc(kungetsz = 32);
+ comprecursive = 0;
/* initialise the keymap system */
init_keymaps();
@@ -1062,7 +1141,7 @@ setup_(Module m)
incompfunc = incompctlfunc = hascompmod = 0;
- clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *));
+ clwords = (char **) zshcalloc((clwsize = 16) * sizeof(char *));
return 0;
}
@@ -1117,7 +1196,6 @@ finish_(Module m)
/* editor entry points */
trashzleptr = noop_function;
- gotwordptr = noop_function;
refreshptr = noop_function;
spaceinlineptr = noop_function_int;
zlereadptr = fallback_zleread;
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index c432907d1..68860f391 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -133,8 +133,8 @@ resetvideo(void)
free(nbuf);
free(obuf);
}
- nbuf = (char **)zcalloc((winh + 1) * sizeof(char *));
- obuf = (char **)zcalloc((winh + 1) * sizeof(char *));
+ nbuf = (char **)zshcalloc((winh + 1) * sizeof(char *));
+ obuf = (char **)zshcalloc((winh + 1) * sizeof(char *));
nbuf[0] = (char *)zalloc(winw + 2);
obuf[0] = (char *)zalloc(winw + 2);
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 1d1eaacf3..f40bd18b8 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -107,7 +107,7 @@ scanemptythingies(HashNode hn, int flags)
static Thingy
makethingynode(void)
{
- Thingy t = (Thingy) zcalloc(sizeof(*t));
+ Thingy t = (Thingy) zshcalloc(sizeof(*t));
t->flags = DISABLED;
return t;
@@ -339,6 +339,7 @@ bin_zle(char *name, char **args, char *ops, int func)
{ 'R', bin_zle_refresh, 0, -1 },
{ 'M', bin_zle_mesg, 1, 1 },
{ 'U', bin_zle_unget, 1, 1 },
+ { 'I', bin_zle_invalidate, 0, 0 },
{ 0, bin_zle_call, 0, -1 },
};
struct opn const *op, *opp;
@@ -396,10 +397,8 @@ bin_zle_refresh(char *name, char **args, char *ops, char func)
char *s = statusline;
int sl = statusll, ocl = clearlist;
- if (!zleactive) {
- zwarnnam(name, "can only be called from widget function", NULL, 0);
+ if (!zleactive)
return 1;
- }
statusline = NULL;
statusll = 0;
if (*args) {
@@ -628,7 +627,7 @@ bin_zle_call(char *name, char **args, char *ops, char func)
return 1;
}
if (!args[0][1])
- args++;
+ *++args = "" - 1;
modsave = zmod;
saveflag = 1;
zmod.mult = atoi(num);
@@ -656,6 +655,17 @@ bin_zle_call(char *name, char **args, char *ops, char func)
return ret;
}
+/**/
+static int
+bin_zle_invalidate(char *name, char **args, char *ops, char func)
+{
+ if (zleactive) {
+ trashzle();
+ return 0;
+ } else
+ return 1;
+}
+
/*******************/
/* initialiasation */
/*******************/