Add search/filter function for the current entry - sacc - sacc(omys), simple console gopher client
git clone git://bitreich.org/sacc/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/sacc/
Log
Files
Refs
Tags
LICENSE
---
commit 40de964b66ff1edbd19b6a61a68cee6f731e735c
parent 4472c9895534239b693171b37c1766352b538419
Author: Hiltjo Posthuma 
Date:   Sat, 21 Oct 2017 14:55:14 +0200

Add search/filter function for the current entry

...also adds keys to search forward and backward using the current
search term.

Diffstat:
  M config.def.h                        |       3 +++
  M ui_ti.c                             |      46 +++++++++++++++++++++++++++++--
  M ui_txt.c                            |      23 ++++++++++++++++++++++-

3 files changed, 69 insertions(+), 3 deletions(-)
---
diff --git a/config.def.h b/config.def.h
@@ -15,6 +15,9 @@
 #define _key_fetch        'L' /* refetch current item */
 #define _key_help        '?' /* display help */
 #define _key_quit        'q' /* exit sacc */
+#define _key_search        '/' /* search */
+#define _key_searchnext        'n' /* search same string forward */
+#define _key_searchprev        'N' /* search same string backward */
 
 /* default plumber */
 static char *plumber = "xdg-open";
diff --git a/ui_ti.c b/ui_ti.c
@@ -86,7 +86,7 @@ uiprompt(char *fmt, ...)
         } else if (input[r - 1] == '\n') {
                 input[--r] = '\0';
         }
-        
+
         return input;
 }
 
@@ -289,7 +289,7 @@ movecurline(Item *item, int l)
                         dir->printoff += l;
                 }
         }
-        
+
         putp(tparm(cursor_address, curline - dir->printoff, 0));
         putp(tparm(enter_standout_mode));
         printitem(&dir->items[curline]);
@@ -339,6 +339,32 @@ jumptoline(Item *entry, ssize_t line, int absolute)
         return;
 }
 
+void
+searchinline(const char *searchstr, Item *entry, int pos)
+{
+        Dir *dir;
+        int i;
+
+        if (!searchstr || !(dir = entry->dat))
+                return;
+
+        if (pos > 0) {
+                for (i = dir->curline + 1; i < dir->nitems; ++i) {
+                        if (strstr(dir->items[i].username, searchstr)) {
+                                jumptoline(entry, i, 1);
+                                break;
+                        }
+                }
+        } else {
+                for (i = dir->curline - 1; i > -1; --i) {
+                        if (strstr(dir->items[i].username, searchstr)) {
+                                jumptoline(entry, i, 1);
+                                break;
+                        }
+                }
+        }
+}
+
 static ssize_t
 nearentry(Item *entry, int direction)
 {
@@ -362,6 +388,7 @@ Item *
 uiselectitem(Item *entry)
 {
         Dir *dir;
+        char *searchstr = NULL;
         int plines = lines-2;
 
         if (!entry || !(dir = entry->dat))
@@ -444,6 +471,21 @@ uiselectitem(Item *entry)
                 home:
                         jumptoline(entry, 0, 0);
                         continue;
+                case _key_search:
+                search:
+                        free(searchstr);
+                        if ((searchstr = uiprompt("Search for: ")) &&
+                            searchstr[0])
+                                goto searchnext;
+                        clear(&searchstr);
+                        continue;
+                case _key_searchnext:
+                searchnext:
+                        searchinline(searchstr, entry, +1);
+                        continue;
+                case _key_searchprev:
+                        searchinline(searchstr, entry, -1);
+                        continue;
                 case _key_quit:
                 quit:
                         return NULL;
diff --git a/ui_txt.c b/ui_txt.c
@@ -163,12 +163,26 @@ printuri(Item *item, size_t i)
         }
 }
 
+void
+searchinline(const char *searchstr, Item *entry)
+{
+        Dir *dir;
+        size_t i;
+
+        if (!(dir = entry->dat))
+                return;
+
+        for (i = 0; i < dir->nitems; ++i)
+                if (strstr(dir->items[i].username, searchstr))
+                        printuri(&(dir->items[i]), i + 1);
+}
+
 Item *
 uiselectitem(Item *entry)
 {
         Dir *dir;
         static char c;
-        char buf[BUFSIZ], nl;
+        char buf[BUFSIZ], nl, *searchstr;
         int item, nitems, lines;
 
         if (!entry || !(dir = entry->dat))
@@ -238,6 +252,13 @@ uiselectitem(Item *entry)
                         if (item > 0 && item <= nitems)
                                 printuri(&dir->items[item-1], item);
                         continue;
+                case '/':
+                        if ((searchstr = uiprompt("Search for: ")) &&
+                            searchstr[0])
+                                searchinline(searchstr, entry);
+                        free(searchstr);
+                        searchstr = NULL;
+                        continue;
                 case 'h':
                 case '?':
                         help();