summaryrefslogtreecommitdiff
path: root/Src/Zle
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/compcore.c5
-rw-r--r--Src/Zle/compctl.c1
-rw-r--r--Src/Zle/computil.c63
-rw-r--r--Src/Zle/zle_main.c47
-rw-r--r--Src/Zle/zle_move.c16
-rw-r--r--Src/Zle/zle_tricky.c29
-rw-r--r--Src/Zle/zle_utils.c1
7 files changed, 116 insertions, 46 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 39d41bdb5..5c5628a8d 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -826,7 +826,6 @@ callcompfunc(char *s, char *fn)
sfcontext = SFC_CWIDGET;
NEWHEAPS(compheap) {
LinkList largs = NULL;
- int olv = lastval;
if (*cfargs) {
char **p = cfargs;
@@ -836,9 +835,7 @@ callcompfunc(char *s, char *fn)
while (*p)
addlinknode(largs, dupstring(*p++));
}
- doshfunc(shfunc, largs, 0);
- cfret = lastval;
- lastval = olv;
+ cfret = doshfunc(shfunc, largs, 1);
} OLDHEAPS;
sfcontext = osc;
endparamscope();
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index 0143370c7..ab1857c0a 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -398,7 +398,6 @@ get_compctl(char *name, char ***av, Compctl cc, int first, int isdef, int cl)
if (cl)
return 1;
else {
- freecompctl(cc);
cclist = COMP_REMOVE;
return 0;
}
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index cd508d0ac..f5e6ba195 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -465,6 +465,7 @@ cd_init(char *nam, char *hide, char *mlen, char *sep,
cd_state.showd = disp;
cd_state.maxg = cd_state.groups = cd_state.descs = 0;
cd_state.maxmlen = atoi(mlen);
+ cd_state.premaxw = 0;
itmp = zterm_columns - cd_state.swidth - 4;
if (cd_state.maxmlen > itmp)
cd_state.maxmlen = itmp;
@@ -643,35 +644,43 @@ cd_get(char **params)
p += str->len;
memset(p, ' ', (l = (cd_state.premaxw - str->width + CM_SPACE)));
p += l;
- strcpy(p, cd_state.sep);
- p += cd_state.slen;
- /*
- * copy a character at once until no more screen width
- * is available. Leave 1 character at the end of screen
- * as safety margin
- */
remw = zterm_columns - cd_state.premaxw -
cd_state.swidth - 3;
- d = str->desc;
- w = MB_METASTRWIDTH(d);
- if (w <= remw)
- strcpy(p, d);
- else {
- pp = p;
- while (remw > 0 && *d) {
- l = MB_METACHARLEN(d);
- memcpy(pp, d, l);
- pp[l] = '\0';
- w = MB_METASTRWIDTH(pp);
- if (w > remw) {
- *pp = '\0';
- break;
- }
+ while (remw < 0 && zterm_columns) {
+ /* line wrapped, use remainder of the extra line */
+ remw += zterm_columns;
+ }
+ if (cd_state.slen < remw) {
+ strcpy(p, cd_state.sep);
+ p += cd_state.slen;
+ remw -= cd_state.slen;
- pp += l;
- d += l;
- remw -= w;
+ /*
+ * copy a character at once until no more screen
+ * width is available. Leave 1 character at the
+ * end of screen as safety margin
+ */
+ d = str->desc;
+ w = MB_METASTRWIDTH(d);
+ if (w <= remw)
+ strcpy(p, d);
+ else {
+ pp = p;
+ while (remw > 0 && *d) {
+ l = MB_METACHARLEN(d);
+ memcpy(pp, d, l);
+ pp[l] = '\0';
+ w = MB_METASTRWIDTH(pp);
+ if (w > remw) {
+ *pp = '\0';
+ break;
+ }
+
+ pp += l;
+ d += l;
+ remw -= w;
+ }
}
}
@@ -1608,7 +1617,7 @@ get_cadef(char *nam, char **args)
return *p;
} else if (!min || !*p || (*p)->lastt < (*min)->lastt)
min = p;
- if (i)
+ if (i > 0)
min = p;
if ((new = parse_cadef(nam, args))) {
freecadef(*min);
@@ -2992,7 +3001,7 @@ get_cvdef(char *nam, char **args)
return *p;
} else if (!min || !*p || (*p)->lastt < (*min)->lastt)
min = p;
- if (i)
+ if (i > 0)
min = p;
if ((new = parse_cvdef(nam, args))) {
freecvdef(*min);
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index e1a575bdb..5798e74b4 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -567,7 +567,9 @@ raw_getbyte(long do_keytmout, char *cptr)
gettyinfo(&ti);
ti.tio.c_cc[VMIN] = 0;
settyinfo(&ti);
+ winch_unblock();
ret = read(SHTTY, cptr, 1);
+ winch_block();
ti.tio.c_cc[VMIN] = 1;
settyinfo(&ti);
if (ret > 0)
@@ -597,7 +599,9 @@ raw_getbyte(long do_keytmout, char *cptr)
else
poll_timeout = -1;
+ winch_unblock();
selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
+ winch_block();
# else
int fdmax = SHTTY;
struct timeval *tvptr;
@@ -622,8 +626,10 @@ raw_getbyte(long do_keytmout, char *cptr)
else
tvptr = NULL;
+ winch_unblock();
selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
NULL, NULL, tvptr);
+ winch_block();
# endif
/*
* Make sure a user interrupt gets passed on straight away.
@@ -788,7 +794,9 @@ raw_getbyte(long do_keytmout, char *cptr)
# else
ioctl(SHTTY, TCSETA, &ti.tio);
# endif
+ winch_unblock();
ret = read(SHTTY, cptr, 1);
+ winch_block();
# ifdef HAVE_TERMIOS_H
tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
# else
@@ -799,7 +807,9 @@ raw_getbyte(long do_keytmout, char *cptr)
#endif
}
+ winch_unblock();
ret = read(SHTTY, cptr, 1);
+ winch_block();
return ret;
}
@@ -1105,7 +1115,7 @@ zlecore(void)
/**/
char *
-zleread(char **lp, char **rp, int flags, int context)
+zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
{
char *s;
int old_errno = errno;
@@ -1178,6 +1188,13 @@ zleread(char **lp, char **rp, int flags, int context)
viinsbegin = 0;
statusline = NULL;
selectkeymap("main", 1);
+ /*
+ * If main is linked to the viins keymap, we need to register
+ * explicitly that we're now in vi insert mode as there's
+ * no user operation to indicate this.
+ */
+ if (openkeymap("main") == openkeymap("viins"))
+ viinsert(NULL);
selectlocalmap(NULL);
fixsuffix();
if ((s = getlinknode(bufstack))) {
@@ -1223,7 +1240,9 @@ zleread(char **lp, char **rp, int flags, int context)
unqueue_signals(); /* Should now be safe to acknowledge SIGWINCH */
- zlecallhook("zle-line-init", NULL);
+ zlecallhook(init, NULL);
+
+ zrefresh();
zlecore();
@@ -1231,7 +1250,7 @@ zleread(char **lp, char **rp, int flags, int context)
setsparam("ZLE_LINE_ABORTED", zlegetline(NULL, NULL));
if (done && !exit_pending && !errflag)
- zlecallhook("zle-line-finish", NULL);
+ zlecallhook(finish, NULL);
statusline = NULL;
invalidatelist();
@@ -1471,7 +1490,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
Param pm = 0;
int ifl;
int type = PM_SCALAR, obreaks = breaks, haso = 0, oSHTTY = 0;
- char *p1, *p2, *main_keymapname, *vicmd_keymapname;
+ char *p1, *p2, *main_keymapname, *vicmd_keymapname, *init, *finish;
Keymap main_keymapsave = NULL, vicmd_keymapsave = NULL;
FILE *oshout = NULL;
@@ -1499,6 +1518,8 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
p2 = OPT_ARG_SAFE(ops,'r');
main_keymapname = OPT_ARG_SAFE(ops,'M');
vicmd_keymapname = OPT_ARG_SAFE(ops,'m');
+ init = OPT_ARG_SAFE(ops,'i');
+ finish = OPT_ARG_SAFE(ops,'f');
if (type != PM_SCALAR && !OPT_ISSET(ops,'c')) {
zwarnnam(name, "-%s ignored", type == PM_ARRAY ? "a" : "A");
@@ -1600,6 +1621,7 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
haso = 1;
}
+
/* edit the parameter value */
zpushnode(bufstack, s);
@@ -1615,7 +1637,10 @@ bin_vared(char *name, char **args, Options ops, UNUSED(int func))
if (OPT_ISSET(ops,'h'))
hbegin(2);
isfirstln = OPT_ISSET(ops,'e');
- t = zleread(&p1, &p2, OPT_ISSET(ops,'h') ? ZLRF_HISTORY : 0, ZLCON_VARED);
+
+ t = zleread(&p1, &p2, OPT_ISSET(ops,'h') ? ZLRF_HISTORY : 0, ZLCON_VARED,
+ init ? init : "zle-line-init",
+ finish ? finish : "zle-line-finish");
if (OPT_ISSET(ops,'h'))
hend(NULL);
isfirstln = ifl;
@@ -1880,7 +1905,8 @@ zle_main_entry(int cmd, va_list ap)
flags = va_arg(ap, int);
context = va_arg(ap, int);
- return zleread(lp, rp, flags, context);
+ return zleread(lp, rp, flags, context,
+ "zle-line-init", "zle-line-finish");
}
case ZLE_CMD_ADD_TO_LINE:
@@ -1915,6 +1941,13 @@ zle_main_entry(int cmd, va_list ap)
break;
}
+ case ZLE_CMD_SET_HIST_LINE:
+ {
+ histline = va_arg(ap, zlong);
+
+ break;
+ }
+
default:
#ifdef DEBUG
dputs("Bad command %d in zle_main_entry", cmd);
@@ -1926,7 +1959,7 @@ zle_main_entry(int cmd, va_list ap)
static struct builtin bintab[] = {
BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL),
- BUILTIN("vared", 0, bin_vared, 1, 1, 0, "aAcehM:m:p:r:t:", NULL),
+ BUILTIN("vared", 0, bin_vared, 1, 1, 0, "aAcef:hi:M:m:p:r:t:", NULL),
BUILTIN("zle", 0, bin_zle, 0, -1, 0, "aAcCDFgGIKlLmMNrRTU", NULL),
};
diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c
index d5f464c2c..7312b3f20 100644
--- a/Src/Zle/zle_move.c
+++ b/Src/Zle/zle_move.c
@@ -30,7 +30,7 @@
#include "zle.mdh"
#include "zle_move.pro"
-static int vimarkcs[26], vimarkline[26];
+static int vimarkcs[27], vimarkline[27];
#ifdef MULTIBYTE_SUPPORT
/*
@@ -825,11 +825,17 @@ int
vigotomark(UNUSED(char **args))
{
ZLE_INT_T ch;
+ int oldcs = zlecs;
+ int oldline = histline;
ch = getfullchar(0);
- if (ch < ZWC('a') || ch > ZWC('z'))
- return 1;
- ch -= ZWC('a');
+ if (ch == ZWC('\'') || ch == ZWC('`'))
+ ch = 26;
+ else {
+ if (ch < ZWC('a') || ch > ZWC('z'))
+ return 1;
+ ch -= ZWC('a');
+ }
if (!vimarkline[ch])
return 1;
if (curhist != vimarkline[ch] && !zle_goto_hist(vimarkline[ch], 0, 0)) {
@@ -837,6 +843,8 @@ vigotomark(UNUSED(char **args))
return 1;
}
zlecs = vimarkcs[ch];
+ vimarkcs[26] = oldcs;
+ vimarkline[26] = oldline;
if (zlecs > zlell)
zlecs = zlell;
return 0;
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 78a9fa490..e30e0b1aa 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1095,6 +1095,7 @@ get_comp_string(void)
* the command word is not at index zero in the array.
*/
int redirpos;
+ int noword;
char *s = NULL, *tmp, *p, *tt = NULL, rdop[20];
char *linptr, *u;
@@ -1165,7 +1166,7 @@ get_comp_string(void)
* and whatnot. */
do {
- qsub = 0;
+ qsub = noword = 0;
lincmd = ((incmdpos && !ins && !incond) ||
(oins == 2 && wordpos == 2) ||
@@ -1239,6 +1240,19 @@ get_comp_string(void)
* leave the loop. */
if (tt)
break;
+ if (ins < 2) {
+ /*
+ * Don't add this as a word, because we're about to start
+ * a new command line: pretend there's no string here.
+ * We don't dare do this if we're using one of the
+ * *really* gross hacks with ins to get later words
+ * to look like command words, because we don't
+ * understand how they work. Quite possibly we
+ * should be using a mechanism like the one here rather
+ * than the ins thing.
+ */
+ noword = 1;
+ }
/* Otherwise reset the variables we are collecting data in. */
wordpos = cp = rd = ins = redirpos = 0;
tt0 = NULLTOK;
@@ -1253,6 +1267,14 @@ get_comp_string(void)
/* If everything before is a redirection, don't reset the index */
if (wordpos != redirpos)
wordpos = redirpos = 0;
+ } else if (tok == SEPER) {
+ /*
+ * A following DOLOOP should cause us to reset to the start
+ * of the command line. For some reason we only recognise
+ * DOLOOP for this purpose (above) if ins is set. Why?
+ * Don't ask pointless questions.
+ */
+ ins = 1;
}
if (!lexflags && tt0 == NULLTOK) {
/* This is done when the lexer reached the word the cursor is on. */
@@ -1322,7 +1344,7 @@ get_comp_string(void)
else if (tok == DAMPER)
tokstr = "&&";
}
- if (!tokstr)
+ if (!tokstr || noword)
continue;
/* Hack to allow completion after `repeat n do'. */
if (oins == 2 && !wordpos && !strcmp(tokstr, "do"))
@@ -2114,8 +2136,8 @@ inststrlen(char *str, int move, int len)
return 0;
if (len == -1)
len = strlen(str);
- spaceinline(len);
if (zlemetaline != NULL) {
+ spaceinline(len);
strncpy(zlemetaline + zlemetacs, str, len);
if (move)
zlemetacs += len;
@@ -2126,6 +2148,7 @@ inststrlen(char *str, int move, int len)
instr = ztrduppfx(str, len);
zlestr = stringaszleline(instr, 0, &zlelen, NULL, NULL);
+ spaceinline(zlelen);
ZS_strncpy(zleline + zlecs, zlestr, zlelen);
free(zlestr);
zsfree(instr);
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index d0e7b5542..b84d253bb 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -145,6 +145,7 @@ zlecharasstring(ZLE_CHAR_T inchar, char *buf)
ptr2--;
}
*ptr = Meta;
+ ptr[1] ^= 32;
ret++;
}