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 --- mc-4.6.1.orig/src/util.c 2006-08-03 14:09:22.000000000 +0200 +++ mc-4.6.1/src/util.c 2006-08-03 14:17:11.000000000 +0200 @@ -102,7 +102,7 @@ mbstrlen (const char *str) if (len > 0) { int wcsize = wcwidth(c); - width += wcsize > 0 ? wcsize : 0; + width += wcsize >= 0 ? wcsize : 1; str += len-1; } } diff -Naurdp mc-4.6.1.orig/src/widget.c mc-4.6.1/src/widget.c --- mc-4.6.1.orig/src/widget.c 2006-08-03 13:46:47.000000000 +0200 +++ mc-4.6.1/src/widget.c 2006-08-03 14:17:04.000000000 +0200 @@ -817,7 +817,7 @@ charcolumn(WInput *in, int idx) l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs); if (l <= 0) return width; - pos += l; width += wcwidth(wc); + pos += l; width += (wcwidth(wc) >= 0 ? wcwidth(wc) : 1); i++; }; return width;