From 180faf73afe07d35e6002993a70d5fe63549ffce Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 21 Mar 2013 16:09:59 +0000 Subject: Allow choose commands to be used outside tmux, so long as at least one client is attached. --- cmd-choose-buffer.c | 40 ++--------- cmd-choose-client.c | 45 ++++-------- cmd-choose-list.c | 35 ++-------- cmd-choose-tree.c | 42 +++--------- cmd-find-window.c | 29 ++------ tmux.1 | 21 ++---- tmux.h | 35 ++++++---- window-choose.c | 192 +++++++++++++++++++++++++++++++--------------------- 8 files changed, 181 insertions(+), 258 deletions(-) diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c index b811a042..a58e38b7 100644 --- a/cmd-choose-buffer.c +++ b/cmd-choose-buffer.c @@ -29,9 +29,6 @@ enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *); -void cmd_choose_buffer_callback(struct window_choose_data *); -void cmd_choose_buffer_free(struct window_choose_data *); - const struct cmd_entry cmd_choose_buffer_entry = { "choose-buffer", NULL, "F:t:", 0, 1, @@ -46,6 +43,7 @@ enum cmd_retval cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; + struct client *c; struct window_choose_data *cdata; struct winlink *wl; struct paste_buffer *pb; @@ -53,8 +51,8 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) const char *template; u_int idx; - if (ctx->curclient == NULL) { - ctx->error(ctx, "must be run interactively"); + if ((c = cmd_current_client(ctx)) == NULL) { + ctx->error(ctx, "no client available"); return (CMD_RETURN_ERROR); } @@ -77,9 +75,8 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) idx = 0; while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) { - cdata = window_choose_data_create(ctx); + cdata = window_choose_data_create(TREE_OTHER, c, c->session); cdata->idx = idx - 1; - cdata->client->references++; cdata->ft_template = xstrdup(template); format_add(cdata->ft, "line", "%u", idx - 1); @@ -93,34 +90,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) } free(action); - window_choose_ready(wl->window->active, - 0, cmd_choose_buffer_callback, cmd_choose_buffer_free); + window_choose_ready(wl->window->active, 0, NULL); return (CMD_RETURN_NORMAL); } - -void -cmd_choose_buffer_callback(struct window_choose_data *cdata) -{ - if (cdata == NULL) - return; - if (cdata->client->flags & CLIENT_DEAD) - return; - - window_choose_ctx(cdata); -} - -void -cmd_choose_buffer_free(struct window_choose_data *data) -{ - struct window_choose_data *cdata = data; - - if (cdata == NULL) - return; - - cdata->client->references--; - - free(cdata->command); - free(cdata->ft_template); - free(cdata); -} diff --git a/cmd-choose-client.c b/cmd-choose-client.c index 1f9741fe..962aefca 100644 --- a/cmd-choose-client.c +++ b/cmd-choose-client.c @@ -30,7 +30,6 @@ enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_ctx *); void cmd_choose_client_callback(struct window_choose_data *); -void cmd_choose_client_free(struct window_choose_data *); const struct cmd_entry cmd_choose_client_entry = { "choose-client", NULL, @@ -50,15 +49,16 @@ enum cmd_retval cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; + struct client *c; + struct client *c1; struct window_choose_data *cdata; struct winlink *wl; - struct client *c; const char *template; char *action; u_int i, idx, cur; - if (ctx->curclient == NULL) { - ctx->error(ctx, "must be run interactively"); + if ((c = cmd_current_client(ctx)) == NULL) { + ctx->error(ctx, "no client available"); return (CMD_RETURN_ERROR); } @@ -78,30 +78,29 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) cur = idx = 0; for (i = 0; i < ARRAY_LENGTH(&clients); i++) { - c = ARRAY_ITEM(&clients, i); - if (c == NULL || c->session == NULL) + c1 = ARRAY_ITEM(&clients, i); + if (c1 == NULL || c1->session == NULL) continue; - if (c == ctx->curclient) + if (c1 == ctx->curclient) cur = idx; idx++; - cdata = window_choose_data_create(ctx); + cdata = window_choose_data_create(TREE_OTHER, c, c->session); cdata->idx = i; - cdata->client->references++; cdata->ft_template = xstrdup(template); format_add(cdata->ft, "line", "%u", i); - format_session(cdata->ft, c->session); - format_client(cdata->ft, c); + format_session(cdata->ft, c1->session); + format_client(cdata->ft, c1); - cdata->command = cmd_template_replace(action, c->tty.path, 1); + cdata->command = cmd_template_replace(action, c1->tty.path, 1); window_choose_add(wl->window->active, cdata); } free(action); - window_choose_ready(wl->window->active, - cur, cmd_choose_client_callback, cmd_choose_client_free); + window_choose_ready(wl->window->active, cur, + cmd_choose_client_callback); return (CMD_RETURN_NORMAL); } @@ -113,7 +112,7 @@ cmd_choose_client_callback(struct window_choose_data *cdata) if (cdata == NULL) return; - if (cdata->client->flags & CLIENT_DEAD) + if (cdata->start_client->flags & CLIENT_DEAD) return; if (cdata->idx > ARRAY_LENGTH(&clients) - 1) @@ -122,19 +121,5 @@ cmd_choose_client_callback(struct window_choose_data *cdata) if (c == NULL || c->session == NULL) return; - window_choose_ctx(cdata); -} - -void -cmd_choose_client_free(struct window_choose_data *cdata) -{ - if (cdata == NULL) - return; - - cdata->client->references--; - - free(cdata->ft_template); - free(cdata->command); - format_free(cdata->ft); - free(cdata); + window_choose_data_run(cdata); } diff --git a/cmd-choose-list.c b/cmd-choose-list.c index 4c32e694..9634fef4 100644 --- a/cmd-choose-list.c +++ b/cmd-choose-list.c @@ -33,9 +33,6 @@ enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_ctx *); -void cmd_choose_list_callback(struct window_choose_data *); -void cmd_choose_list_free(struct window_choose_data *); - const struct cmd_entry cmd_choose_list_entry = { "choose-list", NULL, "l:t:", 0, 1, @@ -50,13 +47,14 @@ enum cmd_retval cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; + struct client *c; struct winlink *wl; const char *list1; char *template, *item, *copy, *list; u_int idx; - if (ctx->curclient == NULL) { - ctx->error(ctx, "must be run interactively"); + if ((c = cmd_current_client(ctx)) == NULL) { + ctx->error(ctx, "no client available"); return (CMD_RETURN_ERROR); } @@ -80,7 +78,7 @@ cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx) { if (*item == '\0') /* no empty entries */ continue; - window_choose_add_item(wl->window->active, ctx, wl, item, + window_choose_add_item(wl->window->active, c, wl, item, template, idx); idx++; } @@ -92,32 +90,9 @@ cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx) return (CMD_RETURN_ERROR); } - window_choose_ready(wl->window->active, 0, cmd_choose_list_callback, - cmd_choose_list_free); + window_choose_ready(wl->window->active, 0, NULL); free(template); return (CMD_RETURN_NORMAL); } - -void -cmd_choose_list_callback(struct window_choose_data *cdata) -{ - if (cdata == NULL || (cdata->client->flags & CLIENT_DEAD)) - return; - - window_choose_ctx(cdata); -} - -void -cmd_choose_list_free(struct window_choose_data *cdata) -{ - cdata->session->references--; - cdata->client->references--; - - free(cdata->ft_template); - free(cdata->command); - format_free(cdata->ft); - free(cdata); - -} diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index b274d561..a111bc07 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -34,9 +34,6 @@ enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_ctx *); -void cmd_choose_tree_callback(struct window_choose_data *); -void cmd_choose_tree_free(struct window_choose_data *); - const struct cmd_entry cmd_choose_tree_entry = { "choose-tree", NULL, "S:W:swub:c:t:", 0, 1, @@ -74,6 +71,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx) struct args *args = self->args; struct winlink *wl, *wm; struct session *s, *s2; + struct client *c; struct window_choose_data *wcd = NULL; const char *ses_template, *win_template; char *final_win_action, *cur_win_template; @@ -86,12 +84,13 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx) ses_template = win_template = NULL; ses_action = win_action = NULL; - if (ctx->curclient == NULL) { - ctx->error(ctx, "must be run interactively"); + if ((c = cmd_current_client(ctx)) == NULL) { + ctx->error(ctx, "no client available"); return (CMD_RETURN_ERROR); } - s = ctx->curclient->session; + if ((s = c->session) == NULL) + return (CMD_RETURN_ERROR); if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); @@ -175,7 +174,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx) } wcd = window_choose_add_session(wl->window->active, - ctx, s2, ses_template, (char *)ses_action, idx_ses); + c, s2, ses_template, (char *)ses_action, idx_ses); /* If we're just choosing sessions, skip choosing windows. */ if (sflag && !wflag) { @@ -213,7 +212,7 @@ windows_only: cur_win_template = final_win_template_last; window_choose_add_window(wl->window->active, - ctx, s2, wm, cur_win_template, + c, s2, wm, cur_win_template, final_win_action, (wflag && !sflag) ? win_ses : idx_ses); @@ -230,35 +229,10 @@ windows_only: free(final_win_template_middle); free(final_win_template_last); - window_choose_ready(wl->window->active, cur_win, - cmd_choose_tree_callback, cmd_choose_tree_free); + window_choose_ready(wl->window->active, cur_win, NULL); if (args_has(args, 'u')) window_choose_expand_all(wl->window->active); return (CMD_RETURN_NORMAL); } - -void -cmd_choose_tree_callback(struct window_choose_data *cdata) -{ - if (cdata == NULL) - return; - - if (cdata->client->flags & CLIENT_DEAD) - return; - - window_choose_ctx(cdata); -} - -void -cmd_choose_tree_free(struct window_choose_data *cdata) -{ - cdata->session->references--; - cdata->client->references--; - - free(cdata->ft_template); - free(cdata->command); - format_free(cdata->ft); - free(cdata); -} diff --git a/cmd-find-window.c b/cmd-find-window.c index f2b20ae7..acd63c84 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -31,7 +31,6 @@ enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_ctx *); void cmd_find_window_callback(struct window_choose_data *); -void cmd_find_window_free(struct window_choose_data *); /* Flags for determining matching behavior. */ #define CMD_FIND_WINDOW_BY_TITLE 0x1 @@ -131,6 +130,7 @@ enum cmd_retval cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; + struct client *c; struct window_choose_data *cdata; struct session *s; struct winlink *wl, *wm; @@ -139,11 +139,11 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) const char *template; u_int i, match_flags; - if (ctx->curclient == NULL) { - ctx->error(ctx, "must be run interactively"); + if ((c = cmd_current_client(ctx)) == NULL) { + ctx->error(ctx, "no client available"); return (CMD_RETURN_ERROR); } - s = ctx->curclient->session; + s = c->session; if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) return (CMD_RETURN_ERROR); @@ -180,9 +180,8 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) for (i = 0; i < ARRAY_LENGTH(&find_list); i++) { wm = ARRAY_ITEM(&find_list, i).wl; - cdata = window_choose_data_create(ctx); + cdata = window_choose_data_create(TREE_OTHER, c, c->session); cdata->idx = wm->idx; - cdata->client->references++; cdata->wl = wm; cdata->ft_template = xstrdup(template); @@ -198,8 +197,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) window_choose_add(wl->window->active, cdata); } - window_choose_ready(wl->window->active, - 0, cmd_find_window_callback, cmd_find_window_free); + window_choose_ready(wl->window->active, 0, cmd_find_window_callback); out: ARRAY_FREE(&find_list); @@ -215,7 +213,7 @@ cmd_find_window_callback(struct window_choose_data *cdata) if (cdata == NULL) return; - s = cdata->session; + s = cdata->start_session; if (!session_alive(s)) return; @@ -228,16 +226,3 @@ cmd_find_window_callback(struct window_choose_data *cdata) recalculate_sizes(); } } - -void -cmd_find_window_free(struct window_choose_data *cdata) -{ - if (cdata == NULL) - return; - - cdata->session->references--; - - free(cdata->ft_template); - format_free(cdata->ft); - free(cdata); -} diff --git a/tmux.1 b/tmux.1 index ceebfcef..0e788130 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1074,8 +1074,7 @@ For the meaning of the flag, see the .Sx FORMATS section. -This command works only from inside -.Nm . +This command works only if at least one client is attached. .It Xo .Ic choose-list .Op Fl l Ar items @@ -1101,8 +1100,7 @@ also accepts format specifiers. For the meaning of this see the .Sx FORMATS section. -This command works only from inside -.Nm . +This command works only if at least one client is attached. .It Xo .Ic choose-session .Op Fl F Ar format @@ -1124,8 +1122,7 @@ For the meaning of the flag, see the .Sx FORMATS section. -This command works only from inside -.Nm . +This command works only if at least one client is attached. .It Xo .Ic choose-tree .Op Fl s @@ -1189,8 +1186,7 @@ and options, see the .Sx FORMATS section. -This command only works from inside -.Nm . +This command works only if at least one client is attached. .It Xo .Ic choose-window .Op Fl F Ar format @@ -1212,8 +1208,7 @@ For the meaning of the flag, see the .Sx FORMATS section. -This command works only from inside -.Nm . +This command works only if at least one client is attached. .It Ic display-panes Op Fl t Ar target-client .D1 (alias: Ic displayp) Display a visible indicator of each pane shown by @@ -1257,8 +1252,7 @@ For the meaning of the flag, see the .Sx FORMATS section. -This command only works from inside -.Nm . +This command works only if at least one client is attached. .It Xo Ic join-pane .Op Fl bdhv .Oo Fl l @@ -3306,8 +3300,7 @@ For the meaning of the flag, see the .Sx FORMATS section. -This command works only from inside -.Nm . +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 ) Remove and free the history for the specified pane. diff --git a/tmux.h b/tmux.h index f6382a70..d12cc3a5 100644 --- a/tmux.h +++ b/tmux.h @@ -883,18 +883,24 @@ struct window_mode { /* Structures for choose mode. */ struct window_choose_data { - struct client *client; - struct session *session; /* Session of current client. */ - struct session *tree_session; /* Session of items in tree. */ - struct format_tree *ft; - struct winlink *wl; - char *ft_template; - char *command; + struct client *start_client; + struct session *start_session; + u_int idx; int type; +#define TREE_OTHER 0x0 #define TREE_WINDOW 0x1 #define TREE_SESSION 0x2 + + struct session *tree_session; /* session of items in tree */ + + struct winlink *wl; int pane_id; + + char *ft_template; + struct format_tree *ft; + + char *command; }; struct window_choose_mode_item { @@ -2196,18 +2202,19 @@ extern const struct window_mode window_choose_mode; void window_choose_add(struct window_pane *, struct window_choose_data *); void window_choose_ready(struct window_pane *, - u_int, void (*)(struct window_choose_data *), - void (*)(struct window_choose_data *)); -struct window_choose_data *window_choose_data_create(struct cmd_ctx *); -void window_choose_ctx(struct window_choose_data *); + u_int, void (*)(struct window_choose_data *)); +struct window_choose_data *window_choose_data_create (int, + struct client *, struct session *); +void window_choose_data_free(struct window_choose_data *); +void window_choose_data_run(struct window_choose_data *); struct window_choose_data *window_choose_add_window(struct window_pane *, - struct cmd_ctx *, struct session *, struct winlink *, + struct client *, struct session *, struct winlink *, const char *, char *, u_int); struct window_choose_data *window_choose_add_session(struct window_pane *, - struct cmd_ctx *, struct session *, const char *, + struct client *, struct session *, const char *, char *, u_int); struct window_choose_data *window_choose_add_item(struct window_pane *, - struct cmd_ctx *, struct winlink *, const char *, + struct client *, struct winlink *, const char *, char *, u_int); void window_choose_expand_all(struct window_pane *); diff --git a/window-choose.c b/window-choose.c index dce026ec..041e1ecb 100644 --- a/window-choose.c +++ b/window-choose.c @@ -31,6 +31,8 @@ void window_choose_key(struct window_pane *, struct session *, int); void window_choose_mouse( struct window_pane *, struct session *, struct mouse_event *); +void window_choose_default_callback(struct window_choose_data *); + void window_choose_fire_callback( struct window_pane *, struct window_choose_data *); void window_choose_redraw_screen(struct window_pane *); @@ -101,8 +103,7 @@ window_choose_add(struct window_pane *wp, struct window_choose_data *wcd) void window_choose_ready(struct window_pane *wp, u_int cur, - void (*callbackfn)(struct window_choose_data *), - void (*freefn)(struct window_choose_data *)) + void (*callbackfn)(struct window_choose_data *)) { struct window_choose_mode_data *data = wp->modedata; struct screen *s = &data->screen; @@ -112,7 +113,8 @@ window_choose_ready(struct window_pane *wp, u_int cur, data->top = ARRAY_LENGTH(&data->list) - screen_size_y(s); data->callbackfn = callbackfn; - data->freefn = freefn; + if (data->callbackfn == NULL) + data->callbackfn = window_choose_default_callback; ARRAY_CONCAT(&data->old_list, &data->list); @@ -154,24 +156,95 @@ window_choose_init(struct window_pane *wp) } struct window_choose_data * -window_choose_data_create(struct cmd_ctx *ctx) +window_choose_data_create(int type, struct client *c, struct session *s) { struct window_choose_data *wcd; wcd = xmalloc(sizeof *wcd); + wcd->type = type; + wcd->ft = format_create(); wcd->ft_template = NULL; + wcd->command = NULL; + wcd->wl = NULL; - wcd->tree_session = NULL; - wcd->client = ctx->curclient; - wcd->session = ctx->curclient->session; + wcd->pane_id = -1; wcd->idx = -1; - wcd->type = 0; + + wcd->tree_session = NULL; + + wcd->start_client = c; + wcd->start_client->references++; + wcd->start_session = s; + wcd->start_session->references++; return (wcd); } +void +window_choose_data_free(struct window_choose_data *wcd) +{ + wcd->start_client->references--; + wcd->start_session->references--; + + if (wcd->tree_session != NULL) + wcd->tree_session->references--; + + free(wcd->ft_template); + format_free(wcd->ft); + + free(wcd->command); + free(wcd); +} + +void +window_choose_data_run(struct window_choose_data *cdata) +{ + struct cmd_ctx ctx; + struct cmd_list *cmdlist; + char *cause; + + /* + * The command template will have already been replaced. But if it's + * NULL, bail here. + */ + if (cdata->command == NULL) + return; + + if (cmd_string_parse(cdata->command, &cmdlist, &cause) != 0) { + if (cause != NULL) { + *cause = toupper((u_char) *cause); + status_message_set(cdata->start_client, "%s", cause); + free(cause); + } + return; + } + + ctx.msgdata = NULL; + ctx.curclient = cdata->start_client; + + ctx.error = key_bindings_error; + ctx.print = key_bindings_print; + ctx.info = key_bindings_info; + + ctx.cmdclient = NULL; + + cmd_list_exec(cmdlist, &ctx); + cmd_list_free(cmdlist); +} + +void +window_choose_default_callback(struct window_choose_data *wcd) +{ + if (wcd == NULL) + return; + if (wcd->start_client->flags & CLIENT_DEAD) + return; + + window_choose_data_run(wcd); +} + void window_choose_free(struct window_pane *wp) { @@ -181,8 +254,7 @@ window_choose_free(struct window_pane *wp) for (i = 0; i < ARRAY_LENGTH(&data->old_list); i++) { item = &ARRAY_ITEM(&data->old_list, i); - if (data->freefn != NULL && item->wcd != NULL) - data->freefn(item->wcd); + window_choose_data_free(item->wcd); free(item->name); } ARRAY_FREE(&data->list); @@ -209,7 +281,7 @@ window_choose_resize(struct window_pane *wp, u_int sx, u_int sy) void window_choose_fire_callback( - struct window_pane *wp, struct window_choose_data *wcd) + struct window_pane *wp, struct window_choose_data *wcd) { struct window_choose_mode_data *data = wp->modedata; const struct window_mode *oldmode; @@ -299,7 +371,7 @@ window_choose_collapse_all(struct window_pane *wp) struct session *s, *chosen; u_int i; - chosen = ARRAY_ITEM(&data->list, data->selected).wcd->session; + chosen = ARRAY_ITEM(&data->list, data->selected).wcd->start_session; RB_FOREACH(s, sessions, &sessions) window_choose_collapse(wp, s); @@ -790,58 +862,23 @@ window_choose_scroll_down(struct window_pane *wp) screen_write_stop(&ctx); } -void -window_choose_ctx(struct window_choose_data *cdata) -{ - struct cmd_ctx ctx; - struct cmd_list *cmdlist; - char *cause; - - /* The command template will have already been replaced. But if it's - * NULL, bail here. - */ - if (cdata->command == NULL) - return; - - if (cmd_string_parse(cdata->command, &cmdlist, &cause) != 0) { - if (cause != NULL) { - *cause = toupper((u_char) *cause); - status_message_set(cdata->client, "%s", cause); - free(cause); - } - return; - } - - ctx.msgdata = NULL; - ctx.curclient = cdata->client; - - ctx.error = key_bindings_error; - ctx.print = key_bindings_print; - ctx.info = key_bindings_info; - - ctx.cmdclient = NULL; - - cmd_list_exec(cmdlist, &ctx); - cmd_list_free(cmdlist); -} - struct window_choose_data * -window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx, +window_choose_add_session(struct window_pane *wp, struct client *c, struct session *s, const char *template, char *action, u_int idx) { struct window_choose_data *wcd; - wcd = window_choose_data_create(ctx); + wcd = window_choose_data_create(TREE_SESSION, c, c->session); wcd->idx = s->idx; + wcd->tree_session = s; - wcd->type = TREE_SESSION; - wcd->command = cmd_template_replace(action, s->name, 1); + wcd->tree_session->references++; + wcd->ft_template = xstrdup(template); format_add(wcd->ft, "line", "%u", idx); format_session(wcd->ft, s); - wcd->client->references++; - wcd->session->references++; + wcd->command = cmd_template_replace(action, s->name, 1); window_choose_add(wp, wcd); @@ -849,63 +886,60 @@ window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx, } struct window_choose_data * -window_choose_add_item(struct window_pane *wp, struct cmd_ctx *ctx, +window_choose_add_item(struct window_pane *wp, struct client *c, struct winlink *wl, const char *template, char *action, u_int idx) { struct window_choose_data *wcd; - char *action_data; + char *expanded; - wcd = window_choose_data_create(ctx); + wcd = window_choose_data_create(TREE_OTHER, c, c->session); wcd->idx = wl->idx; + wcd->ft_template = xstrdup(template); format_add(wcd->ft, "line", "%u", idx); - format_session(wcd->ft, wcd->session); - format_winlink(wcd->ft, wcd->session, wl); + format_session(wcd->ft, wcd->start_session); + format_winlink(wcd->ft, wcd->start_session, wl); format_window_pane(wcd->ft, wl->window->active); - wcd->client->references++; - wcd->session->references++; - - window_choose_add(wp, wcd); - /* - * Interpolate action_data here, since the data we pass back is the - * expanded template itself. + * Interpolate action here, since the data we pass back is the expanded + * template itself. */ - xasprintf(&action_data, "%s", format_expand(wcd->ft, wcd->ft_template)); - wcd->command = cmd_template_replace(action, action_data, 1); - free(action_data); + xasprintf(&expanded, "%s", format_expand(wcd->ft, wcd->ft_template)); + wcd->command = cmd_template_replace(action, expanded, 1); + free(expanded); + + window_choose_add(wp, wcd); return (wcd); } struct window_choose_data * -window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx, +window_choose_add_window(struct window_pane *wp, struct client *c, struct session *s, struct winlink *wl, const char *template, char *action, u_int idx) { struct window_choose_data *wcd; - char *action_data; - - wcd = window_choose_data_create(ctx); - - xasprintf(&action_data, "%s:%d", s->name, wl->idx); - wcd->command = cmd_template_replace(action, action_data, 1); - free(action_data); + char *expanded; + wcd = window_choose_data_create(TREE_WINDOW, c, c->session); wcd->idx = wl->idx; + wcd->wl = wl; + wcd->tree_session = s; - wcd->type = TREE_WINDOW; + wcd->tree_session->references++; + wcd->ft_template = xstrdup(template); format_add(wcd->ft, "line", "%u", idx); format_session(wcd->ft, s); format_winlink(wcd->ft, s, wl); format_window_pane(wcd->ft, wl->window->active); - wcd->client->references++; - wcd->session->references++; + xasprintf(&expanded, "%s:%d", s->name, wl->idx); + wcd->command = cmd_template_replace(action, expanded, 1); + free(expanded); window_choose_add(wp, wcd); -- cgit v1.2.3