diff options
author | Tillmann Karras <tilkax@gmail.com> | 2013-11-26 19:22:11 +0100 |
---|---|---|
committer | Tillmann Karras <tilkax@gmail.com> | 2013-11-26 20:04:16 +0100 |
commit | c370c05a0da7bc5156b94b098dd806f022e0b818 (patch) | |
tree | d97a9acded6a8291c47bdb7dc504203e1792b11f | |
parent | 70ecd6c9cae04505bf97cd90b8f72c585158caf9 (diff) |
Regex searching
-rw-r--r-- | src/ui_util.c | 60 | ||||
-rw-r--r-- | src/uit_fl.c | 6 | ||||
-rw-r--r-- | src/uit_userlist.c | 8 |
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); } |