summaryrefslogtreecommitdiff
path: root/Src/Zle/zle_main.c
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2016-11-20 23:54:45 +0100
committerOliver Kiddle <opk@zsh.org>2016-11-20 23:59:48 +0100
commitcb5f100bd38a3b21739897fb4236db0700b39477 (patch)
tree8ad0e44d32b2bf7e7c11e05f9789b7efef2e9a3f /Src/Zle/zle_main.c
parentfe67ccacf15ee92864f7485fd9e54c3dd1f5d1e3 (diff)
downloadzsh-cb5f100bd38a3b21739897fb4236db0700b39477.tar.gz
zsh-cb5f100bd38a3b21739897fb4236db0700b39477.zip
39986, 39989: improve handling of vi-repeat-change
Save previous vi change and throw away a new change that fails. Add zle -f vichange to allow shell widget to be a single change. Fix repeat of command where numeric arguments were multiplied.
Diffstat (limited to 'Src/Zle/zle_main.c')
-rw-r--r--Src/Zle/zle_main.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 1652b7cd4..938dc0e29 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -924,13 +924,13 @@ getbyte(long do_keytmout, int *timeout)
ret = STOUC(cc);
}
/*
- * vichgbuf is raw bytes, not wide characters, so is dealt
+ * curvichg.buf is raw bytes, not wide characters, so is dealt
* with here.
*/
if (vichgflag) {
- if (vichgbufptr == vichgbufsz)
- vichgbuf = realloc(vichgbuf, vichgbufsz *= 2);
- vichgbuf[vichgbufptr++] = ret;
+ if (curvichg.bufptr == curvichg.bufsz)
+ curvichg.buf = realloc(curvichg.buf, curvichg.bufsz *= 2);
+ curvichg.buf[curvichg.bufptr++] = ret;
}
errno = old_errno;
return lastchar = ret;
@@ -1260,6 +1260,7 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
*zleline = ZWC('\0');
virangeflag = lastcmd = done = zlecs = zlell = mark = yankb = yanke = 0;
vichgflag = 0;
+ viinrepeat = 0;
viinsbegin = 0;
statusline = NULL;
selectkeymap("main", 1);
@@ -1389,6 +1390,8 @@ int
execzlefunc(Thingy func, char **args, int set_bindk)
{
int r = 0, ret = 0, remetafy = 0;
+ int nestedvichg = vichgflag;
+ int isrepeat = (viinrepeat == 3);
Widget w;
Thingy save_bindk = bindk;
@@ -1398,6 +1401,8 @@ execzlefunc(Thingy func, char **args, int set_bindk)
unmetafy_line();
remetafy = 1;
}
+ if (isrepeat)
+ viinrepeat = 2;
if (func->flags & DISABLED) {
/* this thingy is not the name of a widget */
@@ -1523,6 +1528,25 @@ execzlefunc(Thingy func, char **args, int set_bindk)
CCRIGHT();
if (remetafy)
metafy_line();
+
+ /* if this widget constituted the vi change, end it */
+ if (vichgflag == 2 && !nestedvichg) {
+ if (invicmdmode()) {
+ if (ret) {
+ free(curvichg.buf);
+ } else {
+ if (lastvichg.buf)
+ free(lastvichg.buf);
+ lastvichg = curvichg;
+ }
+ vichgflag = 0;
+ curvichg.buf = NULL;
+ } else
+ vichgflag = 1; /* vi change continues while in insert mode */
+ }
+ if (isrepeat)
+ viinrepeat = !invicmdmode();
+
return ret;
}
@@ -2230,7 +2254,7 @@ finish_(UNUSED(Module m))
cleanup_keymaps();
deletehashtable(thingytab);
- zfree(vichgbuf, vichgbufsz);
+ zfree(lastvichg.buf, lastvichg.bufsz);
zfree(kungetbuf, kungetsz);
free_isrch_spots();
if (rdstrs)