mirror of
https://github.com/jarun/nnn.git
synced 2024-11-24 20:01:27 +00:00
Implement reverse sorting
This commit is contained in:
parent
a89b5fd82c
commit
f654e3ca2b
|
@ -40,6 +40,7 @@ Visit the [Wiki](https://github.com/jarun/nnn/wiki) for concepts, program usage,
|
||||||
- Ordered pure numeric names by default (visit _/proc_)
|
- Ordered pure numeric names by default (visit _/proc_)
|
||||||
- Case-insensitive version (_aka_ natural) sort
|
- Case-insensitive version (_aka_ natural) sort
|
||||||
- By file name, modification/access time, size, extension
|
- By file name, modification/access time, size, extension
|
||||||
|
- Reverse sort
|
||||||
- Search
|
- Search
|
||||||
- Instant filtering with *search-as-you-type*
|
- Instant filtering with *search-as-you-type*
|
||||||
- Regex and substring (default) matches
|
- Regex and substring (default) matches
|
||||||
|
|
68
src/nnn.c
68
src/nnn.c
|
@ -1797,7 +1797,7 @@ static int xstrverscasecmp(const char * const s1, const char * const s2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int (*cmpfn)(const char * const s1, const char * const s2) = &xstricmp;
|
static int (*namecmpfn)(const char * const s1, const char * const s2) = &xstricmp;
|
||||||
|
|
||||||
/* Return the integer value of a char representing HEX */
|
/* Return the integer value of a char representing HEX */
|
||||||
static char xchartohex(char c)
|
static char xchartohex(char c)
|
||||||
|
@ -1882,9 +1882,23 @@ static int entrycmp(const void *va, const void *vb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmpfn(pa->name, pb->name);
|
return namecmpfn(pa->name, pb->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int reventrycmp(const void *va, const void *vb)
|
||||||
|
{
|
||||||
|
if ((((pEntry)vb)->flags & DIR_OR_LINK_TO_DIR)
|
||||||
|
!= (((pEntry)va)->flags & DIR_OR_LINK_TO_DIR)) {
|
||||||
|
if (((pEntry)vb)->flags & DIR_OR_LINK_TO_DIR)
|
||||||
|
return 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -entrycmp(va, vb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int (*entrycmpfn)(const void *va, const void *vb) = &entrycmp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns SEL_* if key is bound and 0 otherwise.
|
* Returns SEL_* if key is bound and 0 otherwise.
|
||||||
* Also modifies the run and env pointers (used on SEL_{RUN,RUNARG}).
|
* Also modifies the run and env pointers (used on SEL_{RUN,RUNARG}).
|
||||||
|
@ -2014,7 +2028,7 @@ static int matches(const char *fltr)
|
||||||
if (cfg.filter_re)
|
if (cfg.filter_re)
|
||||||
regfree(&re);
|
regfree(&re);
|
||||||
|
|
||||||
qsort(dents, ndents, sizeof(*dents), entrycmp);
|
qsort(dents, ndents, sizeof(*dents), entrycmpfn);
|
||||||
|
|
||||||
return ndents;
|
return ndents;
|
||||||
}
|
}
|
||||||
|
@ -3501,7 +3515,8 @@ static void show_help(const char *path)
|
||||||
"1ORDER TOGGLES\n"
|
"1ORDER TOGGLES\n"
|
||||||
"cS Disk usage%-14cA Apparent du\n"
|
"cS Disk usage%-14cA Apparent du\n"
|
||||||
"cz Size%-20ct Time\n"
|
"cz Size%-20ct Time\n"
|
||||||
"cv version%-17cE Extension\n"
|
"cv Version%-17cE Extension\n"
|
||||||
|
"cR Reverse%-0c\n"
|
||||||
"1MISC\n"
|
"1MISC\n"
|
||||||
"9! ^] Shell%-17c; x Execute plugin\n"
|
"9! ^] Shell%-17c; x Execute plugin\n"
|
||||||
"c] Cmd prompt%-13c^P Pick plugin\n"
|
"c] Cmd prompt%-13c^P Pick plugin\n"
|
||||||
|
@ -3966,7 +3981,7 @@ static void populate(char *path, char *lastname)
|
||||||
if (!ndents)
|
if (!ndents)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qsort(dents, ndents, sizeof(*dents), entrycmp);
|
qsort(dents, ndents, sizeof(*dents), entrycmpfn);
|
||||||
|
|
||||||
#ifdef DBGMODE
|
#ifdef DBGMODE
|
||||||
clock_gettime(CLOCK_REALTIME, &ts2);
|
clock_gettime(CLOCK_REALTIME, &ts2);
|
||||||
|
@ -4204,7 +4219,7 @@ static void redraw(char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ndents) {
|
if (ndents) {
|
||||||
char sort[] = "\0 \0";
|
char sort[] = "\0 \0\0";
|
||||||
pEntry pent = &dents[cur];
|
pEntry pent = &dents[cur];
|
||||||
|
|
||||||
if (cfg.mtimeorder)
|
if (cfg.mtimeorder)
|
||||||
|
@ -4214,8 +4229,17 @@ static void redraw(char *path)
|
||||||
else if (cfg.extnorder)
|
else if (cfg.extnorder)
|
||||||
sort[0] = 'E';
|
sort[0] = 'E';
|
||||||
|
|
||||||
if (cmpfn == &xstrverscasecmp)
|
if (entrycmpfn == &reventrycmp)
|
||||||
sort[0] ? (sort[1] = 'V', sort[2] = ' ') : (sort[0] = 'V');
|
sort[0] ? (sort[1] = 'R', sort[2] = ' ') : (sort[0] = 'R');
|
||||||
|
|
||||||
|
if (namecmpfn == &xstrverscasecmp) {
|
||||||
|
if (!sort[0])
|
||||||
|
sort[0] = 'V';
|
||||||
|
else if (sort[1] == ' ')
|
||||||
|
sort[1] = 'V', sort[2] = ' ';
|
||||||
|
else
|
||||||
|
sort[2] = 'V', sort[3] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the file extension for regular files */
|
/* Get the file extension for regular files */
|
||||||
if (S_ISREG(pent->mode)) {
|
if (S_ISREG(pent->mode)) {
|
||||||
|
@ -4774,7 +4798,8 @@ nochange:
|
||||||
case SEL_BSIZE: // fallthrough
|
case SEL_BSIZE: // fallthrough
|
||||||
case SEL_EXTN: // fallthrough
|
case SEL_EXTN: // fallthrough
|
||||||
case SEL_MTIME: // fallthrough
|
case SEL_MTIME: // fallthrough
|
||||||
case SEL_VERSION:
|
case SEL_VERSION: // fallthrough
|
||||||
|
case SEL_REVERSE:
|
||||||
switch (sel) {
|
switch (sel) {
|
||||||
case SEL_MFLTR:
|
case SEL_MFLTR:
|
||||||
cfg.filtermode ^= 1;
|
cfg.filtermode ^= 1;
|
||||||
|
@ -4803,6 +4828,8 @@ nochange:
|
||||||
cfg.apparentsz = 0;
|
cfg.apparentsz = 0;
|
||||||
cfg.blkorder = 0;
|
cfg.blkorder = 0;
|
||||||
cfg.extnorder = 0;
|
cfg.extnorder = 0;
|
||||||
|
if (!cfg.sizeorder)
|
||||||
|
entrycmpfn = &entrycmp;
|
||||||
break;
|
break;
|
||||||
case SEL_ASIZE:
|
case SEL_ASIZE:
|
||||||
cfg.apparentsz ^= 1;
|
cfg.apparentsz ^= 1;
|
||||||
|
@ -4811,7 +4838,8 @@ nochange:
|
||||||
cfg.blkorder = 1;
|
cfg.blkorder = 1;
|
||||||
blk_shift = 0;
|
blk_shift = 0;
|
||||||
} else
|
} else
|
||||||
cfg.blkorder = 0; // fallthrough
|
cfg.blkorder = 0;
|
||||||
|
// fallthrough
|
||||||
case SEL_BSIZE:
|
case SEL_BSIZE:
|
||||||
if (sel == SEL_BSIZE) {
|
if (sel == SEL_BSIZE) {
|
||||||
if (!cfg.apparentsz)
|
if (!cfg.apparentsz)
|
||||||
|
@ -4824,7 +4852,8 @@ nochange:
|
||||||
if (cfg.blkorder) {
|
if (cfg.blkorder) {
|
||||||
cfg.showdetail = 1;
|
cfg.showdetail = 1;
|
||||||
printptr = &printent_long;
|
printptr = &printent_long;
|
||||||
}
|
} else
|
||||||
|
entrycmpfn = &entrycmp;
|
||||||
cfg.mtimeorder = 0;
|
cfg.mtimeorder = 0;
|
||||||
cfg.sizeorder = 0;
|
cfg.sizeorder = 0;
|
||||||
cfg.extnorder = 0;
|
cfg.extnorder = 0;
|
||||||
|
@ -4835,6 +4864,8 @@ nochange:
|
||||||
cfg.mtimeorder = 0;
|
cfg.mtimeorder = 0;
|
||||||
cfg.apparentsz = 0;
|
cfg.apparentsz = 0;
|
||||||
cfg.blkorder = 0;
|
cfg.blkorder = 0;
|
||||||
|
if (!cfg.extnorder)
|
||||||
|
entrycmpfn = &entrycmp;
|
||||||
break;
|
break;
|
||||||
case SEL_MTIME:
|
case SEL_MTIME:
|
||||||
cfg.mtimeorder ^= 1;
|
cfg.mtimeorder ^= 1;
|
||||||
|
@ -4842,9 +4873,18 @@ nochange:
|
||||||
cfg.apparentsz = 0;
|
cfg.apparentsz = 0;
|
||||||
cfg.blkorder = 0;
|
cfg.blkorder = 0;
|
||||||
cfg.extnorder = 0;
|
cfg.extnorder = 0;
|
||||||
|
if (!cfg.mtimeorder)
|
||||||
|
entrycmpfn = &entrycmp;
|
||||||
break;
|
break;
|
||||||
default: /* SEL_VERSION */
|
case SEL_VERSION:
|
||||||
cmpfn = (cmpfn == &xstrverscasecmp) ? &xstricmp : &xstrverscasecmp;
|
if (namecmpfn == &xstrverscasecmp) {
|
||||||
|
namecmpfn = &xstricmp;
|
||||||
|
entrycmpfn = &entrycmp;
|
||||||
|
} else
|
||||||
|
namecmpfn = &xstrverscasecmp;
|
||||||
|
break;
|
||||||
|
default: /* SEL_REVERSE */
|
||||||
|
entrycmpfn = (entrycmpfn == &entrycmp) ? &reventrycmp : &entrycmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5744,7 +5784,7 @@ int main(int argc, char *argv[])
|
||||||
check_key_collision();
|
check_key_collision();
|
||||||
return _SUCCESS;
|
return _SUCCESS;
|
||||||
case 'v':
|
case 'v':
|
||||||
cmpfn = &xstrverscasecmp;
|
namecmpfn = &xstrverscasecmp;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
fprintf(stdout, "%s\n", VERSION);
|
fprintf(stdout, "%s\n", VERSION);
|
||||||
|
|
|
@ -73,6 +73,7 @@ enum action {
|
||||||
SEL_EXTN, /* order by extension */
|
SEL_EXTN, /* order by extension */
|
||||||
SEL_MTIME,
|
SEL_MTIME,
|
||||||
SEL_VERSION,
|
SEL_VERSION,
|
||||||
|
SEL_REVERSE,
|
||||||
SEL_REDRAW,
|
SEL_REDRAW,
|
||||||
SEL_SEL,
|
SEL_SEL,
|
||||||
SEL_SELMUL,
|
SEL_SELMUL,
|
||||||
|
@ -194,6 +195,8 @@ static struct key bindings[] = {
|
||||||
{ 't', SEL_MTIME },
|
{ 't', SEL_MTIME },
|
||||||
/* Toggle version sort */
|
/* Toggle version sort */
|
||||||
{ 'v', SEL_VERSION },
|
{ 'v', SEL_VERSION },
|
||||||
|
/* Toggle reverse sort */
|
||||||
|
{ 'R', SEL_REVERSE },
|
||||||
/* Redraw window */
|
/* Redraw window */
|
||||||
{ CONTROL('L'), SEL_REDRAW },
|
{ CONTROL('L'), SEL_REDRAW },
|
||||||
{ KEY_F(5), SEL_REDRAW },
|
{ KEY_F(5), SEL_REDRAW },
|
||||||
|
|
Loading…
Reference in a new issue