commit 576e768d01f0c9890f5ed9b173e847077ef893f6 from: Marcel Rodrigues date: Sat Nov 08 14:59:42 2014 UTC Add file size listing. commit - 6beff8a2df63745c1902d2551b8233e603ca317b commit + 576e768d01f0c9890f5ed9b173e847077ef893f6 blob - 8da95c460b0cb0f5ca1ea8fb6c015e029a5fb445 blob + e9ef826817daec60652ab62275918d7193f92f9a --- rover.c +++ rover.c @@ -13,6 +13,8 @@ #include "config.h" +#define ROWSZ 256 +char ROW[ROWSZ]; #define STATUSSZ 256 char STATUS[STATUSSZ]; #define SEARCHSZ 256 @@ -28,36 +30,55 @@ typedef enum {DEFAULT, RED, GREEN, YELLOW, BLUE, CYAN, #define SHOW_DIRS 0x02u #define SHOW_HIDDEN 0x04u +typedef struct { + char *name; + off_t size; +} row_t; + struct rover_t { int nfiles; int scroll; int fsel; uint8_t flags; - char **fnames; + row_t *rows; WINDOW *window; char cwd[FILENAME_MAX]; } rover; +#define FNAME(I) rover.rows[I].name +#define FSIZE(I) rover.rows[I].size + static int -spcmp(const void *a, const void *b) +rowcmp(const void *a, const void *b) { int isdir1, isdir2, cmpdir; - const char *s1 = *(const char **) a; - const char *s2 = *(const char **) b; - isdir1 = strchr(s1, '/') != NULL; - isdir2 = strchr(s2, '/') != NULL; + const row_t *r1 = a; + const row_t *r2 = b; + isdir1 = strchr(r1->name, '/') != NULL; + isdir2 = strchr(r2->name, '/') != NULL; cmpdir = isdir2 - isdir1; /* FIXME: why doesn't `return cmpdir || strcoll(s1, s2)` work here? */ - return cmpdir ? cmpdir : strcoll(s1, s2); + return cmpdir ? cmpdir : strcoll(r1->name, r2->name); } +void +free_rows(row_t **rowsp, int nfiles) +{ + int i; + + for (i = 0; i < nfiles; i++) + free((*rowsp)[i].name); + free(*rowsp); + *rowsp = NULL; +} + int -ls(char *path, char ***namesp, uint8_t flags) +ls(char *path, row_t **rowsp, uint8_t flags) { DIR *dp; struct dirent *ep; struct stat statbuf; - char **names; + row_t *rows; int i, n; if((dp = opendir(path)) == NULL) @@ -65,7 +86,7 @@ ls(char *path, char ***namesp, uint8_t flags) n = -2; /* We don't want the entries "." and "..". */ while (readdir(dp)) n++; rewinddir(dp); - names = (char **) malloc(n * sizeof(char *)); + rows = (row_t *) malloc(n * sizeof(row_t)); i = 0; while ((ep = readdir(dp))) { if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) @@ -76,22 +97,23 @@ ls(char *path, char ***namesp, uint8_t flags) (void) stat(ep->d_name, &statbuf); if (S_ISDIR(statbuf.st_mode)) { if (flags & SHOW_DIRS) { - names[i] = (char *) malloc(strlen(ep->d_name) + 2); - strcpy(names[i], ep->d_name); - strcat(names[i], "/"); + rows[i].name = (char *) malloc(strlen(ep->d_name) + 2); + strcpy(rows[i].name, ep->d_name); + strcat(rows[i].name, "/"); i++; } } else if (flags & SHOW_FILES) { - names[i] = (char *) malloc(strlen(ep->d_name) + 1); - strcpy(names[i], ep->d_name); + rows[i].name = (char *) malloc(strlen(ep->d_name) + 1); + strcpy(rows[i].name, ep->d_name); + rows[i].size = statbuf.st_size; i++; } } n = i; /* Ignore unused space in array caused by filters. */ - qsort(names, n, sizeof(char *), spcmp); + qsort(rows, n, sizeof(row_t), rowcmp); (void) closedir(dp); - *namesp = names; + *rowsp = rows; return n; } @@ -129,19 +151,27 @@ static void update_browser() { int i, j, n; + int ishidden, isdir; char fmt[32]; for (i = 0, j = rover.scroll; i < HEIGHT && j < rover.nfiles; i++, j++) { + ishidden = FNAME(j)[0] == '.'; + isdir = strchr(FNAME(j), '/') != NULL; if (j == rover.fsel) wattr_on(rover.window, A_REVERSE, NULL); - if (rover.fnames[j][0] == '.') + if (ishidden) wcolor_set(rover.window, RVC_HIDDEN, NULL); - else if (strchr(rover.fnames[j], '/') != NULL) + else if (isdir) wcolor_set(rover.window, RVC_DIR, NULL); else wcolor_set(rover.window, RVC_FILE, NULL); + if (!isdir) + sprintf(ROW, "%s%*d", FNAME(j), + COLS - strlen(FNAME(j)) - 2, (int) FSIZE(j)); + else + strcpy(ROW, FNAME(j)); (void) mvwhline(rover.window, i + 1, 1, ' ', COLS - 2); - (void) mvwaddnstr(rover.window, i + 1, 1, rover.fnames[j], COLS - 2); + (void) mvwaddnstr(rover.window, i + 1, 1, ROW, COLS - 2); wcolor_set(rover.window, DEFAULT, NULL); if (j == rover.fsel) wattr_off(rover.window, A_REVERSE, NULL); @@ -167,8 +197,6 @@ update_browser() static void cd() { - int i; - rover.fsel = 0; rover.scroll = 0; (void) chdir(rover.cwd); @@ -176,17 +204,14 @@ cd() color_set(RVC_CWD, NULL); (void) mvaddnstr(0, 0, rover.cwd, COLS); color_set(DEFAULT, NULL); - for (i = 0; i < rover.nfiles; i++) - free(rover.fnames[i]); if (rover.nfiles) - free(rover.fnames); - rover.nfiles = ls(rover.cwd, &rover.fnames, rover.flags); + free_rows(&rover.rows, rover.nfiles); + rover.nfiles = ls(rover.cwd, &rover.rows, rover.flags); (void) wclear(rover.window); wcolor_set(rover.window, RVC_BORDER, NULL); wborder(rover.window, 0, 0, 0, 0, 0, 0, 0, 0); wcolor_set(rover.window, DEFAULT, NULL); update_browser(); - refresh(); } static void @@ -277,9 +302,9 @@ main() } else if (!strcmp(key, RVK_CD_DOWN)) { if (!rover.nfiles) continue; - if (strchr(rover.fnames[rover.fsel], '/') == NULL) + if (strchr(FNAME(rover.fsel), '/') == NULL) continue; - strcat(rover.cwd, rover.fnames[rover.fsel]); + strcat(rover.cwd, FNAME(rover.fsel)); cd(); } else if (!strcmp(key, RVK_CD_UP)) { @@ -296,7 +321,7 @@ main() ) { dirname[0] = first; dirname[strlen(dirname)] = '/'; - while (strcmp(rover.fnames[rover.fsel], dirname)) + while (strcmp(FNAME(rover.fsel), dirname)) rover.fsel++; if (rover.nfiles > HEIGHT) { rover.scroll = rover.fsel - (HEIGHT >> 1); @@ -325,24 +350,24 @@ main() } else if (!strcmp(key, RVK_VIEW)) { if (!rover.nfiles) continue; - if (strchr(rover.fnames[rover.fsel], '/') != NULL) + if (strchr(FNAME(rover.fsel), '/') != NULL) continue; program = getenv("PAGER"); if (program) { args[0] = program; - args[1] = rover.fnames[rover.fsel]; + args[1] = FNAME(rover.fsel); args[2] = NULL; spawn(); } } else if (!strcmp(key, RVK_EDIT)) { if (!rover.nfiles) continue; - if (strchr(rover.fnames[rover.fsel], '/') != NULL) + if (strchr(FNAME(rover.fsel), '/') != NULL) continue; program = getenv("EDITOR"); if (program) { args[0] = program; - args[1] = rover.fnames[rover.fsel]; + args[1] = FNAME(rover.fsel); args[2] = NULL; spawn(); } @@ -384,7 +409,7 @@ main() } if (length) { for (sel = 0; sel < rover.nfiles; sel++) - if (!strncmp(rover.fnames[sel], SEARCH, length)) + if (!strncmp(FNAME(sel), SEARCH, length)) break; if (sel < rover.nfiles) { color = GREEN; @@ -422,8 +447,9 @@ main() cd(); } } - while (rover.nfiles--) free(rover.fnames[rover.nfiles]); - free(rover.fnames); + if (rover.nfiles) { + free_rows(&rover.rows, rover.nfiles); + } delwin(rover.window); return 0; }