1
0
mirror of https://gittea.dev/nova/th.git synced 2025-10-21 10:20:15 -04:00

improvenments to natural sort

This commit is contained in:
nova
2025-08-28 23:00:54 +02:00
parent a05c3ecd96
commit 9f3042ccac
2 changed files with 75 additions and 30 deletions

View File

@@ -39,16 +39,16 @@
#define COLOR_ORPHAN 9
#define COLOR_PATH 10
#define FILE_TYPE_UNKNOWN COLOR_UNKNOWN
#define FILE_TYPE_DIR COLOR_DIR
#define FILE_TYPE_EXEC COLOR_EXEC
#define FILE_TYPE_REGULAR COLOR_REGULAR
#define FILE_TYPE_SYMLINK COLOR_SYMLINK
#define FILE_TYPE_BLOCK COLOR_BLOCK
#define FILE_TYPE_CHARDEV COLOR_CHARDEV
#define FILE_TYPE_SOCK COLOR_SOCK
#define FILE_TYPE_FIFO COLOR_FIFO
#define FILE_TYPE_ORPHAN COLOR_ORPHAN
#define FILE_TYPE_UNKNOWN 0
#define FILE_TYPE_EXEC 1
#define FILE_TYPE_REGULAR 2
#define FILE_TYPE_BLOCK 3
#define FILE_TYPE_CHARDEV 4
#define FILE_TYPE_SOCK 5
#define FILE_TYPE_FIFO 6
#define FILE_TYPE_ORPHAN 7
#define FILE_TYPE_DIR 32
#define FILE_TYPE_SYMLINK 64
#define FILE_TYPE_OPEN_FILE 128 /* this is only used in rgt_content to print a file preview, not the dir */
#define YANK_IS_USED 1

View File

@@ -4,6 +4,8 @@
#include <stdlib.h>
#include <string.h>
#include "defines.h"
extern unsigned int settings;
extern unsigned int file_modifiers;
@@ -20,31 +22,74 @@ int skip_dot(const struct dirent *entry){
return 1;
}
int sort_natural(const void *file0, const void *file1){
unsigned char file_type0 = ((file*)file0)->file_type;
unsigned char file_type1 = ((file*)file1)->file_type;
int sort_natural(const void *file0_, const void *file1_){
file *file0 = (file*)file0_;
file *file1 = (file*)file1_;
char weight = 0;
if (file_type0 == FILE_TYPE_DIR || file_type0 == FILE_TYPE_SYMLINK) {
weight |= 1;
unsigned char *a = file0->file_name;
unsigned char *b = file1->file_name;
if (file0->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR) && !(file1->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR))) {
return -1;
}
if (file_type1 == FILE_TYPE_DIR || file_type1 == FILE_TYPE_SYMLINK) {
weight |= 2;
}
if (weight == 0 || weight == 3) {
char *file_name0 = ((file*)file0)->file_name;
char *file_name1 = ((file*)file1)->file_name;
return strcasecmp(file_name0, file_name1);
} else {
if (file_type0 > file_type1) {
if (!(file0->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) && file1->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) {
return 1;
} else if (file_type0 < file_type1) {
}
unsigned long num0 = 0;
unsigned long num1 = 0;
/* bitwise OR a with ' ' turns turns caps into small letters
* while doing this on all chars may cause unexpected behaviour on the extended ascii set,
* for now i dont care */
while ((*a | ' ') == (*b | ' ') && *a != '\0') {
if ((*a >= '0') && (*a <= '9')) {
while((*a >= '0') && (*a <= '9')) {
num0 = (num0 * 10) + (*a - '0');
a++;
}
while((*b >= '0') && (*b <= '9')) {
num1 = (num1 * 10) + (*b - '0');
b++;
}
if (num0 != num1) {
break;
}
} else {
a++;
b++;
}
}
if (num0 == num1) {
if (*a == '\0') {
a--;
}
if (*b == '\0') {
b--;
}
unsigned char c0;
unsigned char c1;
/* in this case we actually check for a through z as otherwise unicode characters get ordered wrongly */
if (*a >= 'A' && *a <= 'Z') {
c0 = (*a | ' ');
} else {
c0 = *a;
}
if (*b >= 'A' && *b <= 'Z') {
c1 = (*b | ' ');
} else {
c1 = *b;
}
if (c0 > c1) {
return 1;
} else if (c0 < c1) {
return -1;
} else {
char *file_name0 = ((file*)file0)->file_name;
char *file_name1 = ((file*)file1)->file_name;
return strcasecmp(file_name0, file_name1);
return 0;
}
} else if (num0 > num1) {
return 1;
} else {
return -1;
}
}
int sort_alpha(const void *file0, const void *file1){