summaryrefslogtreecommitdiff
path: root/Src/Zle
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/compcore.c4
-rw-r--r--Src/Zle/compctl.c34
-rw-r--r--Src/Zle/complete.c4
-rw-r--r--Src/Zle/complist.c15
-rw-r--r--Src/Zle/compmatch.c57
-rw-r--r--Src/Zle/computil.c356
-rw-r--r--Src/Zle/textobjects.c9
-rw-r--r--Src/Zle/zle.h7
-rw-r--r--Src/Zle/zle_hist.c17
-rw-r--r--Src/Zle/zle_keymap.c2
-rw-r--r--Src/Zle/zle_main.c8
-rw-r--r--Src/Zle/zle_params.c11
-rw-r--r--Src/Zle/zle_refresh.c12
-rw-r--r--Src/Zle/zle_thingy.c27
-rw-r--r--Src/Zle/zle_tricky.c47
15 files changed, 315 insertions, 295 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index d1cf7a08a..52b0c173f 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -3135,7 +3135,9 @@ matchcmp(Cmatch *a, Cmatch *b)
if ((*b)->disp && !((*b)->flags & CMF_MORDER))
return 1;
- return zstrbcmp((*a)->str, (*b)->str);
+ return zstrcmp((*a)->str, (*b)->str, (SORTIT_IGNORING_BACKSLASHES|
+ (isset(NUMERICGLOBSORT) ?
+ SORTIT_NUMERICALLY : 0)));
}
/* This tests whether two matches are equal (would produce the same
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index 52c6f1233..5414b8ff6 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -99,7 +99,7 @@ freecompctlp(HashNode hn)
}
/**/
-void
+static void
freecompctl(Compctl cc)
{
if (cc == &cc_default ||
@@ -142,7 +142,7 @@ freecompctl(Compctl cc)
}
/**/
-void
+static void
freecompcond(void *a)
{
Compcond cc = (Compcond) a;
@@ -186,7 +186,7 @@ freecompcond(void *a)
}
/**/
-int
+static int
compctlread(char *name, char **args, Options ops, char *reply)
{
char *buf, *bptr;
@@ -1564,6 +1564,8 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
Compctl cc = NULL;
int ret = 0;
+ queue_signals();
+
/* clear static flags */
cclist = 0;
showmask = 0;
@@ -1571,12 +1573,15 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
/* Parse all the arguments */
if (*argv) {
/* Let's see if this is a global matcher definition. */
- if ((ret = get_gmatcher(name, argv)))
+ if ((ret = get_gmatcher(name, argv))) {
+ unqueue_signals();
return ret - 1;
+ }
cc = (Compctl) zshcalloc(sizeof(*cc));
if (get_compctl(name, &argv, cc, 1, 0, 0)) {
freecompctl(cc);
+ unqueue_signals();
return 1;
}
@@ -1604,6 +1609,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
printcompctl((cclist & COMP_LIST) ? "" : "DEFAULT", &cc_default, 0, 0);
printcompctl((cclist & COMP_LIST) ? "" : "FIRST", &cc_first, 0, 0);
print_gmatcher((cclist & COMP_LIST));
+ unqueue_signals();
return ret;
}
@@ -1642,6 +1648,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
printcompctl("", &cc_first, 0, 0);
if (cclist & COMP_LISTMATCH)
print_gmatcher(COMP_LIST);
+ unqueue_signals();
return ret;
}
@@ -1656,6 +1663,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
compctl_process_cc(argv, cc);
}
+ unqueue_signals();
return ret;
}
@@ -1667,12 +1675,18 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
static int
bin_compcall(char *name, UNUSED(char **argv), Options ops, UNUSED(int func))
{
+ int ret;
+
if (incompfunc != 1) {
zwarnnam(name, "can only be called from completion function");
return 1;
}
- return makecomplistctl((OPT_ISSET(ops,'T') ? 0 : CFN_FIRST) |
- (OPT_ISSET(ops,'D') ? 0 : CFN_DEFAULT));
+
+ queue_signals();
+ ret = makecomplistctl((OPT_ISSET(ops,'T') ? 0 : CFN_FIRST) |
+ (OPT_ISSET(ops,'D') ? 0 : CFN_DEFAULT));
+ unqueue_signals();
+ return ret;
}
/*
@@ -1756,6 +1770,8 @@ ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
int onm = nmatches, odm = diffmatches, osi = movefd(0);
LinkNode n;
+ queue_signals();
+
/* We build a copy of the list of matchers to use to make sure that this
* works even if a shell function called from the completion code changes
* the global matchers. */
@@ -1851,6 +1867,7 @@ ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
redup(osi, 0);
dat->lst = 0;
+ unqueue_signals();
return 0;
}
if (lastmatches) {
@@ -1874,6 +1891,7 @@ ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
redup(osi, 0);
dat->lst = 0;
+ unqueue_signals();
return 0;
}
if (!m || !(m = m->next))
@@ -1883,6 +1901,8 @@ ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
}
redup(osi, 0);
dat->lst = 1;
+
+ unqueue_signals();
return 0;
}
@@ -2044,7 +2064,7 @@ maketildelist(void)
/* This does the check for compctl -x `n' and `N' patterns. */
/**/
-int
+static int
getcpat(char *str, int cpatindex, char *cpat, int class)
{
char *s, *t, *p;
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 48fcd4751..68bdf2332 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -901,7 +901,7 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod)
return 0;
singsub(&sa);
- pp = patcompile(sa, PAT_STATIC, NULL);
+ pp = patcompile(sa, PAT_HEAPDUP, NULL);
for (i--, p = compwords + i; i >= 0; p--, i--) {
if (pattry(pp, *p)) {
@@ -955,7 +955,7 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod)
if (!na)
return 0;
- if (!(pp = patcompile(sa, PAT_STATIC, 0)))
+ if (!(pp = patcompile(sa, PAT_HEAPDUP, 0)))
return 0;
if (test == CVT_PREPAT) {
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 2edaf6eca..a83daeff9 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -1993,7 +1993,8 @@ complistmatches(UNUSED(Hookdef dummy), Chdata dat)
if (noselect > 0)
noselect = 0;
- if ((minfo.asked == 2 && mselect < 0) || nlnct >= zterm_lines) {
+ if ((minfo.asked == 2 && mselect < 0) || nlnct >= zterm_lines ||
+ errflag) {
showinglist = 0;
amatches = oamatches;
return (noselect = 1);
@@ -2333,11 +2334,6 @@ msearch(Cmatch **ptr, char *ins, int back, int rep, int *wrapp)
}
}
if (x == ex && y == ey) {
- if (wrap) {
- msearchstate = MS_FAILED | owrap;
- break;
- }
- msearchstate |= MS_WRAPPED;
if (back) {
x = mcols - 1;
@@ -2349,6 +2345,13 @@ msearch(Cmatch **ptr, char *ins, int back, int rep, int *wrapp)
}
ex = mcol;
ey = mline;
+
+ if (wrap || (x == ex && y == ey)) {
+ msearchstate = MS_FAILED | owrap;
+ break;
+ }
+
+ msearchstate |= MS_WRAPPED;
wrap = 1;
*wrapp = 1;
}
diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index aedf463fc..1cdbb8a48 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -1548,27 +1548,11 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws)
{
convchar_t c, wc;
convchar_t ind, wind;
- int len = 0, wlen, mt, wmt;
-#ifdef MULTIBYTE_SUPPORT
- mbstate_t lstate, wstate;
-
- memset(&lstate, 0, sizeof(lstate));
- memset(&wstate, 0, sizeof(wstate));
-#endif
+ int len = 0, wlen = 0, mt, wmt;
while (p && wp && *s && *ws) {
/* First test the word character */
-#ifdef MULTIBYTE_SUPPORT
- wlen = mb_metacharlenconv_r(ws, &wc, &wstate);
-#else
- if (*ws == Meta) {
- wc = STOUC(ws[1]) ^ 32;
- wlen = 2;
- } else {
- wc = STOUC(*ws);
- wlen = 1;
- }
-#endif
+ wc = unmeta_one(ws, &wlen);
wind = pattern_match1(wp, wc, &wmt);
if (!wind)
return 0;
@@ -1576,18 +1560,7 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws)
/*
* Now the line character.
*/
-#ifdef MULTIBYTE_SUPPORT
- len = mb_metacharlenconv_r(s, &c, &lstate);
-#else
- /* We have the character itself. */
- if (*s == Meta) {
- c = STOUC(s[1]) ^ 32;
- len = 2;
- } else {
- c = STOUC(*s);
- len = 1;
- }
-#endif
+ c = unmeta_one(s, &len);
/*
* If either is "?", they match each other; no further tests.
* Apply this even if the character wasn't convertable;
@@ -1627,17 +1600,7 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws)
}
while (p && *s) {
-#ifdef MULTIBYTE_SUPPORT
- len = mb_metacharlenconv_r(s, &c, &lstate);
-#else
- if (*s == Meta) {
- c = STOUC(s[1]) ^ 32;
- len = 2;
- } else {
- c = STOUC(*s);
- len = 1;
- }
-#endif
+ c = unmeta_one(s, &len);
if (!pattern_match1(p, c, &mt))
return 0;
p = p->next;
@@ -1645,17 +1608,7 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws)
}
while (wp && *ws) {
-#ifdef MULTIBYTE_SUPPORT
- wlen = mb_metacharlenconv_r(ws, &wc, &wstate);
-#else
- if (*ws == Meta) {
- wc = STOUC(ws[1]) ^ 32;
- wlen = 2;
- } else {
- wc = STOUC(*ws);
- wlen = 1;
- }
-#endif
+ wc = unmeta_one(ws, &wlen);
if (!pattern_match1(wp, wc, &wmt))
return 0;
wp = wp->next;
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 192ddeab9..e704f9ffa 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -917,7 +917,6 @@ struct cadef {
int argsactive; /* if normal arguments are still allowed */
/* used while parsing a command line */
char *set; /* set name prefix (<name>-), shared */
- char *sname; /* set name */
int flags; /* see CDF_* below */
char *nonarg; /* pattern for non-args (-A argument) */
};
@@ -935,7 +934,7 @@ struct caopt {
Caarg args; /* option arguments */
int active; /* still allowed on command line */
int num; /* it's the num'th option */
- char *set; /* set name, shared */
+ char *gsname; /* group or set name, shared */
int not; /* don't complete this option (`!...') */
};
@@ -956,10 +955,10 @@ struct caarg {
char *end; /* end-pattern for ::<pat>:... */
char *opt; /* option name if for an option */
int num; /* it's the num'th argument */
- int min; /* it's also this argument, using opt. args */
+ int min; /* earliest possible arg pos, given optional args */
int direct; /* true if argument number was given explicitly */
int active; /* still allowed on command line */
- char *set; /* set name, shared */
+ char *gsname; /* group or set name, shared */
};
#define CAA_NORMAL 1
@@ -1020,7 +1019,6 @@ freecadef(Cadef d)
s = d->snext;
zsfree(d->match);
zsfree(d->set);
- zsfree(d->sname);
if (d->defs)
freearray(d->defs);
@@ -1098,7 +1096,7 @@ parse_caarg(int mult, int type, int num, int opt, char *oname, char **def,
ret->type = type;
ret->opt = ztrdup(oname);
ret->direct = 0;
- ret->set = set;
+ ret->gsname = set;
/* Get the description. */
@@ -1147,8 +1145,11 @@ alloc_cadef(char **args, int single, char *match, char *nonarg, int flags)
ret->defs = NULL;
ret->ndefs = 0;
}
+ ret->nopts = 0;
+ ret->ndopts = 0;
+ ret->nodopts = 0;
ret->lastt = time(0);
- ret->set = ret->sname = NULL;
+ ret->set = NULL;
if (single) {
ret->single = (Caopt *) zalloc(256 * sizeof(Caopt));
memset(ret->single, 0, 256 * sizeof(Caopt));
@@ -1182,12 +1183,10 @@ parse_cadef(char *nam, char **args)
Cadef all, ret;
Caopt *optp;
char **orig_args = args, *p, *q, *match = "r:|[_-]=* r:|=*", **xor, **sargs;
- char *adpre, *adsuf, *axor = NULL, *doset = NULL, **setp = NULL;
+ char *adpre, *adsuf, *axor = NULL, *doset = NULL, **pendset = NULL, **curset = NULL;
char *nonarg = NULL;
- int single = 0, anum = 1, xnum, nopts, ndopts, nodopts, flags = 0;
- int state = 0, not = 0;
-
- nopts = ndopts = nodopts = 0;
+ int single = 0, anum = 1, xnum, flags = 0;
+ int foreignset = 0, not = 0;
/* First string is the auto-description definition. */
@@ -1250,51 +1249,72 @@ parse_cadef(char *nam, char **args)
if (nonarg)
tokenize(nonarg = dupstring(nonarg));
-
/* Looks good. Optimistically allocate the cadef structure. */
all = ret = alloc_cadef(orig_args, single, match, nonarg, flags);
optp = &(ret->opts);
- anum = 1;
-
sargs = args;
/* Get the definitions. */
- for (; *args; args++) {
+ for (; *args || pendset; args++) {
+ if (!*args) {
+ /* start new set */
+ args = sargs; /* go back and repeat parse of common options */
+ doset = NULL;
+ set_cadef_opts(ret);
+ ret = ret->snext = alloc_cadef(NULL, single, match, nonarg, flags);
+ optp = &(ret->opts);
+ anum = 1;
+ foreignset = 0;
+ curset = pendset;
+ pendset = 0;
+ }
if (args[0][0] == '-' && !args[0][1] && args[1]) {
- if (!state) {
- char *p;
- int l;
-
- if (setp)
- args = setp;
- p = *++args;
- l = strlen(p) - 1;
+ if ((foreignset = curset && args != curset)) {
+ if (!pendset && args > curset)
+ pendset = args; /* mark pointer to next pending set */
+ ++args;
+ } else {
+ /* Carrying on: this is the current set */
+ char *p = *++args;
+ int l = strlen(p) - 1;
+
if (*p == '(' && p[l] == ')') {
axor = p = dupstring(p + 1);
p[l - 1] = '\0';
} else
axor = NULL;
+ if (!*p) {
+ freecadef(all);
+ zwarnnam(nam, "empty set name");
+ return NULL;
+ }
ret->set = doset = tricat(p, "-", "");
- ret->sname = ztrdup(p);
- state = 1;
- } else {
- setp = args;
- state = 0;
- args = sargs - 1;
- doset = NULL;
- ret->nopts = nopts;
- ret->ndopts = ndopts;
- ret->nodopts = nodopts;
- set_cadef_opts(ret);
- ret = ret->snext = alloc_cadef(NULL, single, NULL, nonarg, flags);
- optp = &(ret->opts);
- nopts = ndopts = nodopts = 0;
- anum = 1;
+ curset = args; /* needed for the first set */
}
continue;
- }
+ } else if (args[0][0] == '+' && !args[0][1] && args[1]) {
+ char *p;
+ int l;
+
+ foreignset = 0; /* group not in any set, don't want to skip it */
+ p = *++args;
+ l = strlen(p) - 1;
+ if (*p == '(' && p[l] == ')') {
+ axor = p = dupstring(p + 1);
+ p[l - 1] = '\0';
+ } else
+ axor = NULL;
+ if (!*p) {
+ freecadef(all);
+ zwarnnam(nam, "empty group name");
+ return NULL;
+ }
+ doset = tricat(p, "-", "");
+ continue;
+ } else if (foreignset) /* skipping over a different set */
+ continue;
p = dupstring(*args);
xnum = 0;
if ((not = (*p == '!')))
@@ -1506,7 +1526,7 @@ parse_cadef(char *nam, char **args)
optp = &((*optp)->next);
opt->next = NULL;
- opt->set = doset;
+ opt->gsname = doset;
opt->name = ztrdup(rembslashcolon(name));
if (descr)
opt->descr = ztrdup(descr);
@@ -1526,13 +1546,13 @@ parse_cadef(char *nam, char **args)
opt->xor = (again == 1 && xor ? zarrdup(xor) : xor);
opt->type = otype;
opt->args = oargs;
- opt->num = nopts++;
+ opt->num = ret->nopts++;
opt->not = not;
if (otype == CAO_DIRECT || otype == CAO_EQUAL)
- ndopts++;
+ ret->ndopts++;
else if (otype == CAO_ODIRECT || otype == CAO_OEQUAL)
- nodopts++;
+ ret->nodopts++;
/* If this is for single-letter option we also store a
* pointer for the definition in the array for fast lookup.
@@ -1584,7 +1604,7 @@ parse_cadef(char *nam, char **args)
continue;
if ((direct = idigit(*p))) {
- /* Argment number is given. */
+ /* Argument number is given. */
int num = 0;
while (*p && idigit(*p))
@@ -1630,9 +1650,6 @@ parse_cadef(char *nam, char **args)
ret->args = arg;
}
}
- ret->nopts = nopts;
- ret->ndopts = ndopts;
- ret->nodopts = nodopts;
set_cadef_opts(ret);
return all;
@@ -1751,6 +1768,27 @@ ca_get_sopt(Cadef d, char *line, char **end, LinkList *lp)
return pp;
}
+/* Search for an option in all sets except the current one.
+ * Return true if found */
+
+static int
+ca_foreign_opt(Cadef curset, Cadef all, char *option)
+{
+ Cadef d;
+ Caopt p;
+
+ for (d = all; d; d = d->snext) {
+ if (d == curset)
+ continue;
+
+ for (p = d->opts; p; p = p->next) {
+ if (!strcmp(p->name, option))
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* Return the n'th argument definition. */
static Caarg
@@ -1776,77 +1814,95 @@ ca_get_arg(Cadef d, int n)
* d: option definitions for a set
* pass either:
* xor: a list if exclusions
- * opts: if set, all options excluded leaving only nornal/rest arguments
- * if ca_xor list initialised, exclusions are added to it */
-
-static LinkList ca_xor;
+ * opts: if set, all options excluded leaving only nornal/rest arguments */
-static int
-ca_inactive(Cadef d, char **xor, int cur, int opts, char *optname)
+static void
+ca_inactive(Cadef d, char **xor, int cur, int opts)
{
if ((xor || opts) && cur <= compcurrent) {
Caopt opt;
char *x;
- int sl = (d->set ? (int)strlen(d->set) : -1), set = 0;
+ /* current word could be a prefix of a longer one so only do
+ * exclusions for single-letter options (for option clumping) */
+ int single = (cur == compcurrent);
for (; (x = (opts ? "-" : *xor)); xor++) {
- if (optname && optname[0] == x[0] && strcmp(optname, x))
- continue;
- if (ca_xor)
- addlinknode(ca_xor, x);
- set = 0;
- if (sl > 0) {
- if (strpfx(d->set, x)) {
- x += sl;
- set = 1;
- } else if (!strncmp(d->set, x, sl - 1)) {
- Caopt p;
-
- for (p = d->opts; p; p = p->next)
- if (p->set)
- p->active = 0;
-
- x = ":";
- set = 1;
+ int excludeall = 0;
+ char *grp = NULL;
+ size_t grplen;
+ char *next, *sep = x;
+
+ while (*sep != '+' && *sep != '-' && *sep != ':' && *sep != '*' && !idigit(*sep)) {
+ if (!(next = strchr(sep, '-')) || !*++next) {
+ /* exclusion is just the name of a set or group */
+ excludeall = 1; /* excluding options and args */
+ sep += strlen(sep);
+ /* A trailing '-' is included in the various gsname fields but is not
+ * there for this branch. This is why we add excludeall to grplen
+ * when checking for the null in a few places below */
+ break;
}
+ sep = next;
+ }
+ if (sep > x) { /* exclusion included a set or group name */
+ grp = x;
+ grplen = sep - grp;
+ x = sep;
}
- if (x[0] == ':' && !x[1]) {
- if (set) {
+
+ if (excludeall || (x[0] == ':' && !x[1])) {
+ if (grp) {
Caarg a;
for (a = d->args; a; a = a->next)
- if (a->set)
+ if (a->gsname && !strncmp(a->gsname, grp, grplen) &&
+ !a->gsname[grplen + excludeall])
a->active = 0;
- if (d->rest && (!set || d->rest->set))
+ if (d->rest && d->rest->gsname &&
+ !strncmp(d->rest->gsname, grp, grplen) &&
+ !d->rest->gsname[grplen + excludeall])
d->rest->active = 0;
} else
d->argsactive = 0;
- } else if (x[0] == '-' && !x[1]) {
+ }
+
+ if (excludeall || (x[0] == '-' && !x[1])) {
Caopt p;
for (p = d->opts; p; p = p->next)
- if (!set || p->set)
+ if ((!grp || (p->gsname && !strncmp(p->gsname, grp, grplen) &&
+ !p->gsname[grplen + excludeall])) &&
+ !(single && *p->name && p->name[1] && p->name[2]))
p->active = 0;
- } else if (x[0] == '*' && !x[1]) {
- if (d->rest && (!set || d->rest->set))
- d->rest->active = 0;
- } else if (idigit(x[0])) {
- int n = atoi(x);
- Caarg a = d->args;
-
- while (a && a->num < n)
- a = a->next;
+ }
- if (a && a->num == n && (!set || a->set))
- a->active = 0;
- } else if ((opt = ca_get_opt(d, x, 1, NULL)) && (!set || opt->set))
- opt->active = 0;
+ if (excludeall || (x[0] == '*' && !x[1])) {
+ if (d->rest && (!grp || (d->rest->gsname &&
+ !strncmp(d->rest->gsname, grp, grplen) &&
+ !d->rest->gsname[grplen + excludeall])))
+ d->rest->active = 0;
+ }
- if (opts)
- break;
+ if (!excludeall) {
+ if (idigit(x[0])) {
+ int n = atoi(x);
+ Caarg a = d->args;
+
+ while (a && a->num < n)
+ a = a->next;
+
+ if (a && a->num == n && (!grp || (a->gsname &&
+ !strncmp(a->gsname, grp, grplen))))
+ a->active = 0;
+ } else if ((opt = ca_get_opt(d, x, 1, NULL)) &&
+ (!grp || (opt->gsname && !strncmp(opt->gsname, grp, grplen))) &&
+ !(single && *opt->name && opt->name[1] && opt->name[2]))
+ opt->active = 0;
+ if (opts)
+ break;
+ }
}
}
- return 0;
}
/* State when parsing a command line. */
@@ -1875,7 +1931,6 @@ struct castate {
int curpos; /* current word position */
int argend; /* total number of words */
int inopt; /* set to current word pos if word is a recognised option */
- int inrest; /* unused */
int inarg; /* in a normal argument */
int nth; /* number of current normal arg */
int doff; /* length of current option */
@@ -1934,7 +1989,7 @@ ca_opt_arg(Caopt opt, char *line)
* existing options on the line. */
static int
-ca_parse_line(Cadef d, int multi, int first)
+ca_parse_line(Cadef d, Cadef all, int multi, int first)
{
Caarg adef, ddef;
Caopt ptr, wasopt = NULL, dopt;
@@ -1978,7 +2033,7 @@ ca_parse_line(Cadef d, int multi, int first)
state.argbeg = state.optbeg = state.nargbeg = state.restbeg = state.actopts =
state.nth = state.inopt = state.inarg = state.opt = state.arg = 1;
state.argend = argend = arrlen(compwords) - 1;
- state.inrest = state.doff = state.singles = state.oopt = 0;
+ state.doff = state.singles = state.oopt = 0;
state.curpos = compcurrent;
state.args = znewlinklist();
state.oargs = (LinkList *) zalloc(d->nopts * sizeof(LinkList));
@@ -2025,10 +2080,9 @@ ca_parse_line(Cadef d, int multi, int first)
remnulargs(line);
untokenize(line);
- if (ca_inactive(d, argxor, cur, 0, NULL) ||
- ((d->flags & CDF_SEP) && cur != compcurrent && !strcmp(line, "--"))) {
- if (ca_inactive(d, NULL, cur, 1, NULL))
- return 1;
+ ca_inactive(d, argxor, cur, 0);
+ if ((d->flags & CDF_SEP) && cur != compcurrent && !strcmp(line, "--")) {
+ ca_inactive(d, NULL, cur, 1);
continue;
}
@@ -2104,9 +2158,7 @@ ca_parse_line(Cadef d, int multi, int first)
if (!state.oargs[state.curopt->num])
state.oargs[state.curopt->num] = znewlinklist();
- if (ca_inactive(d, state.curopt->xor, cur, 0,
- (cur == compcurrent ? state.curopt->name : NULL)))
- return 1;
+ ca_inactive(d, state.curopt->xor, cur, 0);
/* Collect the argument strings. Maybe. */
@@ -2159,9 +2211,7 @@ ca_parse_line(Cadef d, int multi, int first)
if (!state.oargs[tmpopt->num])
state.oargs[tmpopt->num] = znewlinklist();
- if (ca_inactive(d, tmpopt->xor, cur, 0,
- (cur == compcurrent ? tmpopt->name : NULL)))
- return 1;
+ ca_inactive(d, tmpopt->xor, cur, 0);
}
}
if (state.def &&
@@ -2183,20 +2233,13 @@ ca_parse_line(Cadef d, int multi, int first)
else
state.curopt = NULL;
} else if (multi && (*line == '-' || *line == '+') && cur != compcurrent
-#if 0
- /**** Ouch. Using this will disable the mutual exclusion
- of different sets. Not using it will make the -A
- pattern be effectively ignored with multiple sets. */
- && (!napat || !pattry(napat, line))
-#endif
- )
+ && (ca_foreign_opt(d, all, line)))
return 1;
else if (state.arg &&
(!napat || cur <= compcurrent || !pattry(napat, line))) {
/* Otherwise it's a normal argument. */
- if (napat && cur <= compcurrent &&
- ca_inactive(d, NULL, cur + 1, 1, NULL))
- return 1;
+ if (napat && cur <= compcurrent)
+ ca_inactive(d, NULL, cur + 1, 1);
arglast = 1;
/* if this is the first normal arg after an option, may have been
@@ -2231,7 +2274,6 @@ ca_parse_line(Cadef d, int multi, int first)
if (ca_laststate.def)
break;
- state.inrest = 0;
state.opt = (cur == state.nargbeg + 1 &&
(!multi || !*line ||
*line == '-' || *line == '+'));
@@ -2421,19 +2463,19 @@ ca_set_data(LinkList descr, LinkList act, LinkList subc,
restrict_range(ca_laststate.argbeg, ca_laststate.argend);
}
if (arg->opt) {
- buf = (char *) zhalloc((arg->set ? strlen(arg->set) : 0) +
+ buf = (char *) zhalloc((arg->gsname ? strlen(arg->gsname) : 0) +
strlen(arg->opt) + 40);
if (arg->num > 0 && arg->type < CAA_REST)
sprintf(buf, "%soption%s-%d",
- (arg->set ? arg->set : ""), arg->opt, arg->num);
+ (arg->gsname ? arg->gsname : ""), arg->opt, arg->num);
else
sprintf(buf, "%soption%s-rest",
- (arg->set ? arg->set : ""), arg->opt);
+ (arg->gsname ? arg->gsname : ""), arg->opt);
} else if (arg->num > 0) {
sprintf(nbuf, "argument-%d", arg->num);
- buf = (arg->set ? dyncat(arg->set, nbuf) : dupstring(nbuf));
+ buf = (arg->gsname ? dyncat(arg->gsname, nbuf) : dupstring(nbuf));
} else
- buf = (arg->set ? dyncat(arg->set, "argument-rest") :
+ buf = (arg->gsname ? dyncat(arg->gsname, "argument-rest") :
dupstring("argument-rest"));
addlinknode(subc, buf);
@@ -2537,47 +2579,29 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
* auto-description string, the optional -s, -S, -A and -M options
* given to _arguments and the specs. */
if (compcurrent > 1 && compwords[0]) {
- Cadef def;
+ Cadef def, all;
int cap = ca_parsed, multi, first = 1, use, ret = 0;
- LinkList cax = ca_xor, nx;
- LinkNode node;
Castate states = NULL, sp;
- char *xor[2];
ca_parsed = 0;
- xor[1] = NULL;
- if (!(def = get_cadef(nam, args + 1)))
+ if (!(def = all = get_cadef(nam, args + 1)))
return 1;
multi = !!def->snext; /* if we have sets */
ca_parsed = cap;
- ca_xor = (multi ? newlinklist() : NULL);
while (def) { /* for each set */
- use = !ca_parse_line(def, multi, first);
- nx = ca_xor;
- ca_xor = NULL; /* don't want to duplicate the xors in the list */
- while ((def = def->snext)) {
- if (nx) {
- for (node = firstnode(nx); node; incnode(node)) {
- xor[0] = (char *) getdata(node);
- if (!strcmp(xor[0], def->sname) ||
- ca_inactive(def, xor, compcurrent, 0, NULL))
- break; /* exclude this whole set */
- }
- if (!node) /* continue with this set */
- break;
- }
- /* entire set was excluded, continue to next set */
- }
- ca_xor = nx;
+ use = !ca_parse_line(def, all, multi, first);
+ def = def->snext;
if (use && def) {
+ /* entry needed so save it into list */
sp = (Castate) zalloc(sizeof(*sp));
memcpy(sp, &ca_laststate, sizeof(*sp));
sp->snext = states;
states = sp;
} else if (!use && !def) {
+ /* final entry not needed */
if (states) {
freecastate(&ca_laststate);
memcpy(&ca_laststate, states, sizeof(*sp));
@@ -2589,7 +2613,6 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
}
first = 0;
}
- ca_xor = cax;
ca_parsed = 1;
ca_laststate.snext = states;
@@ -2602,7 +2625,7 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
* things _arguments has to execute at this place on the line (the
* sub-contexts are used as tags).
* The return value is particularly important here, it says if
- * there are arguments to completely at all. */
+ * there are arguments to complete at all. */
{
LinkList descr, act, subc;
Caarg arg;
@@ -2805,7 +2828,7 @@ bin_comparguments(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
for (s = lstate; s; s = s->snext)
for (o = s->d->opts, a = s->oargs; o; o = o->next, a++)
if (*a) {
- *p++ = (o->set ? tricat(o->set, o->name, "") :
+ *p++ = (o->gsname ? tricat(o->gsname, o->name, "") :
ztrdup(o->name));
*p++ = ca_colonlist(*a);
}
@@ -3546,8 +3569,8 @@ bin_compvalues(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
Cvval val = cv_get_val(cv_laststate.d, args[1]);
if (val && val->arg) {
- setsparam(args[2], val->arg->descr);
- setsparam(args[3], val->arg->action);
+ setsparam(args[2], ztrdup(val->arg->descr));
+ setsparam(args[3], ztrdup(val->arg->action));
if (args[4])
setsparam(args[4], ztrdup(val->name));
@@ -3905,6 +3928,8 @@ bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
if (*q) {
char *qq, *qqq;
+ queue_signals();
+
if (c)
*c = '\0';
@@ -3976,6 +4001,8 @@ bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
}
if (c)
*c = ':';
+
+ unqueue_signals();
}
}
if (num) {
@@ -4438,17 +4465,24 @@ cfp_matcher_pats(char *matcher, char *add)
if (m && m != pcm_err) {
char *tmp;
int al = strlen(add), zl = ztrlen(add), tl, cl;
- VARARR(Cmatcher, ms, zl);
+ VARARR(Cmatcher, ms, zl); /* One Cmatcher per character */
Cmatcher *mp;
Cpattern stopp;
int stopl = 0;
+ /* zl >= (number of wide characters) is guaranteed */
memset(ms, 0, zl * sizeof(Cmatcher));
for (; m && *add; m = m->next) {
stopp = NULL;
if (!(m->flags & (CMF_LEFT|CMF_RIGHT))) {
if (m->llen == 1 && m->wlen == 1) {
+ /*
+ * In this loop and similar loops below we step
+ * through tmp one (possibly wide) character at a
+ * time. pattern_match() compares only the first
+ * character using unmeta_one() so keep in step.
+ */
for (tmp = add, tl = al, mp = ms; tl; ) {
if (pattern_match(m->line, tmp, NULL, NULL)) {
if (*mp) {
@@ -4458,10 +4492,10 @@ cfp_matcher_pats(char *matcher, char *add)
} else
*mp = m;
}
- cl = (*tmp == Meta) ? 2 : 1;
+ (void) unmeta_one(tmp, &cl);
tl -= cl;
tmp += cl;
- mp += cl;
+ mp++;
}
} else {
stopp = m->line;
@@ -4478,10 +4512,10 @@ cfp_matcher_pats(char *matcher, char *add)
} else
*mp = m;
}
- cl = (*tmp == Meta) ? 2 : 1;
+ (void) unmeta_one(tmp, &cl);
tl -= cl;
tmp += cl;
- mp += cl;
+ mp++;
}
} else if (m->llen) {
stopp = m->line;
@@ -4504,7 +4538,7 @@ cfp_matcher_pats(char *matcher, char *add)
al = tmp - add;
break;
}
- cl = (*tmp == Meta) ? 2 : 1;
+ (void) unmeta_one(tmp, &cl);
tl -= cl;
tmp += cl;
}
@@ -4685,6 +4719,8 @@ cfp_add_sdirs(LinkList final, LinkList orig, char *skipped,
if (!*p)
continue;
+ queue_signals(); /* Protect PAT_STATIC */
+
tokenize(f);
pprog = patcompile(f, PAT_STATIC, NULL);
untokenize(f);
@@ -4717,6 +4753,8 @@ cfp_add_sdirs(LinkList final, LinkList orig, char *skipped,
}
}
}
+
+ unqueue_signals();
}
}
}
diff --git a/Src/Zle/textobjects.c b/Src/Zle/textobjects.c
index 3db0781ff..bf83906f2 100644
--- a/Src/Zle/textobjects.c
+++ b/Src/Zle/textobjects.c
@@ -48,9 +48,10 @@ int
selectword(UNUSED(char **args))
{
int n = zmult;
- int all = (bindk == t_selectaword || bindk == t_selectablankword);
- int (*viclass)(ZLE_CHAR_T) = (bindk == t_selectaword ||
- bindk == t_selectinword) ? wordclass : blankwordclass;
+ int all = IS_THINGY(bindk, selectaword) ||
+ IS_THINGY(bindk, selectablankword);
+ int (*viclass)(ZLE_CHAR_T) = (IS_THINGY(bindk, selectaword) ||
+ IS_THINGY(bindk, selectinword)) ? wordclass : blankwordclass;
int sclass = viclass(zleline[zlecs]);
int doblanks = all && sclass;
@@ -288,7 +289,7 @@ selectargument(UNUSED(char **args))
free(stringaszleline(linein, wstarts[wcur], &zlecs, &tmpsz, &mark));
free(linein);
- if (bindk == t_selectinshellword) {
+ if (IS_THINGY(bindk, selectinshellword)) {
ZLE_CHAR_T *match = ZWS("`\'\"");
ZLE_CHAR_T *lmatch = ZWS("\'({"), *rmatch = ZWS("\')}");
ZLE_CHAR_T *ematch = match, *found;
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index 8f92e5611..07b310180 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -230,6 +230,13 @@ struct thingy {
/* DISABLED is (1<<0) */
#define TH_IMMORTAL (1<<1) /* can't refer to a different widget */
+/*
+ * Check if bindk refers to named thingy (a set of bare characters),
+ * also checking the special .thingy widget.
+ */
+#define IS_THINGY(bindk, name) \
+ ((bindk) == t_ ## name || (bindk) == t_D ## name)
+
/* command modifier prefixes */
struct modifier {
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index abd6e1749..581ca4979 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -1220,13 +1220,14 @@ doisearch(char **args, int dir, int pattern)
char *patbuf = ztrdup(sbuf);
char *patstring;
/*
- * Use static pattern buffer since we don't need
- * to maintain it and won't call other pattern functions
- * meanwhile.
- * Use PAT_NOANCH because we don't need the match
- * anchored to the end, even if it is at the start.
+ * Do not use static pattern buffer (PAT_STATIC) since we
+ * call zle hooks, which might call other pattern
+ * functions. Use PAT_ZDUP because we re-use the pattern
+ * in subsequent loops, so we can't pushheap/popheap.
+ * Use PAT_NOANCH because we don't need the match anchored
+ * to the end, even if it is at the start.
*/
- int patflags = PAT_STATIC|PAT_NOANCH;
+ int patflags = PAT_ZDUP|PAT_NOANCH;
if (sbuf[0] == '^') {
/*
* We'll handle the anchor later when
@@ -1521,6 +1522,7 @@ doisearch(char **args, int dir, int pattern)
if (only_one || !top_spot || old_sbptr != sbptr)
break;
}
+ freepatprog(patprog);
patprog = NULL;
nosearch = 1;
skip_pos = 0;
@@ -1632,6 +1634,7 @@ doisearch(char **args, int dir, int pattern)
}
strcpy(sbuf + sbptr, paste);
sbptr += pastelen;
+ freepatprog(patprog);
patprog = NULL;
free(paste);
} else if (cmd == Th(z_acceptsearch)) {
@@ -1682,6 +1685,7 @@ doisearch(char **args, int dir, int pattern)
* always valid at this point.
*/
sbptr += zlecharasstring(LASTFULLCHAR, sbuf + sbptr);
+ freepatprog(patprog);
patprog = NULL;
}
if (feep)
@@ -1702,6 +1706,7 @@ doisearch(char **args, int dir, int pattern)
zsfree(okeymap);
if (matchlist)
freematchlist(matchlist);
+ freepatprog(patprog);
isearch_active = 0;
/*
* Don't allow unused characters provided as a string to the
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 04eb70675..2e96ac780 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -961,7 +961,7 @@ bin_bindkey_meta(char *name, char *kmname, Keymap km, UNUSED(char **argv), UNUSE
m[0] = i;
metafy(m, 1, META_NOALLOC);
fn = keybind(km, m, &str);
- if(fn == t_selfinsert || fn == t_undefinedkey)
+ if(IS_THINGY(fn, selfinsert) || fn == t_undefinedkey)
bindkey(km, m, refthingy(Th(metabind[i - 128])), NULL);
}
return 0;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 15ea79643..be2b062b0 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1245,6 +1245,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
resetneeded = 0;
fetchttyinfo = 0;
trashedzle = 0;
+ clearflag = 0;
raw_lp = lp;
lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL, &pmpt_attr);
raw_rp = rp;
@@ -1484,6 +1485,13 @@ execzlefunc(Thingy func, char **args, int set_bindk)
int inuse = w->flags & WIDGET_INUSE;
w->flags |= WIDGET_INUSE;
+ if (osi > 0) {
+ /*
+ * Many commands don't like having a closed stdin, open on
+ * /dev/null instead
+ */
+ open("/dev/null", O_RDWR | O_NOCTTY); /* ignore failure */
+ }
if (*args) {
largs = newlinklist();
addlinknode(largs, dupstring(w->u.fnnam));
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index 1e4c5b832..0a922d2d6 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -85,6 +85,8 @@ static const struct gsu_integer cursor_gsu =
{ get_cursor, set_cursor, zleunsetfn };
static const struct gsu_integer histno_gsu =
{ get_histno, set_histno, zleunsetfn };
+static const struct gsu_integer keys_queued_count_gsu =
+{ get_keys_queued_count, NULL, zleunsetfn };
static const struct gsu_integer mark_gsu =
{ get_mark, set_mark, zleunsetfn };
static const struct gsu_integer numeric_gsu =
@@ -146,6 +148,8 @@ static struct zleparam {
{ "HISTNO", PM_INTEGER, GSU(histno_gsu), NULL },
{ "KEYMAP", PM_SCALAR | PM_READONLY, GSU(keymap_gsu), NULL },
{ "KEYS", PM_SCALAR | PM_READONLY, GSU(keys_gsu), NULL },
+ { "KEYS_QUEUED_COUNT", PM_INTEGER | PM_READONLY, GSU(keys_queued_count_gsu),
+ NULL},
{ "killring", PM_ARRAY, GSU(killring_gsu), NULL },
{ "LASTABORTEDSEARCH", PM_SCALAR | PM_READONLY, GSU(lastabortedsearch_gsu),
NULL },
@@ -458,6 +462,13 @@ get_keys(UNUSED(Param pm))
}
/**/
+static zlong
+get_keys_queued_count(UNUSED(Param pm))
+{
+ return kungetct;
+}
+
+/**/
static void
set_numeric(UNUSED(Param pm), zlong x)
{
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 8d173cda1..d0dd1ef06 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1278,7 +1278,7 @@ zrefresh(void)
#ifdef __STDC_ISO_10646__
!ZSH_INVALID_WCHAR_TEST(*t) &&
#endif
- iswprint(*t) && (width = WCWIDTH(*t)) > 0) {
+ WC_ISPRINT(*t) && (width = WCWIDTH(*t)) > 0) {
int ichars;
if (width > rpms.sen - rpms.s) {
int started = 0;
@@ -1460,7 +1460,7 @@ zrefresh(void)
u = outputline;
for (; u < outputline + outll; u++) {
#ifdef MULTIBYTE_SUPPORT
- if (iswprint(*u)) {
+ if (WC_ISPRINT(*u)) {
int width = WCWIDTH(*u);
/* Handle wide characters as above */
if (width > rpms.sen - rpms.s) {
@@ -2434,8 +2434,8 @@ redisplay(UNUSED(char **args))
moveto(0, 0);
zputc(&zr_cr); /* extra care */
tc_upcurs(lprompth - 1);
- resetneeded = !showinglist;
- clearflag = showinglist;
+ resetneeded = 1;
+ clearflag = 0;
return 0;
}
@@ -2468,7 +2468,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
if (tmpline[t0] == ZWC('\t'))
vsiz = (vsiz | 7) + 2;
#ifdef MULTIBYTE_SUPPORT
- else if (iswprint(tmpline[t0]) && ((width = WCWIDTH(tmpline[t0])) > 0)) {
+ else if (WC_ISPRINT(tmpline[t0]) && ((width = WCWIDTH(tmpline[t0])) > 0)) {
vsiz += width;
if (isset(COMBININGCHARS) && IS_BASECHAR(tmpline[t0])) {
while (t0 < tmpll-1 && IS_COMBINING(tmpline[t0+1]))
@@ -2556,7 +2556,7 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
vp->atr = all_atr_on | all_atr_off;
vp++;
#ifdef MULTIBYTE_SUPPORT
- } else if (iswprint(tmpline[t0]) &&
+ } else if (WC_ISPRINT(tmpline[t0]) &&
(width = WCWIDTH(tmpline[t0])) > 0) {
int ichars;
if (isset(COMBININGCHARS) && IS_BASECHAR(tmpline[t0])) {
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index c7092854a..f7e9829c2 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -602,7 +602,7 @@ bin_zle_complete(char *name, char **args, UNUSED(Options ops), UNUSED(char func)
Thingy t;
Widget w, cw;
- if (require_module("zsh/complete", NULL) == 1) {
+ if (require_module("zsh/complete", NULL, 0) == 1) {
zwarnnam(name, "can't load complete module");
return 1;
}
@@ -703,7 +703,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
{
Thingy t;
struct modifier modsave = zmod;
- int ret, saveflag = 0, setbindk = 0;
+ int ret, saveflag = 0, setbindk = 0, remetafy;
char *wname = *args++, *keymap_restore = NULL, *keymap_tmp;
if (!wname)
@@ -714,7 +714,15 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
return 1;
}
- UNMETACHECK();
+ /*
+ * zle is callable in traps, so we can't be sure the line is
+ * in its normal state.
+ */
+ if (zlemetaline) {
+ unmetafy_line();
+ remetafy = 1;
+ } else
+ remetafy = 0;
while (*args && **args == '-') {
char *num;
@@ -728,6 +736,8 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
num = args[0][1] ? args[0]+1 : args[1];
if (!num) {
zwarnnam(name, "number expected after -%c", **args);
+ if (remetafy)
+ metafy_line();
return 1;
}
if (!args[0][1])
@@ -745,19 +755,26 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
keymap_tmp = args[0][1] ? args[0]+1 : args[1];
if (!keymap_tmp) {
zwarnnam(name, "keymap expected after -%c", **args);
+ if (remetafy)
+ metafy_line();
return 1;
}
if (!args[0][1])
*++args = "" - 1;
keymap_restore = dupstring(curkeymapname);
- if (selectkeymap(keymap_tmp, 0))
+ if (selectkeymap(keymap_tmp, 0)) {
+ if (remetafy)
+ metafy_line();
return 1;
+ }
break;
case 'w':
setbindk = 1;
break;
default:
zwarnnam(name, "unknown option: %s", *args);
+ if (remetafy)
+ metafy_line();
return 1;
}
}
@@ -775,6 +792,8 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
zmod = modsave;
if (keymap_restore)
selectkeymap(keymap_restore, 0);
+ if (remetafy)
+ metafy_line();
return ret;
}
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 3d8679119..5a9cccb6f 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -2407,53 +2407,6 @@ sfxlen(char *s, char *t)
}
#endif
-/* This is zstrcmp with ignoring backslashes. */
-
-/**/
-mod_export int
-zstrbcmp(const char *a, const char *b)
-{
- const char *astart = a;
-
- while (*a && *b) {
- if (*a == '\\')
- a++;
- if (*b == '\\')
- b++;
- if (*a != *b || !*a)
- break;
- a++;
- b++;
- }
- if (isset(NUMERICGLOBSORT) && (idigit(*a) || idigit(*b))) {
- for (; a > astart && idigit(a[-1]); a--, b--);
- if (idigit(*a) && idigit(*b)) {
- while (*a == '0')
- a++;
- while (*b == '0')
- b++;
- for (; idigit(*a) && *a == *b; a++, b++);
- if (idigit(*a) || idigit(*b)) {
- int cmp = (int) STOUC(*a) - (int) STOUC(*b);
-
- while (idigit(*a) && idigit(*b))
- a++, b++;
- if (idigit(*a) && !idigit(*b))
- return 1;
- if (idigit(*b) && !idigit(*a))
- return -1;
-
- return cmp;
- }
- }
- }
-#ifndef HAVE_STRCOLL
- return (int)(*a - *b);
-#else
- return strcoll(a,b);
-#endif
-}
-
/* This is used to print the strings (e.g. explanations). *
* It returns the number of lines printed. */