mc/00-78-utf8-filename-search-input.patch

73 lines
1.9 KiB
Diff

Fix quick filename search (^S):
- Avoid matching partial multibyte character.
E.g. a quick search for fooá when the only file beginning with foo is fooé
don't match the first byte of é.
- Backspace remove a whole multibyte character, not just one byte.
================================================================================
--- mc-4.6.1-pre2b/src/screen.c
+++ mc-4.6.1-pre2b/src/screen.c
@@ -2001,11 +2001,24 @@
int i;
int wrapped = 0;
int found;
+ int prevpos, pos;
+ int j;
+ mbstate_t mbs;
l = strlen (panel->search_buffer);
if (c_code == KEY_BACKSPACE) {
- if (l)
- panel->search_buffer[--l] = '\0';
+ if (l) {
+ prevpos = pos = 0;
+ memset (&mbs, 0, sizeof (mbs));
+ while (pos < l) {
+ prevpos = pos;
+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs);
+ if (j <= 0) break;
+ pos += j;
+ }
+ --l;
+ panel->search_buffer[prevpos] = 0;
+ }
} else {
if (c_code && l < sizeof (panel->search_buffer)) {
panel->search_buffer[l] = c_code;
@@ -2014,6 +2027,14 @@
}
}
+ prevpos = pos = 0;
+ memset (&mbs, 0, sizeof (mbs));
+ while (pos < l) {
+ prevpos = pos;
+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs);
+ if (j <= 0) break;
+ pos += j;
+ }
found = 0;
for (i = panel->selected; !wrapped || i != panel->selected; i++) {
if (i >= panel->count) {
@@ -2024,9 +2045,9 @@
}
if (panel->
case_sensitive
- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l)
+ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos)
== 0) : (g_strncasecmp (panel->dir.list[i].fname,
- panel->search_buffer, l) == 0)) {
+ panel->search_buffer, pos) == 0)) {
unselect_item (panel);
panel->selected = i;
select_item (panel);
@@ -2035,7 +2056,7 @@
}
}
if (!found)
- panel->search_buffer[--l] = 0;
+ panel->search_buffer[prevpos] = 0;
paint_panel (panel);
}