diff --git a/ChangeLog b/ChangeLog index f3457ce7..859195d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -57,6 +57,9 @@ CVS code - - Rename variable next to nextdir to avoid confusion. (DLR) input_tab() - Since list is a bool, assign it FALSE instead of 0. (DLR) + - Add multibyte/wide character support, so that we don't end up + with a string that contains only part of a multibyte + character during tab completion. (DLR) do_browser() - Don't treat NANO_CANCEL_KEY as NANO_EXIT_KEY anymore, for consistency. (DLR) diff --git a/src/files.c b/src/files.c index 7d8d13d0..661f6793 100644 --- a/src/files.c +++ b/src/files.c @@ -2180,20 +2180,32 @@ char *input_tab(char *buf, size_t *place, bool *lastwastab, bool *list) const char *lastslash = revstrstr(buf, "/", buf + *place); size_t lastslash_len = (lastslash == NULL) ? 0 : lastslash - buf + 1; + char *match1_mb = charalloc(mb_cur_max() + 1); + char *match2_mb = charalloc(mb_cur_max() + 1); + int match1_mb_len, match2_mb_len; while (TRUE) { for (match = 1; match < num_matches; match++) { - if (matches[0][common_len] != - matches[match][common_len]) + match1_mb_len = parse_mbchar(matches[0] + common_len, + match1_mb, NULL, NULL); + match2_mb_len = parse_mbchar(matches[match] + + common_len, match2_mb, NULL, NULL); + match1_mb[match1_mb_len] = '\0'; + match2_mb[match2_mb_len] = '\0'; + if (strcmp(match1_mb, match2_mb) != 0) break; } if (match < num_matches || matches[0][common_len] == '\0') break; - common_len++; + common_len += parse_mbchar(buf + common_len, NULL, NULL, + NULL); } + free(match1_mb); + free(match2_mb); + mzero = charalloc(lastslash_len + common_len + 1); sprintf(mzero, "%.*s%.*s", lastslash_len, buf, common_len, matches[0]);