From 4bf17cb7bc64d6adb2fa09b48b294cc736c22fdd Mon Sep 17 00:00:00 2001 From: Arun Prakash Jana Date: Thu, 30 Mar 2017 01:51:52 +0530 Subject: [PATCH] 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. --- README.md | 10 ++++--- config.def.h | 6 +++++ noice.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9df00db3..fe82d1c9 100644 --- a/README.md +++ b/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` | diff --git a/config.def.h b/config.def.h index bffc69d5..9c6ae7e8 100644 --- a/config.def.h +++ b/config.def.h @@ -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 }, diff --git a/noice.c b/noice.c index 25f2f951..a3e7617c 100644 --- a/noice.c +++ b/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 {