]> Sergey Matveev's repositories - nnn.git/commitdiff
Basic filter-as-you-type mode
authorlostd <lostd@2f30.org>
Tue, 27 Jan 2015 08:47:57 +0000 (10:47 +0200)
committerlostd <lostd@2f30.org>
Tue, 27 Jan 2015 08:47:57 +0000 (10:47 +0200)
config.def.h
noice.c

index 150968e5858c089e963258fd07d8462486d3f51b..4c7ade3e59394be05c3a9b9a6fee6509a70550c2 100644 (file)
@@ -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 784ccb959e5067b99b0046fb3fb63a7d273e129c..e841efa9504b42e46f032cb563e58a81aecc5640 100644 (file)
--- 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++;