diff options
Diffstat (limited to 'window-choose.c')
-rw-r--r-- | window-choose.c | 228 |
1 files changed, 126 insertions, 102 deletions
diff --git a/window-choose.c b/window-choose.c index 6dc149f0..3c68d101 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 *); @@ -73,9 +75,9 @@ struct window_choose_mode_data { char *input_str; void (*callbackfn)(struct window_choose_data *); - void (*freefn)(struct window_choose_data *); }; +void window_choose_free1(struct window_choose_mode_data *); int window_choose_key_index(struct window_choose_mode_data *, u_int); int window_choose_index_key(struct window_choose_mode_data *, int); void window_choose_prompt_input(enum window_choose_input_type, @@ -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); @@ -129,7 +131,6 @@ window_choose_init(struct window_pane *wp) wp->modedata = data = xmalloc(sizeof *data); data->callbackfn = NULL; - data->freefn = NULL; data->input_type = WINDOW_CHOOSE_NORMAL; data->input_str = xstrdup(""); data->input_prompt = NULL; @@ -154,35 +155,104 @@ 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_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, NULL, 0, &cause) != 0) { + if (cause != NULL) { + *cause = toupper((u_char) *cause); + status_message_set(cdata->start_client, "%s", cause); + free(cause); + } + return; + } + + cmdq_run(cdata->start_client->cmdq, cmdlist); + 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) { - struct window_choose_mode_data *data = wp->modedata; + if (wp->modedata != NULL) + window_choose_free1(wp->modedata); +} + +void +window_choose_free1(struct window_choose_mode_data *data) +{ struct window_choose_mode_item *item; u_int i; + if (data == NULL) + return; + 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,17 +279,16 @@ 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; - oldmode = wp->mode; - wp->mode = NULL; + wp->modedata = NULL; + window_pane_reset_mode(wp); data->callbackfn(wcd); - wp->mode = oldmode; + window_choose_free1(data); } void @@ -299,7 +368,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); @@ -401,7 +470,6 @@ window_choose_expand(struct window_pane *wp, struct session *s, u_int pos) } } -/* ARGSUSED */ void window_choose_key(struct window_pane *wp, unused struct session *sess, int key) { @@ -416,7 +484,7 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) items = ARRAY_LENGTH(&data->list); if (data->input_type == WINDOW_CHOOSE_GOTO_ITEM) { - switch (mode_key_lookup(&data->mdata, key)) { + switch (mode_key_lookup(&data->mdata, key, NULL)) { case MODEKEYCHOICE_CANCEL: data->input_type = WINDOW_CHOOSE_NORMAL; window_choose_redraw_screen(wp); @@ -430,7 +498,6 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) } item = &ARRAY_ITEM(&data->list, n); window_choose_fire_callback(wp, item->wcd); - window_pane_reset_mode(wp); break; case MODEKEYCHOICE_BACKSPACE: input_len = strlen(data->input_str); @@ -448,15 +515,13 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) return; } - switch (mode_key_lookup(&data->mdata, key)) { + switch (mode_key_lookup(&data->mdata, key, NULL)) { case MODEKEYCHOICE_CANCEL: window_choose_fire_callback(wp, NULL); - window_pane_reset_mode(wp); break; case MODEKEYCHOICE_CHOOSE: item = &ARRAY_ITEM(&data->list, data->selected); window_choose_fire_callback(wp, item->wcd); - window_pane_reset_mode(wp); break; case MODEKEYCHOICE_TREE_TOGGLE: item = &ARRAY_ITEM(&data->list, data->selected); @@ -606,12 +671,10 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) item = &ARRAY_ITEM(&data->list, data->selected); window_choose_fire_callback(wp, item->wcd); - window_pane_reset_mode(wp); break; } } -/* ARGSUSED */ void window_choose_mouse( struct window_pane *wp, unused struct session *sess, struct mouse_event *m) @@ -635,7 +698,6 @@ window_choose_mouse( item = &ARRAY_ITEM(&data->list, data->selected); window_choose_fire_callback(wp, item->wcd); - window_pane_reset_mode(wp); } void @@ -681,7 +743,7 @@ window_choose_write_line( (item->wcd->type & TREE_SESSION) ? (item->state & TREE_EXPANDED ? "-" : "+") : "", item->name); } - while (s->cx < screen_size_x(s)) + while (s->cx < screen_size_x(s) - 1) screen_write_putc(ctx, &gc, ' '); if (data->input_type != WINDOW_CHOOSE_NORMAL) { @@ -707,7 +769,7 @@ window_choose_key_index(struct window_choose_mode_data *data, u_int idx) int mkey; for (ptr = keys; *ptr != '\0'; ptr++) { - mkey = mode_key_lookup(&data->mdata, *ptr); + mkey = mode_key_lookup(&data->mdata, *ptr, NULL); if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) continue; if (idx-- == 0) @@ -727,7 +789,7 @@ window_choose_index_key(struct window_choose_mode_data *data, int key) u_int idx = 0; for (ptr = keys; *ptr != '\0'; ptr++) { - mkey = mode_key_lookup(&data->mdata, *ptr); + mkey = mode_key_lookup(&data->mdata, *ptr, NULL); if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) continue; if (key == *ptr) @@ -790,58 +852,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, - struct session *s, const char *template, char *action, u_int idx) +window_choose_add_session(struct window_pane *wp, struct client *c, + struct session *s, const char *template, const char *action, u_int idx) { struct window_choose_data *wcd; - wcd = window_choose_data_create(ctx); - wcd->idx = s->idx; + wcd = window_choose_data_create(TREE_SESSION, c, c->session); + wcd->idx = s->id; + 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 +876,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, - struct winlink *wl, const char *template, char *action, u_int idx) +window_choose_add_item(struct window_pane *wp, struct client *c, + struct winlink *wl, const char *template, const 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) + const 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); |