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:
Arun Prakash Jana 2017-03-30 01:51:52 +05:30
parent c64327b4a6
commit 4bf17cb7bc
No known key found for this signature in database
GPG key ID: A75979F35C080412
3 changed files with 79 additions and 10 deletions

View file

@ -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` |

View file

@ -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
View file

@ -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 {