sacc

sacc (saccomys): simple gopher client.
Log | Files | Refs | LICENSE

commit 40de964b66ff1edbd19b6a61a68cee6f731e735c
parent 4472c9895534239b693171b37c1766352b538419
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
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:
config.def.h | 3+++
ui_ti.c | 46++++++++++++++++++++++++++++++++++++++++++++--
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();