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 *
|
static char *
|
||||||
str_utf8_create_key_gen (const char *text, int case_sen,
|
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;
|
char *result;
|
||||||
|
|
||||||
if (case_sen) {
|
if (case_sen) {
|
||||||
result = str_utf8_normalize (text);
|
result = str_utf8_normalize (text);
|
||||||
} else {
|
} else {
|
||||||
|
gboolean dot;
|
||||||
|
GString *fixed;
|
||||||
const char *start, *end;
|
const char *start, *end;
|
||||||
char *fold, *key;
|
char *fold, *key;
|
||||||
GString *fixed = g_string_new ("");
|
|
||||||
|
|
||||||
|
dot = text[0] == '.';
|
||||||
|
fixed = g_string_sized_new (16);
|
||||||
|
|
||||||
|
if (!dot)
|
||||||
start = text;
|
start = text;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = text + 1;
|
||||||
|
g_string_append_c (fixed, '.');
|
||||||
|
}
|
||||||
|
|
||||||
while (!g_utf8_validate (start, -1, &end) && start[0] != '\0')
|
while (!g_utf8_validate (start, -1, &end) && start[0] != '\0')
|
||||||
{
|
{
|
||||||
if (start != end)
|
if (start != end)
|
||||||
@ -1248,9 +1259,19 @@ str_utf8_create_key_gen (const char *text, int case_sen,
|
|||||||
|
|
||||||
if (start == text)
|
if (start == text)
|
||||||
{
|
{
|
||||||
fold = g_utf8_casefold (text, -1);
|
fold = g_utf8_casefold (start, -1);
|
||||||
result = keygen (fold, -1);
|
result = keygen (fold, -1);
|
||||||
g_free (fold);
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -1262,9 +1283,8 @@ str_utf8_create_key_gen (const char *text, int case_sen,
|
|||||||
g_free (key);
|
g_free (key);
|
||||||
g_free (fold);
|
g_free (fold);
|
||||||
}
|
}
|
||||||
result = g_strdup (fixed->str);
|
result = g_string_free (fixed, FALSE);
|
||||||
}
|
}
|
||||||
g_string_free (fixed, TRUE);
|
|
||||||
}
|
}
|
||||||
return result;
|
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
|
int
|
||||||
unsorted (file_entry *a, file_entry *b)
|
unsorted (file_entry *a, file_entry *b)
|
||||||
{
|
{
|
||||||
@ -84,8 +111,7 @@ sort_name (file_entry *a, file_entry *b)
|
|||||||
if (b->sort_key == NULL)
|
if (b->sort_key == NULL)
|
||||||
b->sort_key = str_create_key_for_filename (b->fname, case_sensitive);
|
b->sort_key = str_create_key_for_filename (b->fname, case_sensitive);
|
||||||
|
|
||||||
return str_key_collate (a->sort_key, b->sort_key, case_sensitive)
|
return key_collate (a->sort_key, b->sort_key);
|
||||||
* reverse;
|
|
||||||
}
|
}
|
||||||
return bd - ad;
|
return bd - ad;
|
||||||
}
|
}
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user