]> Sergey Matveev's repositories - nnn.git/commitdiff
Support sort by numeric value for numeric names
authorArun Prakash Jana <engineerarun@gmail.com>
Sat, 1 Apr 2017 17:40:12 +0000 (23:10 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Sat, 1 Apr 2017 19:51:31 +0000 (01:21 +0530)
README.md
nnn.c

index 20a9f113dc423b043f03a142de61e3bd6186c28a..5fa00f73b4b3e6dd368f9aefaf3bb0a1157bd194 100644 (file)
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ I chose to fork because:
   - 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)
   - 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`)
 - File associations
   - Environment variable `NNN_OPENER` to let desktop opener handle it all. E.g.:
diff --git a/nnn.c b/nnn.c
index 4392efffcfc379dde24cd9e076613f2648751e98..2939dac25b3a1d8a2fa678453e543eb44f78303b 100644 (file)
--- a/nnn.c
+++ b/nnn.c
@@ -278,16 +278,67 @@ xgetenv(char *name, char *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
 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++;
 
        /* In case of alphabetically same names, make sure
           lower case one comes before upper case one */
        if (!*s1 && !*s2)
                return 1;
+
        return (int) (TOUPPER(*s1) - TOUPPER(*s2));
 }
 
@@ -489,17 +540,17 @@ static void
 printent(struct entry *ent, int active)
 {
        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))
-               printw("%s%s@\n", active ? CURSR : EMPTY, ent->name);
+               printw("%s%s@\n", CURSYM(active), ent->name);
        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))
-               printw("%s%s|\n", active ? CURSR : EMPTY, ent->name);
+               printw("%s%s|\n", CURSYM(active), ent->name);
        else if (ent->mode & S_IXUSR)
-               printw("%s%s*\n", active ? CURSR : EMPTY, ent->name);
+               printw("%s%s*\n", CURSYM(active), ent->name);
        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;
@@ -928,7 +979,7 @@ nochange:
                        }
                        strlcpy(path, newpath, sizeof(path));
                        /* Reset filter */
-                       strlcpy(fltr, ifilter, sizeof(fltr))
+                       strlcpy(fltr, ifilter, sizeof(fltr));
                        DPRINTF_S(path);
                        goto begin;
                case SEL_CDHOME: