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 - Jump to home directory
- Filter contents in current directory - Filter contents in current directory
- Show/hide hidden files - Show/hide hidden files
- Sort entries by time modified - Sort entries by time modified (newest to oldest)
- Spawn a shell in current directory - Spawn a shell in current directory
- Run `top` - Run `top`
- Open a file with `vim` or `less` - Open a file with `vim` or `less`
@ -43,8 +43,10 @@ I chose to fork noice because:
### Fork toppings ### Fork toppings
- Behaviour and navigation - Behaviour and navigation
- Case-insensitive alphabetic content listing instead of upper case first. - Optional detailed view with file type and size (default: disabled)
- Roll over at the first and last entries of a directory (with Up/Down keys). - 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 - File associations
- Environment variable `NOICE_OPENER` to override all associations and open all files with your desktop environments default file opener. Examples: - 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 | | `~` | jump to home dir |
| `/`, `&` | filter dir contents | | `/`, `&` | filter dir contents |
| `c` | show change dir prompt | | `c` | show change dir prompt |
| 'd' | toggle detail view |
| `.` | toggle hide dot files | | `.` | toggle hide dot files |
| `s` | toggle sort by file size |
| `t` | toggle sort by modified time | | `t` | toggle sort by modified time |
| `!` | spawn a shell in current dir | | `!` | spawn a shell in current dir |
| `e` | edit entry in `vim` | | `e` | edit entry in `vim` |

View file

@ -4,8 +4,10 @@
#define EMPTY " " #define EMPTY " "
int mtimeorder = 0; /* Set to 1 to sort by time modified */ 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 idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */
int showhidden = 0; /* Set to 1 to show hidden files by default */ 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 */ char *idlecmd = "rain"; /* The screensaver program */
struct assoc assocs[] = { struct assoc assocs[] = {
@ -62,6 +64,10 @@ struct key bindings[] = {
{ '~', SEL_CDHOME }, { '~', SEL_CDHOME },
/* Toggle hide .dot files */ /* Toggle hide .dot files */
{ '.', SEL_TOGGLEDOT }, { '.', SEL_TOGGLEDOT },
/* Detailed listing */
{ 'd', SEL_DETAIL },
/* Toggle sort by size */
{ 's', SEL_FSIZE },
/* Toggle sort by time */ /* Toggle sort by time */
{ 't', SEL_MTIME }, { 't', SEL_MTIME },
{ CONTROL('L'), SEL_REDRAW }, { CONTROL('L'), SEL_REDRAW },

73
noice.c
View file

@ -62,6 +62,8 @@ enum action {
SEL_CD, SEL_CD,
SEL_CDHOME, SEL_CDHOME,
SEL_TOGGLEDOT, SEL_TOGGLEDOT,
SEL_DETAIL,
SEL_FSIZE,
SEL_MTIME, SEL_MTIME,
SEL_REDRAW, SEL_REDRAW,
SEL_RUN, SEL_RUN,
@ -81,6 +83,7 @@ struct entry {
char name[PATH_MAX]; char name[PATH_MAX];
mode_t mode; mode_t mode;
time_t t; time_t t;
off_t size;
}; };
/* Global context */ /* Global context */
@ -89,6 +92,8 @@ int ndents, cur;
int idle; int idle;
char *opener = NULL; char *opener = NULL;
char *fallback_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: * Layout:
@ -107,6 +112,7 @@ char *fallback_opener = NULL;
* '------ * '------
*/ */
void (*printptr)(struct entry *ent, int active);
void printmsg(char *); void printmsg(char *);
void printwarn(void); void printwarn(void);
void printerr(int, char *); void printerr(int, char *);
@ -271,11 +277,13 @@ visible(regex_t *regex, char *file)
int int
entrycmp(const void *va, const void *vb) entrycmp(const void *va, const void *vb)
{ {
const struct entry *a = va, *b = vb;
if (mtimeorder) if (mtimeorder)
return b->t - a->t; return ((struct entry *)vb)->t - ((struct entry *)va)->t;
return xstricmp(a->name, b->name);
if (sizeorder)
return ((struct entry *)vb)->size - ((struct entry *)va)->size;
return xstricmp(((struct entry *)va)->name, ((struct entry *)vb)->name);
} }
void void
@ -446,6 +454,42 @@ printent(struct entry *ent, int active)
printw("%s%s%c\n", active ? CURSR : EMPTY, name, cm); 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 int
dentfill(char *path, struct entry **dents, dentfill(char *path, struct entry **dents,
int (*filter)(regex_t *, char *), regex_t *re) int (*filter)(regex_t *, char *), regex_t *re)
@ -476,6 +520,7 @@ dentfill(char *path, struct entry **dents,
printerr(1, "lstat"); printerr(1, "lstat");
(*dents)[n].mode = sb.st_mode; (*dents)[n].mode = sb.st_mode;
(*dents)[n].t = sb.st_mtime; (*dents)[n].t = sb.st_mtime;
(*dents)[n].size = sb.st_size;
n++; n++;
} }
@ -580,14 +625,14 @@ redraw(char *path)
odd = ISODD(nlines); odd = ISODD(nlines);
if (cur < (nlines >> 1)) { if (cur < (nlines >> 1)) {
for (i = 0; i < nlines; i++) for (i = 0; i < nlines; i++)
printent(&dents[i], i == cur); printptr(&dents[i], i == cur);
} else if (cur >= ndents - (nlines >> 1)) { } else if (cur >= ndents - (nlines >> 1)) {
for (i = ndents - nlines; i < ndents; i++) for (i = ndents - nlines; i < ndents; i++)
printent(&dents[i], i == cur); printptr(&dents[i], i == cur);
} else { } else {
nlines >>= 1; nlines >>= 1;
for (i = cur - nlines; i < cur + nlines + odd; i++) 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); initfilter(showhidden, &ifilter);
strlcpy(fltr, ifilter, sizeof(fltr)); strlcpy(fltr, ifilter, sizeof(fltr));
goto begin; 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: case SEL_MTIME:
mtimeorder = !mtimeorder; mtimeorder = !mtimeorder;
sizeorder = 0;
/* Save current */ /* Save current */
if (ndents > 0) if (ndents > 0)
mkpath(path, dents[cur].name, oldpath, sizeof(oldpath)); mkpath(path, dents[cur].name, oldpath, sizeof(oldpath));
@ -864,6 +921,8 @@ main(int argc, char *argv[])
showhidden = 1; showhidden = 1;
initfilter(showhidden, &ifilter); initfilter(showhidden, &ifilter);
printptr = &printent;
if (argv[1] != NULL) { if (argv[1] != NULL) {
ipath = argv[1]; ipath = argv[1];
} else { } else {