summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTillmann Karras <tilkax@gmail.com>2013-11-26 19:22:11 +0100
committerTillmann Karras <tilkax@gmail.com>2013-11-26 20:04:16 +0100
commitc370c05a0da7bc5156b94b098dd806f022e0b818 (patch)
treed97a9acded6a8291c47bdb7dc504203e1792b11f
parent70ecd6c9cae04505bf97cd90b8f72c585158caf9 (diff)
Regex searching
-rw-r--r--src/ui_util.c60
-rw-r--r--src/uit_fl.c6
-rw-r--r--src/uit_userlist.c8
3 files changed, 42 insertions, 32 deletions
diff --git a/src/ui_util.c b/src/ui_util.c
index 0e14bae..a1694be 100644
--- a/src/ui_util.c
+++ b/src/ui_util.c
@@ -1057,7 +1057,7 @@ struct ui_listing_t {
gboolean (*skip)(ui_listing_t *, GSequenceIter *, void *);
void *dat;
ui_textinput_t *query;
- gboolean (*search_func)(GSequenceIter *, const char *, size_t);
+ const char *(*to_string)(GSequenceIter *);
}
// does not free the GSequence (we don't control the list, after all)
@@ -1154,7 +1154,7 @@ void ui_listing_skipchanged(ui_listing_t *ul) {
}
-ui_listing_t *ui_listing_create(GSequence *list, gboolean (*skip)(ui_listing_t *, GSequenceIter *, void *), void *dat, gboolean (*search_func)(GSequenceIter *, const char *, size_t)) {
+ui_listing_t *ui_listing_create(GSequence *list, gboolean (*skip)(ui_listing_t *, GSequenceIter *, void *), void *dat, const char *(*to_string)(GSequenceIter *)) {
ui_listing_t *ul = g_slice_new0(ui_listing_t);
ul->list = list;
ul->sel = ul->top = ui_listing_getbegin(ul);
@@ -1162,39 +1162,49 @@ ui_listing_t *ui_listing_create(GSequence *list, gboolean (*skip)(ui_listing_t *
ul->skip = skip;
ul->dat = dat;
ul->query = NULL;
- ul->search_func = search_func;
+ ul->to_string = to_string;
return ul;
}
+static void ui_listing_search(ui_listing_t *ul, guint64 key) {
+ char *complete_query = NULL;
+ ui_textinput_key(ul->query, key, &complete_query);
+ if(complete_query) {
+ // enter pressed -> exit search mode
+ g_free(complete_query);
+ ui_textinput_free(ul->query);
+ ul->query = NULL;
+ return;
+ }
+ char *pattern = ui_textinput_get(ul->query);
+ GRegex *regex = g_regex_new(pattern, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_HARD, NULL);
+ if (!regex)
+ return;
+ GSequenceIter *pos = g_sequence_get_begin_iter(ul->list);
+ while(!g_sequence_iter_is_end(pos)) {
+ const char *candidate = ul->to_string(pos);
+ if (g_regex_match(regex, candidate, 0, NULL))
+ break;
+ pos = ui_listing_next(ul, pos);
+ }
+ g_regex_unref(regex);
+ g_free(pattern);
+ if(!g_sequence_iter_is_end(pos)) {
+ ul->sel = pos;
+ }
+}
+
+
gboolean ui_listing_key(ui_listing_t *ul, guint64 key, int page) {
- if(ul->query && ul->search_func) {
- char *complete_query = NULL;
- ui_textinput_key(ul->query, key, &complete_query);
- GSequenceIter *pos = ul->sel;
- char *str = ui_textinput_get(ul->query);
- size_t str_len = strlen(str);
- while(ul->search_func(pos, str, str_len)) {
- pos = ui_listing_next(ul, pos);
- if(g_sequence_iter_is_end(pos))
- break;
- }
- g_free(str);
- if(!g_sequence_iter_is_end(pos)) {
- ul->sel = pos;
- }
- if(complete_query) {
- // enter pressed -> exit search mode
- g_free(complete_query);
- ui_textinput_free(ul->query);
- ul->query = NULL;
- }
+ if(ul->query) {
+ ui_listing_search(ul, key);
return TRUE;
}
switch(key) {
case INPT_CHAR('/'):
- if (ul->search_func)
+ if (ul->to_string)
ul->query = ui_textinput_create(FALSE, NULL);
break;
case INPT_KEY(KEY_NPAGE): { // page down
diff --git a/src/uit_fl.c b/src/uit_fl.c
index bc31966..e23efd5 100644
--- a/src/uit_fl.c
+++ b/src/uit_fl.c
@@ -68,9 +68,9 @@ static gint sort_func(gconstpointer a, gconstpointer b, gpointer dat) {
}
-static gboolean search_func(GSequenceIter *iter, const char *query, size_t str_len) {
+static const char *get_name(GSequenceIter *iter) {
fl_list_t *fl = g_sequence_get(iter);
- return !!strncasecmp(fl->name, query, str_len);
+ return fl->name;
}
@@ -91,7 +91,7 @@ static void setdir(tab_t *t, fl_list_t *fl, fl_list_t *sel) {
if(sel == g_ptr_array_index(fl->sub, i))
seli = iter;
}
- t->list = ui_listing_create(seq, NULL, NULL, search_func);
+ t->list = ui_listing_create(seq, NULL, NULL, get_name);
if(seli)
t->list->sel = seli;
}
diff --git a/src/uit_userlist.c b/src/uit_userlist.c
index a60360a..f727df4 100644
--- a/src/uit_userlist.c
+++ b/src/uit_userlist.c
@@ -87,9 +87,9 @@ static gint sort_func(gconstpointer da, gconstpointer db, gpointer dat) {
}
-static gboolean search_func(GSequenceIter *iter, const char *query, size_t str_len) {
+static const char *get_name(GSequenceIter *iter) {
hub_user_t *u = g_sequence_get(iter);
- return !!strncasecmp(u->name, query, str_len);
+ return u->name;
}
@@ -114,7 +114,7 @@ ui_tab_t *uit_userlist_create(hub_t *hub) {
hub_user_t *u;
while(g_hash_table_iter_next(&iter, NULL, (gpointer *)&u))
u->iter = g_sequence_insert_sorted(users, u, sort_func, t);
- t->list = ui_listing_create(users, NULL, t, search_func);
+ t->list = ui_listing_create(users, NULL, t, get_name);
return (ui_tab_t *)t;
}
@@ -426,7 +426,7 @@ void uit_userlist_disconnect(ui_tab_t *tab) {
g_sequence_free(t->list->list);
ui_listing_free(t->list);
- t->list = ui_listing_create(g_sequence_new(NULL), NULL, t, search_func);
+ t->list = ui_listing_create(g_sequence_new(NULL), NULL, t, get_name);
}