about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2015-09-11 21:40:45 +0100
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2015-09-11 21:40:45 +0100
commite1c0a947cc845c71dd844db44016d07922cfcefa (patch)
treef952b7ac97712807e1d2b696987a00afdaf7ddf8
parent560a23033d2d0e029bbbcda0366053d8d87a37d9 (diff)
downloadzsh-e1c0a947cc845c71dd844db44016d07922cfcefa.tar.gz
zsh-e1c0a947cc845c71dd844db44016d07922cfcefa.tar.xz
zsh-e1c0a947cc845c71dd844db44016d07922cfcefa.zip
Read full multibyte string early for self-insert
-rw-r--r--ChangeLog5
-rw-r--r--Src/Zle/zle_hist.c4
-rw-r--r--Src/Zle/zle_keymap.c37
-rw-r--r--Src/Zle/zle_main.c10
-rw-r--r--Src/Zle/zle_misc.c6
-rw-r--r--Src/Zle/zle_vi.c2
6 files changed, 47 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 06427e7a9..914ee4e47 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2015-09-11  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
+	* 36496 (plus tweak for key buffer length): Src/Zle/zle_hist.c,
+	Src/Zle/zle_keymap.c, Src/Zle/zle_main.c, Src/Zle/zle_misc.c,
+	Src/Zle/zle_vi.c: Read full multibyte string early for
+	self-insert.
+
 	* unposted: Config/version.mk: Update internal build to
 	5.1.1-dev-0
 
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index c61b4ef0e..0cff0391a 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -1643,7 +1643,7 @@ doisearch(char **args, int dir, int pattern)
 	    } else if (cmd == Th(z_selfinsert)) {
 #ifdef MULTIBYTE_SUPPORT
 		if (!lastchar_wide_valid)
-		    if (getrestchar(lastchar) == WEOF) {
+		    if (getrestchar(lastchar, NULL, NULL) == WEOF) {
 			handlefeep(zlenoargs);
 			continue;
 		    }
@@ -1877,7 +1877,7 @@ getvisrchstr(void)
 	    } else {
 #ifdef MULTIBYTE_SUPPORT
 		if (!lastchar_wide_valid)
-		    if (getrestchar(lastchar) == WEOF) {
+		    if (getrestchar(lastchar, NULL, NULL) == WEOF) {
 			handlefeep(zlenoargs);
 			continue;
 		    }
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 5b4189faa..069580f8a 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -1501,6 +1501,20 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
 	     * they wait till a key is pressed for the movement anyway      */
 	    timeout = !(!virangeflag && !region_active && f && f->widget &&
 		    f->widget->flags & ZLE_VIOPER);
+#ifdef MULTIBYTE_SUPPORT
+	    if ((f == Th(z_selfinsert) || f == Th(z_selfinsertunmeta)) &&
+		!lastchar_wide_valid) {
+		int len;
+		VARARR(char, mbc, MB_CUR_MAX);
+		ZLE_INT_T inchar = getrestchar(lastchar, mbc, &len);
+		if (inchar != WEOF && len) {
+		    char *ptr = mbc;
+		    while (len--)
+			addkeybuf(STOUC(*ptr++));
+		    lastlen = keybuflen;
+		}
+	    }
+#endif
 	}
 	if (!ispfx)
 	    break;
@@ -1521,6 +1535,20 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp)
     return keybuf;
 }
 
+/**/
+static void
+addkeybuf(int c)
+{
+    if(keybuflen + 3 > keybufsz)
+	keybuf = realloc(keybuf, keybufsz *= 2);
+    if(imeta(c)) {
+	keybuf[keybuflen++] = Meta;
+	keybuf[keybuflen++] = c ^ 32;
+    } else
+	keybuf[keybuflen++] = c;
+    keybuf[keybuflen] = 0;
+}
+
 /*
  * Add a (possibly metafied) byte to the key input so far.
  * This handles individual bytes of a multibyte string separately;
@@ -1542,14 +1570,7 @@ getkeybuf(int w)
 
     if(c < 0)
 	return EOF;
-    if(keybuflen + 3 > keybufsz)
-	keybuf = realloc(keybuf, keybufsz *= 2);
-    if(imeta(c)) {
-	keybuf[keybuflen++] = Meta;
-	keybuf[keybuflen++] = c ^ 32;
-    } else
-	keybuf[keybuflen++] = c;
-    keybuf[keybuflen] = 0;
+    addkeybuf(c);
     return c;
 }
 
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index ec3d2c354..992f152df 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -933,7 +933,7 @@ getfullchar(int do_keytmout)
     int inchar = getbyte((long)do_keytmout, NULL);
 
 #ifdef MULTIBYTE_SUPPORT
-    return getrestchar(inchar);
+    return getrestchar(inchar, NULL, NULL);
 #else
     return inchar;
 #endif
@@ -951,7 +951,7 @@ getfullchar(int do_keytmout)
 
 /**/
 mod_export ZLE_INT_T
-getrestchar(int inchar)
+getrestchar(int inchar, char *outstr, int *outcount)
 {
     char c = inchar;
     wchar_t outchar;
@@ -965,6 +965,8 @@ getrestchar(int inchar)
      */
     lastchar_wide_valid = 1;
 
+    if (outcount)
+	*outcount = 0;
     if (inchar == EOF) {
 	/* End of input, so reset the shift state. */
 	memset(&mbs, 0, sizeof mbs);
@@ -1013,6 +1015,10 @@ getrestchar(int inchar)
 		return lastchar_wide = WEOF;
 	}
 	c = inchar;
+	if (outstr) {
+	    *outstr++ = c;
+	    (*outcount)++;
+	}
     }
     return lastchar_wide = (ZLE_INT_T)outchar;
 }
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 2d1862813..12143e05f 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -115,9 +115,7 @@ selfinsert(UNUSED(char **args))
     ZLE_CHAR_T tmp;
 
 #ifdef MULTIBYTE_SUPPORT
-    if (!lastchar_wide_valid)
-	if (getrestchar(lastchar) == WEOF)
-	    return 1;
+    DPUTS(!lastchar_wide_valid, "keybuf did not read full wide character");
 #endif
     tmp = LASTFULLCHAR;
     doinsert(&tmp, 1);
@@ -1431,7 +1429,7 @@ executenamedcommand(char *prmt)
 		else {
 #ifdef MULTIBYTE_SUPPORT
 		    if (!lastchar_wide_valid)
-			getrestchar(lastchar);
+			getrestchar(lastchar, NULL, NULL);
 		    if (lastchar_wide == WEOF)
 			feep = 1;
 		    else
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 42dc46e7e..86840bdd6 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -151,7 +151,7 @@ vigetkey(void)
 #ifdef MULTIBYTE_SUPPORT
     if (!lastchar_wide_valid)
     {
-	getrestchar(lastchar);
+	getrestchar(lastchar, NULL, NULL);
     }
 #endif
     return LASTFULLCHAR;