Fix the line-editing widget not to go completely crazy when seeing a literal
newline (Shift+Enter or ^Q Enter).
The real cause of the problem is making no proper distinction between
length and width. Actually mbstrlen() returns the width (ignoring
non-printable characters), not the length. On the other hand, other pieces
of the code expect it to return the length. In fact, this function should be
called mbstrwidth() and we should have a completely different one called
mbstrlen(). A lot of problems regarding double-width characters still remain
due to this misconcept.
Another bug is counting non-printable characters (e.g. newline) as zero width.
The proper approach is to count them as 1 since we're printing a replacement
character for them.
diff -Naurdp mc-4.6.1.orig/src/util.c mc-4.6.1/src/util.c
old
|
new
|
mbstrlen (const char *str) |
102 | 102 | |
103 | 103 | if (len > 0) { |
104 | 104 | int wcsize = wcwidth(c); |
105 | | width += wcsize > 0 ? wcsize : 0; |
| 105 | width += wcsize >= 0 ? wcsize : 1; |
106 | 106 | str += len-1; |
107 | 107 | } |
108 | 108 | } |
diff -Naurdp mc-4.6.1.orig/src/widget.c mc-4.6.1/src/widget.c
old
|
new
|
charcolumn(WInput *in, int idx) |
817 | 817 | l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs); |
818 | 818 | if (l <= 0) |
819 | 819 | return width; |
820 | | pos += l; width += wcwidth(wc); |
| 820 | pos += l; width += (wcwidth(wc) >= 0 ? wcwidth(wc) : 1); |
821 | 821 | i++; |
822 | 822 | }; |
823 | 823 | return width; |