From 84e124bb465889c957c4501679cdd38670b26d64 Mon Sep 17 00:00:00 2001 From: lostd Date: Tue, 27 Jan 2015 10:47:57 +0200 Subject: [PATCH] Basic filter-as-you-type mode --- config.def.h | 2 ++ noice.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/config.def.h b/config.def.h index 150968e5..4c7ade3e 100644 --- a/config.def.h +++ b/config.def.h @@ -26,6 +26,8 @@ struct key bindings[] = { /* Filter */ { '/', SEL_FLTR }, { '&', SEL_FLTR }, + /* Type */ + { '?', SEL_TYPE }, /* Next */ { 'j', SEL_NEXT }, { KEY_DOWN, SEL_NEXT }, diff --git a/noice.c b/noice.c index 784ccb95..e841efa9 100644 --- a/noice.c +++ b/noice.c @@ -49,6 +49,7 @@ enum action { SEL_BACK, SEL_GOIN, SEL_FLTR, + SEL_TYPE, SEL_NEXT, SEL_PREV, SEL_PGDN, @@ -359,6 +360,55 @@ readln(void) return ln; } +/* + * Read one key and modify the provided string accordingly. + * Returns 0 when more input is expected and 1 on completion. + */ +int +readmore(char **str) +{ + int c; + int i; + char *ln = *str; + int ret = 0; + + if (ln != NULL) + i = strlen(ln); + else + i = 0; + + DPRINTF_D(i); + + curs_set(TRUE); + + c = getch(); + if (c == KEY_ENTER || c == '\r') { + ret = 1; + goto out; + } + if (c == KEY_BACKSPACE) { + i--; + if (i > 0) { + ln = xrealloc(ln, (i + 1) * sizeof(*ln)); + ln[i] = '\0'; + } else { + free(ln); + ln = NULL; + } + goto out; + } + ln = xrealloc(ln, (i + 2) * sizeof(*ln)); + ln[i] = c; + i++; + ln[i] = '\0'; +out: + curs_set(FALSE); + + *str = ln; + + return ret; +} + int canopendir(char *path) { @@ -518,6 +568,7 @@ browse(const char *ipath, const char *ifilter) char *cwd, *newpath, *oldpath = NULL; struct stat sb; char *name, *bin, *dir, *tmp; + int nowtyping = 0; begin: /* Path and filter should be malloc(3)-ed strings at all times */ @@ -580,6 +631,10 @@ begin: printent(&dents[i], i == cur); } + /* Handle filter-as-you-type mode */ + if (nowtyping) + goto moretyping; + nochange: switch (nextsel()) { case SEL_QUIT: @@ -679,6 +734,35 @@ nochange: if (n > 0) oldpath = makepath(path, dents[cur].name); goto out; + case SEL_TYPE: + nowtyping = 1; + tmp = NULL; +moretyping: + printprompt("type: "); + if (tmp != NULL) + printw("%s", tmp); + r = readmore(&tmp); + DPRINTF_D(r); + DPRINTF_S(tmp); + if (r == 1) + nowtyping = 0; + /* Check regex errors */ + if (tmp != NULL) + r = setfilter(&re, tmp); + if (r != 0 && nowtyping) + goto moretyping; + /* Copy or reset filter */ + free(filter); + if (tmp != NULL) + filter = xstrdup(tmp); + else + filter = xstrdup(ifilter); + /* Save current */ + if (n > 0) + oldpath = makepath(path, dents[cur].name); + if (!nowtyping) + free(tmp); + goto out; case SEL_NEXT: if (cur < n - 1) cur++;