diff options
Diffstat (limited to 'mode-tree.c')
-rw-r--r-- | mode-tree.c | 85 |
1 files changed, 72 insertions, 13 deletions
diff --git a/mode-tree.c b/mode-tree.c index 1093aff3..10a56304 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -39,7 +39,8 @@ struct mode_tree_data { u_int sort_size; u_int sort_type; - void (*buildcb)(void *, u_int, uint64_t *); + void (*buildcb)(void *, u_int, uint64_t *, + const char *); struct screen *(*drawcb)(void *, void *, u_int, u_int); int (*searchcb)(void*, void *, const char *); @@ -59,7 +60,8 @@ struct mode_tree_data { struct screen screen; - char *ss; + char *search; + char *filter; }; struct mode_tree_item { @@ -273,12 +275,15 @@ mode_tree_each_tagged(struct mode_tree_data *mtd, void (*cb)(void *, void *, } struct mode_tree_data * -mode_tree_start(struct window_pane *wp, void (*buildcb)(void *, u_int, - uint64_t *), struct screen *(*drawcb)(void *, void *, u_int, u_int), +mode_tree_start(struct window_pane *wp, struct args *args, + void (*buildcb)(void *, u_int, uint64_t *, const char *), + struct screen *(*drawcb)(void *, void *, u_int, u_int), int (*searchcb)(void *, void *, const char *), void *modedata, const char **sort_list, u_int sort_size, struct screen **s) { struct mode_tree_data *mtd; + const char *sort; + u_int i; mtd = xcalloc(1, sizeof *mtd); mtd->references = 1; @@ -290,6 +295,19 @@ mode_tree_start(struct window_pane *wp, void (*buildcb)(void *, u_int, mtd->sort_size = sort_size; mtd->sort_type = 0; + sort = args_get(args, 'O'); + if (sort != NULL) { + for (i = 0; i < sort_size; i++) { + if (strcasecmp(sort, sort_list[i]) == 0) + mtd->sort_type = i; + } + } + + if (args_has(args, 'f')) + mtd->filter = xstrdup(args_get(args, 'f')); + else + mtd->filter = NULL; + mtd->buildcb = buildcb; mtd->drawcb = drawcb; mtd->searchcb = searchcb; @@ -317,7 +335,9 @@ mode_tree_build(struct mode_tree_data *mtd) TAILQ_CONCAT(&mtd->saved, &mtd->children, entry); TAILQ_INIT(&mtd->children); - mtd->buildcb(mtd->modedata, mtd->sort_type, &tag); + mtd->buildcb(mtd->modedata, mtd->sort_type, &tag, mtd->filter); + if (TAILQ_EMPTY(&mtd->children)) + mtd->buildcb(mtd->modedata, mtd->sort_type, &tag, NULL); mode_tree_free_items(&mtd->saved); TAILQ_INIT(&mtd->saved); @@ -351,6 +371,9 @@ mode_tree_free(struct mode_tree_data *mtd) mode_tree_clear_lines(mtd); screen_free(&mtd->screen); + free(mtd->search); + free(mtd->filter); + mtd->dead = 1; mode_tree_remove_ref(mtd); } @@ -564,7 +587,7 @@ mode_tree_search_for(struct mode_tree_data *mtd) { struct mode_tree_item *mti, *last, *next; - if (mtd->ss == NULL) + if (mtd->search == NULL) return (NULL); mti = last = mtd->line_list[mtd->current].item; @@ -590,11 +613,11 @@ mode_tree_search_for(struct mode_tree_data *mtd) break; if (mtd->searchcb == NULL) { - if (strstr(mti->name, mtd->ss) != NULL) + if (strstr(mti->name, mtd->search) != NULL) return (mti); continue; } - if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->ss)) + if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search)) return (mti); } return (NULL); @@ -616,10 +639,11 @@ mode_tree_search_set(struct mode_tree_data *mtd) loop->expanded = 1; loop = loop->parent; } - mode_tree_build(mtd); + mode_tree_build(mtd); mode_tree_set_current(mtd, tag); mode_tree_draw(mtd); + mtd->wp->flags |= PANE_REDRAW; } static int @@ -631,12 +655,12 @@ mode_tree_search_callback(__unused struct client *c, void *data, const char *s, if (mtd->dead) return (0); - free(mtd->ss); - if (*s == '\0') { - mtd->ss = NULL; + free(mtd->search); + if (s == NULL || *s == '\0') { + mtd->search = NULL; return (0); } - mtd->ss = xstrdup(s); + mtd->search = xstrdup(s); mode_tree_search_set(mtd); return (0); @@ -648,6 +672,35 @@ mode_tree_search_free(void *data) mode_tree_remove_ref(data); } +static int +mode_tree_filter_callback(__unused struct client *c, void *data, const char *s, + __unused int done) +{ + struct mode_tree_data *mtd = data; + + if (mtd->dead) + return (0); + + if (mtd->filter != NULL) + free(mtd->filter); + if (s == NULL || *s == '\0') + mtd->filter = NULL; + else + mtd->filter = xstrdup(s); + + mode_tree_build(mtd); + mode_tree_draw(mtd); + mtd->wp->flags |= PANE_REDRAW; + + return (0); +} + +static void +mode_tree_filter_free(void *data) +{ + mode_tree_remove_ref(data); +} + int mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, struct mouse_event *m) @@ -801,6 +854,12 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key, case 'n': mode_tree_search_set(mtd); break; + case 'f': + mtd->references++; + status_prompt_set(c, "(filter) ", mtd->filter, + mode_tree_filter_callback, mode_tree_filter_free, mtd, + PROMPT_NOFORMAT); + break; } return (0); } |