about summary refs log tree commit diff
path: root/Src/Zle/zle_misc.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-04-21 17:30:34 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-04-21 17:30:34 +0000
commitf9224e5a0493a5f41882988cf467c80a531e331f (patch)
tree0d7879e448c7da4d05934f93e5f5009f7f21d097 /Src/Zle/zle_misc.c
parent5a0c547e919bded1d4966213beb9a3ae89b08698 (diff)
downloadzsh-f9224e5a0493a5f41882988cf467c80a531e331f.tar.gz
zsh-f9224e5a0493a5f41882988cf467c80a531e331f.tar.xz
zsh-f9224e5a0493a5f41882988cf467c80a531e331f.zip
24859: combining chars: overwriting and vi replace and append
Diffstat (limited to 'Src/Zle/zle_misc.c')
-rw-r--r--Src/Zle/zle_misc.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 27253a333..e00f22b04 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -47,14 +47,27 @@ doinsert(ZLE_STRING_T zstr, int len)
     iremovesuffix(c1, 0);
     invalidatelist();
 
-    if(insmode)
+    if (insmode)
 	spaceinline(m * len);
-    else if(zlecs + m * len > zlell)
-	spaceinline(zlecs + m * len - zlell);
-    while(m--)
-	for(s = zstr, count = len; count; s++, count--)
+    else {
+	int pos = zlecs, count = m * len, i = count, diff;
+	/*
+	 * Ensure we replace a complete combining character
+	 * for each character we overwrite.
+	 */
+	while (pos < zlell && i--) {
+	    INCPOS(pos);
+	}
+	diff = pos - zlecs - count;
+	if (diff < 0) {
+	    spaceinline(-diff);
+	} else if (diff > 0)
+	    foredel(diff, CUT_RAW);
+    }
+    while (m--)
+	for (s = zstr, count = len; count; s++, count--)
 	    zleline[zlecs++] = *s;
-    if(neg)
+    if (neg)
 	zlecs += zmult * len;
     /* if we ended up on a combining character, skip over it */
     CCRIGHT();