Support sort by numeric value for numeric names

This commit is contained in:
Arun Prakash Jana 2017-04-01 23:10:12 +05:30
parent 6e7aaa18fb
commit 0e82544199
No known key found for this signature in database
GPG key ID: A75979F35C080412
2 changed files with 60 additions and 8 deletions

View file

@ -58,6 +58,7 @@ I chose to fork because:
- Roll over at the first and last entries of a directory (with Up/Down keys) - Roll over at the first and last entries of a directory (with Up/Down keys)
- Removed navigation restriction with relative paths (and let permissions handle it) - Removed navigation restriction with relative paths (and let permissions handle it)
- Sort entries by file size (largest to smallest) - Sort entries by file size (largest to smallest)
- Sort numeric names in numeric order
- Shortcut to invoke file name copier (set using environment variable `NNN_COPIER`) - Shortcut to invoke file name copier (set using environment variable `NNN_COPIER`)
- File associations - File associations
- Environment variable `NNN_OPENER` to let desktop opener handle it all. E.g.: - Environment variable `NNN_OPENER` to let desktop opener handle it all. E.g.:

67
nnn.c
View file

@ -278,16 +278,67 @@ xgetenv(char *name, char *fallback)
return value && value[0] ? value : fallback; return value && value[0] ? value : fallback;
} }
int xisdigit(const char c) {
if (c >= '0' && c <= '9') \
return 1; \
return 0;
}
/*
* We assume none of the strings are NULL.
*
* Let's have the logic to sort numeric names in numeric order.
* E.g., the order '1, 10, 2' doesn't make sense to human eyes.
*
* If the absolute numeric values are same, we fallback to alphasort.
*/
static int static int
xstricmp(const char *s1, const char *s2) xstricmp(const char *s1, const char *s2)
{ {
while (*s2 != 0 && TOUPPER(*s1) == TOUPPER(*s2)) static int s1_num, s2_num;
static const char *ps1, *ps2;
static long long num1, num2;
s1_num = s2_num = 0;
ps1 = s1;
if (*ps1 == '-')
ps1++;
while (*ps1 && xisdigit(*ps1))
ps1++;
if (!*ps1)
s1_num = 1;
ps2 = s2;
if (*ps2 == '-')
ps2++;
while (*ps2 && xisdigit(*ps2))
ps2++;
if (!*ps2)
s2_num = 1;
if (s1_num && s2_num) {
num1 = strtoll(s1, NULL, 10);
num2 = strtoll(s2, NULL, 10);
if (num1 != num2) {
if (num1 > num2)
return 1;
else
return -1;
}
}
while (*s2 && *s1 && TOUPPER(*s1) == TOUPPER(*s2))
s1++, s2++; s1++, s2++;
/* In case of alphabetically same names, make sure /* In case of alphabetically same names, make sure
lower case one comes before upper case one */ lower case one comes before upper case one */
if (!*s1 && !*s2) if (!*s1 && !*s2)
return 1; return 1;
return (int) (TOUPPER(*s1) - TOUPPER(*s2)); return (int) (TOUPPER(*s1) - TOUPPER(*s2));
} }
@ -489,17 +540,17 @@ static void
printent(struct entry *ent, int active) printent(struct entry *ent, int active)
{ {
if (S_ISDIR(ent->mode)) if (S_ISDIR(ent->mode))
printw("%s%s/\n", active ? CURSR : EMPTY, ent->name); printw("%s%s/\n", CURSYM(active), ent->name);
else if (S_ISLNK(ent->mode)) else if (S_ISLNK(ent->mode))
printw("%s%s@\n", active ? CURSR : EMPTY, ent->name); printw("%s%s@\n", CURSYM(active), ent->name);
else if (S_ISSOCK(ent->mode)) else if (S_ISSOCK(ent->mode))
printw("%s%s=\n", active ? CURSR : EMPTY, ent->name); printw("%s%s=\n", CURSYM(active), ent->name);
else if (S_ISFIFO(ent->mode)) else if (S_ISFIFO(ent->mode))
printw("%s%s|\n", active ? CURSR : EMPTY, ent->name); printw("%s%s|\n", CURSYM(active), ent->name);
else if (ent->mode & S_IXUSR) else if (ent->mode & S_IXUSR)
printw("%s%s*\n", active ? CURSR : EMPTY, ent->name); printw("%s%s*\n", CURSYM(active), ent->name);
else else
printw("%s%s\n", active ? CURSR : EMPTY, ent->name); printw("%s%s\n", CURSYM(active), ent->name);
} }
static void (*printptr)(struct entry *ent, int active) = &printent; static void (*printptr)(struct entry *ent, int active) = &printent;
@ -928,7 +979,7 @@ nochange:
} }
strlcpy(path, newpath, sizeof(path)); strlcpy(path, newpath, sizeof(path));
/* Reset filter */ /* Reset filter */
strlcpy(fltr, ifilter, sizeof(fltr)) strlcpy(fltr, ifilter, sizeof(fltr));
DPRINTF_S(path); DPRINTF_S(path);
goto begin; goto begin;
case SEL_CDHOME: case SEL_CDHOME: