config.def.h | 2 ++ noice.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/config.def.h b/config.def.h index 150968e5858c089e963258fd07d8462486d3f51b..4c7ade3e59394be05c3a9b9a6fee6509a70550c2 100644 --- a/config.def.h +++ b/config.def.h @@ -26,6 +26,8 @@ { 'l', SEL_GOIN }, /* 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 784ccb959e5067b99b0046fb3fb63a7d273e129c..e841efa9504b42e46f032cb563e58a81aecc5640 100644 --- a/noice.c +++ b/noice.c @@ -49,6 +49,7 @@ SEL_QUIT = 1, SEL_BACK, SEL_GOIN, SEL_FLTR, + SEL_TYPE, SEL_NEXT, SEL_PREV, SEL_PGDN, @@ -359,6 +360,55 @@ 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 @@ regex_t filter_re, re; 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 @@ i < cur + nlines / 2 + odd; i++) printent(&dents[i], i == cur); } + /* Handle filter-as-you-type mode */ + if (nowtyping) + goto moretyping; + nochange: switch (nextsel()) { case SEL_QUIT: @@ -678,6 +733,35 @@ DPRINTF_S(filter); /* Save current */ 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)