diff options
author | Thomas Adam <thomas@xteddy.org> | 2017-06-09 18:01:14 +0100 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2017-06-09 18:01:14 +0100 |
commit | 4dbab75855aac5bc9d404b241d8a40e7290c3963 (patch) | |
tree | 64ee1e45a4e0ae0582f54777771ed8d7e02b7097 | |
parent | ed45052d6d1aabdd94827b4fe70e978b9dbd4446 (diff) | |
parent | adcd5aff6fb86036ef736c10b04005da77a465f6 (diff) | |
download | rtmux-4dbab75855aac5bc9d404b241d8a40e7290c3963.tar.gz rtmux-4dbab75855aac5bc9d404b241d8a40e7290c3963.tar.bz2 rtmux-4dbab75855aac5bc9d404b241d8a40e7290c3963.zip |
Merge branch 'obsd-master'
-rw-r--r-- | cmd-choose-tree.c | 12 | ||||
-rw-r--r-- | mode-tree.c | 85 | ||||
-rw-r--r-- | tmux.1 | 33 | ||||
-rw-r--r-- | tmux.h | 9 | ||||
-rw-r--r-- | window-buffer.c | 29 | ||||
-rw-r--r-- | window-client.c | 21 | ||||
-rw-r--r-- | window-tree.c | 84 |
7 files changed, 164 insertions, 109 deletions
diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index f8f24f12..873b0286 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -30,8 +30,8 @@ const struct cmd_entry cmd_choose_tree_entry = { .name = "choose-tree", .alias = NULL, - .args = { "st:w", 0, 1 }, - .usage = "[-sw] " CMD_TARGET_PANE_USAGE, + .args = { "f:O:st:w", 0, 1 }, + .usage = "[-sw] [-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE, .target = { 't', CMD_FIND_PANE, 0 }, @@ -43,8 +43,8 @@ const struct cmd_entry cmd_choose_client_entry = { .name = "choose-client", .alias = NULL, - .args = { "t:", 0, 1 }, - .usage = CMD_TARGET_PANE_USAGE, + .args = { "f:O:t:", 0, 1 }, + .usage = "[-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE, .target = { 't', CMD_FIND_PANE, 0 }, @@ -56,8 +56,8 @@ const struct cmd_entry cmd_choose_buffer_entry = { .name = "choose-buffer", .alias = NULL, - .args = { "t:", 0, 1 }, - .usage = CMD_TARGET_PANE_USAGE, + .args = { "f:O:t:", 0, 1 }, + .usage = "[-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE, .target = { 't', CMD_FIND_PANE, 0 }, 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); } @@ -1358,6 +1358,8 @@ the end of the visible pane. The default is to capture only the visible contents of the pane. .It Xo .Ic choose-client +.Op Fl f Ar filter +.Op Fl O Ar sort-order .Op Fl t Ar target-pane .Op Ar template .Xc @@ -1380,6 +1382,7 @@ The following keys may be used in client mode: .It Li "X" Ta "Detach and HUP tagged clients" .It Li "z" Ta "Suspend selected client" .It Li "Z" Ta "Suspend tagged clients" +.It Li "f" Ta "Enter a format to filter items" .It Li "O" Ta "Change sort order" .It Li "q" Ta "Exit mode" .El @@ -1393,10 +1396,21 @@ If .Ar template is not given, "detach-client -t '%%'" is used. .Pp +.Fl O +specifies the initial sort order: one of +.Ql name , +.Ql size , +.Ql creation , +or +.Ql activity . +.Fl f +specifies an initial filter. This command works only if at least one client is attached. .It Xo .Ic choose-tree .Op Fl sw +.Op Fl f Ar filter +.Op Fl O Ar sort-order .Op Fl t Ar target-pane .Op Ar template .Xc @@ -1432,6 +1446,14 @@ If .Ar template is not given, "switch-client -t '%%'" is used. .Pp +.Fl O +specifies the initial sort order: one of +.Ql index , +.Ql name , +or +.Ql time . +.Fl f +specifies an initial filter. This command works only if at least one client is attached. .It Xo .Ic display-panes @@ -3963,6 +3985,8 @@ The buffer commands are as follows: .Bl -tag -width Ds .It Xo .Ic choose-buffer +.Op Fl f Ar filter +.Op Fl O Ar sort-order .Op Fl t Ar target-pane .Op Ar template .Xc @@ -3981,6 +4005,7 @@ The following keys may be used in buffer mode: .It Li "C-t" Ta "Tag all buffers" .It Li "d" Ta "Delete selected buffer" .It Li "D" Ta "Delete tagged buffers" +.It Li "f" Ta "Enter a format to filter items" .It Li "O" Ta "Change sort order" .It Li "q" Ta "Exit mode" .El @@ -3994,6 +4019,14 @@ If .Ar template is not given, "paste-buffer -b '%%'" is used. .Pp +.Fl O +specifies the initial sort order: one of +.Ql time , +.Ql name +or +.Ql size . +.Fl f +specifies an initial filter. This command works only if at least one client is attached. .It Ic clear-history Op Fl t Ar target-pane .D1 (alias: Ic clearhist ) @@ -2205,10 +2205,11 @@ void mode_tree_each_tagged(struct mode_tree_data *, void (*)(void *, void *, key_code), key_code, int); void mode_tree_up(struct mode_tree_data *, int); void mode_tree_down(struct mode_tree_data *, int); -struct mode_tree_data *mode_tree_start(struct window_pane *, - void (*)(void *, u_int, uint64_t *), struct screen *(*)(void *, - void *, u_int, u_int), int (*)(void *, void *, const char *), - void *, const char **, u_int, struct screen **); +struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *, + void (*)(void *, u_int, uint64_t *, const char *), + struct screen *(*)(void *, void *, u_int, u_int), + int (*)(void *, void *, const char *), void *, const char **, + u_int, struct screen **); void mode_tree_build(struct mode_tree_data *); void mode_tree_free(struct mode_tree_data *); void mode_tree_resize(struct mode_tree_data *, u_int, u_int); diff --git a/window-buffer.c b/window-buffer.c index daceafbe..cc05ceef 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -45,13 +45,13 @@ const struct window_mode window_buffer_mode = { }; enum window_buffer_sort_type { - WINDOW_BUFFER_BY_NAME, WINDOW_BUFFER_BY_TIME, + WINDOW_BUFFER_BY_NAME, WINDOW_BUFFER_BY_SIZE, }; static const char *window_buffer_sort_list[] = { - "name", "time", + "name", "size" }; @@ -124,14 +124,15 @@ window_buffer_cmp_size(const void *a0, const void *b0) } static void -window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag) +window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag, + const char *filter) { struct window_buffer_modedata *data = modedata; struct window_buffer_itemdata *item; u_int i; struct paste_buffer *pb; - char *tim; - char *text; + char *tim, *text, *cp; + struct format_tree *ft; for (i = 0; i < data->item_size; i++) window_buffer_free_item(data->item_list[i]); @@ -166,6 +167,22 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag) for (i = 0; i < data->item_size; i++) { item = data->item_list[i]; + if (filter != NULL) { + pb = paste_get_name(item->name); + if (pb == NULL) + continue; + ft = format_create(NULL, NULL, FORMAT_NONE, 0); + format_defaults_paste_buffer(ft, pb); + cp = format_expand(ft, filter); + if (!format_true(cp)) { + free(cp); + format_free(ft); + continue; + } + free(cp); + format_free(ft); + } + tim = ctime(&item->created); *strchr(tim, '\n') = '\0'; @@ -256,7 +273,7 @@ window_buffer_init(struct window_pane *wp, __unused struct cmd_find_state *fs, else data->command = xstrdup(args->argv[0]); - data->data = mode_tree_start(wp, window_buffer_build, + data->data = mode_tree_start(wp, args, window_buffer_build, window_buffer_draw, window_buffer_search, data, window_buffer_sort_list, nitems(window_buffer_sort_list), &s); diff --git a/window-client.c b/window-client.c index 483ce8fe..9da8431e 100644 --- a/window-client.c +++ b/window-client.c @@ -54,8 +54,8 @@ enum window_client_sort_type { static const char *window_client_sort_list[] = { "name", "size", - "creation time", - "activity time" + "creation", + "activity" }; struct window_client_itemdata { @@ -141,14 +141,14 @@ window_client_cmp_activity_time(const void *a0, const void *b0) } static void -window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag) +window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag, + const char *filter) { struct window_client_modedata *data = modedata; struct window_client_itemdata *item; u_int i; struct client *c; - char *tim; - char *text; + char *tim, *text, *cp; for (i = 0; i < data->item_size; i++) window_client_free_item(data->item_list[i]); @@ -189,6 +189,15 @@ window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag) item = data->item_list[i]; c = item->c; + if (filter != NULL) { + cp = format_single(NULL, filter, c, NULL, NULL, NULL); + if (!format_true(cp)) { + free(cp); + continue; + } + free(cp); + } + tim = ctime(&c->activity_time.tv_sec); *strchr(tim, '\n') = '\0'; @@ -247,7 +256,7 @@ window_client_init(struct window_pane *wp, __unused struct cmd_find_state *fs, else data->command = xstrdup(args->argv[0]); - data->data = mode_tree_start(wp, window_client_build, + data->data = mode_tree_start(wp, args, window_client_build, window_client_draw, NULL, data, window_client_sort_list, nitems(window_client_sort_list), &s); diff --git a/window-tree.c b/window-tree.c index b19ee9e6..d8ff061e 100644 --- a/window-tree.c +++ b/window-tree.c @@ -81,8 +81,6 @@ struct window_tree_modedata { struct client *client; const char *entered; - char *filter; - struct cmd_find_state fs; enum window_tree_type type; }; @@ -227,7 +225,7 @@ window_tree_build_pane(struct session *s, struct winlink *wl, static int window_tree_build_window(struct session *s, struct winlink *wl, void* modedata, - u_int sort_type, struct mode_tree_item *parent, int no_filter) + u_int sort_type, struct mode_tree_item *parent, const char *filter) { struct window_tree_modedata *data = modedata; struct window_tree_itemdata *item; @@ -261,8 +259,8 @@ window_tree_build_window(struct session *s, struct winlink *wl, void* modedata, l = NULL; n = 0; TAILQ_FOREACH(wp, &wl->window->panes, entry) { - if (!no_filter && data->filter != NULL) { - cp = format_single(NULL, data->filter, NULL, s, wl, wp); + if (filter != NULL) { + cp = format_single(NULL, filter, NULL, s, wl, wp); if (!format_true(cp)) { free(cp); continue; @@ -298,7 +296,7 @@ window_tree_build_window(struct session *s, struct winlink *wl, void* modedata, static void window_tree_build_session(struct session *s, void* modedata, - u_int sort_type, int no_filter) + u_int sort_type, const char *filter) { struct window_tree_modedata *data = modedata; struct window_tree_itemdata *item; @@ -349,7 +347,7 @@ window_tree_build_session(struct session *s, void* modedata, empty = 0; for (i = 0; i < n; i++) { if (!window_tree_build_window(s, l[i], modedata, sort_type, mti, - no_filter)) + filter)) empty++; } if (empty == n) { @@ -361,14 +359,13 @@ window_tree_build_session(struct session *s, void* modedata, } static void -window_tree_build(void *modedata, u_int sort_type, uint64_t *tag) +window_tree_build(void *modedata, u_int sort_type, uint64_t *tag, + const char *filter) { struct window_tree_modedata *data = modedata; struct session *s, **l; u_int n, i; - int no_filter = 0; -restart: for (i = 0; i < data->item_size; i++) window_tree_free_item(data->item_list[i]); free(data->item_list); @@ -393,14 +390,9 @@ restart: } for (i = 0; i < n; i++) - window_tree_build_session(l[i], modedata, sort_type, no_filter); + window_tree_build_session(l[i], modedata, sort_type, filter); free(l); - if (!no_filter && data->item_size == 0) { - no_filter = 1; - goto restart; - } - switch (data->type) { case WINDOW_TREE_NONE: break; @@ -493,18 +485,13 @@ window_tree_init(struct window_pane *wp, struct cmd_find_state *fs, data->wp = wp; data->references = 1; - if (args_has(args, 'f')) - data->filter = xstrdup(args_get(args, 'f')); - else - data->filter = NULL; - if (args == NULL || args->argc == 0) data->command = xstrdup(WINDOW_TREE_DEFAULT_COMMAND); else data->command = xstrdup(args->argv[0]); - data->data = mode_tree_start(wp, window_tree_build, window_tree_draw, - window_tree_search, data, window_tree_sort_list, + data->data = mode_tree_start(wp, args, window_tree_build, + window_tree_draw, window_tree_search, data, window_tree_sort_list, nitems(window_tree_sort_list), &s); mode_tree_build(data->data); @@ -529,8 +516,6 @@ window_tree_destroy(struct window_tree_modedata *data) window_tree_free_item(data->item_list[i]); free(data->item_list); - free(data->filter); - free(data->command); free(data); } @@ -653,37 +638,6 @@ window_tree_command_free(void *modedata) window_tree_destroy(data); } -static int -window_tree_filter_callback(__unused struct client *c, void *modedata, - const char *s, __unused int done) -{ - struct window_tree_modedata *data = modedata; - - if (data->dead) - return (0); - - if (data->filter != NULL) - free(data->filter); - if (s == NULL || *s == '\0') - data->filter = NULL; - else - data->filter = xstrdup(s); - - mode_tree_build(data->data); - mode_tree_draw(data->data); - data->wp->flags |= PANE_REDRAW; - - return (0); -} - -static void -window_tree_filter_free(void *modedata) -{ - struct window_tree_modedata *data = modedata; - - window_tree_destroy(data); -} - static void window_tree_key(struct window_pane *wp, struct client *c, __unused struct session *s, key_code key, struct mouse_event *m) @@ -695,26 +649,8 @@ window_tree_key(struct window_pane *wp, struct client *c, int finished; u_int tagged; - /* - * t = toggle tag - * T = tag none - * C-t = tag all - * q = exit - * O = change sort order - * - * Enter = select item - * : = enter command - * f = enter filter - */ - finished = mode_tree_key(data->data, c, &key, m); switch (key) { - case 'f': - data->references++; - status_prompt_set(c, "(filter) ", data->filter, - window_tree_filter_callback, window_tree_filter_free, data, - PROMPT_NOFORMAT); - break; case ':': tagged = mode_tree_count_tagged(data->data); if (tagged != 0) |