mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 05:41:31 +00:00
Support time type (access/change/mod) change
This commit is contained in:
parent
7e063f49d1
commit
22ccf5e2e6
|
@ -65,7 +65,7 @@ It runs smoothly on the Pi, [Termux](https://www.youtube.com/watch?v=AbaauM7gUJw
|
||||||
- Sort
|
- Sort
|
||||||
- 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, access/change/mod (default) time, size, extension
|
||||||
- Reverse sort
|
- Reverse sort
|
||||||
- Mimes
|
- Mimes
|
||||||
- Open with desktop opener or specify a custom app
|
- Open with desktop opener or specify a custom app
|
||||||
|
|
|
@ -12,7 +12,6 @@ _nnn ()
|
||||||
local cur=$2 prev=$3
|
local cur=$2 prev=$3
|
||||||
local -a opts
|
local -a opts
|
||||||
opts=(
|
opts=(
|
||||||
-a
|
|
||||||
-A
|
-A
|
||||||
-b
|
-b
|
||||||
-c
|
-c
|
||||||
|
|
|
@ -11,7 +11,6 @@ else
|
||||||
set sessions_dir $HOME/.config/nnn/sessions
|
set sessions_dir $HOME/.config/nnn/sessions
|
||||||
end
|
end
|
||||||
|
|
||||||
complete -c nnn -s a -d 'use access time'
|
|
||||||
complete -c nnn -s A -d 'disable dir auto-select'
|
complete -c nnn -s A -d 'disable dir auto-select'
|
||||||
complete -c nnn -s b -r -d 'bookmark key to open' -x -a '(echo $NNN_BMS | awk -F: -v RS=\; \'{print $1"\t"$2}\')'
|
complete -c nnn -s b -r -d 'bookmark key to open' -x -a '(echo $NNN_BMS | awk -F: -v RS=\; \'{print $1"\t"$2}\')'
|
||||||
complete -c nnn -s c -d 'cli-only opener'
|
complete -c nnn -s c -d 'cli-only opener'
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
setopt localoptions noshwordsplit noksharrays
|
setopt localoptions noshwordsplit noksharrays
|
||||||
local -a args
|
local -a args
|
||||||
args=(
|
args=(
|
||||||
'(-a)-a[use access time]'
|
|
||||||
'(-A)-A[disable dir auto-select]'
|
'(-A)-A[disable dir auto-select]'
|
||||||
'(-b)-b[bookmark key to open]:key char'
|
'(-b)-b[bookmark key to open]:key char'
|
||||||
'(-c)-c[cli-only opener]'
|
'(-c)-c[cli-only opener]'
|
||||||
|
|
4
nnn.1
4
nnn.1
|
@ -6,7 +6,6 @@
|
||||||
.Nd the missing terminal file manager for X
|
.Nd the missing terminal file manager for X
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Ar -a
|
|
||||||
.Op Ar -A
|
.Op Ar -A
|
||||||
.Op Ar -b key
|
.Op Ar -b key
|
||||||
.Op Ar -c
|
.Op Ar -c
|
||||||
|
@ -53,9 +52,6 @@ to see the list of keybinds.
|
||||||
.Nm
|
.Nm
|
||||||
supports the following options:
|
supports the following options:
|
||||||
.Pp
|
.Pp
|
||||||
.Fl a
|
|
||||||
use access time for all operations (default: modification time)
|
|
||||||
.Pp
|
|
||||||
.Fl A
|
.Fl A
|
||||||
disable directory auto-select in navigate-as-you-type mode
|
disable directory auto-select in navigate-as-you-type mode
|
||||||
.Pp
|
.Pp
|
||||||
|
|
102
src/nnn.c
102
src/nnn.c
|
@ -246,7 +246,7 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint filtermode : 1; /* Set to enter filter mode */
|
uint filtermode : 1; /* Set to enter filter mode */
|
||||||
uint mtimeorder : 1; /* Set to sort by time modified */
|
uint timeorder : 1; /* Set to sort by time */
|
||||||
uint sizeorder : 1; /* Set to sort by file size */
|
uint sizeorder : 1; /* Set to sort by file size */
|
||||||
uint apparentsz : 1; /* Set to sort by apparent size (disk usage) */
|
uint apparentsz : 1; /* Set to sort by apparent size (disk usage) */
|
||||||
uint blkorder : 1; /* Set to sort by blocks used (disk usage) */
|
uint blkorder : 1; /* Set to sort by blocks used (disk usage) */
|
||||||
|
@ -269,8 +269,7 @@ typedef struct {
|
||||||
uint runctx : 2; /* The context in which plugin is to be run */
|
uint runctx : 2; /* The context in which plugin is to be run */
|
||||||
uint regex : 1; /* Use regex filters */
|
uint regex : 1; /* Use regex filters */
|
||||||
uint x11 : 1; /* Copy to system clipboard and show notis */
|
uint x11 : 1; /* Copy to system clipboard and show notis */
|
||||||
uint reserved2 : 1;
|
uint timetype : 2; /* Time sort type (0: access, 1: change, 2: modification) */
|
||||||
uint mtime : 1; /* Use modification time (else access time) */
|
|
||||||
uint cliopener : 1; /* All-CLI app opener */
|
uint cliopener : 1; /* All-CLI app opener */
|
||||||
uint waitedit : 1; /* For ops that can't be detached, used EDITOR */
|
uint waitedit : 1; /* For ops that can't be detached, used EDITOR */
|
||||||
uint rollover : 1; /* Roll over at edges */
|
uint rollover : 1; /* Roll over at edges */
|
||||||
|
@ -299,7 +298,7 @@ typedef struct {
|
||||||
/* Configuration, contexts */
|
/* Configuration, contexts */
|
||||||
static settings cfg = {
|
static settings cfg = {
|
||||||
0, /* filtermode */
|
0, /* filtermode */
|
||||||
0, /* mtimeorder */
|
0, /* timeorder */
|
||||||
0, /* sizeorder */
|
0, /* sizeorder */
|
||||||
0, /* apparentsz */
|
0, /* apparentsz */
|
||||||
0, /* blkorder */
|
0, /* blkorder */
|
||||||
|
@ -321,8 +320,7 @@ static settings cfg = {
|
||||||
0, /* runctx */
|
0, /* runctx */
|
||||||
0, /* regex */
|
0, /* regex */
|
||||||
0, /* x11 */
|
0, /* x11 */
|
||||||
0, /* reserved2 */
|
2, /* timetype (T_MOD) */
|
||||||
1, /* mtime */
|
|
||||||
0, /* cliopener */
|
0, /* cliopener */
|
||||||
0, /* waitedit */
|
0, /* waitedit */
|
||||||
1, /* rollover */
|
1, /* rollover */
|
||||||
|
@ -517,8 +515,9 @@ static char * const utils[] = {
|
||||||
#define MSG_LAZY 38
|
#define MSG_LAZY 38
|
||||||
#define MSG_IGNORED 39
|
#define MSG_IGNORED 39
|
||||||
#define MSG_RM_TMP 40
|
#define MSG_RM_TMP 40
|
||||||
|
#define MSG_NOCHNAGE 41
|
||||||
#ifndef DIR_LIMITED_SELECTION
|
#ifndef DIR_LIMITED_SELECTION
|
||||||
#define MSG_DIR_CHANGED 41 /* Must be the last entry */
|
#define MSG_DIR_CHANGED 42 /* Must be the last entry */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char * const messages[] = {
|
static const char * const messages[] = {
|
||||||
|
@ -563,6 +562,7 @@ static const char * const messages[] = {
|
||||||
"unmount failed! try lazy?",
|
"unmount failed! try lazy?",
|
||||||
"ignoring invalid paths...",
|
"ignoring invalid paths...",
|
||||||
"remove tmp file?",
|
"remove tmp file?",
|
||||||
|
"unchanged",
|
||||||
#ifndef DIR_LIMITED_SELECTION
|
#ifndef DIR_LIMITED_SELECTION
|
||||||
"dir changed, range sel off", /* Must be the last entry */
|
"dir changed, range sel off", /* Must be the last entry */
|
||||||
#endif
|
#endif
|
||||||
|
@ -608,6 +608,17 @@ static const char * const envs[] = {
|
||||||
"nnn",
|
"nnn",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Time type used */
|
||||||
|
#define T_ACCESS 0
|
||||||
|
#define T_CHANGE 1
|
||||||
|
#define T_MOD 2
|
||||||
|
|
||||||
|
static const char * const time_type[] = {
|
||||||
|
"'a'ccess",
|
||||||
|
"'c'hange",
|
||||||
|
"'m'od",
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
static char cp[] = "cp -iRp";
|
static char cp[] = "cp -iRp";
|
||||||
static char mv[] = "mv -i";
|
static char mv[] = "mv -i";
|
||||||
|
@ -2217,7 +2228,7 @@ static int entrycmp(const void *va, const void *vb)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sort based on specified order */
|
/* Sort based on specified order */
|
||||||
if (cfg.mtimeorder) {
|
if (cfg.timeorder) {
|
||||||
if (pb->t > pa->t)
|
if (pb->t > pa->t)
|
||||||
return 1;
|
return 1;
|
||||||
if (pb->t < pa->t)
|
if (pb->t < pa->t)
|
||||||
|
@ -2356,8 +2367,8 @@ static int getorderstr(char *sort)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (cfg.mtimeorder)
|
if (cfg.timeorder)
|
||||||
sort[0] = cfg.mtime ? 'T' : 'A';
|
sort[0] = (cfg.timetype == T_MOD) ? 'M' : ((cfg.timetype == T_ACCESS) ? 'A' : 'C');
|
||||||
else if (cfg.sizeorder)
|
else if (cfg.sizeorder)
|
||||||
sort[0] = 'S';
|
sort[0] = 'S';
|
||||||
else if (cfg.extnorder)
|
else if (cfg.extnorder)
|
||||||
|
@ -4108,6 +4119,7 @@ static void show_help(const char *path)
|
||||||
"9! ^] Shell%-19c] Cmd prompt\n"
|
"9! ^] Shell%-19c] Cmd prompt\n"
|
||||||
"cc Connect remote%-10cu Unmount\n"
|
"cc Connect remote%-10cu Unmount\n"
|
||||||
"9t ^T Sort toggles%-12cs Manage session\n"
|
"9t ^T Sort toggles%-12cs Manage session\n"
|
||||||
|
"cT Set time type%-0c\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
fd = create_tmp_file();
|
fd = create_tmp_file();
|
||||||
|
@ -4491,7 +4503,9 @@ static int dentfill(char *path, struct entry **dents)
|
||||||
off += dentp->nlen;
|
off += dentp->nlen;
|
||||||
|
|
||||||
/* Copy other fields */
|
/* Copy other fields */
|
||||||
dentp->t = cfg.mtime ? sb.st_mtime : sb.st_atime;
|
dentp->t = ((cfg.timetype == T_MOD)
|
||||||
|
? sb.st_mtime
|
||||||
|
: ((cfg.timetype == T_ACCESS) ? sb.st_atime : sb.st_ctime));
|
||||||
#if !(defined(__sun) || defined(__HAIKU__))
|
#if !(defined(__sun) || defined(__HAIKU__))
|
||||||
if (!flags && dp->d_type == DT_LNK) {
|
if (!flags && dp->d_type == DT_LNK) {
|
||||||
/* Do not add sizes for links */
|
/* Do not add sizes for links */
|
||||||
|
@ -4746,7 +4760,7 @@ static bool set_sort_flags(int r)
|
||||||
cfg.showdetail = 1;
|
cfg.showdetail = 1;
|
||||||
printptr = &printent_long;
|
printptr = &printent_long;
|
||||||
}
|
}
|
||||||
cfg.mtimeorder = 0;
|
cfg.timeorder = 0;
|
||||||
cfg.sizeorder = 0;
|
cfg.sizeorder = 0;
|
||||||
cfg.extnorder = 0;
|
cfg.extnorder = 0;
|
||||||
entrycmpfn = &entrycmp;
|
entrycmpfn = &entrycmp;
|
||||||
|
@ -4754,7 +4768,7 @@ static bool set_sort_flags(int r)
|
||||||
endselection(); /* We are going to reload dir */
|
endselection(); /* We are going to reload dir */
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
cfg.mtimeorder = 0;
|
cfg.timeorder = 0;
|
||||||
cfg.sizeorder = 0;
|
cfg.sizeorder = 0;
|
||||||
cfg.apparentsz = 0;
|
cfg.apparentsz = 0;
|
||||||
cfg.blkorder = 0;
|
cfg.blkorder = 0;
|
||||||
|
@ -4765,7 +4779,7 @@ static bool set_sort_flags(int r)
|
||||||
case 'e': /* File extension */
|
case 'e': /* File extension */
|
||||||
cfg.extnorder ^= 1;
|
cfg.extnorder ^= 1;
|
||||||
cfg.sizeorder = 0;
|
cfg.sizeorder = 0;
|
||||||
cfg.mtimeorder = 0;
|
cfg.timeorder = 0;
|
||||||
cfg.apparentsz = 0;
|
cfg.apparentsz = 0;
|
||||||
cfg.blkorder = 0;
|
cfg.blkorder = 0;
|
||||||
entrycmpfn = &entrycmp;
|
entrycmpfn = &entrycmp;
|
||||||
|
@ -4775,14 +4789,14 @@ static bool set_sort_flags(int r)
|
||||||
break;
|
break;
|
||||||
case 's': /* File size */
|
case 's': /* File size */
|
||||||
cfg.sizeorder ^= 1;
|
cfg.sizeorder ^= 1;
|
||||||
cfg.mtimeorder = 0;
|
cfg.timeorder = 0;
|
||||||
cfg.apparentsz = 0;
|
cfg.apparentsz = 0;
|
||||||
cfg.blkorder = 0;
|
cfg.blkorder = 0;
|
||||||
cfg.extnorder = 0;
|
cfg.extnorder = 0;
|
||||||
entrycmpfn = &entrycmp;
|
entrycmpfn = &entrycmp;
|
||||||
break;
|
break;
|
||||||
case 't': /* Modification or access time */
|
case 't': /* Time */
|
||||||
cfg.mtimeorder ^= 1;
|
cfg.timeorder ^= 1;
|
||||||
cfg.sizeorder = 0;
|
cfg.sizeorder = 0;
|
||||||
cfg.apparentsz = 0;
|
cfg.apparentsz = 0;
|
||||||
cfg.blkorder = 0;
|
cfg.blkorder = 0;
|
||||||
|
@ -4799,6 +4813,47 @@ static bool set_sort_flags(int r)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool set_time_type(int *presel)
|
||||||
|
{
|
||||||
|
char buf[24];
|
||||||
|
bool first = TRUE;
|
||||||
|
int r = 0;
|
||||||
|
size_t chars = 0;
|
||||||
|
|
||||||
|
for (; r < (int)ELEMENTS(time_type); ++r)
|
||||||
|
if (r != cfg.timetype) {
|
||||||
|
chars += xstrlcpy(buf + chars, time_type[r], sizeof(buf) - chars) - 1;
|
||||||
|
if (first) {
|
||||||
|
buf[chars++] = ' ';
|
||||||
|
buf[chars++] = '/';
|
||||||
|
buf[chars++] = ' ';
|
||||||
|
first = FALSE;
|
||||||
|
} else {
|
||||||
|
buf[chars++] = '?';
|
||||||
|
buf[chars] = '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = get_input(buf);
|
||||||
|
if (r == 'a' || r == 'c' || r == 'm') {
|
||||||
|
r = (r == 'm') ? T_MOD : ((r == 'a') ? T_ACCESS : T_CHANGE);
|
||||||
|
if (cfg.timetype == r) {
|
||||||
|
printwait(messages[MSG_NOCHNAGE], presel);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.timetype = r;
|
||||||
|
|
||||||
|
if (cfg.filtermode || g_ctx[cfg.curctx].c_fltr[1])
|
||||||
|
*presel = FILTER;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printwait(messages[MSG_INVALID_KEY], presel);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void statusbar(char *path)
|
static void statusbar(char *path)
|
||||||
{
|
{
|
||||||
int i = 0, extnlen = 0;
|
int i = 0, extnlen = 0;
|
||||||
|
@ -5596,8 +5651,6 @@ nochange:
|
||||||
continue;
|
continue;
|
||||||
default: /* SEL_SORT */
|
default: /* SEL_SORT */
|
||||||
if (!set_sort_flags(get_input(messages[MSG_ORDER]))) {
|
if (!set_sort_flags(get_input(messages[MSG_ORDER]))) {
|
||||||
if (cfg.filtermode)
|
|
||||||
presel = FILTER;
|
|
||||||
printwait(messages[MSG_INVALID_KEY], &presel);
|
printwait(messages[MSG_INVALID_KEY], &presel);
|
||||||
goto nochange;
|
goto nochange;
|
||||||
}
|
}
|
||||||
|
@ -6261,6 +6314,11 @@ nochange:
|
||||||
export_file_list();
|
export_file_list();
|
||||||
cfg.filtermode ? presel = FILTER : statusbar(path);
|
cfg.filtermode ? presel = FILTER : statusbar(path);
|
||||||
goto nochange;
|
goto nochange;
|
||||||
|
case SEL_TIMETYPE:
|
||||||
|
if (!set_time_type(&presel))
|
||||||
|
goto nochange;
|
||||||
|
|
||||||
|
goto begin;
|
||||||
default:
|
default:
|
||||||
if (xlines != LINES || xcols != COLS)
|
if (xlines != LINES || xcols != COLS)
|
||||||
setdirwatch(); /* Terminal resized */
|
setdirwatch(); /* Terminal resized */
|
||||||
|
@ -6511,7 +6569,6 @@ static void usage(void)
|
||||||
"positional args:\n"
|
"positional args:\n"
|
||||||
" PATH start dir [default: .]\n\n"
|
" PATH start dir [default: .]\n\n"
|
||||||
"optional args:\n"
|
"optional args:\n"
|
||||||
" -a use access time\n"
|
|
||||||
" -A no dir auto-select\n"
|
" -A no dir auto-select\n"
|
||||||
" -b key open bookmark key\n"
|
" -b key open bookmark key\n"
|
||||||
" -c cli-only opener (overrides -e)\n"
|
" -c cli-only opener (overrides -e)\n"
|
||||||
|
@ -6685,11 +6742,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
while ((opt = (env_opts_id > 0
|
while ((opt = (env_opts_id > 0
|
||||||
? env_opts[--env_opts_id]
|
? env_opts[--env_opts_id]
|
||||||
: getopt(argc, argv, "aAb:cdeEfgHKnop:QrRs:St:T:Vxh"))) != -1) {
|
: getopt(argc, argv, "Ab:cdeEfgHKnop:QrRs:St:T:Vxh"))) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'a':
|
|
||||||
cfg.mtime = 0;
|
|
||||||
break;
|
|
||||||
case 'A':
|
case 'A':
|
||||||
cfg.autoselect = 0;
|
cfg.autoselect = 0;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -97,6 +97,7 @@ enum action {
|
||||||
SEL_QUIT,
|
SEL_QUIT,
|
||||||
SEL_QUITFAIL,
|
SEL_QUITFAIL,
|
||||||
SEL_EXPORT,
|
SEL_EXPORT,
|
||||||
|
SEL_TIMETYPE,
|
||||||
#ifndef NOMOUSE
|
#ifndef NOMOUSE
|
||||||
SEL_CLICK,
|
SEL_CLICK,
|
||||||
#endif
|
#endif
|
||||||
|
@ -249,6 +250,7 @@ static struct key bindings[] = {
|
||||||
/* Quit with an error code */
|
/* Quit with an error code */
|
||||||
{ 'Q', SEL_QUITFAIL },
|
{ 'Q', SEL_QUITFAIL },
|
||||||
{ '>', SEL_EXPORT },
|
{ '>', SEL_EXPORT },
|
||||||
|
{ 'T', SEL_TIMETYPE },
|
||||||
#ifndef NOMOUSE
|
#ifndef NOMOUSE
|
||||||
{ KEY_MOUSE, SEL_CLICK },
|
{ KEY_MOUSE, SEL_CLICK },
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue