Przeglądaj źródła

Search filter support with a very basic readline

master
lostd 10 lat temu
rodzic
commit
b0df3806de
1 zmienionych plików z 114 dodań i 2 usunięć
  1. +114
    -2
      noice.c

+ 114
- 2
noice.c Wyświetl plik

@@ -79,6 +79,10 @@ struct entry {

int die = 0;

void printmsg(char *msg);
void printwarn(void);
void printerr(int ret, char *prefix);

char *
openwith(char *file)
{
@@ -100,6 +104,31 @@ openwith(char *file)
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
entrycmp(const void *va, const void *vb)
{
@@ -159,6 +188,7 @@ printerr(int ret, char *prefix)
* Returns 1 on quit
* Returns 2 on go in
* Returns 3 on go up
* Returns 4 on search
*/
int
nextsel(int *cur, int max)
@@ -180,6 +210,10 @@ nextsel(int *cur, int max)
case KEY_RIGHT:
case 'l':
return 3;
/* search */
case '/':
case '&':
return 4;
/* next */
case 'j':
case KEY_DOWN:
@@ -199,6 +233,52 @@ nextsel(int *cur, int max)
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
testopendir(char *path)
{
@@ -246,7 +326,7 @@ printent(struct entry *ent, int active)
}

void
browse(const char *ipath)
browse(const char *ipath, const char *ifilter)
{
DIR *dirp;
int dfd;
@@ -255,6 +335,8 @@ browse(const char *ipath)
int i, n, cur;
int r, ret;
char *path = strdup(ipath);
char *filter = strdup(ifilter);
regex_t filter_re;
char *cwd;
struct stat sb;

@@ -270,6 +352,11 @@ begin:
goto nochange;
}

/* Search filter */
r = setfilter(&filter_re, filter);
if (r != 0)
goto nochange;

while ((dp = readdir(dirp)) != NULL) {
char *name;

@@ -277,6 +364,8 @@ begin:
if (strcmp(dp->d_name, ".") == 0
|| strcmp(dp->d_name, "..") == 0)
continue;
if (!visible(&filter_re, dp->d_name))
continue;
/* Deep copy because readdir(3) reuses the entries */
dents = realloc(dents, (n + 1) * sizeof(*dents));
if (dents == NULL)
@@ -432,6 +521,28 @@ nochange:
free(pathnew);
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:
@@ -450,6 +561,7 @@ int
main(int argc, char *argv[])
{
char *ipath = argv[1] != NULL ? argv[1] : "/";
char *ifilter = "^[^.].*"; /* Hide dotfiles */

/* Test initial path */
if (!testopendir(ipath))
@@ -460,7 +572,7 @@ main(int argc, char *argv[])

initcurses();

browse(ipath);
browse(ipath, ifilter);

exitcurses();



Ładowanie…
Anuluj
Zapisz