commit - 6beff8a2df63745c1902d2551b8233e603ca317b
commit + 576e768d01f0c9890f5ed9b173e847077ef893f6
blob - 8da95c460b0cb0f5ca1ea8fb6c015e029a5fb445
blob + e9ef826817daec60652ab62275918d7193f92f9a
--- rover.c
+++ rover.c
#include "config.h"
+#define ROWSZ 256
+char ROW[ROWSZ];
#define STATUSSZ 256
char STATUS[STATUSSZ];
#define SEARCHSZ 256
#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)
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, ".."))
(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;
}
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);
static void
cd()
{
- int i;
-
rover.fsel = 0;
rover.scroll = 0;
(void) chdir(rover.cwd);
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
}
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)) {
) {
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);
}
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();
}
}
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;
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;
}