summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--Src/Zle/compcore.c86
-rw-r--r--Src/Zle/compctl.c76
-rw-r--r--Src/Zle/complist.c134
-rw-r--r--Src/Zle/compresult.c275
-rw-r--r--Src/Zle/zle.h13
-rw-r--r--Src/Zle/zle_hist.c22
-rw-r--r--Src/Zle/zle_main.c5
-rw-r--r--Src/Zle/zle_misc.c23
-rw-r--r--Src/Zle/zle_params.c50
-rw-r--r--Src/Zle/zle_refresh.c71
-rw-r--r--Src/Zle/zle_thingy.c4
-rw-r--r--Src/Zle/zle_tricky.c419
-rw-r--r--Src/Zle/zle_utils.c229
-rw-r--r--Src/hist.c56
-rw-r--r--Src/lex.c19
-rw-r--r--Src/utils.c2
17 files changed, 943 insertions, 553 deletions
diff --git a/ChangeLog b/ChangeLog
index d3b5d90ac..8fe4b035e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2005-08-10 Peter Stephenson <pws@csr.com>
+
+ * c.f. 21590: Src/hist.c, Src/lex.c, Src/utils.c,
+ Src/Zle/compcore.c, Src/Zle/compctl.c, Src/Zle/complist.c,
+ Src/Zle/compresult.c, Src/Zle/zle.h, Src/Zle/zle_hist.c,
+ Src/Zle/zle_main.c, Src/Zle/zle_misc.c, Src/Zle/zle_params.c,
+ Src/Zle/zle_refresh.c, Src/Zle/zle_thingy.c, Src/Zle/zle_tricky.c,
+ Src/Zle/zle_utils.c: upgrade metafy_line()/unmetafy_line() to
+ take account of wide characters. Add extra conversion where
+ necessary. Also attempt fix for singlerefresh() prompt with
+ ZLE_UNICODE_SUPPORT (untested).
+
2005-08-10 Wayne Davison <wayned@users.sourceforge.net>
* 21579: Thorsten Dahlheimer: Src/builtin.c: Made printf %s
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 0c1f13078..df43cc1ac 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -281,7 +281,10 @@ mod_export int lastend;
#define inststr(X) inststrlen((X),1,-1)
-/* Main completion entry point, called from zle. */
+/*
+ * Main completion entry point, called from zle.
+ * At this point the line is already metafied.
+ */
/**/
int
@@ -292,6 +295,8 @@ do_completion(UNUSED(Hookdef dummy), Compldat dat)
char *opm;
LinkNode n;
+ METACHECK();
+
pushheap();
ainfo = fainfo = NULL;
@@ -329,7 +334,7 @@ do_completion(UNUSED(Hookdef dummy), Compldat dat)
(isset(LISTPACKED) ? "packed rows" : "rows") :
(isset(LISTPACKED) ? "packed" : ""));
startauto = isset(AUTOMENU);
- movetoend = ((zlecs == we || isset(ALWAYSTOEND)) ? 2 : 1);
+ movetoend = ((zlemetacs == we || isset(ALWAYSTOEND)) ? 2 : 1);
showinglist = 0;
hasmatched = hasunmatched = 0;
minmlen = 1000000;
@@ -341,10 +346,10 @@ do_completion(UNUSED(Hookdef dummy), Compldat dat)
/* Make sure we have the completion list and compctl. */
if (makecomplist(s, incmd, lst)) {
/* Error condition: feeeeeeeeeeeeep(). */
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
inststr(origline);
- zlecs = origcs;
+ zlemetacs = origcs;
clearlist = 1;
ret = 1;
minfo.cur = NULL;
@@ -366,10 +371,10 @@ do_completion(UNUSED(Hookdef dummy), Compldat dat)
ret = selfinsert(zlenoargs);
else if (!useline && uselist) {
/* All this and the guy only wants to see the list, sigh. */
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
inststr(origline);
- zlecs = origcs;
+ zlemetacs = origcs;
showinglist = -2;
} else if (useline == 2 && nmatches > 1) {
do_allmatches(1);
@@ -414,10 +419,10 @@ do_completion(UNUSED(Hookdef dummy), Compldat dat)
invalidatelist();
if (forcelist)
clearlist = 1;
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
inststr(origline);
- zlecs = origcs;
+ zlemetacs = origcs;
}
/* Print the explanation strings if needed. */
if (!showinglist && validlist && usemenu != 2 && uselist &&
@@ -430,9 +435,9 @@ do_completion(UNUSED(Hookdef dummy), Compldat dat)
for (n = firstnode(matchers); n; incnode(n))
freecmatcher((Cmatcher) getdata(n));
- zlell = strlen((char *)zleline);
- if (zlecs > zlell)
- zlecs = zlell;
+ zlemetall = strlen((char *)zlemetaline);
+ if (zlemetacs > zlemetall)
+ zlemetacs = zlemetall;
popheap();
return ret;
@@ -469,6 +474,11 @@ before_complete(UNUSED(Hookdef dummy), int *lst)
/* We may have to reset the cursor to its position after the *
* string inserted by the last completion. */
+ /*
+ * Currently this hook runs before metafication.
+ * This is the only hook of the three defined here of
+ * which that is true.
+ */
if ((fromcomp & FC_INWORD) && (zlecs = lastend) > zlell)
zlecs = zlell;
@@ -499,10 +509,10 @@ after_complete(UNUSED(Hookdef dummy), int *dat)
minfo.cur = NULL;
if (ret >= 2) {
fixsuffix();
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
inststr(origline);
- zlecs = origcs;
+ zlemetacs = origcs;
if (ret == 2) {
clearlist = 1;
invalidatelist();
@@ -525,6 +535,8 @@ callcompfunc(char *s, char *fn)
int lv = lastval;
char buf[20];
+ METACHECK();
+
if ((prog = getshfunc(fn)) != &dummy_eprog) {
char **p, *tmp;
int aadd = 0, usea = 1, icf = incompfunc, osc = sfcontext;
@@ -683,10 +695,10 @@ callcompfunc(char *s, char *fn)
int l;
compiprefix = (char *) zalloc((l = wb - parwb) + 1);
- memcpy(compiprefix, zleline + parwb, l);
+ memcpy(compiprefix, zlemetaline + parwb, l);
compiprefix[l] = '\0';
compisuffix = (char *) zalloc((l = parwe - we) + 1);
- memcpy(compisuffix, zleline + we, l);
+ memcpy(compisuffix, zlemetaline + we, l);
compisuffix[l] = '\0';
wb = parwb;
@@ -1152,7 +1164,7 @@ check_param(char *s, int set, int test)
}
/* And adjust wb, we, and offs again. */
offs -= b - s;
- wb = zlecs - offs;
+ wb = zlemetacs - offs;
we = wb + e - b;
ispar = (br >= 2 ? 2 : 1);
b[we-wb] = '\0';
@@ -1265,6 +1277,11 @@ comp_str(int *ipl, int *pl, int untok)
return str;
}
+/*
+ * This is the code behind compset -q, which splits the
+ * the current word as if it were a command line.
+ */
+
/**/
int
set_comp_sep(void)
@@ -1273,11 +1290,13 @@ set_comp_sep(void)
char *s = comp_str(&lip, &lp, 1);
LinkList foo = newlinklist();
LinkNode n;
- int owe = we, owb = wb, ocs = zlecs, swb, swe, scs, soffs, ne = noerrs;
- int tl, got = 0, i = 0, j, cur = -1, oll = zlell, sl, css = 0;
+ int owe = we, owb = wb, ocs, swb, swe, scs, soffs, ne = noerrs;
+ int tl, got = 0, i = 0, j, cur = -1, oll, sl, css = 0;
int remq = 0, dq = 0, odq, sq = 0, osq, issq = 0, sqq = 0, lsq = 0, qa = 0;
int ois = instring, oib = inbackt, noffs = lp, ona = noaliases;
- char *tmp, *p, *ns, *ol = (char *) zleline, sav, *qp, *qs, *ts, qc = '\0';
+ char *tmp, *p, *ns, *ol, sav, *qp, *qs, *ts, qc = '\0';
+
+ METACHECK();
s += lip;
wb += lip;
@@ -1289,13 +1308,16 @@ set_comp_sep(void)
/* Put the string in the lexer buffer and call the lexer to *
* get the words we have to expand. */
zleparse = 1;
+ ocs = zlemetacs;
+ oll = zlemetall;
+ ol = (char *)zlemetaline;
addedx = 1;
noerrs = 1;
lexsave();
tmp = (char *) zhalloc(tl = 3 + strlen(s));
tmp[0] = ' ';
memcpy(tmp + 1, s, noffs);
- tmp[(scs = zlecs = 1 + noffs)] = 'x';
+ tmp[(scs = zlemetacs = 1 + noffs)] = 'x';
strcpy(tmp + 2 + noffs, s + noffs);
switch (*compqstack) {
@@ -1318,8 +1340,8 @@ set_comp_sep(void)
if (*p == '\\' && p[1] == '\\') {
dq++;
chuck(p);
- if (j > zlecs) {
- zlecs++;
+ if (j > zlemetacs) {
+ zlemetacs++;
css++;
}
if (!*p)
@@ -1329,8 +1351,8 @@ set_comp_sep(void)
odq = dq;
osq = sq;
inpush(dupstrspace(tmp), 0, NULL);
- zleline = (unsigned char *) tmp;
- zlell = tl - 1;
+ zlemetaline = (unsigned char *) tmp;
+ zlemetall = tl - 1;
strinbeg(0);
noaliases = 1;
do {
@@ -1383,7 +1405,7 @@ set_comp_sep(void)
swb = wb - 1 - dq - sq;
swe = we - 1 - dq - sq;
sqq = lsq;
- soffs = zlecs - swb - css;
+ soffs = zlemetacs - swb - css;
chuck(p + soffs);
ns = dupstring(p);
}
@@ -1397,9 +1419,9 @@ set_comp_sep(void)
lexrestore();
wb = owb;
we = owe;
- zlecs = ocs;
- zleline = (unsigned char *) ol;
- zlell = oll;
+ zlemetacs = ocs;
+ zlemetaline = (unsigned char *) ol;
+ zlemetall = oll;
if (cur < 0 || i < 1)
return 1;
owb = offs;
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index 4b33a2921..2789068e7 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -198,16 +198,21 @@ compctlread(char *name, char **args, Options ops, char *reply)
return 1;
}
+ METACHECK();
+
if (OPT_ISSET(ops,'l')) {
- /* -ln gives the index of the word the cursor is currently on, which is
- available in zlecs (but remember that Zsh counts from one, not zero!) */
+ /*
+ * -ln gives the index of the word the cursor is currently on, which
+ * is available in zlemetacs (but remember that Zsh counts from one,
+ * not zero!)
+ */
if (OPT_ISSET(ops,'n')) {
char nbuf[14];
if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E'))
- printf("%d\n", zlecs + 1);
+ printf("%d\n", zlemetacs + 1);
if (!OPT_ISSET(ops,'e')) {
- sprintf(nbuf, "%d", zlecs + 1);
+ sprintf(nbuf, "%d", zlemetacs + 1);
setsparam(reply, ztrdup(nbuf));
}
return 0;
@@ -215,11 +220,11 @@ compctlread(char *name, char **args, Options ops, char *reply)
/* without -n, the current line is assigned to the given parameter as a
scalar */
if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) {
- zputs((char *) zleline, stdout);
+ zputs((char *) zlemetaline, stdout);
putchar('\n');
}
if (!OPT_ISSET(ops,'e'))
- setsparam(reply, ztrdup((char *) zleline));
+ setsparam(reply, ztrdup((char *) zlemetaline));
} else {
int i;
@@ -2560,7 +2565,9 @@ makecomplistor(Compctl cc, char *s, int incmd, int compadd, int sub)
static void
makecomplistlist(Compctl cc, char *s, int incmd, int compadd)
{
- int oloffs = offs, owe = we, owb = wb, ocs = zlecs;
+ int oloffs = offs, owe = we, owb = wb, ocs = zlemetacs;
+
+ METACHECK();
if (cc->ext)
/* Handle extended completion. */
@@ -2574,7 +2581,7 @@ makecomplistlist(Compctl cc, char *s, int incmd, int compadd)
offs = oloffs;
wb = owb;
we = owe;
- zlecs = ocs;
+ zlemetacs = ocs;
}
/* This add matches for extended completion patterns */
@@ -2751,15 +2758,17 @@ sep_comp_string(char *ss, char *s, int noffs)
{
LinkList foo = newlinklist();
LinkNode n;
- int owe = we, owb = wb, ocs = zlecs, swb, swe, scs, soffs, ne = noerrs;
- int sl = strlen(ss), tl, got = 0, i = 0, cur = -1, oll = zlell, remq;
+ int owe = we, owb = wb, ocs = zlemetacs, swb, swe, scs, soffs, ne = noerrs;
+ int sl = strlen(ss), tl, got = 0, i = 0, cur = -1, oll = zlemetall, remq;
int ois = instring, oib = inbackt, ona = noaliases;
- char *tmp, *p, *ns, *ol = (char *) zleline, sav, *oaq = autoq, *qp, *qs;
- char *ts, qc = '\0';
+ char *tmp, *p, *ns, *ol = (char *) zlemetaline, sav, *oaq = autoq;
+ char *qp, *qs, *ts, qc = '\0';
swb = swe = soffs = 0;
ns = NULL;
+ METACHECK();
+
/* Put the string in the lexer buffer and call the lexer to *
* get the words we have to expand. */
zleparse = 1;
@@ -2770,13 +2779,13 @@ sep_comp_string(char *ss, char *s, int noffs)
strcpy(tmp, ss);
tmp[sl] = ' ';
memcpy(tmp + sl + 1, s, noffs);
- tmp[(scs = zlecs = sl + 1 + noffs)] = 'x';
+ tmp[(scs = zlemetacs = sl + 1 + noffs)] = 'x';
strcpy(tmp + sl + 2 + noffs, s + noffs);
if ((remq = (*compqstack == '\\')))
tmp = rembslash(tmp);
inpush(dupstrspace(tmp), 0, NULL);
- zleline = (unsigned char *) tmp;
- zlell = tl - 1;
+ zlemetaline = (unsigned char *) tmp;
+ zlemetall = tl - 1;
strinbeg(0);
noaliases = 1;
do {
@@ -2807,7 +2816,7 @@ sep_comp_string(char *ss, char *s, int noffs)
cur = i;
swb = wb - 1;
swe = we - 1;
- soffs = zlecs - swb;
+ soffs = zlemetacs - swb;
chuck(p + soffs);
ns = dupstring(p);
}
@@ -2821,9 +2830,9 @@ sep_comp_string(char *ss, char *s, int noffs)
lexrestore();
wb = owb;
we = owe;
- zlecs = ocs;
- zleline = (unsigned char *) ol;
- zlell = oll;
+ zlemetacs = ocs;
+ zlemetaline = (unsigned char *) ol;
+ zlemetall = oll;
if (cur < 0 || i < 1)
return 1;
owb = offs;
@@ -2979,8 +2988,8 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
addlinknode(allccs, cc);
}
/* Go to the end of the word if complete_in_word is not set. */
- if (unset(COMPLETEINWORD) && zlecs != we)
- zlecs = we, offs = strlen(s);
+ if (unset(COMPLETEINWORD) && zlemetacs != we)
+ zlemetacs = we, offs = strlen(s);
s = dupstring(s);
delit = ispattern = 0;
@@ -3200,15 +3209,15 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
ppre = dupstrpfx(rpre, s1 - rpre + 1);
psuf = dupstring(s2);
- if (zlecs != wb) {
- char save = zleline[zlecs];
+ if (zlemetacs != wb) {
+ char save = zlemetaline[zlemetacs];
- zleline[zlecs] = 0;
- lppre = dupstring((char *) zleline + wb +
+ zlemetaline[zlemetacs] = 0;
+ lppre = dupstring((char *) zlemetaline + wb +
(qipre && *qipre ?
(strlen(qipre) -
(*qipre == '\'' || *qipre == '\"')) : 0));
- zleline[zlecs] = save;
+ zlemetaline[zlemetacs] = save;
if (brbeg) {
Brinfo bp;
@@ -3230,25 +3239,26 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
lppre = NULL;
lppl = 0;
}
- if (zlecs != we) {
+ if (zlemetacs != we) {
int end = we;
- char save = zleline[end];
+ char save = zlemetaline[end];
if (qisuf && *qisuf) {
int ql = strlen(qisuf);
end -= ql - (qisuf[ql-1] == '\'' || qisuf[ql-1] == '"');
}
- zleline[end] = 0;
- lpsuf = dupstring((char *) (zleline + zlecs));
- zleline[end] = save;
+ zlemetaline[end] = 0;
+ lpsuf = dupstring((char *) (zlemetaline + zlemetacs));
+ zlemetaline[end] = save;
if (brend) {
Brinfo bp;
char *p;
int bl;
for (bp = brend; bp; bp = bp->next) {
- p = lpsuf + (we - zlecs) - bp->qpos - (bl = strlen(bp->str));
+ p = lpsuf + (we - zlemetacs) - bp->qpos -
+ (bl = strlen(bp->str));
strcpy(p, p + bl);
}
}
@@ -3262,7 +3272,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
/* And get the file prefix. */
fpre = dupstring(((s1 == s || s1 == rpre || ic) &&
- (*s != '/' || zlecs == wb)) ? s1 : s1 + 1);
+ (*s != '/' || zlemetacs == wb)) ? s1 : s1 + 1);
qfpre = quotename(fpre, NULL);
/* And the suffix. */
fsuf = dupstrpfx(rsuf, s2 - rsuf);
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 3a3d77971..045e86837 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -1771,28 +1771,30 @@ setmstatus(char *status, char *sline, int sll, int scs,
char *p, *s, *ret = NULL;
int pl, sl, max;
+ METACHECK();
+
if (csp) {
- *csp = zlecs;
- *llp = zlell;
+ *csp = zlemetacs;
+ *llp = zlemetall;
*lenp = lastend - wb;
- ret = dupstring((char *) zleline);
+ ret = dupstring((char *) zlemetaline);
- p = (char *) zhalloc(zlecs - wb + 1);
- strncpy(p, (char *) zleline + wb, zlecs - wb);
- p[zlecs - wb] = '\0';
- if (lastend < zlecs)
+ p = (char *) zhalloc(zlemetacs - wb + 1);
+ strncpy(p, (char *) zlemetaline + wb, zlemetacs - wb);
+ p[zlemetacs - wb] = '\0';
+ if (lastend < zlemetacs)
s = "";
else {
- s = (char *) zhalloc(lastend - zlecs + 1);
- strncpy(s, (char *) zleline + zlecs, lastend - zlecs);
- s[lastend - zlecs] = '\0';
+ s = (char *) zhalloc(lastend - zlemetacs + 1);
+ strncpy(s, (char *) zlemetaline + zlemetacs, lastend - zlemetacs);
+ s[lastend - zlemetacs] = '\0';
}
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(sll);
- memcpy(zleline, sline, sll);
- zlecs = scs;
+ memcpy(zlemetaline, sline, sll);
+ zlemetacs = scs;
} else {
p = complastprefix;
s = complastsuffix;
@@ -1970,7 +1972,7 @@ domenuselect(Hookdef dummy, Chdata dat)
Menustack u = NULL;
int i = 0, acc = 0, wishcol = 0, setwish = 0, oe = onlyexpl, wasnext = 0;
int space, lbeg = 0, step = 1, wrap, pl = nlnct, broken = 0, first = 1;
- int nolist = 0, mode = 0, modecs, modell, modelen;
+ int nolist = 0, mode = 0, modecs, modell, modelen, wasmeta;
char *s;
char status[MAX_STATUS], *modeline = NULL;
@@ -1990,6 +1992,23 @@ domenuselect(Hookdef dummy, Chdata dat)
unqueue_signals();
return 0;
}
+ /*
+ * Lots of the logic here doesn't really make sense if the
+ * line isn't metafied, but the evidence was that only used
+ * to be metafied locally in a couple of places.
+ * It's horrifically difficult to work out where the line
+ * is metafied, so I've resorted to the following.
+ * Unfortunately we need to unmetatfy in zrefresh() when
+ * we want to display something. Maybe this function can
+ * be done better.
+ */
+ if (zlemetaline != NULL)
+ wasmeta = 1;
+ else {
+ wasmeta = 0;
+ metafy_line();
+ }
+
if ((s = getsparam("MENUSCROLL"))) {
if (!(step = mathevali(s)))
step = (lines - nlnct) >> 1;
@@ -2010,11 +2029,11 @@ domenuselect(Hookdef dummy, Chdata dat)
* was before completion started.
*/
mode = MM_INTER;
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(l);
- strncpy((char *) zleline, origline, l);
- zlecs = origcs;
+ strncpy((char *) zlemetaline, origline, l);
+ zlemetacs = origcs;
setmstatus(status, NULL, 0 , 0, NULL, NULL, NULL);
} else if (strpfx("search", s)) {
mode = (strstr(s, "back") ? MM_BSEARCH : MM_FSEARCH);
@@ -2108,15 +2127,15 @@ domenuselect(Hookdef dummy, Chdata dat)
* completion we don't want that, we always want to
* be able to type the next character.
*/
- modeline = dupstring(zleline);
- modecs = zlecs;
- modell = zlell;
+ modeline = dupstring((char *)zlemetaline);
+ modecs = zlemetacs;
+ modell = zlemetall;
modelen = minfo.len;
}
first = 0;
if (mode == MM_INTER) {
- statusline = stringaszleline((unsigned char *)status,
- &statusll, NULL);
+ statusline = stringaszleline((unsigned char *)status, 0,
+ &statusll, NULL, NULL);
} else if (mode) {
int l = sprintf(status, "%s%sisearch%s: ",
((msearchstate & MS_FAILED) ? "failed " : ""),
@@ -2125,8 +2144,8 @@ domenuselect(Hookdef dummy, Chdata dat)
strncat(status, msearchstr, MAX_STATUS - l - 1);
- statusline = stringaszleline((unsigned char *)status,
- &statusll, NULL);
+ statusline = stringaszleline((unsigned char *)status, 0,
+ &statusll, NULL, NULL);
} else {
statusline = NULL;
statusll = 0;
@@ -2207,11 +2226,11 @@ domenuselect(Hookdef dummy, Chdata dat)
* start.
*/
mode = MM_INTER;
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(l);
- strncpy((char *) zleline, origline, l);
- zlecs = origcs;
+ strncpy((char *) zlemetaline, origline, l);
+ zlemetacs = origcs;
setmstatus(status, NULL, 0, 0, NULL, NULL, NULL);
continue;
@@ -2226,8 +2245,8 @@ domenuselect(Hookdef dummy, Chdata dat)
s->prev = u;
u = s;
- s->line = dupstring((char *) zleline);
- s->cs = zlecs;
+ s->line = dupstring((char *) zlemetaline);
+ s->cs = zlemetacs;
s->mline = mline;
s->mlbeg = mlbeg;
memcpy(&(s->info), &minfo, sizeof(struct menuinfo));
@@ -2266,21 +2285,21 @@ domenuselect(Hookdef dummy, Chdata dat)
* the command line as it is with just the
* characters typed by the user.
*/
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(l);
- strncpy((char *) zleline, origline, l);
- zlecs = origcs;
+ strncpy((char *) zlemetaline, origline, l);
+ zlemetacs = origcs;
if (cmd == Th(z_selfinsert))
selfinsert(zlenoargs);
else
selfinsertunmeta(zlenoargs);
- saveline = (char *) zhalloc(zlell);
- memcpy(saveline, zleline, zlell);
- savell = zlell;
- savecs = zlecs;
+ saveline = (char *) zhalloc(zlemetall);
+ memcpy(saveline, zlemetaline, zlemetall);
+ savell = zlemetall;
+ savecs = zlemetacs;
iforcemenu = -1;
} else
mode = 0;
@@ -2294,8 +2313,8 @@ domenuselect(Hookdef dummy, Chdata dat)
if (nmatches < 1 || !minfo.cur || !*(minfo.cur)) {
nolist = 1;
if (mode == MM_INTER) {
- statusline = stringaszleline((unsigned char *)status,
- &statusll, NULL);
+ statusline = stringaszleline((unsigned char *)status, 0,
+ &statusll, NULL, NULL);
} else {
/* paranoia */
statusline = NULL;
@@ -2339,8 +2358,8 @@ domenuselect(Hookdef dummy, Chdata dat)
mode = 0;
s->prev = u;
u = s;
- s->line = dupstring((char *) zleline);
- s->cs = zlecs;
+ s->line = dupstring((char *) zlemetaline);
+ s->cs = zlemetacs;
s->mline = mline;
s->mlbeg = mlbeg;
memcpy(&(s->info), &minfo, sizeof(struct menuinfo));
@@ -2394,11 +2413,11 @@ domenuselect(Hookdef dummy, Chdata dat)
break;
handleundo();
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(l = strlen(u->line));
- strncpy((char *) zleline, u->line, l);
- zlecs = u->cs;
+ strncpy((char *) zlemetaline, u->line, l);
+ zlemetacs = u->cs;
menuacc = u->acc;
memcpy(&minfo, &(u->info), sizeof(struct menuinfo));
p = &(minfo.cur);
@@ -2435,8 +2454,8 @@ domenuselect(Hookdef dummy, Chdata dat)
if (nolist) {
if (mode == MM_INTER) {
- statusline = stringaszleline((unsigned char *)status,
- &statusll, NULL);
+ statusline = stringaszleline((unsigned char *)status, 0,
+ &statusll, NULL, NULL);
} else {
/* paranoia */
statusline = NULL;
@@ -2783,11 +2802,11 @@ domenuselect(Hookdef dummy, Chdata dat)
origline = modeline;
origcs = modecs;
origll = modell;
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(origll);
- strncpy((char *) zleline, origline, origll);
- zlecs = origcs;
+ strncpy((char *) zlemetaline, origline, origll);
+ zlemetacs = origcs;
minfo.len = modelen;
} else {
mode = 0;
@@ -2880,9 +2899,7 @@ domenuselect(Hookdef dummy, Chdata dat)
acc = 1;
break;
}
- metafy_line();
do_single(**p);
- unmetafy_line();
mselect = (**p)->gnum;
}
if (u)
@@ -2898,9 +2915,7 @@ domenuselect(Hookdef dummy, Chdata dat)
clearlist = listshown = 1;
if (acc && validlist && minfo.cur) {
menucmp = lastambig = hasoldlist = 0;
- metafy_line();
do_single(*(minfo.cur));
- unmetafy_line();
}
if (wasnext || broken) {
menucmp = 2;
@@ -2923,6 +2938,9 @@ domenuselect(Hookdef dummy, Chdata dat)
mlbeg = -1;
fdat = NULL;
+ if (!wasmeta)
+ unmetafy_line();
+
return (broken == 2 ? 3 :
((dat && !broken) ? (acc ? 1 : 2) : (!noselect ^ acc)));
}
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index b07e71aff..09794813f 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -169,11 +169,13 @@ static char *
cline_str(Cline l, int ins, int *csp, LinkList posl)
{
Cline s;
- int ocs = zlecs, ncs, pcs, scs, opos = -1, npos;
+ int ocs = zlemetacs, ncs, pcs, scs, opos = -1, npos;
int pm, pmax, pmm, pma, sm, smax, smm, sma, d, dm, mid;
int i, j, li = 0, cbr, padd = (ins ? wb - ocs : -ocs);
Brinfo brp, brs;
+ METACHECK();
+
l = cut_cline(l);
pmm = pma = smm = sma = dm = pcs = scs = 0;
@@ -205,7 +207,7 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
}
while (brs && !brs->curpos) {
if (cbr < 0)
- cbr = zlecs;
+ cbr = zlemetacs;
inststrlen(brs->str, 1, -1);
brs = brs->prev;
}
@@ -214,21 +216,21 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
while (l) {
/* Insert the original string if no prefix. */
if (l->olen && !(l->flags & CLF_SUF) && !l->prefix) {
- pcs = zlecs + l->olen;
+ pcs = zlemetacs + l->olen;
inststrlen(l->orig, 1, l->olen);
} else {
/* Otherwise insert the prefix. */
for (s = l->prefix; s; s = s->next) {
- pcs = zlecs + s->llen;
+ pcs = zlemetacs + s->llen;
if (s->flags & CLF_LINE)
inststrlen(s->line, 1, s->llen);
else
inststrlen(s->word, 1, s->wlen);
- scs = zlecs;
+ scs = zlemetacs;
if ((s->flags & CLF_DIFF) && (!dm || (s->flags & CLF_MATCHED))) {
- d = zlecs; dm = s->flags & CLF_MATCHED;
- if (posl && (npos = zlecs + padd) != opos) {
+ d = zlemetacs; dm = s->flags & CLF_MATCHED;
+ if (posl && (npos = zlemetacs + padd) != opos) {
opos = npos;
addlinknode(posl, (void *) ((long) npos));
}
@@ -240,11 +242,11 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
int ocs, bl;
while (brp && li >= brp->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brp->str);
- zlecs = pcs - (li - brp->curpos);
+ zlemetacs = pcs - (li - brp->curpos);
inststrlen(brp->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
scs += bl;
brp = brp->next;
@@ -253,14 +255,14 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
/* Remember the position if this is the first prefix with
* missing characters. */
if ((l->flags & CLF_MISS) && !(l->flags & CLF_SUF)) {
- if (posl && (npos = zlecs + padd) != opos) {
+ if (posl && (npos = zlemetacs + padd) != opos) {
opos = npos;
addlinknode(posl, (void *) ((long) npos));
}
if (((pmax <= (l->max - l->min) || (pma && l->max != l->min)) &&
(!pmm || (l->flags & CLF_MATCHED))) ||
((l->flags & CLF_MATCHED) && !pmm)) {
- pm = zlecs; pmax = l->max - l->min; pmm = l->flags & CLF_MATCHED;
+ pm = zlemetacs; pmax = l->max - l->min; pmm = l->flags & CLF_MATCHED;
pma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
}
}
@@ -268,35 +270,35 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
int ocs, bl;
while (brs && li >= brs->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brs->str);
- zlecs = scs - (li - brs->curpos);
+ zlemetacs = scs - (li - brs->curpos);
if (cbr < 0)
- cbr = zlecs;
+ cbr = zlemetacs;
inststrlen(brs->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
brs = brs->prev;
}
}
- pcs = zlecs;
+ pcs = zlemetacs;
/* Insert the anchor. */
if (l->flags & CLF_LINE)
inststrlen(l->line, 1, l->llen);
else
inststrlen(l->word, 1, l->wlen);
- scs = zlecs;
+ scs = zlemetacs;
if (ins) {
int ocs, bl;
li += l->llen;
while (brp && li >= brp->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brp->str);
- zlecs = pcs + l->llen - (li - brp->curpos);
+ zlemetacs = pcs + l->llen - (li - brp->curpos);
inststrlen(brp->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
scs += bl;
brp = brp->next;
@@ -305,16 +307,16 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
/* Remember the cursor position for suffixes and mids. */
if (l->flags & CLF_MISS) {
if (l->flags & CLF_MID)
- mid = zlecs;
+ mid = zlemetacs;
else if (l->flags & CLF_SUF) {
- if (posl && (npos = zlecs + padd) != opos) {
+ if (posl && (npos = zlemetacs + padd) != opos) {
opos = npos;
addlinknode(posl, (void *) ((long) npos));
}
if (((smax <= (l->min - l->max) || (sma && l->max != l->min)) &&
(!smm || (l->flags & CLF_MATCHED))) ||
((l->flags & CLF_MATCHED) && !smm)) {
- sm = zlecs; smax = l->min - l->max; smm = l->flags & CLF_MATCHED;
+ sm = zlemetacs; smax = l->min - l->max; smm = l->flags & CLF_MATCHED;
sma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
}
}
@@ -323,20 +325,20 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
int ocs, bl;
while (brs && li >= brs->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brs->str);
- zlecs = scs - (li - brs->curpos);
+ zlemetacs = scs - (li - brs->curpos);
if (cbr < 0)
- cbr = zlecs;
+ cbr = zlemetacs;
inststrlen(brs->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
brs = brs->prev;
}
}
/* And now insert the suffix or the original string. */
if (l->olen && (l->flags & CLF_SUF) && !l->suffix) {
- pcs = zlecs;
+ pcs = zlemetacs;
inststrlen(l->orig, 1, l->olen);
if (ins) {
int ocs, bl;
@@ -344,22 +346,22 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
li += l->olen;
while (brp && li >= brp->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brp->str);
- zlecs = pcs + l->olen - (li - brp->curpos);
+ zlemetacs = pcs + l->olen - (li - brp->curpos);
inststrlen(brp->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
brp = brp->next;
}
while (brs && li >= brs->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brs->str);
- zlecs = pcs + l->olen - (li - brs->curpos);
+ zlemetacs = pcs + l->olen - (li - brs->curpos);
if (cbr < 0)
- cbr = zlecs;
+ cbr = zlemetacs;
inststrlen(brs->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
brs = brs->prev;
}
@@ -370,13 +372,13 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
for (j = -1, i = 0, s = l->suffix; s; s = s->next) {
if (j < 0 && (s->flags & CLF_DIFF))
j = i, js = s;
- pcs = zlecs;
+ pcs = zlemetacs;
if (s->flags & CLF_LINE) {
inststrlen(s->line, 0, s->llen);
- i += s->llen; scs = zlecs + s->llen;
+ i += s->llen; scs = zlemetacs + s->llen;
} else {
inststrlen(s->word, 0, s->wlen);
- i += s->wlen; scs = zlecs + s->wlen;
+ i += s->wlen; scs = zlemetacs + s->wlen;
}
if (ins) {
int ocs, bl;
@@ -384,32 +386,32 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
li += s->llen;
while (brp && li >= brp->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brp->str);
- zlecs = pcs + (li - brp->curpos);
+ zlemetacs = pcs + (li - brp->curpos);
inststrlen(brp->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
scs += bl;
brp = brp->next;
}
while (brs && li >= brs->curpos) {
- ocs = zlecs;
+ ocs = zlemetacs;
bl = strlen(brs->str);
- zlecs = scs - (li - brs->curpos);
+ zlemetacs = scs - (li - brs->curpos);
if (cbr < 0)
- cbr = zlecs;
+ cbr = zlemetacs;
inststrlen(brs->str, 1, bl);
- zlecs = ocs + bl;
+ zlemetacs = ocs + bl;
pcs += bl;
brs = brs->prev;
}
}
}
- zlecs += i;
+ zlemetacs += i;
if (j >= 0 && (!dm || (js->flags & CLF_MATCHED))) {
- d = zlecs - j; dm = js->flags & CLF_MATCHED;
- if (posl && (npos = zlecs - j + padd) != opos) {
+ d = zlemetacs - j; dm = js->flags & CLF_MATCHED;
+ if (posl && (npos = zlemetacs - j + padd) != opos) {
opos = npos;
addlinknode(posl, (void *) ((long) npos));
}
@@ -417,7 +419,7 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
}
l = l->next;
}
- if (posl && (npos = zlecs + padd) != opos)
+ if (posl && (npos = zlemetacs + padd) != opos)
#if 0
/* This could be used to put an extra colon before the end-of-word
* position if there is nothing missing. */
@@ -426,23 +428,23 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
addlinknode(posl, (void *) ((long) npos));
if (ins) {
- int ocs = zlecs;
+ int ocs = zlemetacs;
for (; brp; brp = brp->next)
inststrlen(brp->str, 1, -1);
for (; brs; brs = brs->prev) {
if (cbr < 0)
- cbr = zlecs;
+ cbr = zlemetacs;
inststrlen(brs->str, 1, -1);
}
if (mid >= ocs)
- mid += zlecs - ocs;
+ mid += zlemetacs - ocs;
if (pm >= ocs)
- pm += zlecs - ocs;
+ pm += zlemetacs - ocs;
if (sm >= ocs)
- sm += zlecs - ocs;
+ sm += zlemetacs - ocs;
if (d >= ocs)
- d += zlecs - ocs;
+ d += zlemetacs - ocs;
if (posl) {
LinkNode node;
@@ -451,7 +453,7 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
for (node = firstnode(posl); node; incnode(node)) {
p = (long) getdata(node);
if (p >= ocs)
- setdata(node, (void *) (p + zlecs - ocs));
+ setdata(node, (void *) (p + zlemetacs - ocs));
}
}
}
@@ -461,16 +463,16 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
* suffix, and finally a place where the matches differ. */
ncs = (mid >= 0 ? mid :
(cbr >= 0 ? cbr :
- (pm >= 0 ? pm : (sm >= 0 ? sm : (d >= 0 ? d : zlecs)))));
+ (pm >= 0 ? pm : (sm >= 0 ? sm : (d >= 0 ? d : zlemetacs)))));
if (ins != 1) {
/* We always inserted the string in the line. If that was not
* requested, we copy it and remove from the line. */
- char *r = zalloc((i = zlecs - ocs) + 1);
+ char *r = zalloc((i = zlemetacs - ocs) + 1);
- memcpy(r, (char *) (zleline + ocs), i);
+ memcpy(r, (char *) (zlemetaline + ocs), i);
r[i] = '\0';
- zlecs = ocs;
+ zlemetacs = ocs;
foredel(i);
if (csp)
@@ -478,8 +480,8 @@ cline_str(Cline l, int ins, int *csp, LinkList posl)
return r;
}
- lastend = zlecs;
- zlecs = ncs;
+ lastend = zlemetacs;
+ zlemetacs = ncs;
return NULL;
}
@@ -579,9 +581,11 @@ unambig_data(int *cp, char **pp, char **ip)
static int
instmatch(Cmatch m, int *scs)
{
- int l, r = 0, ocs, a = zlecs, brb = 0, bradd, *brpos;
+ int l, r = 0, ocs, a = zlemetacs, brb = 0, bradd, *brpos;
Brinfo bp;
+ METACHECK();
+
zsfree(lastprebr);
zsfree(lastpostbr);
lastprebr = lastpostbr = NULL;
@@ -606,28 +610,28 @@ instmatch(Cmatch m, int *scs)
/* The string itself. */
inststrlen(m->str, 1, (l = strlen(m->str)));
r += l;
- ocs = zlecs;
+ ocs = zlemetacs;
/* Re-insert the brace beginnings, if any. */
if (brbeg) {
- int pcs = zlecs;
+ int pcs = zlemetacs;
l = 0;
for (bp = brbeg, brpos = m->brpl,
bradd = (m->pre ? strlen(m->pre) : 0);
bp; bp = bp->next, brpos++) {
- zlecs = a + *brpos + bradd;
- pcs = zlecs;
+ zlemetacs = a + *brpos + bradd;
+ pcs = zlemetacs;
l = strlen(bp->str);
bradd += l;
- brpcs = zlecs;
+ brpcs = zlemetacs;
inststrlen(bp->str, 1, l);
r += l;
ocs += l;
}
lastprebr = (char *) zalloc(pcs - a + 1);
- memcpy(lastprebr, (char *) zleline + a, pcs - a);
+ memcpy(lastprebr, (char *) zlemetaline + a, pcs - a);
lastprebr[pcs - a] = '\0';
- zlecs = ocs;
+ zlemetacs = ocs;
}
/* Path suffix. */
if (m->psuf) {
@@ -636,24 +640,24 @@ instmatch(Cmatch m, int *scs)
}
/* Re-insert the brace end. */
if (brend) {
- a = zlecs;
+ a = zlemetacs;
for (bp = brend, brpos = m->brsl, bradd = 0; bp; bp = bp->next, brpos++) {
- zlecs = a - *brpos;
- ocs = brscs = zlecs;
+ zlemetacs = a - *brpos;
+ ocs = brscs = zlemetacs;
l = strlen(bp->str);
bradd += l;
inststrlen(bp->str, 1, l);
- brb = zlecs;
+ brb = zlemetacs;
r += l;
}
- zlecs = a + bradd;
+ zlemetacs = a + bradd;
if (scs)
*scs = ocs;
} else {
brscs = -1;
if (scs)
- *scs = zlecs;
+ *scs = zlemetacs;
}
/* -S suffix */
if (m->suf) {
@@ -666,12 +670,12 @@ instmatch(Cmatch m, int *scs)
r += l;
}
if (brend) {
- lastpostbr = (char *) zalloc(zlecs - brb + 1);
- memcpy(lastpostbr, (char *) zleline + brb, zlecs - brb);
- lastpostbr[zlecs - brb] = '\0';
+ lastpostbr = (char *) zalloc(zlemetacs - brb + 1);
+ memcpy(lastpostbr, (char *) zlemetaline + brb, zlemetacs - brb);
+ lastpostbr[zlemetacs - brb] = '\0';
}
- lastend = zlecs;
- zlecs = ocs;
+ lastend = zlemetacs;
+ zlemetacs = ocs;
return r;
}
@@ -687,20 +691,20 @@ hasbrpsfx(Cmatch m, char *pre, char *suf)
return 1;
else {
char *op = lastprebr, *os = lastpostbr;
- VARARR(char, oline, zlell);
- int oll = zlell, ocs = zlecs, ole = lastend, opcs = brpcs, oscs = brscs, ret;
+ VARARR(char, oline, zlemetall);
+ int oll = zlemetall, ocs = zlemetacs, ole = lastend, opcs = brpcs, oscs = brscs, ret;
- memcpy(oline, zleline, zlell);
+ memcpy(oline, zlemetaline, zlemetall);
lastprebr = lastpostbr = NULL;
instmatch(m, NULL);
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(oll);
- memcpy(zleline, oline, oll);
- zlecs = ocs;
+ memcpy(zlemetaline, oline, oll);
+ zlemetacs = ocs;
lastend = ole;
brpcs = opcs;
brscs = oscs;
@@ -754,7 +758,7 @@ do_ambiguous(void)
* completion options. */
do_ambig_menu();
} else if (ainfo) {
- int atend = (zlecs == we), la, eq, tcs;
+ int atend = (zlemetacs == we), la, eq, tcs;
VARARR(char, old, we - wb);
minfo.cur = NULL;
@@ -763,9 +767,9 @@ do_ambiguous(void)
fixsuffix();
/* First remove the old string from the line. */
- tcs = zlecs;
- zlecs = wb;
- memcpy(old, (char *) zleline + wb, we - wb);
+ tcs = zlemetacs;
+ zlemetacs = wb;
+ memcpy(old, (char *) zlemetaline + wb, we - wb);
foredel(we - wb);
/* Now get the unambiguous string and insert it into the line. */
@@ -776,23 +780,23 @@ do_ambiguous(void)
* old string. Unless there were matches added with -U, that is. */
if (lastend < we && !lenchanged && !hasunmatched) {
- zlecs = wb;
+ zlemetacs = wb;
foredel(lastend - wb);
inststrlen(old, 0, we - wb);
lastend = we;
- zlecs = tcs;
+ zlemetacs = tcs;
}
if (eparq) {
- tcs = zlecs;
- zlecs = lastend;
+ tcs = zlemetacs;
+ zlemetacs = lastend;
for (eq = eparq; eq; eq--)
inststrlen("\"", 0, 1);
- zlecs = tcs;
+ zlemetacs = tcs;
}
/* la is non-zero if listambiguous may be used. Copying and
* comparing the line looks like BFI but it is the easiest
* solution. Really. */
- la = (zlell != origll || strncmp(origline, (char *) zleline, zlell));
+ la = (zlemetall != origll || strncmp(origline, (char *) zlemetaline, zlemetall));
/* If REC_EXACT and AUTO_MENU are set and what we inserted is an *
* exact match, we want menu completion the next time round *
@@ -800,11 +804,11 @@ do_ambiguous(void)
* taken as an exact match. Also we remember if we just moved the *
* cursor into the word. */
fromcomp = ((isset(AUTOMENU) ? FC_LINE : 0) |
- ((atend && zlecs != lastend) ? FC_INWORD : 0));
+ ((atend && zlemetacs != lastend) ? FC_INWORD : 0));
/* Probably move the cursor to the end. */
if (movetoend == 3)
- zlecs = lastend;
+ zlemetacs = lastend;
/* If the LIST_AMBIGUOUS option (meaning roughly `show a list only *
* if the completion is completely ambiguous') is set, and some *
@@ -947,7 +951,7 @@ do_single(Cmatch m)
* so set the position variables. */
minfo.pos = wb;
minfo.we = (movetoend >= 2 || (movetoend == 1 && !menucmp) ||
- (!movetoend && zlecs == we));
+ (!movetoend && zlemetacs == we));
minfo.end = we;
}
/* If we are already in a menu-completion or if we have done a *
@@ -959,7 +963,7 @@ do_single(Cmatch m)
l = we - wb;
minfo.insc = 0;
- zlecs = minfo.pos;
+ zlemetacs = minfo.pos;
foredel(l);
if (m->flags & CMF_ALL) {
@@ -969,8 +973,8 @@ do_single(Cmatch m)
/* And then we insert the new string. */
minfo.len = instmatch(m, &scs);
- minfo.end = zlecs;
- zlecs = minfo.pos + minfo.len;
+ minfo.end = zlemetacs;
+ zlemetacs = minfo.pos + minfo.len;
if (m->suf) {
havesuff = 1;
@@ -987,13 +991,13 @@ do_single(Cmatch m)
} else {
/* There is no user-specified suffix, *
* so generate one automagically. */
- zlecs = scs;
+ zlemetacs = scs;
if (partest && (m->flags & CMF_PARBR)) {
int pq;
/*{{*/
/* Completing a parameter in braces. Add a removable `}' suffix. */
- zlecs += eparq;
+ zlemetacs += eparq;
for (pq = parq; pq; pq--)
inststrlen("\"", 1, 1);
minfo.insc += parq;
@@ -1005,7 +1009,7 @@ do_single(Cmatch m)
havesuff = 1;
}
if (((m->flags & CMF_FILE) || (partest && isset(AUTOPARAMSLASH))) &&
- zlecs > 0 && zleline[zlecs - 1] != '/') {
+ zlemetacs > 0 && zlemetaline[zlemetacs - 1] != '/') {
/* If we have a filename or we completed a parameter name *
* and AUTO_PARAM_SLASH is set, lets see if it is a directory. *
* If it is, we append a slash. */
@@ -1079,7 +1083,7 @@ do_single(Cmatch m)
}
}
if (!minfo.insc)
- zlecs = minfo.pos + minfo.len - m->qisl;
+ zlemetacs = minfo.pos + minfo.len - m->qisl;
}
/* If completing in a brace expansion... */
if (brbeg) {
@@ -1092,7 +1096,7 @@ do_single(Cmatch m)
} else if (!menucmp) {
/*{{*/
/* Otherwise, add a `,' suffix, and let `}' remove it. */
- zlecs = scs;
+ zlemetacs = scs;
havesuff = 1;
inststrlen(",", 1, 1);
minfo.insc++;
@@ -1121,9 +1125,9 @@ do_single(Cmatch m)
makeparamsuffix(((m->flags & CMF_PARBR) ? 1 : 0), minfo.insc - parq);
if ((menucmp && !minfo.we) || !movetoend) {
- zlecs = minfo.end;
- if (zlecs + m->qisl == lastend)
- zlecs += minfo.insc;
+ zlemetacs = minfo.end;
+ if (zlemetacs + m->qisl == lastend)
+ zlemetacs += minfo.insc;
}
{
Cmatch *om = minfo.cur;
@@ -1169,9 +1173,13 @@ do_menucmp(int lst)
(((*minfo.cur)->flags & (CMF_NOLIST | CMF_MULT)) &&
(!(*minfo.cur)->str || !*(*minfo.cur)->str)));
/* ... and insert it into the command line. */
- metafy_line();
- do_single(*(minfo.cur));
- unmetafy_line();
+ /* Already metafied when called from domenuselect already */
+ if (zlemetaline == NULL) {
+ metafy_line();
+ do_single(*minfo.cur);
+ unmetafy_line();
+ } else
+ do_single(*minfo.cur);
}
/**/
@@ -1207,6 +1215,15 @@ reverse_menu(UNUSED(Hookdef dummy), UNUSED(void *dummy2))
mod_export int
accept_last(void)
{
+ /* give up trying to work out what state it should be in */
+ int wasmeta;
+ if (zlemetaline != NULL) {
+ wasmeta = 1;
+ } else {
+ wasmeta = 0;
+ metafy_line();
+ }
+
if (!menuacc) {
zsfree(minfo.prebr);
minfo.prebr = ztrdup(lastprebr);
@@ -1232,29 +1249,32 @@ accept_last(void)
iremovesuffix(',', 1);
- l = (brscs >= 0 ? brscs : zlecs) - brpcs;
+ l = (brscs >= 0 ? brscs : zlemetacs) - brpcs;
zsfree(lastbrbeg->str);
lastbrbeg->str = (char *) zalloc(l + 2);
- memcpy(lastbrbeg->str, zleline + brpcs, l);
+ memcpy(lastbrbeg->str, zlemetaline + brpcs, l);
lastbrbeg->str[l] = ',';
lastbrbeg->str[l + 1] = '\0';
} else {
int l;
- zlecs = minfo.pos + minfo.len + minfo.insc;
+ zlemetacs = minfo.pos + minfo.len + minfo.insc;
iremovesuffix(' ', 1);
- l = zlecs;
- zlecs = minfo.pos + minfo.len + minfo.insc - (*(minfo.cur))->qisl;
- if (zlecs < l)
- foredel(l - zlecs);
- else if (zlecs > zlell)
- zlecs = zlell;
+ l = zlemetacs;
+ zlemetacs = minfo.pos + minfo.len + minfo.insc - (*(minfo.cur))->qisl;
+ if (zlemetacs < l)
+ foredel(l - zlemetacs);
+ else if (zlemetacs > zlemetall)
+ zlemetacs = zlemetall;
inststrlen(" ", 1, 1);
minfo.insc = minfo.len = 0;
- minfo.pos = zlecs;
+ minfo.pos = zlemetacs;
minfo.we = 1;
}
+
+ if (!wasmeta)
+ unmetafy_line();
return 0;
}
@@ -2182,8 +2202,9 @@ invalidate_list(void)
{
invcount++;
if (validlist) {
- if (showinglist == -2)
+ if (showinglist == -2) {
zrefresh();
+ }
freematches(lastmatches, 1);
lastmatches = NULL;
hasoldlist = 0;
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index f23d7aa2c..ff4d81b47 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -279,3 +279,16 @@ enum {
ZSL_COPY = 1, /* Copy the argument, don't modify it */
ZSL_TOEND = 2, /* Go to the end of the new line */
};
+
+#ifdef DEBUG
+#define STRINGIFY_LITERAL(x) # x
+#define STRINGIFY(x) STRINGIFY_LITERAL(x)
+#define ERRMSG(x) (__FILE__ ":" STRINGIFY(__LINE__) ": " x)
+#define METACHECK() \
+ DPUTS(zlemetaline == NULL, ERRMSG("line not metafied"))
+#define UNMETACHECK() \
+ DPUTS(zlemetaline != NULL, ERRMSG("line metafied"))
+#else
+#define METACHECK()
+#define UNMETACHECK()
+#endif
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index bed66ac0e..c00eafe18 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -82,7 +82,8 @@ zletext(Histent ent, struct zle_text *zt)
return;
}
- zt->text = stringaszleline(ent->text, &zt->len, NULL);
+ zt->text = stringaszleline((unsigned char *)ent->text, 0,
+ &zt->len, NULL, NULL);
zt->alloced = 1;
}
@@ -351,7 +352,7 @@ historysearchbackward(char **args)
return ret;
}
if (*args) {
- str = stringaszleline((unsigned char *)*args, &hp, NULL);
+ str = stringaszleline((unsigned char *)*args, 0, &hp, NULL, NULL);
} else {
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
mark != 0 || ZS_memcmp(srch_str, zleline, histpos) != 0) {
@@ -410,7 +411,7 @@ historysearchforward(char **args)
return ret;
}
if (*args) {
- str = stringaszleline((unsigned char *)*args, &hp, NULL);
+ str = stringaszleline((unsigned char *)*args, 0, &hp, NULL, NULL);
} else {
if (histline == curhist || histline != srch_hl || zlecs != srch_cs ||
mark != 0 || ZS_memcmp(srch_str, zleline, histpos) != 0) {
@@ -631,7 +632,7 @@ insertlastword(char **args)
n = zmult;
zmult = 1;
- zs = stringaszleline((unsigned char *)s, &len, NULL);
+ zs = stringaszleline((unsigned char *)s, 0, &len, NULL, NULL);
doinsert(zs, len);
free(zs);
zmult = n;
@@ -736,8 +737,8 @@ pushlineoredit(char **args)
if (zmult < 0)
return 1;
if (hline && *hline) {
- ZLE_STRING_T zhline = stringaszleline((unsigned char *)hline,
- &ics, NULL);
+ ZLE_STRING_T zhline = stringaszleline((unsigned char *)hline, 0,
+ &ics, NULL, NULL);
sizeline(ics + zlell + 1);
/* careful of overlapping copy */
@@ -780,7 +781,7 @@ zgetline(UNUSED(char **args))
return 1;
} else {
int cc;
- ZLE_STRING_T lineadd = stringaszleline(s, &cc, NULL);
+ ZLE_STRING_T lineadd = stringaszleline(s, 0, &cc, NULL, NULL);
spaceinline(cc);
ZS_memcpy(zleline + zlecs, lineadd, cc);
@@ -1257,8 +1258,8 @@ getvisrchstr(void)
cmd == Th(z_vicmdmode)) {
int newlen;
sbuf[sptr] = ZWC('\0');
- visrchstr = zlelineasstring(sbuf + 1, sptr - 1, 0, &newlen,
- NULL, 0);
+ visrchstr = (char *)zlelineasstring(sbuf + 1, sptr - 1, 0, &newlen,
+ NULL, 0);
if (!newlen) {
zsfree(visrchstr);
visrchstr = ztrdup(vipenultsrchstr);
@@ -1378,7 +1379,8 @@ virepeatsearch(UNUSED(char **args))
n = -n;
visrchsense = -visrchsense;
}
- srcstr = stringaszleline(visrchstr, &srclen, NULL);
+ srcstr = stringaszleline((unsigned char *)visrchstr, 0,
+ &srclen, NULL, NULL);
if (!(he = quietgethist(histline)))
return 1;
while ((he = movehistent(he, visrchsense, hist_skip_flags))) {
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 1acff3bbb..2522f67fd 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -42,6 +42,11 @@
/**/
mod_export ZLE_STRING_T zleline;
+/* Cursor position and line length in zle */
+
+/**/
+mod_export int zlecs, zlell;
+
/* != 0 if in a shell function called from completion, such that read -[cl] *
* will work (i.e., the line is metafied, and the above word arrays are OK). */
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 44bc611d5..9ade372b1 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -69,7 +69,7 @@ selfinsert(UNUSED(char **args))
tmp = lastchar_wide;
doinsert(&tmp, 1);
#else
- char s = lastchar;
+ unsigned char s = lastchar;
doinsert(&s, 1);
#endif
return 0;
@@ -480,7 +480,8 @@ whatcursorposition(UNUSED(char **args))
* convert a single character, remembering it may
* turn into a multibyte string or be metafied.
*/
- mbstr = zlelineasstring(zleline+zlecs, 1, 0, &len, NULL, 1);
+ mbstr = (char *)zlelineasstring(zleline+zlecs, 1, 0,
+ &len, NULL, 1);
strcpy(s, mbstr);
s += len;
}
@@ -654,7 +655,7 @@ copyprevshellword(UNUSED(char **args))
if (p) {
int len;
- ZLE_STRING_T lineadd = stringaszleline(p, &len, NULL);
+ ZLE_STRING_T lineadd = stringaszleline(p, 0, &len, NULL, NULL);
spaceinline(len);
ZS_memcpy(zleline + zlecs, lineadd, len);
@@ -777,7 +778,7 @@ executenamedcommand(char *prmt)
clearlist = 1;
/* prmt may be constant */
prmt = ztrdup(prmt);
- zprmt = stringaszleline((unsigned char *)prmt, &l, NULL);
+ zprmt = stringaszleline((unsigned char *)prmt, 0, &l, NULL, NULL);
cmdbuf = zhalloc((l + NAMLEN + 2) * ZLE_CHAR_SIZE);
ZS_memcpy(cmdbuf, zprmt, l);
free(zprmt);
@@ -860,7 +861,8 @@ executenamedcommand(char *prmt)
Thingy r;
unambiguous:
*ptr = 0;
- namedcmdstr = zlelineasstring(cmdbuf, len, 0, NULL, NULL, 0);
+ namedcmdstr = (char *)zlelineasstring(cmdbuf, len, 0,
+ NULL, NULL, 0);
r = rthingy(namedcmdstr);
free(namedcmdstr);
namedcmdstr = NULL;
@@ -890,7 +892,8 @@ executenamedcommand(char *prmt)
namedcmdll = newlinklist();
- namedcmdstr = zlelineasstring(cmdbuf, len, 0, NULL, NULL, 0);
+ namedcmdstr = (char *)zlelineasstring(cmdbuf, len, 0,
+ NULL, NULL, 0);
scanhashtable(thingytab, 1, 0, DISABLED, scancompcmd, 0);
free(namedcmdstr);
namedcmdstr = NULL;
@@ -912,7 +915,9 @@ executenamedcommand(char *prmt)
zmult = zmultsav;
} else if (!nextnode(firstnode(namedcmdll))) {
char *peekstr = ztrdup(peekfirst(namedcmdll));
- ZLE_STRING_T ztmp = stringaszleline(peekstr, &len, NULL);
+ ZLE_STRING_T ztmp =
+ stringaszleline((unsigned char *)peekstr, 0, &len,
+ NULL, NULL);
zsfree(peekstr);
ZS_memcpy(ptr = cmdbuf, ztmp, len);
ptr += len;
@@ -922,7 +927,9 @@ executenamedcommand(char *prmt)
} else {
int ltmp;
char *peekstr = ztrdup(peekfirst(namedcmdll));
- ZLE_STRING_T ztmp = stringaszleline(peekstr, &ltmp, NULL);
+ ZLE_STRING_T ztmp =
+ stringaszleline((unsigned char *)peekstr, 0, &ltmp,
+ NULL, NULL);
zsfree(peekstr);
ZS_memcpy(cmdbuf, ztmp, ltmp);
free(ztmp);
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index f089a5f47..7aef5959d 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -126,6 +126,8 @@ static struct zleparam {
{ NULL, 0, NULL, NULL }
};
+/* ro means parameters are readonly, used from completion */
+
/**/
mod_export void
makezleparams(int ro)
@@ -187,7 +189,10 @@ set_buffer(UNUSED(Param pm), char *x)
static char *
get_buffer(UNUSED(Param pm))
{
- return (char *)zlelineasstring(zleline, zlell, 0, NULL, NULL, 1);
+ if (zlemetaline != 0)
+ return dupstring((char *)zlemetaline);
+ else
+ return (char *)zlelineasstring(zleline, zlell, 0, NULL, NULL, 1);
}
/**/
@@ -208,7 +213,17 @@ set_cursor(UNUSED(Param pm), zlong x)
static zlong
get_cursor(UNUSED(Param pm))
{
- return zlecs;
+ if (zlemetaline != NULL) {
+ /* A lot of work for one number, but still... */
+ ZLE_STRING_T tmpline;
+ int tmpcs, tmpll, tmpsz;
+ tmpline = stringaszleline(zlemetaline, zlemetacs,
+ &tmpll, &tmpsz, &tmpcs);
+ free(tmpline);
+ return tmpcs;
+ }
+ else
+ return zlecs;
}
/**/
@@ -238,9 +253,9 @@ set_lbuffer(UNUSED(Param pm), char *x)
int len;
if (x && *x != ZWC('\0'))
- y = stringaszleline((unsigned char *)x, &len, NULL);
+ y = stringaszleline((unsigned char *)x, 0, &len, NULL, NULL);
else
- y = ZWC(""), len = 0;
+ y = ZWS(""), len = 0;
sizeline(zlell - zlecs + len);
ZS_memmove(zleline + len, zleline + zlecs, zlell - zlecs);
ZS_memcpy(zleline, y, len);
@@ -257,7 +272,10 @@ set_lbuffer(UNUSED(Param pm), char *x)
static char *
get_lbuffer(UNUSED(Param pm))
{
- return (char *)zlelineasstring(zleline, zlecs, 0, NULL, NULL, 1);
+ if (zlemetaline != NULL)
+ return dupstrpfx((char *)zlemetaline, zlemetacs);
+ else
+ return (char *)zlelineasstring(zleline, zlecs, 0, NULL, NULL, 1);
}
/**/
@@ -268,9 +286,9 @@ set_rbuffer(UNUSED(Param pm), char *x)
int len;
if (x && *x != ZWC('\0'))
- y = stringaszleline((unsigned char *)x, &len, NULL);
+ y = stringaszleline((unsigned char *)x, 0, &len, NULL, NULL);
else
- y = ZWC(""), len = 0;
+ y = ZWS(""), len = 0;
sizeline(zlell = zlecs + len);
ZS_memcpy(zleline + zlecs, y, len);
zsfree(x);
@@ -284,8 +302,11 @@ set_rbuffer(UNUSED(Param pm), char *x)
static char *
get_rbuffer(UNUSED(Param pm))
{
- return (char *)zlelineasstring(zleline + zlecs, zlell - zlecs,
- 0, NULL, NULL, 1);
+ if (zlemetaline != NULL)
+ return dupstrpfx((char *)zleline + zlemetacs, zlemetall - zlemetacs);
+ else
+ return (char *)zlelineasstring(zleline + zlecs, zlell - zlecs,
+ 0, NULL, NULL, 1);
}
/**/
@@ -435,7 +456,7 @@ set_cutbuffer(UNUSED(Param pm), char *x)
cutbuf.flags = 0;
if (x) {
int n;
- cutbuf.buf = stringaszleline((unsigned char *)x, &n, NULL);
+ cutbuf.buf = stringaszleline((unsigned char *)x, 0, &n, NULL, NULL);
cutbuf.len = n;
free(x);
} else {
@@ -490,7 +511,8 @@ set_killring(UNUSED(Param pm), char **x)
int n, len = strlen(*p);
kptr = kring + kpos;
- kptr->buf = stringaszleline((unsigned char *)*p, &n, NULL);
+ kptr->buf = stringaszleline((unsigned char *)*p, 0, &n,
+ NULL, NULL);
kptr->len = n;
zfree(*p, len+1);
@@ -556,7 +578,7 @@ set_prepost(ZLE_STRING_T *textvar, int *lenvar, char *x)
*lenvar = 0;
}
if (x) {
- *textvar = stringaszleline((unsigned char *)x, lenvar, NULL);
+ *textvar = stringaszleline((unsigned char *)x, 0, lenvar, NULL, NULL);
free(x);
}
}
@@ -610,8 +632,8 @@ static char *
get_lsearch(UNUSED(Param pm))
{
if (previous_search_len)
- return zlelineasstring(previous_search, previous_search_len, 0,
- NULL, NULL, 1);
+ return (char *)zlelineasstring(previous_search, previous_search_len, 0,
+ NULL, NULL, 1);
else
return "";
}
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index b45047ac2..da9fe45b7 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -333,7 +333,8 @@ zrefresh(void)
*qbuf; /* tmp */
int tmpcs, tmpll; /* ditto cursor position and line length */
int tmpalloced; /* flag to free tmpline when finished */
-
+ int remetafy; /* flag that zle line is metafied */
+
if (trashedzle)
reexpandprompt();
@@ -344,6 +345,17 @@ zrefresh(void)
if (inlist)
return;
+ /*
+ * zrefresh() is called from all over the place, so we can't
+ * be sure if the line is metafied for completion or not.
+ */
+ if (zlemetaline != NULL) {
+ remetafy = 1;
+ unmetafy_line();
+ }
+ else
+ remetafy = 0;
+
if (predisplaylen || postdisplaylen) {
/* There is extra text to display at the start or end of the line */
tmpline = zalloc((zlell + predisplaylen + postdisplaylen)*sizeof(*tmpline));
@@ -743,6 +755,9 @@ singlelineout:
}
if (showinglist == -1)
showinglist = nlnct;
+
+ if (remetafy)
+ metafy_line();
}
#define tcinscost(X) (tccan(TCMULTINS) ? tclen[TCMULTINS] : (X)*tclen[TCINS])
@@ -1189,6 +1204,12 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
int t0, /* tmp */
vsiz, /* size of new video buffer */
nvcs = 0; /* new video cursor column */
+#ifdef ZLE_UNICODE_SUPPORT
+ ZLE_STRING_T lpwbuf, lpwp; /* converted lprompt and pointer */
+ char *lpptr, /* pointer into multibyte lprompt */
+ lpend; /* end of multibyte lprompt */
+ mbstate_t ps; /* shift state */
+#endif
nlnct = 1;
/* generate the new line buffer completely */
@@ -1208,14 +1229,44 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
}
/* only use last part of prompt */
- /* TODO convert prompt to wide char */
#ifdef ZLE_UNICODE_SUPPORT
- t0 = mbtowc(vbuf, strchr(lpromptbuf, 0) - lpromptw, lpromptw);
- if (t0 >= 0) {
- vbuf[t0] = ZWC('\0');
- vp = vbuf + t0;
- } else
- /* FIXME What to do? */ ;
+ /*
+ * Convert the entire lprompt so that we know how to count
+ * characters.
+ *
+ * TODO screen widths are still not correct, indeed lpromptw knows
+ * nothing about multibyte characters so may be too long.
+ */
+ lpend = strchr(lpromptbuf, 0);
+ /* Worst case number of characters, not null-terminated */
+ lpwp = lpwbuf = (ZLE_STRING_T)zalloc((lpend - lpromptbuf)
+ * sizeof(*lpwbuf));
+ /* Reset shift state, maybe. */
+ memset(&ps, '\0', sizeof(ps));
+ for (lpptr = lpromptbuf; lpptr < lpend; ) {
+ t0 = mbrtowc(lpwp, lpptr, lpend - lpptr, &ps);
+ if (t0 > 0) {
+ /* successfully converted */
+ lpptr += t0;
+ lpwp++;
+ } else {
+ /* dunno, try to recover */
+ lpptr++;
+ *lpwp++ = ZWC('?');
+ }
+ }
+ if (lpwp - lpwbuf < lpromptw) {
+ /* Not enough characters for lpromptw. */
+ ZS_memcpy(vbuf, lpwbuf, lpwp - lpwbuf);
+ vp = vbuf + (lpwp - lpwbuf);
+ while (vp < vbuf + lpromptw)
+ *vp++ = ZWC(' ');
+ } else {
+ ZS_memcpy(vbuf, lpwp - lpromptw, lpromptw);
+ vp = vbuf + lpromptw;
+ }
+ *vp = ZWC('\0');
+ zfree(lpwbuf, lpromptw * sizeof(*lpwbuf));
#else
memcpy(vbuf, strchr(lpromptbuf, 0) - lpromptw, lpromptw);
vbuf[lpromptw] = '\0';
@@ -1223,10 +1274,10 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs)
#endif
for (t0 = 0; t0 < tmpll; t0++) {
- if (tmpline[t0] == ZWC('\t'))
+ if (tmpline[t0] == ZWC('\t')) {
for (*vp++ = ZWC(' '); (vp - vbuf) & 7; )
*vp++ = ZWC(' ');
- else if (tmpline[t0] == ZWC('\n')) {
+ } else if (tmpline[t0] == ZWC('\n')) {
*vp++ = ZWC('\\');
*vp++ = ZWC('n');
} else if (ZC_icntrl(tmpline[t0])) {
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 5885fb10f..d756b94e6 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -416,8 +416,8 @@ bin_zle_refresh(UNUSED(char *name), char **args, Options ops, UNUSED(char func))
statusll = 0;
if (*args) {
if (**args) {
- statusline = stringaszleline((unsigned char *)*args, &statusll,
- NULL);
+ statusline = stringaszleline((unsigned char *)*args, 0, &statusll,
+ NULL, NULL);
}
if (*++args) {
LinkList l = newlinklist();
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index f59823f0b..ba149cfe8 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -33,19 +33,40 @@
/*
* The main part of ZLE maintains the line being edited as binary data,
* but here, where we interface with the lexer and other bits of zsh, we
- * need the line metafied. The technique used is quite simple: on entry
- * to the expansion/completion system, we metafy the line in place,
- * adjusting zlell and zlecs to match. All completion and expansion is
- * done on the metafied line. Immediately before returning, the line is
- * unmetafied again, changing zlell and zlecs back. (zlell and zlecs
- * might have changed during completion, so they can't be merely saved
- * and restored.) The various indexes into the line that are used in
- * this file only are not translated: they remain indexes into the
- * metafied line.
+ * need the line metafied and, if necessary, converted from wide
+ * characters into multibyte strings. On entry to the
+ * expansion/completion system, we metafy the line from zleline into
+ * zlemetaline, with zlell and zlecs adjusted into zlemetall zlemetacs
+ * to match. zlemetall and zlemetacs refer to raw character positions,
+ * in other words a metafied character contributes 2 to each. All
+ * completion and expansion is done on the metafied line. Immediately
+ * before returning, the line is unmetafied again, so that zleline,
+ * zlell and zlecs are once again valid. (zlell and zlecs might have
+ * changed during completion, so they can't be merely saved and
+ * restored.) The various indexes into the line that are used in this
+ * file only are not translated: they remain indexes into the metafied
+ * line.
+ *
+ * zlemetaline is always NULL when not in use and non-NULL when in use.
+ * This can be used to test if the line is metafied. It would be
+ * possible to use zlecs and zlell directly, updated as appropriate when
+ * metafying and unmetafying, instead of zlemetacs and zlemetall,
+ * however the current system seems clearer.
*/
#define inststr(X) inststrlen((X),1,-1)
+/*
+ * The state of the line being edited between metafy_line()
+ * unmetafy_line().
+ *
+ * zlemetacs and zlemetall are defined in lex.c.
+ */
+/**/
+mod_export unsigned char *zlemetaline;
+/**/
+mod_export int metalinesz;
+
/* The line before completion was tried. */
/**/
@@ -153,7 +174,10 @@ mod_export int comprecursive;
/**/
int hascompwidgets;
-/* Find out if we have to insert a tab (instead of trying to complete). */
+/*
+ * Find out if we have to insert a tab (instead of trying to complete).
+ * The line is not metafied here.
+ */
/**/
static int
@@ -250,6 +274,7 @@ deletecharorlist(char **args)
useglob = isset(GLOBCOMPLETE);
wouldinstab = 0;
+ /* Line not yet metafied */
if (zlecs != zlell) {
fixsuffix();
invalidatelist();
@@ -583,32 +608,24 @@ docomplete(int lst)
return 0;
}
- /*
- * TODO: metafy_line() currently tries to metafy in place.
- * For ZLE_UNICODE_SUPPORT we need to metafy into a separate
- * string, replacing all use of zleline, zlecs and zlell here
- * with those values, then restoring at the end.
- *
- * The alternative is probably too horrendous to contemplate.
- */
metafy_line();
- ocs = zlecs;
- origline = dupstring((char *) zleline);
- origcs = zlecs;
- origll = zlell;
+ ocs = zlemetacs;
+ origline = dupstring((char *) zlemetaline);
+ origcs = zlemetacs;
+ origll = zlemetall;
if (!isfirstln && chline != NULL) {
/* If we are completing in a multi-line buffer (which was not *
* taken from the history), we have to prepend the stuff saved *
* in chline to the contents of line. */
- ol = dupstring((char *)zleline);
+ ol = dupstring((char *)zlemetaline);
/* Make sure that chline is zero-terminated. */
*hptr = '\0';
- zlecs = 0;
+ zlemetacs = 0;
inststr(chline);
- chl = zlecs;
- zlecs += ocs;
+ chl = zlemetacs;
+ zlemetacs += ocs;
} else
ol = NULL;
inwhat = IN_NOTHING;
@@ -622,35 +639,35 @@ docomplete(int lst)
* NOTE: get_comp_string() calls pushheap(), but not popheap(). */
noerrs = 1;
s = get_comp_string();
- DPUTS(wb < 0 || zlecs < wb || zlecs > we,
- "BUG: 0 <= wb <= zlecs <= we is not true!");
+ DPUTS(wb < 0 || zlemetacs < wb || zlemetacs > we,
+ "BUG: 0 <= wb <= zlemetacs <= we is not true!");
noerrs = ne;
/* For vi mode, reset the start-of-insertion pointer to the beginning *
* of the word being completed, if it is currently later. Vi itself *
* would never change the pointer in the middle of an insertion, but *
* then vi doesn't have completion. More to the point, this is only *
* an emulation. */
- if (viinsbegin > ztrsub((char *) zleline + wb, (char *) zleline))
- viinsbegin = ztrsub((char *) zleline + wb, (char *) zleline);
+ if (viinsbegin > ztrsub((char *) zlemetaline + wb, (char *) zlemetaline))
+ viinsbegin = ztrsub((char *) zlemetaline + wb, (char *) zlemetaline);
/* If we added chline to the line buffer, reset the original contents. */
if (ol) {
- zlecs -= chl;
+ zlemetacs -= chl;
wb -= chl;
we -= chl;
if (wb < 0) {
- strcpy((char *) zleline, ol);
- zlell = strlen((char *) zleline);
- zlecs = ocs;
+ strcpy((char *) zlemetaline, ol);
+ zlemetall = strlen((char *) zlemetaline);
+ zlemetacs = ocs;
popheap();
unmetafy_line();
zsfree(s);
active = 0;
return 1;
}
- ocs = zlecs;
- zlecs = 0;
+ ocs = zlemetacs;
+ zlemetacs = 0;
foredel(chl);
- zlecs = ocs;
+ zlemetacs = ocs;
}
freeheap();
/* Save the lexer state, in case the completion code uses the lexer *
@@ -694,7 +711,7 @@ docomplete(int lst)
if (*q == String && q[1] != Inpar && q[1] != Inbrack) {
if (*++q == Inbrace) {
if (! skipparens(Inbrace, Outbrace, &q) &&
- q == s + zlecs - wb)
+ q == s + zlemetacs - wb)
lst = COMP_EXPAND;
} else {
char *t, sav, sav2;
@@ -725,7 +742,7 @@ docomplete(int lst)
q++;
sav = *q;
*q = '\0';
- if (zlecs - wb == q - s &&
+ if (zlemetacs - wb == q - s &&
(idigit(sav2) || checkparams(t)))
lst = COMP_EXPAND;
*q = sav;
@@ -735,7 +752,7 @@ docomplete(int lst)
lst = COMP_COMPLETE;
} else
break;
- } while (q < s + zlecs - wb);
+ } while (q < s + zlemetacs - wb);
if (lst == COMP_EXPAND_COMPLETE) {
/* If it is still not clear if we should use expansion or *
* completion and there is a `$' or a backtick in the word, *
@@ -760,7 +777,7 @@ docomplete(int lst)
for (q = w; *q; q++)
if (INULL(*q))
*q = Nularg;
- zlecs = wb;
+ zlemetacs = wb;
foredel(we - wb);
untokenize(x = ox = dupstring(w));
@@ -775,8 +792,8 @@ docomplete(int lst)
/* Do expansion. */
char *ol = (olst == COMP_EXPAND ||
olst == COMP_EXPAND_COMPLETE) ?
- dupstring((char *)zleline) : (char *)zleline;
- int ocs = zlecs, ne = noerrs;
+ dupstring((char *)zlemetaline) : (char *)zlemetaline;
+ int ocs = zlemetacs, ne = noerrs;
noerrs = 1;
ret = doexpansion(origword, lst, olst, lincmd);
@@ -786,8 +803,8 @@ docomplete(int lst)
/* If expandorcomplete was invoked and the expansion didn't *
* change the command line, do completion. */
if (olst == COMP_EXPAND_COMPLETE &&
- !strcmp(ol, (char *)zleline)) {
- zlecs = ocs;
+ !strcmp(ol, (char *)zlemetaline)) {
+ zlemetacs = ocs;
errflag = 0;
if (!compfunc) {
@@ -808,15 +825,15 @@ docomplete(int lst)
} else {
if (ret)
clearlist = 1;
- if (!strcmp(ol, (char *)zleline)) {
+ if (!strcmp(ol, (char *)zlemetaline)) {
/* We may have removed some quotes. For completion, other
* parts of the code re-install them, but for expansion
* we have to do it here. */
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(origll);
- memcpy(zleline, origline, origll);
- zlecs = origcs;
+ memcpy(zlemetaline, origline, origll);
+ zlemetacs = origcs;
}
}
} else
@@ -828,11 +845,11 @@ docomplete(int lst)
/* Reset the lexer state, pop the heap. */
lexrestore();
popheap();
- unmetafy_line();
dat[0] = lst;
dat[1] = ret;
runhookdef(AFTERCOMPLETEHOOK, (void *) dat);
+ unmetafy_line();
active = 0;
return dat[1];
@@ -865,23 +882,26 @@ addx(char **ptmp)
{
int addspace = 0;
- if (!zleline[zlecs] || zleline[zlecs] == '\n' ||
- (iblank(zleline[zlecs]) && (!zlecs || zleline[zlecs-1] != '\\')) ||
- zleline[zlecs] == ')' || zleline[zlecs] == '`' ||
- zleline[zlecs] == '}' ||
- zleline[zlecs] == ';' || zleline[zlecs] == '|' ||
- zleline[zlecs] == '&' ||
- zleline[zlecs] == '>' || zleline[zlecs] == '<' ||
- (instring && (zleline[zlecs] == '"' || zleline[zlecs] == '\'')) ||
- (addspace = (comppref && !iblank(zleline[zlecs])))) {
- *ptmp = (char *)zleline;
- zleline = (ZLE_STRING_T)zhalloc(strlen((char *)zleline) + 3 +
- addspace);
- memcpy(zleline, *ptmp, zlecs);
- zleline[zlecs] = 'x';
+ if (!zlemetaline[zlemetacs] || zlemetaline[zlemetacs] == '\n' ||
+ (iblank(zlemetaline[zlemetacs]) &&
+ (!zlemetacs || zlemetaline[zlemetacs-1] != '\\')) ||
+ zlemetaline[zlemetacs] == ')' || zlemetaline[zlemetacs] == '`' ||
+ zlemetaline[zlemetacs] == '}' ||
+ zlemetaline[zlemetacs] == ';' || zlemetaline[zlemetacs] == '|' ||
+ zlemetaline[zlemetacs] == '&' ||
+ zlemetaline[zlemetacs] == '>' || zlemetaline[zlemetacs] == '<' ||
+ (instring && (zlemetaline[zlemetacs] == '"' ||
+ zlemetaline[zlemetacs] == '\'')) ||
+ (addspace = (comppref && !iblank(zlemetaline[zlemetacs])))) {
+ *ptmp = (char *)zlemetaline;
+ zlemetaline = (unsigned char *)zhalloc(strlen((char *)zlemetaline)
+ + 3 + addspace);
+ memcpy(zlemetaline, *ptmp, zlemetacs);
+ zlemetaline[zlemetacs] = 'x';
if (addspace)
- zleline[zlecs+1] = ' ';
- strcpy((char *)zleline + zlecs + 1 + addspace, (*ptmp) + zlecs);
+ zlemetaline[zlemetacs+1] = ' ';
+ strcpy((char *)zlemetaline + zlemetacs + 1 + addspace,
+ (*ptmp) + zlemetacs);
addedx = 1 + addspace;
} else {
addedx = 0;
@@ -902,35 +922,47 @@ dupstrspace(const char *str)
return t;
}
-/* These functions metafy and unmetafy the ZLE buffer, as described at the *
- * top of this file. Note that zlell and zlecs are translated. They *must* be *
- * called in matching pairs, around all the expansion/completion code. *
- * Currently, there are four pairs: in history expansion, in the main *
- * completion function, and one in each of the middle-of-menu-completion *
- * functions (there's one for each direction). */
+/*
+ * These functions metafy and unmetafy the ZLE buffer, as described at
+ * the top of this file. They *must* be called in matching pairs,
+ * around all the expansion/completion code.
+ *
+ * The variables zleline, zlell and zlecs are metafied into
+ * zlemetaline, zlemetall and zlemetacs. Only the latter variables
+ * should be referred to from above zle (i.e. in the main shell),
+ * or when using the completion API (if that's not too strong a
+ * way of referring to it).
+ */
/**/
mod_export void
metafy_line(void)
{
- int len = zlell;
- char *s;
+ UNMETACHECK();
+
+ zlemetaline = zlelineasstring(zleline, zlell, zlecs,
+ &zlemetall, &zlemetacs, 0);
+ metalinesz = zlemetall;
- for (s = (char *) zleline; s < (char *) zleline + zlell;)
- if (imeta(*s++))
- len++;
- sizeline(len);
- (void) metafy((char *) zleline, zlell, META_NOALLOC);
- zlell = len;
- zlecs = metalen((char *) zleline, zlecs);
+ /*
+ * We will always allocate a new zleline based on zlemetaline.
+ */
+ free(zleline);
+ zleline = NULL;
}
/**/
mod_export void
unmetafy_line(void)
{
- zlecs = ztrsub((char *) zleline + zlecs, (char *) zleline);
- (void) unmetafy((char *) zleline, &zlell);
+ METACHECK();
+
+ /* paranoia */
+ zlemetaline[zlemetall] = '\0';
+ zleline = stringaszleline(zlemetaline, zlemetacs, &zlell, &linesz, &zlecs);
+
+ free(zlemetaline);
+ zlemetaline = NULL;
}
/* Free a brinfo list. */
@@ -1004,6 +1036,8 @@ get_comp_string(void)
int ona = noaliases, qsub;
char *s = NULL, *linptr, *tmp, *p, *tt = NULL, rdop[20];
+ METACHECK();
+
freebrinfo(brbeg);
freebrinfo(brend);
brbeg = lastbrbeg = brend = lastbrend = NULL;
@@ -1025,7 +1059,8 @@ get_comp_string(void)
* "...", `...`, or ((...)). Nowadays this is only used to find *
* out if we are inside `...`. */
- for (i = j = k = 0, p = (char *)zleline; p < (char *)zleline + zlecs; p++)
+ for (i = j = k = 0, p = (char *)zlemetaline;
+ p < (char *)zlemetaline + zlemetacs; p++)
if (*p == '`' && !(k & 1))
i++;
else if (*p == '\"' && !(k & 1) && !(i & 1))
@@ -1037,7 +1072,7 @@ get_comp_string(void)
inbackt = (i & 1);
instring = 0;
addx(&tmp);
- linptr = (char *)zleline;
+ linptr = (char *)zlemetaline;
pushheap();
start:
@@ -1146,14 +1181,14 @@ get_comp_string(void)
tt = tokstr ? dupstring(tokstr) : NULL;
if (isset(RCQUOTES) && *tt == Snull) {
- char *p, *e = tt + zlecs - wb;
+ char *p, *e = tt + zlemetacs - wb;
for (p = tt; *p && p < e; p++)
if (*p == '\'')
qsub++;
}
/* If we added a `x', remove it. */
if (addedx && tt)
- chuck(tt + zlecs - wb - qsub);
+ chuck(tt + zlemetacs - wb - qsub);
tt0 = tok;
/* Store the number of this word. */
clwpos = i;
@@ -1201,8 +1236,8 @@ get_comp_string(void)
/* If this is the word the cursor is in and we added a `x', *
* remove it. */
if (clwpos == i++ && addedx)
- chuck(&clwords[i - 1][((zlecs - wb - qsub) >= sl) ?
- (sl - 1) : (zlecs - wb - qsub)]);
+ chuck(&clwords[i - 1][((zlemetacs - wb - qsub) >= sl) ?
+ (sl - 1) : (zlemetacs - wb - qsub)]);
} while (tok != LEXERR && tok != ENDINPUT &&
(tok != SEPER || (zleparse && !tt0)));
/* Calculate the number of words stored in the clwords array. */
@@ -1224,13 +1259,14 @@ get_comp_string(void)
/* We are in command or process substitution if we are not in
* a $((...)). */
if (parend >= 0 && !tmp)
- zleline = (unsigned char *) dupstring(tmp = (char *)zleline);
- linptr = (char *) zleline + zlell + addedx - parbegin + 1;
- if ((linptr - (char *) zleline) < 3 || *linptr != '(' ||
+ zlemetaline = (unsigned char *)
+ dupstring(tmp = (char *)zlemetaline);
+ linptr = (char *) zlemetaline + zlemetall + addedx - parbegin + 1;
+ if ((linptr - (char *) zlemetaline) < 3 || *linptr != '(' ||
linptr[-1] != '(' || linptr[-2] != '$') {
if (parend >= 0) {
- zlell -= parend;
- zleline[zlell + addedx] = '\0';
+ zlemetall -= parend;
+ zlemetaline[zlemetall + addedx] = '\0';
}
lexrestore();
tt = NULL;
@@ -1243,7 +1279,7 @@ get_comp_string(void)
else if (!t0 || t0 == ENDINPUT) {
/* There was no word (empty line). */
s = ztrdup("");
- we = wb = zlecs;
+ we = wb = zlemetacs;
clwpos = clwnum;
t0 = STRING;
} else if (t0 == STRING) {
@@ -1264,7 +1300,7 @@ get_comp_string(void)
*s = sav;
if (*s == '+')
s++;
- if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + zlecs - wb) {
+ if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + zlemetacs - wb) {
s = NULL;
inwhat = IN_MATH;
if ((keypm = (Param) paramtab->getnode(paramtab, varname)) &&
@@ -1273,7 +1309,7 @@ get_comp_string(void)
else
insubscr = 1;
} else if (*s == '=') {
- if (zlecs > wb + (s - tt)) {
+ if (zlemetacs > wb + (s - tt)) {
s++;
wb += s - tt;
s = ztrdup(s);
@@ -1294,17 +1330,17 @@ get_comp_string(void)
}
lincmd = 1;
}
- if (we > zlell)
- we = zlell;
- tt = (char *)zleline;
+ if (we > zlemetall)
+ we = zlemetall;
+ tt = (char *)zlemetaline;
if (tmp) {
- zleline = (unsigned char *)tmp;
- zlell = strlen((char *)zleline);
+ zlemetaline = (unsigned char *)tmp;
+ zlemetall = strlen((char *)zlemetaline);
}
if (t0 != STRING && inwhat != IN_MATH) {
if (tmp) {
tmp = NULL;
- linptr = (char *)zleline;
+ linptr = (char *)zlemetaline;
lexrestore();
addedx = 0;
goto start;
@@ -1325,7 +1361,7 @@ get_comp_string(void)
int i = 0;
char *nnb = (iident(*s) ? s : s + 1), *nb = NULL, *ne = NULL;
- for (tt = s; ++tt < s + zlecs - wb;)
+ for (tt = s; ++tt < s + zlemetacs - wb;)
if (*tt == Inbrack) {
i++;
nb = nnb;
@@ -1354,23 +1390,23 @@ get_comp_string(void)
int lev;
char *p;
- for (wb = zlecs - 1, lev = 0; wb > 0; wb--)
- if (zleline[wb] == ']' || zleline[wb] == ')')
+ for (wb = zlemetacs - 1, lev = 0; wb > 0; wb--)
+ if (zlemetaline[wb] == ']' || zlemetaline[wb] == ')')
lev++;
- else if (zleline[wb] == '[') {
+ else if (zlemetaline[wb] == '[') {
if (!lev--)
break;
- } else if (zleline[wb] == '(') {
- if (!lev && zleline[wb - 1] == '(')
+ } else if (zlemetaline[wb] == '(') {
+ if (!lev && zlemetaline[wb - 1] == '(')
break;
if (lev)
lev--;
}
- p = (char *) zleline + wb;
+ p = (char *) zlemetaline + wb;
wb++;
if (wb && (*p == '[' || *p == '(') &&
!skipparens(*p, (*p == '[' ? ']' : ')'), &p)) {
- we = (p - (char *) zleline) - 1;
+ we = (p - (char *) zlemetaline) - 1;
if (insubscr == 2)
insubscr = 3;
}
@@ -1378,25 +1414,26 @@ get_comp_string(void)
/* In mathematical expression, we complete parameter names *
* (even if they don't have a `$' in front of them). So we *
* have to find that name. */
- for (we = zlecs; iident(zleline[we]); we++);
- for (wb = zlecs; --wb >= 0 && iident(zleline[wb]););
+ for (we = zlemetacs; iident(zlemetaline[we]); we++);
+ for (wb = zlemetacs; --wb >= 0 && iident(zlemetaline[wb]););
wb++;
}
zsfree(s);
s = zalloc(we - wb + 1);
- strncpy(s, (char *) zleline + wb, we - wb);
+ strncpy(s, (char *) zlemetaline + wb, we - wb);
s[we - wb] = '\0';
- if (wb > 2 && zleline[wb - 1] == '[' && iident(zleline[wb - 2])) {
+ if (wb > 2 && zlemetaline[wb - 1] == '[' &&
+ iident(zlemetaline[wb - 2])) {
int i = wb - 3;
- unsigned char sav = zleline[wb - 1];
+ unsigned char sav = zlemetaline[wb - 1];
- while (i >= 0 && iident(zleline[i]))
+ while (i >= 0 && iident(zlemetaline[i]))
i--;
- zleline[wb - 1] = '\0';
+ zlemetaline[wb - 1] = '\0';
zsfree(varname);
- varname = ztrdup((char *) zleline + i + 1);
- zleline[wb - 1] = sav;
+ varname = ztrdup((char *) zlemetaline + i + 1);
+ zlemetaline[wb - 1] = sav;
if ((keypm = (Param) paramtab->getnode(paramtab, varname)) &&
(keypm->flags & PM_HASHED)) {
if (insubscr != 3)
@@ -1407,7 +1444,7 @@ get_comp_string(void)
parse_subst_string(s);
}
/* This variable will hold the current word in quoted form. */
- offs = zlecs - wb;
+ offs = zlemetacs - wb;
if ((p = parambeg(s))) {
for (p = s; *p; p++)
if (*p == Dnull)
@@ -1451,34 +1488,34 @@ get_comp_string(void)
/* While building the quoted form, we also clean up the command line. */
for (p = s, i = wb, j = 0; *p; p++, i++)
if (INULL(*p)) {
- if (i < zlecs)
+ if (i < zlemetacs)
offs--;
if (*p == Snull && isset(RCQUOTES))
j = 1-j;
if (p[1] || *p != Bnull) {
if (*p == Bnull) {
- if (zlecs == i + 1)
- zlecs++, offs++;
+ if (zlemetacs == i + 1)
+ zlemetacs++, offs++;
} else {
- ocs = zlecs;
- zlecs = i;
+ ocs = zlemetacs;
+ zlemetacs = i;
foredel(1);
- if ((zlecs = ocs) > i--)
- zlecs--;
+ if ((zlemetacs = ocs) > i--)
+ zlemetacs--;
we--;
}
} else {
- ocs = zlecs;
- zlecs = we;
+ ocs = zlemetacs;
+ zlemetacs = we;
backdel(1);
if (ocs == we)
- zlecs = we - 1;
+ zlemetacs = we - 1;
else
- zlecs = ocs;
+ zlemetacs = ocs;
we--;
}
chuck(p--);
- } else if (j && *p == '\'' && i < zlecs)
+ } else if (j && *p == '\'' && i < zlemetacs)
offs--;
zsfree(origword);
@@ -1746,9 +1783,24 @@ inststrlen(char *str, int move, int len)
if (len == -1)
len = strlen(str);
spaceinline(len);
- strncpy((char *)(zleline + zlecs), str, len);
- if (move)
- zlecs += len;
+ if (zlemetaline != NULL)
+ {
+ strncpy((char *)(zlemetaline + zlemetacs), str, len);
+ if (move)
+ zlemetacs += len;
+ }
+ else
+ {
+ unsigned char *instr;
+ ZLE_STRING_T zlestr;
+ int zlelen;
+
+ instr = (unsigned char *)ztrduppfx((char *)str, len);
+ zlestr = stringaszleline(instr, 0, &zlelen, NULL, NULL);
+ ZS_strncpy(zleline + zlecs, zlestr, zlelen);
+ free(zlestr);
+ zsfree((char *)instr);
+ }
return len;
}
@@ -1801,17 +1853,17 @@ doexpansion(char *s, int lst, int olst, int explincmd)
if (lst == COMP_LIST_EXPAND) {
/* Only the list of expansions was requested. Restore the
* command line. */
- zlecs = 0;
- foredel(zlell);
+ zlemetacs = 0;
+ foredel(zlemetall);
spaceinline(origll);
- memcpy(zleline, origline, origll);
- zlecs = origcs;
+ memcpy(zlemetaline, origline, origll);
+ zlemetacs = origcs;
ret = listlist(vl);
showinglist = 0;
goto end;
}
/* Remove the current word and put the expansions there. */
- zlecs = wb;
+ zlemetacs = wb;
foredel(we - wb);
while ((ss = (char *)ugetnode(vl))) {
ret = 0;
@@ -1820,11 +1872,11 @@ doexpansion(char *s, int lst, int olst, int explincmd)
inststr(ss);
#if 0
if (olst != COMP_EXPAND_COMPLETE || nonempty(vl) ||
- (zlecs && zleline[zlecs-1] != '/')) {
+ (zlemetacs && zlemetaline[zlemetacs-1] != '/')) {
#endif
if (nonempty(vl) || !first) {
spaceinline(1);
- zleline[zlecs++] = ' ';
+ zlemetaline[zlemetacs++] = ' ';
}
first = 0;
}
@@ -2250,14 +2302,16 @@ doexpandhist(void)
unsigned char *ol;
int oll, ocs, ne = noerrs, err, ona = noaliases;
+ UNMETACHECK();
+
pushheap();
metafy_line();
- oll = zlell;
- ocs = zlecs;
- ol = (unsigned char *)dupstring((char *)zleline);
+ oll = zlemetall;
+ ocs = zlemetacs;
+ ol = (unsigned char *)dupstring((char *)zlemetaline);
expanding = 1;
- excs = zlecs;
- zlell = zlecs = 0;
+ excs = zlemetacs;
+ zlemetall = zlemetacs = 0;
lexsave();
/* We push ol as it will remain unchanged */
inpush((char *) ol, 0, NULL);
@@ -2283,8 +2337,8 @@ doexpandhist(void)
expanding = 0;
if (!err) {
- zlecs = excs;
- if (strcmp((char *)zleline, (char *)ol)) {
+ zlemetacs = excs;
+ if (strcmp((char *)zlemetaline, (char *)ol)) {
unmetafy_line();
/* For vi mode -- reset the beginning-of-insertion pointer *
* to the beginning of the line. This seems a little silly, *
@@ -2296,9 +2350,9 @@ doexpandhist(void)
}
}
- strcpy((char *)zleline, (char *)ol);
- zlell = oll;
- zlecs = ocs;
+ strcpy((char *)zlemetaline, (char *)ol);
+ zlemetall = oll;
+ zlemetacs = ocs;
unmetafy_line();
popheap();
@@ -2325,26 +2379,35 @@ fixmagicspace(void)
int
magicspace(char **args)
{
- char *bangq;
+ ZLE_STRING_T bangq;
+ ZLE_CHAR_T zlebangchar[1];
int ret;
fixmagicspace();
- for (bangq = (char *)zleline; (bangq = strchr(bangq, bangchar));
- bangq += 2)
- if (bangq[1] == '"' && (bangq == (char *)zleline || bangq[-1] != '\\'))
- break;
+
#ifdef ZLE_UNICODE_SUPPORT
/*
- * TODO: expansion and completion with Unicode are currently
- * fundamentally broken. Most of the code for this hasn't been
- * commented out, but crashing the shell just because you entered
- * a space seems to be worth guarding against.
+ * TODO: bangchar should really be a multibyte string representing
+ * a single character, since there's no fundamental reason why
+ * it shouldn't be a Unicode character. In practice this is
+ * very minor, however.
*/
- ret = selfinsert(args);
+ if (mbtowc(zlebangchar, (char *)&bangchar, 1) < 0)
+ return selfinsert(args);
#else
+ zlebangchar[0] = bangchar;
+#endif
+ for (bangq = zleline; bangq < zleline + zlell; bangq++)
+ {
+ if (*bangq != zlebangchar[0])
+ continue;
+ if (bangq[1] == ZWC('"') &&
+ (bangq == zleline || bangq[-1] == ZWC('\\')))
+ break;
+ }
+
if (!(ret = selfinsert(args)) &&
- (!bangq || bangq + 2 > (char *)zleline + zlecs))
+ (!bangq || bangq + 2 > zleline + zlecs))
doexpandhist();
-#endif
return ret;
}
@@ -2369,8 +2432,7 @@ getcurcmd(void)
zleparse = 2;
lexsave();
metafy_line();
- inpush(dupstrspace((char *) zleline), 0, NULL);
- unmetafy_line();
+ inpush(dupstrspace((char *) zlemetaline), 0, NULL);
strinbeg(1);
pushheap();
do {
@@ -2381,8 +2443,8 @@ getcurcmd(void)
if (tok == STRING && curlincmd) {
zsfree(s);
s = ztrdup(tokstr);
- cmdwb = zlell - wordbeg;
- cmdwe = zlell + 1 - inbufct;
+ cmdwb = zlemetall - wordbeg;
+ cmdwe = zlemetall + 1 - inbufct;
}
}
while (tok != ENDINPUT && tok != LEXERR && zleparse);
@@ -2390,6 +2452,7 @@ getcurcmd(void)
strinend();
inpop();
errflag = zleparse = 0;
+ unmetafy_line();
lexrestore();
return s;
@@ -2426,8 +2489,13 @@ processcmd(UNUSED(char **args))
int
expandcmdpath(UNUSED(char **args))
{
- int oldcs = zlecs, na = noaliases;
+ /*
+ * zleline is not metafied for most of this function
+ * (that happens within getcurcmd()).
+ */
+ int oldcs = zlecs, na = noaliases, strll;
char *s, *str;
+ ZLE_STRING_T zlestr;
noaliases = 1;
s = getcurcmd();
@@ -2440,8 +2508,11 @@ expandcmdpath(UNUSED(char **args))
return 1;
zlecs = cmdwb;
foredel(cmdwe - cmdwb);
- spaceinline(strlen(str));
- strncpy((char *)zleline + zlecs, str, strlen(str));
+ zlestr = stringaszleline((unsigned char *)str, 0,
+ &strll, NULL, NULL);
+ spaceinline(strll);
+ ZS_strncpy(zleline + zlecs, zlestr, strll);
+ free(zlestr);
zlecs = oldcs;
if (zlecs >= cmdwe - 1)
zlecs += cmdwe - cmdwb + strlen(str);
@@ -2461,7 +2532,7 @@ expandorcompleteprefix(char **args)
comppref = 1;
ret = expandorcomplete(args);
- if (zlecs && zleline[zlecs - 1] == ' ')
+ if (zlecs && zleline[zlecs - 1] == ZWC(' '))
makesuffixstr(NULL, "\\-", 0);
comppref = 0;
return ret;
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index aa691bcdc..f8c4d2013 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -66,21 +66,36 @@ int linesz;
void
sizeline(int sz)
{
- while (sz > linesz)
+ int cursz = (zlemetaline != NULL) ? metalinesz : linesz;
+
+ while (sz > cursz)
{
- if (linesz < 256)
- linesz = 256;
+ if (cursz < 256)
+ cursz = 256;
else
- linesz *= 4;
+ cursz *= 4;
- zleline =
- (ZLE_STRING_T)realloc(zleline,
- (linesz + 2) * ZLE_CHAR_SIZE);
+ if (zlemetaline != NULL) {
+ /* One spare character for the NULL */
+ zlemetaline = (unsigned char *)realloc(zlemetaline, cursz + 1);
+ } else {
+ /* One spare character for the NULL, one for the newline */
+ zleline =
+ (ZLE_STRING_T)realloc(zleline,
+ (cursz + 2) * ZLE_CHAR_SIZE);
+ }
}
+
+ if (zlemetaline != NULL)
+ metalinesz = cursz;
+ else
+ linesz = cursz;
}
/*
* Insert a character, called from main shell.
+ * Note this always operates on the metafied multibyte version of the
+ * line.
*/
/**/
@@ -88,20 +103,7 @@ mod_export void
zleaddtoline(int chr)
{
spaceinline(1);
-#ifdef ZLE_UNICODE_SUPPORT
- /*
- * TODO: the main shell has as yet very little notion of multibyte
- * characters. Until this gets fixed we just have to assume
- * this is a complete character.
- *
- * Possibly we could get away with attempting to build up a
- * multibyte character here, storing partial characters between
- * calls.
- */
- zleline[zlecs++] = (ZLE_CHAR_T)chr;
-#else
- zleline[zlecs++] = chr;
-#endif
+ zlemetaline[zlemetacs++] = chr;
}
/*
@@ -125,9 +127,11 @@ zleaddtoline(int chr)
/**/
mod_export unsigned char *
-zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outll,
- int *outcs, int useheap)
+zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outllp,
+ int *outcsp, int useheap)
{
+ int outcs, outll;
+
#ifdef ZLE_UNICODE_SUPPORT
char *s;
int i, j;
@@ -135,9 +139,10 @@ zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outll,
s = zalloc(inll * MB_CUR_MAX + 1);
+ outcs = 0;
for(i=0; i < inll; i++, incs--) {
- if (outcs != NULL && incs == 0)
- *outcs = mb_len;
+ if (incs == 0)
+ outcs = mb_len;
j = wctomb(s + mb_len, instr[i]);
if (j == -1) {
/* invalid char; what to do? */
@@ -147,8 +152,41 @@ zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outll,
}
s[mb_len] = '\0';
- if (outll != NULL)
- *outll = mb_len;
+ outll = mb_len;
+#else
+ outll = inll;
+ outcs = incs;
+#endif
+
+ /*
+ * *outcsp and *outllp are to be indexes into the final string,
+ * not character offsets, so we need to take account of any
+ * metafiable characters.
+ */
+ if (outcsp != NULL || outllp != NULL) {
+#ifdef ZLE_UNICODE_SUPPORT
+ unsigned char *strp = (unsigned char *)s;
+#else
+ unsigned char *strp = instr;
+#endif
+ unsigned char *stopcs = strp + outcs;
+ unsigned char *stopll = strp + outll;
+
+ while (strp < stopll) {
+ if (imeta(*strp)) {
+ if (strp < stopcs)
+ outcs++;
+ outll++;
+ }
+ strp++;
+ }
+ if (outcsp != NULL)
+ *outcsp = outcs;
+ if (outllp != NULL)
+ *outllp = outll;
+ }
+
+#ifdef ZLE_UNICODE_SUPPORT
if (useheap)
{
unsigned char *ret =
@@ -163,11 +201,6 @@ zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outll,
return (unsigned char *) metafy((char *) s, mb_len, META_REALLOC);
}
#else
- if (outll != NULL)
- *outll = inll;
- if (outcs != NULL)
- *outcs = incs;
-
return (unsigned char *) metafy((char *) instr, inll,
useheap ? META_HEAPDUP : META_DUP);
#endif
@@ -186,6 +219,11 @@ zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outll,
* may take a newline and a null at a later stage.) These are not
* included in *outsz.
*
+ * If outcs is non-NULL, the character position in the original
+ * string incs (a standard string offset, i.e. incremented 2 for
+ * each metafied character) is converted into the corresponding
+ * character position in *outcs.
+ *
* Note that instr is modified in place, hence should be copied
* first if necessary;
*
@@ -196,7 +234,8 @@ zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outll,
/**/
mod_export ZLE_STRING_T
-stringaszleline(unsigned char *instr, int *outll, int *outsz)
+stringaszleline(unsigned char *instr, int incs,
+ int *outll, int *outsz, int *outcs)
{
ZLE_STRING_T outstr;
int ll, sz;
@@ -204,7 +243,23 @@ stringaszleline(unsigned char *instr, int *outll, int *outsz)
mbstate_t ps;
#endif
- unmetafy(instr, &ll);
+ if (outcs) {
+ /*
+ * Take account of Meta characters in the input string
+ * before we unmetafy it. This does not yet take account
+ * of multibyte characters. If there are none, this
+ * is all the processing required to calculate outcs.
+ */
+ unsigned char *inptr = instr, *cspos = instr + incs;
+ while (*inptr && inptr < cspos) {
+ if (*inptr == STOUC(Meta)) {
+ inptr++;
+ incs--;
+ }
+ inptr++;
+ }
+ }
+ unmetafy((char *)instr, &ll);
/*
* ll is the maximum number of characters there can be in
@@ -246,29 +301,53 @@ stringaszleline(unsigned char *instr, int *outll, int *outsz)
if (*outptr == L'\0' && ret == 0)
ret = 1;
+ if (outcs) {
+ int offs = inptr - (char *)instr;
+ if (offs <= incs && incs < offs + ret)
+ *outcs = outptr - outstr;
+ }
+
inptr += ret;
outptr++;
ll -= ret;
}
*outll = outptr - outstr;
- }
- else
+ } else {
*outll = 0;
+ if (outcs)
+ *outcs = 0;
+ }
#else
memcpy((char *)outstr, (char *)instr, ll);
*outll = ll;
+ if (outcs)
+ *outcs = incs;
#endif
return outstr;
}
-
+/*
+ * This function is called when we are playing very nasty tricks
+ * indeed: see bufferwords in hist.c. Consequently we can make
+ * absolutely no assumption about the state whatsoever, except
+ * that it has one.
+ */
/**/
mod_export unsigned char *
zlegetline(int *ll, int *cs)
{
- return zlelineasstring(zleline, zlell, zlecs, ll, cs, 0);
+ if (zlemetaline != NULL) {
+ *ll = zlemetall;
+ *cs = zlemetacs;
+ return (unsigned char *)ztrdup((char *)zlemetaline);
+ } else if (zleline) {
+ return zlelineasstring(zleline, zlell, zlecs, ll, cs, 0);
+ } else {
+ *ll = *cs = 0;
+ return (unsigned char *)ztrdup("");
+ }
}
@@ -280,14 +359,25 @@ spaceinline(int ct)
{
int i;
- sizeline(ct + zlell);
- for (i = zlell; --i >= zlecs;)
- zleline[i + ct] = zleline[i];
- zlell += ct;
- zleline[zlell] = ZWC('\0');
+ if (zlemetaline) {
+ sizeline(ct + zlemetall);
+ for (i = zlemetall; --i >= zlemetacs;)
+ zlemetaline[i + ct] = zlemetaline[i];
+ zlemetall += ct;
+ zlemetaline[zlemetall] = '\0';
- if (mark > zlecs)
- mark += ct;
+ if (mark > zlemetacs)
+ mark += ct;
+ } else {
+ sizeline(ct + zlell);
+ for (i = zlell; --i >= zlecs;)
+ zleline[i + ct] = zleline[i];
+ zlell += ct;
+ zleline[zlell] = ZWC('\0');
+
+ if (mark > zlecs)
+ mark += ct;
+ }
}
/**/
@@ -299,11 +389,19 @@ shiftchars(int to, int cnt)
else if (mark > to)
mark = to;
- while (to + cnt < zlell) {
- zleline[to] = zleline[to + cnt];
- to++;
+ if (zlemetaline) {
+ while (to + cnt < zlemetall) {
+ zlemetaline[to] = zlemetaline[to + cnt];
+ to++;
+ }
+ zlemetaline[zlemetall = to] = '\0';
+ } else {
+ while (to + cnt < zlell) {
+ zleline[to] = zleline[to + cnt];
+ to++;
+ }
+ zleline[zlell = to] = ZWC('\0');
}
- zleline[zlell = to] = ZWC('\0');
}
/**/
@@ -333,6 +431,7 @@ cut(int i, int ct, int dir)
if (!ct)
return;
+ UNMETACHECK();
if (zmod.flags & MOD_VIBUF) {
struct cutbuffer *b = &vibuf[zmod.vibuf];
@@ -411,14 +510,20 @@ cut(int i, int ct, int dir)
mod_export void
backdel(int ct)
{
- shiftchars(zlecs -= ct, ct);
+ if (zlemetaline != NULL)
+ shiftchars(zlemetacs -= ct, ct);
+ else
+ shiftchars(zlecs -= ct, ct);
}
/**/
mod_export void
foredel(int ct)
{
- shiftchars(zlecs, ct);
+ if (zlemetaline != NULL)
+ shiftchars(zlemetacs, ct);
+ else
+ shiftchars(zlecs, ct);
}
/**/
@@ -437,7 +542,7 @@ setline(char *s, int flags)
*/
free(zleline);
- zleline = stringaszleline(scp, &zlell, &linesz);
+ zleline = stringaszleline((unsigned char *)scp, 0, &zlell, &linesz, NULL);
if ((flags & ZSL_TOEND) && (zlecs = zlell) && invicmdmode())
zlecs--;
@@ -760,6 +865,19 @@ freechanges(struct change *p)
mod_export void
handleundo(void)
{
+ int remetafy;
+
+ /*
+ * Yuk: we call this from within the completion system,
+ * so we need to convert back to the form which can be
+ * copied into undo entries.
+ */
+ if (zlemetaline != NULL) {
+ unmetafy_line();
+ remetafy = 1;
+ } else
+ remetafy = 0;
+
mkundoent();
if(!nextchanges)
return;
@@ -780,6 +898,9 @@ handleundo(void)
curchange->prev = endnextchanges;
endnextchanges->next = curchange;
nextchanges = endnextchanges = NULL;
+
+ if (remetafy)
+ metafy_line();
}
/* add an entry to the undo system, if anything has changed */
@@ -792,7 +913,8 @@ mkundoent(void)
int sh = zlell < lastll ? zlell : lastll;
struct change *ch;
- if(lastll == zlell && !memcmp(lastline, zleline, zlell * ZLE_CHAR_SIZE))
+ UNMETACHECK();
+ if(lastll == zlell && !ZS_memcmp(lastline, zleline, zlell))
return;
for(pre = 0; pre < sh && zleline[pre] == lastline[pre]; )
pre++;
@@ -840,6 +962,7 @@ mkundoent(void)
void
setlastline(void)
{
+ UNMETACHECK();
if(lastlinesz != linesz)
lastline = realloc(lastline, (lastlinesz = linesz) * ZLE_CHAR_SIZE);
ZS_memcpy(lastline, zleline, (lastll = zlell));
diff --git a/Src/hist.c b/Src/hist.c
index 6b3aa3b33..00773cd74 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -222,12 +222,12 @@ iaddtoline(int c)
exlast--;
zleaddtolineptr('\\');
}
- if (excs > zlecs) {
+ if (excs > zlemetacs) {
excs += 1 + inbufct - exlast;
- if (excs < zlecs)
+ if (excs < zlemetacs)
/* this case could be handled better but it is *
* so rare that it does not worth it */
- excs = zlecs;
+ excs = zlemetacs;
}
exlast = inbufct;
zleaddtolineptr(itok(c) ? ztokens[c - Pound] : c);
@@ -662,8 +662,8 @@ ihungetc(int c)
hungetc('\n'), hungetc('\\');
if (expanding) {
- zlecs--;
- zlell--;
+ zlemetacs--;
+ zlemetall--;
exlast++;
}
DPUTS(hptr <= chline, "BUG: hungetc attempted at buffer start");
@@ -2241,15 +2241,27 @@ histfileIsLocked(void)
return lockhistct > 0;
}
-/* Get the words in the current buffer. Using the lexer. */
+/*
+ * Get the words in the current buffer. Using the lexer.
+ *
+ * As far as I can make out, this is a gross hack based on a gross hack.
+ * When analysing lines from within zle, we tweak the metafied line
+ * positions (zlemetall and zlemetacs) directly in the lexer. That's
+ * bad enough, but this function appears to be designed to be called
+ * from outside zle, pretending to be in zle and calling out, so
+ * we set zlemetall and zlemetacs locally and copy the current zle line,
+ * which may not even be valid at this point.
+ *
+ * However, I'm so confused it could simply be baking Bakewell tarts.
+ */
/**/
mod_export LinkList
bufferwords(LinkList list, char *buf, int *index)
{
- int num = 0, cur = -1, got = 0, ne = noerrs, ocs = zlecs, oll = zlell;
+ int num = 0, cur = -1, got = 0, ne = noerrs;
int owb = wb, owe = we, oadx = addedx, ozp = zleparse, onc = nocomments;
- int ona = noaliases;
+ int ona = noaliases, ocs = zlemetacs, oll = zlemetall;
char *p;
if (!list)
@@ -2267,47 +2279,47 @@ bufferwords(LinkList list, char *buf, int *index)
p[l] = ' ';
p[l + 1] = '\0';
inpush(p, 0, NULL);
- zlell = strlen(p) ;
- zlecs = zlell + 1;
+ zlemetall = strlen(p) ;
+ zlemetacs = zlemetall + 1;
nocomments = 1;
} else {
int ll, cs;
char *linein;
if (zlegetlineptr) {
- linein = zlegetlineptr(&ll, &cs);
+ linein = (char *)zlegetlineptr(&ll, &cs);
} else {
linein = ztrdup("");
ll = cs = 0;
}
- zlell = ll + 1; /* length of line plus space added below */
- zlecs = cs;
+ zlemetall = ll + 1; /* length of line plus space added below */
+ zlemetacs = cs;
if (!isfirstln && chline) {
p = (char *) zhalloc(hptr - chline + ll + 2);
memcpy(p, chline, hptr - chline);
memcpy(p + (hptr - chline), linein, ll);
p[(hptr - chline) + ll] = ' ';
- p[(hptr - chline) + zlell] = '\0';
+ p[(hptr - chline) + zlemetall] = '\0';
inpush(p, 0, NULL);
/*
* advance line length and character position over
* prepended string.
*/
- zlell += hptr - chline;
- zlecs += hptr - chline;
+ zlemetall += hptr - chline;
+ zlemetacs += hptr - chline;
} else {
p = (char *) zhalloc(ll + 2);
memcpy(p, linein, ll);
p[ll] = ' ';
- p[zlell] = '\0';
+ p[zlemetall] = '\0';
inpush(p, 0, NULL);
}
- zsfree(linein);
+ zsfree(linein);
}
- if (zlecs)
- zlecs--;
+ if (zlemetacs)
+ zlemetacs--;
strinbeg(0);
noaliases = 1;
do {
@@ -2363,8 +2375,8 @@ bufferwords(LinkList list, char *buf, int *index)
nocomments = onc;
noerrs = ne;
lexrestore();
- zlecs = ocs;
- zlell = oll;
+ zlemetacs = ocs;
+ zlemetall = oll;
wb = owb;
we = owe;
addedx = oadx;
diff --git a/Src/lex.c b/Src/lex.c
index 482090ad1..bf2adb1dc 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -72,11 +72,12 @@ int inalmore;
int nocorrect;
/*
- * Cursor position and line length in zle
+ * Cursor position and line length in zle when the line is
+ * metafied for access from the main shell.
*/
/**/
-mod_export int zlecs, zlell;
+mod_export int zlemetacs, zlemetall;
/* inwhat says what exactly we are in *
* (its value is one of the IN_* things). */
@@ -521,10 +522,10 @@ add(int c)
}
}
-#define SETPARBEGIN {if (zleparse && !(inbufflags & INP_ALIAS) && zlecs >= zlell+1-inbufct) parbegin = inbufct;}
+#define SETPARBEGIN {if (zleparse && !(inbufflags & INP_ALIAS) && zlemetacs >= zlemetall+1-inbufct) parbegin = inbufct;}
#define SETPAREND {\
if (zleparse && !(inbufflags & INP_ALIAS) && parbegin != -1 && parend == -1) {\
- if (zlecs >= zlell + 1 - inbufct)\
+ if (zlemetacs >= zlemetall + 1 - inbufct)\
parbegin = -1;\
else\
parend = inbufct;} }
@@ -1293,7 +1294,7 @@ dquote_parse(char endchar, int sub)
int pct = 0, brct = 0, bct = 0, intick = 0, err = 0;
int c;
int math = endchar == ')' || endchar == ']';
- int zlemath = math && zlecs > zlell + addedx - inbufct;
+ int zlemath = math && zlemetacs > zlemetall + addedx - inbufct;
while (((c = hgetc()) != endchar || bct ||
(math && ((pct > 0) || (brct > 0))) ||
@@ -1420,7 +1421,7 @@ dquote_parse(char endchar, int sub)
err = intick || endchar || err;
else if (err == 1)
err = c;
- if (zlemath && zlecs <= zlell + 1 - inbufct)
+ if (zlemath && zlemetacs <= zlemetall + 1 - inbufct)
inwhat = IN_MATH;
return err;
}
@@ -1549,9 +1550,9 @@ parse_subst_string(char *s)
mod_export void
gotword(void)
{
- we = zlell + 1 - inbufct + (addedx == 2 ? 1 : 0);
- if (zlecs <= we) {
- wb = zlell - wordbeg + addedx;
+ we = zlemetall + 1 - inbufct + (addedx == 2 ? 1 : 0);
+ if (zlemetacs <= we) {
+ wb = zlemetall - wordbeg + addedx;
zleparse = 0;
}
}
diff --git a/Src/utils.c b/Src/utils.c
index cafcc7fbc..e7a85f5da 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -2812,7 +2812,7 @@ getbaudrate(struct ttyinfo *shttyinfo)
* META_NOALLOC: buf points to a memory area which is long enough to hold *
* the quoted form, just quote it and return buf. *
* META_STATIC: store the quoted string in a static area. The original *
- * string should be at most PATH_MAX long. *
+ * string should be at most PATH_MAX long. *
* META_ALLOC: allocate memory for the new string with zalloc(). *
* META_DUP: leave buf unchanged and allocate space for the return *
* value even if buf does not contains special characters *