1
1

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>
Этот коммит содержится в:
Andrew Borodin 2010-08-26 21:19:45 +04:00
родитель f8a47dae4c
Коммит 4aec2187e1
2 изменённых файлов: 54 добавлений и 8 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}