summaryrefslogtreecommitdiff
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
parent5a0c547e919bded1d4966213beb9a3ae89b08698 (diff)
downloadzsh-f9224e5a0493a5f41882988cf467c80a531e331f.tar.gz
zsh-f9224e5a0493a5f41882988cf467c80a531e331f.zip
24859: combining chars: overwriting and vi replace and append
-rw-r--r--ChangeLog4
-rw-r--r--Src/Zle/zle_misc.c25
-rw-r--r--Src/Zle/zle_vi.c27
-rw-r--r--Src/Zle/zle_word.c4
4 files changed, 43 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 8d0711630..09f6cc096 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2008-04-21 Peter Stephenson <pws@csr.com>
+ * 24859: Src/Zle/zle_misc.c, Src/Zle/zle_vi.c, Src/Zle/zle_word.c:
+ overwriting combining characters and replacing them and appending
+ after them in vi mode.
+
* 24856: Src/utils.c, Src/zsh.h, Src/Zle/zle_move.c,
Src/Zle/zle_refresh.c: use IS_COMBINING() and IS_BASECHAR()
tests for combining characters. Widen definitions of characters
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();
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index b8215454f..16b741b75 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -498,18 +498,19 @@ int
vireplacechars(UNUSED(char **args))
{
ZLE_INT_T ch;
- int n = zmult, origcs = zlecs, fail = 0;
+ int n = zmult, fail = 0, newchars = 0;
if (n > 0) {
+ int pos = zlecs;
while (n-- > 0) {
- if (zlecs == zlell || zleline[zlell] == ZWC('\n')) {
+ if (pos == zlell || zleline[pos] == ZWC('\n')) {
fail = 1;
break;
}
- INCCS();
+ newchars++;
+ INCPOS(pos);
}
- n = zlecs - origcs;
- zlecs = origcs;
+ n = pos - zlecs;
}
startvichange(1);
/* check argument range */
@@ -535,8 +536,16 @@ vireplacechars(UNUSED(char **args))
backkill(n - 1, CUT_RAW);
zleline[zlecs++] = '\n';
} else {
- /* HERE: we shouldn't replace combining chars, we should delete them */
- while (n--)
+ /*
+ * Make sure we delete displayed characters, including
+ * attach combining characters. n includes this as a raw
+ * buffer offset.
+ */
+ if (n > newchars)
+ foredel(n - newchars, CUT_RAW);
+ else if (n < newchars)
+ spaceinline(newchars - n);
+ while (newchars--)
zleline[zlecs++] = ch;
zlecs--;
}
@@ -792,14 +801,14 @@ viputafter(UNUSED(char **args))
vifirstnonblank(zlenoargs);
} else {
if (zlecs != findeol())
- zlecs++;
+ INCCS();
while (n--) {
spaceinline(buf->len);
ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
zlecs += buf->len;
}
if (zlecs)
- zlecs--;
+ DECCS();
}
return 0;
}
diff --git a/Src/Zle/zle_word.c b/Src/Zle/zle_word.c
index 368079053..e59304ecd 100644
--- a/Src/Zle/zle_word.c
+++ b/Src/Zle/zle_word.c
@@ -441,7 +441,7 @@ vibackwardkillword(UNUSED(char **args))
}
}
}
- backkill(zlecs - x, CUT_FRONT);
+ backkill(zlecs - x, CUT_FRONT|CUT_RAW);
return 0;
}
@@ -475,7 +475,7 @@ backwardkillword(char **args)
x = pos;
}
}
- backkill(zlecs - x, CUT_FRONT);
+ backkill(zlecs - x, CUT_FRONT|CUT_RAW);
return 0;
}