diff options
author | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2010-02-24 01:36:22 -0500 |
---|---|---|
committer | Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> | 2010-02-24 01:36:22 -0500 |
commit | ca397618071bc4e494f2810b9368c791c157942f (patch) | |
tree | 9bcb7beae47cf52d11dc8a8381f9e564edc665b7 | |
parent | 24246d27ea5be518c2c43b36b3187295cb8456a6 (diff) | |
download | screen-ca397618071bc4e494f2810b9368c791c157942f.tar.gz |
Allow searching in the window list.
Press '/' to enter the search string, then pressing 'n' will search
forward, and 'N' will search backward. Press '/' again to change the
search string.
-rw-r--r-- | src/list_display.c | 3 | ||||
-rw-r--r-- | src/list_generic.c | 92 | ||||
-rw-r--r-- | src/list_generic.h | 3 | ||||
-rw-r--r-- | src/list_window.c | 12 |
4 files changed, 108 insertions, 2 deletions
diff --git a/src/list_display.c b/src/list_display.c index 56e7f08..19566ec 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -218,7 +218,8 @@ static struct GenericList gl_Display = gl_Display_row, gl_Display_input, gl_Display_freerow, - gl_Display_free + gl_Display_free, + NULL /* We do not allow searching in the display list, at the moment */ }; void diff --git a/src/list_generic.c b/src/list_generic.c index 02eb220..369e35a 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -24,6 +24,7 @@ #include "screen.h" #include "list_generic.h" #include "layer.h" +#include "extern.h" /* Deals with a generic list display */ @@ -78,6 +79,67 @@ glist_decide_top(struct ListData *ldata) ldata->top = top; } +static struct ListRow * +glist_search_dir(struct ListData *ldata, struct ListRow *start, int dir) +{ + struct ListRow *row = (dir == 1) ? start->next : start->prev; + for (; row; row = (dir == 1) ? row->next : row->prev) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + return row; + + if (dir == 1) + { + for (row = ldata->root; row != start; row = row->next) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + } + else + { + /* First, go to the end */ + if (!start->next) + row = start; + else + for (row = start->next; row->next; row = row->next) + ; + for (; row != start; row = row->prev) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + } + + return row; +} + +static void +glist_search(char *buf, int len, char *data) +{ + struct ListData *ldata = (struct ListData *)data; + struct ListRow *row; + + if (ldata->search) + Free(ldata->search); + if (len > 0) + ldata->search = SaveStr(buf); + else + return; + + for (row = ldata->selected; row; row = row->next) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + + if (!row) + for (row = ldata->root; row != ldata->selected; row = row->next) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + + if (row == ldata->selected) + return; + + ldata->selected = row; + if (ldata->selected->y == -1) + glist_decide_top(ldata); + glist_display_all(ldata); +} + static void ListProcess(char **ppbuf, int *plen) { struct ListData *ldata = flayer->l_data; @@ -166,6 +228,34 @@ static void ListProcess(char **ppbuf, int *plen) ; break; + case '/': /* start searching */ + if (ldata->list_fn->gl_matchrow) + { + char *s; + Input("Search: ", 80, INP_COOKED, glist_search, (char *)ldata, 0); + if ((s = ldata->search)) + { + for (; *s; s++) + { + char *ss = s; + int n = 1; + LayProcess(&ss, &n); + } + } + } + break; + + /* The following deal with searching. */ + + case 'n': /* search next */ + if (ldata->list_fn->gl_matchrow && ldata->search) + ldata->selected = glist_search_dir(ldata, ldata->selected, 1); + break; + + case 'N': /* search prev */ + if (ldata->list_fn->gl_matchrow && ldata->search) + ldata->selected = glist_search_dir(ldata, ldata->selected, -1); + break; } if (old == ldata->selected) /* The selection didn't change */ @@ -195,6 +285,8 @@ static void ListAbort(void) glist_remove_rows(ldata); if (ldata->list_fn->gl_free) ldata->list_fn->gl_free(ldata); + if (ldata->search) + Free(ldata->search); LAY_CALL_UP(LRefreshAll(flayer, 0)); ExitOverlayPage(); } diff --git a/src/list_generic.h b/src/list_generic.h index 489694c..234f6de 100644 --- a/src/list_generic.h +++ b/src/list_generic.h @@ -37,6 +37,7 @@ struct GenericList int (*gl_pinput) __P((struct ListData *, char **inp, int *len)); /* Process input */ int (*gl_freerow) __P((struct ListData *, struct ListRow *)); /* Free data for a row */ int (*gl_free) __P((struct ListData *)); /* Free data for the list */ + int (*gl_matchrow) __P((struct ListData *, struct ListRow *, const char *)); }; struct ListData @@ -48,6 +49,8 @@ struct ListData struct GenericList *list_fn; /* The functions that deal with the list */ + char *search; /* The search term, if any */ + void *data; /* List specific data */ }; diff --git a/src/list_window.c b/src/list_window.c index f21b4f6..982b781 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -373,6 +373,15 @@ gl_Window_free(struct ListData *ldata) return 0; } +static int +gl_Window_match(struct ListData *ldata, struct ListRow *row, const char *needle) +{ + struct win *w = row->data; + if (InStr(w->w_title, needle)) + return 1; + return 0; +} + static struct GenericList gl_Window = { gl_Window_header, @@ -380,7 +389,8 @@ static struct GenericList gl_Window = gl_Window_row, gl_Window_input, gl_Window_freerow, - gl_Window_free + gl_Window_free, + gl_Window_match }; void |