summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-24 01:36:22 -0500
committerSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-24 01:36:22 -0500
commitca397618071bc4e494f2810b9368c791c157942f (patch)
tree9bcb7beae47cf52d11dc8a8381f9e564edc665b7
parent24246d27ea5be518c2c43b36b3187295cb8456a6 (diff)
downloadscreen-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.c3
-rw-r--r--src/list_generic.c92
-rw-r--r--src/list_generic.h3
-rw-r--r--src/list_window.c12
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