|
@@ -79,6 +79,10 @@ struct entry { |
|
|
|
|
|
|
|
|
int die = 0; |
|
|
int die = 0; |
|
|
|
|
|
|
|
|
|
|
|
void printmsg(char *msg); |
|
|
|
|
|
void printwarn(void); |
|
|
|
|
|
void printerr(int ret, char *prefix); |
|
|
|
|
|
|
|
|
char * |
|
|
char * |
|
|
openwith(char *file) |
|
|
openwith(char *file) |
|
|
{ |
|
|
{ |
|
@@ -100,6 +104,31 @@ openwith(char *file) |
|
|
return bin; |
|
|
return bin; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
|
setfilter(regex_t *regex, char *filter) |
|
|
|
|
|
{ |
|
|
|
|
|
char *errbuf; |
|
|
|
|
|
int r; |
|
|
|
|
|
|
|
|
|
|
|
r = regcomp(regex, filter, REG_NOSUB | REG_EXTENDED); |
|
|
|
|
|
if (r != 0) { |
|
|
|
|
|
errbuf = malloc(COLS * sizeof(char)); |
|
|
|
|
|
regerror(r, regex, errbuf, COLS * sizeof(char)); |
|
|
|
|
|
printmsg(errbuf); |
|
|
|
|
|
free(errbuf); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return r; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
|
visible(regex_t *regex, char *file) |
|
|
|
|
|
{ |
|
|
|
|
|
if (regexec(regex, file, 0, NULL, 0) != REG_NOMATCH) |
|
|
|
|
|
return 1; |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int |
|
|
int |
|
|
entrycmp(const void *va, const void *vb) |
|
|
entrycmp(const void *va, const void *vb) |
|
|
{ |
|
|
{ |
|
@@ -159,6 +188,7 @@ printerr(int ret, char *prefix) |
|
|
* Returns 1 on quit |
|
|
* Returns 1 on quit |
|
|
* Returns 2 on go in |
|
|
* Returns 2 on go in |
|
|
* Returns 3 on go up |
|
|
* Returns 3 on go up |
|
|
|
|
|
* Returns 4 on search |
|
|
*/ |
|
|
*/ |
|
|
int |
|
|
int |
|
|
nextsel(int *cur, int max) |
|
|
nextsel(int *cur, int max) |
|
@@ -180,6 +210,10 @@ nextsel(int *cur, int max) |
|
|
case KEY_RIGHT: |
|
|
case KEY_RIGHT: |
|
|
case 'l': |
|
|
case 'l': |
|
|
return 3; |
|
|
return 3; |
|
|
|
|
|
/* search */ |
|
|
|
|
|
case '/': |
|
|
|
|
|
case '&': |
|
|
|
|
|
return 4; |
|
|
/* next */ |
|
|
/* next */ |
|
|
case 'j': |
|
|
case 'j': |
|
|
case KEY_DOWN: |
|
|
case KEY_DOWN: |
|
@@ -199,6 +233,52 @@ nextsel(int *cur, int max) |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
char * |
|
|
|
|
|
readln(void) |
|
|
|
|
|
{ |
|
|
|
|
|
int c; |
|
|
|
|
|
int i = 0; |
|
|
|
|
|
char *ln = NULL; |
|
|
|
|
|
int y, x, x0; |
|
|
|
|
|
|
|
|
|
|
|
echo(); |
|
|
|
|
|
curs_set(TRUE); |
|
|
|
|
|
|
|
|
|
|
|
/* Starting point */ |
|
|
|
|
|
getyx(stdscr, y, x); |
|
|
|
|
|
x0 = x; |
|
|
|
|
|
|
|
|
|
|
|
while (c = getch()) { |
|
|
|
|
|
if (c == KEY_ENTER || c == '\r') |
|
|
|
|
|
break; |
|
|
|
|
|
if (c == KEY_BACKSPACE) { |
|
|
|
|
|
getyx(stdscr, y, x); |
|
|
|
|
|
if (x >= x0) { |
|
|
|
|
|
ln = realloc(ln, (i - 1) * sizeof(*ln)); |
|
|
|
|
|
i--; |
|
|
|
|
|
move(y, x); |
|
|
|
|
|
printw("%c", ' '); |
|
|
|
|
|
move(y, x); |
|
|
|
|
|
} else { |
|
|
|
|
|
move(y, x0); |
|
|
|
|
|
} |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
ln = realloc(ln, (i + 1) * sizeof(*ln)); |
|
|
|
|
|
ln[i] = c; |
|
|
|
|
|
i++; |
|
|
|
|
|
} |
|
|
|
|
|
if (ln != NULL) { |
|
|
|
|
|
ln = realloc(ln, (i + 1) * sizeof(*ln)); |
|
|
|
|
|
ln[i] = '\0'; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
curs_set(FALSE); |
|
|
|
|
|
noecho(); |
|
|
|
|
|
|
|
|
|
|
|
return ln; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int |
|
|
int |
|
|
testopendir(char *path) |
|
|
testopendir(char *path) |
|
|
{ |
|
|
{ |
|
@@ -246,7 +326,7 @@ printent(struct entry *ent, int active) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
browse(const char *ipath) |
|
|
|
|
|
|
|
|
browse(const char *ipath, const char *ifilter) |
|
|
{ |
|
|
{ |
|
|
DIR *dirp; |
|
|
DIR *dirp; |
|
|
int dfd; |
|
|
int dfd; |
|
@@ -255,6 +335,8 @@ browse(const char *ipath) |
|
|
int i, n, cur; |
|
|
int i, n, cur; |
|
|
int r, ret; |
|
|
int r, ret; |
|
|
char *path = strdup(ipath); |
|
|
char *path = strdup(ipath); |
|
|
|
|
|
char *filter = strdup(ifilter); |
|
|
|
|
|
regex_t filter_re; |
|
|
char *cwd; |
|
|
char *cwd; |
|
|
struct stat sb; |
|
|
struct stat sb; |
|
|
|
|
|
|
|
@@ -270,6 +352,11 @@ begin: |
|
|
goto nochange; |
|
|
goto nochange; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Search filter */ |
|
|
|
|
|
r = setfilter(&filter_re, filter); |
|
|
|
|
|
if (r != 0) |
|
|
|
|
|
goto nochange; |
|
|
|
|
|
|
|
|
while ((dp = readdir(dirp)) != NULL) { |
|
|
while ((dp = readdir(dirp)) != NULL) { |
|
|
char *name; |
|
|
char *name; |
|
|
|
|
|
|
|
@@ -277,6 +364,8 @@ begin: |
|
|
if (strcmp(dp->d_name, ".") == 0 |
|
|
if (strcmp(dp->d_name, ".") == 0 |
|
|
|| strcmp(dp->d_name, "..") == 0) |
|
|
|| strcmp(dp->d_name, "..") == 0) |
|
|
continue; |
|
|
continue; |
|
|
|
|
|
if (!visible(&filter_re, dp->d_name)) |
|
|
|
|
|
continue; |
|
|
/* Deep copy because readdir(3) reuses the entries */ |
|
|
/* Deep copy because readdir(3) reuses the entries */ |
|
|
dents = realloc(dents, (n + 1) * sizeof(*dents)); |
|
|
dents = realloc(dents, (n + 1) * sizeof(*dents)); |
|
|
if (dents == NULL) |
|
|
if (dents == NULL) |
|
@@ -432,6 +521,28 @@ nochange: |
|
|
free(pathnew); |
|
|
free(pathnew); |
|
|
goto nochange; |
|
|
goto nochange; |
|
|
} |
|
|
} |
|
|
|
|
|
if (ret == 4) { |
|
|
|
|
|
char *tmp; |
|
|
|
|
|
regex_t re; |
|
|
|
|
|
|
|
|
|
|
|
/* Read filter */ |
|
|
|
|
|
move(LINES - 1, 0); |
|
|
|
|
|
printw("filter: "); |
|
|
|
|
|
tmp = readln(); |
|
|
|
|
|
if (tmp == NULL) { |
|
|
|
|
|
printmsg(""); |
|
|
|
|
|
goto nochange; |
|
|
|
|
|
} |
|
|
|
|
|
r = setfilter(&re, tmp); |
|
|
|
|
|
if (r != 0) { |
|
|
|
|
|
printmsg(""); |
|
|
|
|
|
goto nochange; |
|
|
|
|
|
} |
|
|
|
|
|
filter = tmp; |
|
|
|
|
|
filter_re = re; |
|
|
|
|
|
DPRINTF_S(filter); |
|
|
|
|
|
goto out; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
out: |
|
|
out: |
|
@@ -450,6 +561,7 @@ int |
|
|
main(int argc, char *argv[]) |
|
|
main(int argc, char *argv[]) |
|
|
{ |
|
|
{ |
|
|
char *ipath = argv[1] != NULL ? argv[1] : "/"; |
|
|
char *ipath = argv[1] != NULL ? argv[1] : "/"; |
|
|
|
|
|
char *ifilter = "^[^.].*"; /* Hide dotfiles */ |
|
|
|
|
|
|
|
|
/* Test initial path */ |
|
|
/* Test initial path */ |
|
|
if (!testopendir(ipath)) |
|
|
if (!testopendir(ipath)) |
|
@@ -460,7 +572,7 @@ main(int argc, char *argv[]) |
|
|
|
|
|
|
|
|
initcurses(); |
|
|
initcurses(); |
|
|
|
|
|
|
|
|
browse(ipath); |
|
|
|
|
|
|
|
|
browse(ipath, ifilter); |
|
|
|
|
|
|
|
|
exitcurses(); |
|
|
exitcurses(); |
|
|
|
|
|
|
|
|