summaryrefslogtreecommitdiff
path: root/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'display.c')
-rw-r--r--display.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/display.c b/display.c
index 35c0949..b90437f 100644
--- a/display.c
+++ b/display.c
@@ -266,6 +266,8 @@ static int *local_prompt_newlines;
lines and the current line is so marked. */
static int modmark;
+static int line_totbytes;
+
/* Variables to save and restore prompt and display information. */
/* These are getting numerous enough that it's time to create a struct. */
@@ -465,6 +467,7 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
if (physchars > bound) /* should rarely happen */
{
#if defined (HANDLE_MULTIBYTE)
+ *r = '\0'; /* need null-termination for strlen */
if (mb_cur_max > 1 && rl_byte_oriented == 0)
new = _rl_find_prev_mbchar (ret, r - ret, MB_FIND_ANY);
else
@@ -1072,6 +1075,7 @@ rl_redisplay (void)
#endif
}
line[out] = '\0';
+ line_totbytes = out;
if (cpos_buffer_position < 0)
{
cpos_buffer_position = out;
@@ -1480,6 +1484,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
the screen and dealing with changes to what's visible by modifying
OLD to match it. Complicated by the presence of multi-width
characters at the end of the line or beginning of the new one. */
+ /* old is always somewhere in visible_line; new is always somewhere in
+ invisible_line. These should always be null-terminated. */
#if defined (HANDLE_MULTIBYTE)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
@@ -1513,6 +1519,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
oldwidth = 0;
else
oldwidth = WCWIDTH (wc);
+ if (oldwidth < 0)
+ oldwidth = 1;
/* 2. how many screen positions does the first char in new consume? */
memset (&ps, 0, sizeof (mbstate_t));
@@ -1527,12 +1535,16 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
newwidth = 0;
else
newwidth = WCWIDTH (wc);
+ if (newwidth < 0)
+ newwidth = 1;
/* 3. if the new width is less than the old width, we need to keep
going in new until we have consumed at least that many screen
positions, and figure out how many bytes that will take */
while (newbytes < nmax && newwidth < oldwidth)
{
+ int t;
+
ret = mbrtowc (&wc, new+newbytes, mb_cur_max, &ps);
if (MB_INVALIDCH (ret))
{
@@ -1543,7 +1555,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
break;
else
{
- newwidth += WCWIDTH (wc);
+ t = WCWIDTH (wc);
+ newwidth += (t >= 0) ? t : 1;
newbytes += ret;
}
}
@@ -1552,6 +1565,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
figure out how many bytes that will take. This is an optimization */
while (oldbytes < omax && oldwidth < newwidth)
{
+ int t;
+
ret = mbrtowc (&wc, old+oldbytes, mb_cur_max, &ps);
if (MB_INVALIDCH (ret))
{
@@ -1562,7 +1577,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
break;
else
{
- oldwidth += WCWIDTH (wc);
+ t = WCWIDTH (wc);
+ oldwidth += (t >= 0) ? t : 1;
oldbytes += ret;
}
}
@@ -1593,8 +1609,9 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
{
/* We have written as many bytes from new as we need to
consume the first character of old. Fix up `old' so it
- reflects the new screen contents */
- memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes));
+ reflects the new screen contents. We use +1 in the
+ memmove call to copy the trailing NUL. */
+ memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1);
memcpy (old, new, newbytes);
j = newbytes - oldbytes;
@@ -1627,7 +1644,6 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
}
}
-
/* Find first difference. */
#if defined (HANDLE_MULTIBYTE)
if (mb_cur_max > 1 && rl_byte_oriented == 0)
@@ -2112,6 +2128,7 @@ dumb_update:
}
#if 1
+#ifdef HANDLE_MULTIBYTE
/* If we write a non-space into the last screen column,
remove the note that we added a space to compensate for
a multibyte double-width character that didn't fit, since
@@ -2122,6 +2139,7 @@ dumb_update:
nfd[bytes_to_insert-1] != ' ')
line_state_invisible->wrapped_line[current_line+1] = 0;
#endif
+#endif
}
else
_rl_last_c_pos += bytes_to_insert;