Ticket #1894: sort order should not mix hidden files with others.
In case sensitive sort, the order of files and directories is following: hidden dirs dirs hidden files files In case insensitive mode, directories are mixed and files are mixed too: dirs (hidden and not are mixed) files (hidden and not are mixed). This commit defines the sort order independently of case sensitivity: hidden dirs dirs hidden files files Files in UTF-8 locale require special handling: leading dot must not be processed in g_utf8_casefold() funcion. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Этот коммит содержится в:
родитель
f8a47dae4c
Коммит
4aec2187e1
@ -1220,18 +1220,29 @@ str_utf8_caseprefix (const char *text, const char *prefix)
|
||||
|
||||
static char *
|
||||
str_utf8_create_key_gen (const char *text, int case_sen,
|
||||
gchar * (*keygen) (const gchar *, gssize size))
|
||||
gchar * (*keygen) (const gchar *text, gssize size))
|
||||
{
|
||||
char *result;
|
||||
|
||||
if (case_sen) {
|
||||
result = str_utf8_normalize (text);
|
||||
} else {
|
||||
gboolean dot;
|
||||
GString *fixed;
|
||||
const char *start, *end;
|
||||
char *fold, *key;
|
||||
GString *fixed = g_string_new ("");
|
||||
|
||||
start = text;
|
||||
dot = text[0] == '.';
|
||||
fixed = g_string_sized_new (16);
|
||||
|
||||
if (!dot)
|
||||
start = text;
|
||||
else
|
||||
{
|
||||
start = text + 1;
|
||||
g_string_append_c (fixed, '.');
|
||||
}
|
||||
|
||||
while (!g_utf8_validate (start, -1, &end) && start[0] != '\0')
|
||||
{
|
||||
if (start != end)
|
||||
@ -1248,9 +1259,19 @@ str_utf8_create_key_gen (const char *text, int case_sen,
|
||||
|
||||
if (start == text)
|
||||
{
|
||||
fold = g_utf8_casefold (text, -1);
|
||||
fold = g_utf8_casefold (start, -1);
|
||||
result = keygen (fold, -1);
|
||||
g_free (fold);
|
||||
g_string_free (fixed, TRUE);
|
||||
}
|
||||
else if (dot && (start == text + 1))
|
||||
{
|
||||
fold = g_utf8_casefold (start, -1);
|
||||
key = keygen (fold, -1);
|
||||
g_string_append (fixed, key);
|
||||
g_free (key);
|
||||
g_free (fold);
|
||||
result = g_string_free (fixed, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1262,9 +1283,8 @@ str_utf8_create_key_gen (const char *text, int case_sen,
|
||||
g_free (key);
|
||||
g_free (fold);
|
||||
}
|
||||
result = g_strdup (fixed->str);
|
||||
result = g_string_free (fixed, FALSE);
|
||||
}
|
||||
g_string_free (fixed, TRUE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
30
src/dir.c
30
src/dir.c
@ -63,6 +63,33 @@ sort_orders_t sort_orders [SORT_TYPES_TOTAL] = {
|
||||
};
|
||||
*/
|
||||
|
||||
static inline int
|
||||
key_collate (const char *t1, const char *t2)
|
||||
{
|
||||
int dotdot = 0;
|
||||
int ret;
|
||||
|
||||
dotdot = (t1[0] == '.' ? 1 : 0) | ((t2[0] == '.' ? 1 : 0) << 1);
|
||||
|
||||
switch (dotdot)
|
||||
{
|
||||
case 0:
|
||||
case 3:
|
||||
ret = str_key_collate (t1, t2, case_sensitive) * reverse;
|
||||
break;
|
||||
case 1:
|
||||
ret = -1; /* t1 < t2 */
|
||||
break;
|
||||
case 2:
|
||||
ret = 1; /* t1 > t2 */
|
||||
break;
|
||||
default:
|
||||
ret = 0; /* it must not happen */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
unsorted (file_entry *a, file_entry *b)
|
||||
{
|
||||
@ -84,8 +111,7 @@ sort_name (file_entry *a, file_entry *b)
|
||||
if (b->sort_key == NULL)
|
||||
b->sort_key = str_create_key_for_filename (b->fname, case_sensitive);
|
||||
|
||||
return str_key_collate (a->sort_key, b->sort_key, case_sensitive)
|
||||
* reverse;
|
||||
return key_collate (a->sort_key, b->sort_key);
|
||||
}
|
||||
return bd - ad;
|
||||
}
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user