mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 05:41:31 +00:00
Switches to toggle detail view, file size sort
1. The detailed view shows file type and size using keybind 'd'. Disabled by default. 2. Option 's' sorts dir entries by descending order of size.
This commit is contained in:
parent
c64327b4a6
commit
4bf17cb7bc
10
README.md
10
README.md
|
@ -35,7 +35,7 @@ I chose to fork noice because:
|
|||
- Jump to home directory
|
||||
- Filter contents in current directory
|
||||
- Show/hide hidden files
|
||||
- Sort entries by time modified
|
||||
- Sort entries by time modified (newest to oldest)
|
||||
- Spawn a shell in current directory
|
||||
- Run `top`
|
||||
- Open a file with `vim` or `less`
|
||||
|
@ -43,8 +43,10 @@ I chose to fork noice because:
|
|||
### Fork toppings
|
||||
|
||||
- Behaviour and navigation
|
||||
- Case-insensitive alphabetic content listing instead of upper case first.
|
||||
- Roll over at the first and last entries of a directory (with Up/Down keys).
|
||||
- Optional detailed view with file type and size (default: disabled)
|
||||
- Case-insensitive alphabetic content listing instead of upper case first
|
||||
- Roll over at the first and last entries of a directory (with Up/Down keys)
|
||||
- Sort entries by file size (largest to smallest)
|
||||
- File associations
|
||||
- Environment variable `NOICE_OPENER` to override all associations and open all files with your desktop environments default file opener. Examples:
|
||||
|
||||
|
@ -95,7 +97,9 @@ Start noice (default: current directory):
|
|||
| `~` | jump to home dir |
|
||||
| `/`, `&` | filter dir contents |
|
||||
| `c` | show change dir prompt |
|
||||
| 'd' | toggle detail view |
|
||||
| `.` | toggle hide dot files |
|
||||
| `s` | toggle sort by file size |
|
||||
| `t` | toggle sort by modified time |
|
||||
| `!` | spawn a shell in current dir |
|
||||
| `e` | edit entry in `vim` |
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
#define EMPTY " "
|
||||
|
||||
int mtimeorder = 0; /* Set to 1 to sort by time modified */
|
||||
int sizeorder = 0; /* Set to 1 to sort by file size */
|
||||
int idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */
|
||||
int showhidden = 0; /* Set to 1 to show hidden files by default */
|
||||
int showdetail = 0; /* Set to show additional file info */
|
||||
char *idlecmd = "rain"; /* The screensaver program */
|
||||
|
||||
struct assoc assocs[] = {
|
||||
|
@ -62,6 +64,10 @@ struct key bindings[] = {
|
|||
{ '~', SEL_CDHOME },
|
||||
/* Toggle hide .dot files */
|
||||
{ '.', SEL_TOGGLEDOT },
|
||||
/* Detailed listing */
|
||||
{ 'd', SEL_DETAIL },
|
||||
/* Toggle sort by size */
|
||||
{ 's', SEL_FSIZE },
|
||||
/* Toggle sort by time */
|
||||
{ 't', SEL_MTIME },
|
||||
{ CONTROL('L'), SEL_REDRAW },
|
||||
|
|
73
noice.c
73
noice.c
|
@ -62,6 +62,8 @@ enum action {
|
|||
SEL_CD,
|
||||
SEL_CDHOME,
|
||||
SEL_TOGGLEDOT,
|
||||
SEL_DETAIL,
|
||||
SEL_FSIZE,
|
||||
SEL_MTIME,
|
||||
SEL_REDRAW,
|
||||
SEL_RUN,
|
||||
|
@ -81,6 +83,7 @@ struct entry {
|
|||
char name[PATH_MAX];
|
||||
mode_t mode;
|
||||
time_t t;
|
||||
off_t size;
|
||||
};
|
||||
|
||||
/* Global context */
|
||||
|
@ -89,6 +92,8 @@ int ndents, cur;
|
|||
int idle;
|
||||
char *opener = NULL;
|
||||
char *fallback_opener = NULL;
|
||||
char size_buf[12]; /* Buffer to hold human readable size */
|
||||
const char* size_units[] = {"B", "K", "M", "G", "T", "P", "E", "Z", "Y"};
|
||||
|
||||
/*
|
||||
* Layout:
|
||||
|
@ -107,6 +112,7 @@ char *fallback_opener = NULL;
|
|||
* '------
|
||||
*/
|
||||
|
||||
void (*printptr)(struct entry *ent, int active);
|
||||
void printmsg(char *);
|
||||
void printwarn(void);
|
||||
void printerr(int, char *);
|
||||
|
@ -271,11 +277,13 @@ visible(regex_t *regex, char *file)
|
|||
int
|
||||
entrycmp(const void *va, const void *vb)
|
||||
{
|
||||
const struct entry *a = va, *b = vb;
|
||||
|
||||
if (mtimeorder)
|
||||
return b->t - a->t;
|
||||
return xstricmp(a->name, b->name);
|
||||
return ((struct entry *)vb)->t - ((struct entry *)va)->t;
|
||||
|
||||
if (sizeorder)
|
||||
return ((struct entry *)vb)->size - ((struct entry *)va)->size;
|
||||
|
||||
return xstricmp(((struct entry *)va)->name, ((struct entry *)vb)->name);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -446,6 +454,42 @@ printent(struct entry *ent, int active)
|
|||
printw("%s%s%c\n", active ? CURSR : EMPTY, name, cm);
|
||||
}
|
||||
|
||||
char*
|
||||
coolsize(off_t size)
|
||||
{
|
||||
int i = 0;
|
||||
long double fsize = (double)size;
|
||||
|
||||
while (fsize > 1024) {
|
||||
fsize /= 1024;
|
||||
i++;
|
||||
}
|
||||
|
||||
snprintf(size_buf, 12, "%.*Lf%s", i, fsize, size_units[i]);
|
||||
return size_buf;
|
||||
}
|
||||
|
||||
void
|
||||
printent_long(struct entry *ent, int active)
|
||||
{
|
||||
if (S_ISDIR(ent->mode))
|
||||
printw("%s%-32.32s DIR\n", active ? CURSR : EMPTY, ent->name);
|
||||
else if (S_ISLNK(ent->mode))
|
||||
printw("%s%-32.32s SYM\n", active ? CURSR : EMPTY, ent->name);
|
||||
else if (S_ISSOCK(ent->mode))
|
||||
printw("%s%-32.32s SOCK\n", active ? CURSR : EMPTY, ent->name);
|
||||
else if (S_ISFIFO(ent->mode))
|
||||
printw("%s%-32.32s FIFO\n", active ? CURSR : EMPTY, ent->name);
|
||||
else if (S_ISBLK(ent->mode))
|
||||
printw("%s%-32.32s BLK\n", active ? CURSR : EMPTY, ent->name);
|
||||
else if (S_ISCHR(ent->mode))
|
||||
printw("%s%-32.32s CHR\n", active ? CURSR : EMPTY, ent->name);
|
||||
else if (ent->mode & S_IXUSR)
|
||||
printw("%s%-32.32s EXE %s\n", active ? CURSR : EMPTY, ent->name, coolsize(ent->size));
|
||||
else
|
||||
printw("%s%-32.32s REG %s\n", active ? CURSR : EMPTY, ent->name, coolsize(ent->size));
|
||||
}
|
||||
|
||||
int
|
||||
dentfill(char *path, struct entry **dents,
|
||||
int (*filter)(regex_t *, char *), regex_t *re)
|
||||
|
@ -476,6 +520,7 @@ dentfill(char *path, struct entry **dents,
|
|||
printerr(1, "lstat");
|
||||
(*dents)[n].mode = sb.st_mode;
|
||||
(*dents)[n].t = sb.st_mtime;
|
||||
(*dents)[n].size = sb.st_size;
|
||||
n++;
|
||||
}
|
||||
|
||||
|
@ -580,14 +625,14 @@ redraw(char *path)
|
|||
odd = ISODD(nlines);
|
||||
if (cur < (nlines >> 1)) {
|
||||
for (i = 0; i < nlines; i++)
|
||||
printent(&dents[i], i == cur);
|
||||
printptr(&dents[i], i == cur);
|
||||
} else if (cur >= ndents - (nlines >> 1)) {
|
||||
for (i = ndents - nlines; i < ndents; i++)
|
||||
printent(&dents[i], i == cur);
|
||||
printptr(&dents[i], i == cur);
|
||||
} else {
|
||||
nlines >>= 1;
|
||||
for (i = cur - nlines; i < cur + nlines + odd; i++)
|
||||
printent(&dents[i], i == cur);
|
||||
printptr(&dents[i], i == cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -803,8 +848,20 @@ nochange:
|
|||
initfilter(showhidden, &ifilter);
|
||||
strlcpy(fltr, ifilter, sizeof(fltr));
|
||||
goto begin;
|
||||
case SEL_DETAIL:
|
||||
showdetail = !showdetail;
|
||||
showdetail ? (printptr = &printent_long) : (printptr = &printent);
|
||||
goto begin;
|
||||
case SEL_FSIZE:
|
||||
sizeorder = !sizeorder;
|
||||
mtimeorder = 0;
|
||||
/* Save current */
|
||||
if (ndents > 0)
|
||||
mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));
|
||||
goto begin;
|
||||
case SEL_MTIME:
|
||||
mtimeorder = !mtimeorder;
|
||||
sizeorder = 0;
|
||||
/* Save current */
|
||||
if (ndents > 0)
|
||||
mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));
|
||||
|
@ -864,6 +921,8 @@ main(int argc, char *argv[])
|
|||
showhidden = 1;
|
||||
initfilter(showhidden, &ifilter);
|
||||
|
||||
printptr = &printent;
|
||||
|
||||
if (argv[1] != NULL) {
|
||||
ipath = argv[1];
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue