commit b2f2a6fe76bdbba48c0174b4f1eb05caf1a74b71
parent 6b1ec1959954145d7942ba3b7e65f5cde30485a1
Author: Lazaros Koromilas <lostd@2f30.org>
Date: Mon, 8 Apr 2019 12:48:24 +0300
Add sort by version number mode
Diffstat:
6 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,9 +7,9 @@ MANPREFIX = $(PREFIX)/man
#CFLAGS = -g
LDLIBS = -lcurses
-DISTFILES = noice.c strlcat.c strlcpy.c util.h config.def.h\
+DISTFILES = noice.c strlcat.c strlcpy.c strverscmp.c util.h config.def.h\
noice.1 Makefile README LICENSE
-OBJ = noice.o strlcat.o strlcpy.o
+OBJ = noice.o strlcat.o strlcpy.o strverscmp.o
BIN = noice
all: $(BIN)
diff --git a/config.def.h b/config.def.h
@@ -6,6 +6,7 @@
int dirorder = 0; /* Set to 1 to sort by directory first */
int mtimeorder = 0; /* Set to 1 to sort by time modified */
int icaseorder = 0; /* Set to 1 to sort by ignoring case */
+int versorder = 0; /* Set to 1 to sort by version number */
int idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */
int showhidden = 0; /* Set to 1 to show hidden files by default */
int usecolor = 0; /* Set to 1 to enable color attributes */
@@ -89,6 +90,8 @@ struct key bindings[] = {
{ 't', SEL_MTIME },
/* Toggle case sensitivity */
{ 'i', SEL_ICASE },
+ /* Toggle sort by version number */
+ { 'v', SEL_VERS },
{ CONTROL('L'), SEL_REDRAW },
/* Run command */
{ 'z', SEL_RUN, "top" },
diff --git a/noice.1 b/noice.1
@@ -63,6 +63,8 @@ Toggle sort by directory first.
Toggle sort by time modified.
.It Ic i
Toggle case sensitive sort.
+.It Ic v
+Toggle sort by version number.
.It Ic C-l
Force a redraw.
.It Ic \&!
diff --git a/noice.c b/noice.c
@@ -58,6 +58,7 @@ enum action {
SEL_DSORT,
SEL_MTIME,
SEL_ICASE,
+ SEL_VERS,
SEL_REDRAW,
SEL_RUN,
SEL_RUNARG,
@@ -308,8 +309,9 @@ entrycmp(const void *va, const void *vb)
return b->t - a->t;
if (icaseorder)
return strcasecmp(a->name, b->name);
- else
- return strcmp(a->name, b->name);
+ if (versorder)
+ return strverscmp(a->name, b->name);
+ return strcmp(a->name, b->name);
}
void
@@ -850,6 +852,12 @@ nochange:
if (ndents > 0)
mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));
goto begin;
+ case SEL_VERS:
+ versorder = !versorder;
+ /* Save current */
+ if (ndents > 0)
+ mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));
+ goto begin;
case SEL_REDRAW:
/* Save current */
if (ndents > 0)
diff --git a/strverscmp.c b/strverscmp.c
@@ -0,0 +1,47 @@
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "util.h"
+
+int
+strverscmp(const char *str1, const char *str2)
+{
+ size_t len1 = strlen(str1);
+ size_t len2 = strlen(str2);
+ size_t i1 = 0;
+ size_t i2 = 0;
+ for (; i1 < len1 && i2 < len2; i1++, i2++) {
+ char c1 = str1[i1];
+ char c2 = str2[i2];
+ if (isdigit(c1) && isdigit(c2)) {
+ unsigned long long int num1;
+ unsigned long long int num2;
+ char *end1;
+ char *end2;
+ num1 = strtoull(str1 + i1, &end1, 10);
+ num2 = strtoull(str2 + i2, &end2, 10);
+ DPRINTF_LLU(num1);
+ DPRINTF_LLU(num2);
+ if (num1 < num2)
+ return -1;
+ if (num1 > num2)
+ return 1;
+ i1 = end1 - str1 - 1;
+ i2 = end2 - str2 - 1;
+ if (i1 < i2)
+ return -1;
+ if (i1 > i2)
+ return 1;
+ } else {
+ if (c1 < c2)
+ return -1;
+ if (c1 > c2)
+ return 1;
+ }
+ }
+ if (len1 < len2)
+ return -1;
+ if (len1 > len2)
+ return 1;
+ return 0;
+}
diff --git a/util.h b/util.h
@@ -5,6 +5,8 @@ size_t strlcat(char *, const char *, size_t);
size_t strlcpy(char *, const char *, size_t);
#undef dprintf
int dprintf(int, const char *, ...);
+#undef strverscmp
+int strverscmp(const char *, const char *);
#ifdef DEBUG
#define DEBUG_FD 8
@@ -12,9 +14,11 @@ int dprintf(int, const char *, ...);
#define DPRINTF_U(x) dprintf(DEBUG_FD, #x "=%u\n", x)
#define DPRINTF_S(x) dprintf(DEBUG_FD, #x "=%s\n", x)
#define DPRINTF_P(x) dprintf(DEBUG_FD, #x "=0x%p\n", x)
+#define DPRINTF_LLU(x) dprintf(DEBUG_FD, #x "=%llu\n", x)
#else
#define DPRINTF_D(x)
#define DPRINTF_U(x)
#define DPRINTF_S(x)
#define DPRINTF_P(x)
+#define DPRINTF_LLU(x)
#endif /* DEBUG */