From b992c5e6a1cecafa0cd3133b767bd460f50d0057 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 25 Jun 2012 14:08:56 +0000 Subject: Clean up and simplify the choose mode code, from Thomas Adam. --- usr.bin/tmux/cmd-choose-buffer.c | 92 ++++++++++--------------------- usr.bin/tmux/cmd-choose-client.c | 90 +++++++++++------------------- usr.bin/tmux/cmd-choose-session.c | 93 +++++++++++-------------------- usr.bin/tmux/cmd-choose-window.c | 103 ++++++++++++----------------------- usr.bin/tmux/cmd-find-window.c | 61 ++++++++++----------- usr.bin/tmux/tmux.h | 28 ++++++++-- usr.bin/tmux/window-choose.c | 112 ++++++++++++++++++++++++++------------ 7 files changed, 256 insertions(+), 323 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/tmux/cmd-choose-buffer.c b/usr.bin/tmux/cmd-choose-buffer.c index 2513ab35981..056c7138d0c 100644 --- a/usr.bin/tmux/cmd-choose-buffer.c +++ b/usr.bin/tmux/cmd-choose-buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-choose-buffer.c,v 1.5 2012/05/22 11:35:37 nicm Exp $ */ +/* $OpenBSD: cmd-choose-buffer.c,v 1.6 2012/06/25 14:08:55 nicm Exp $ */ /* * Copyright (c) 2010 Nicholas Marriott @@ -28,8 +28,8 @@ int cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *); -void cmd_choose_buffer_callback(void *, int); -void cmd_choose_buffer_free(void *); +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, @@ -41,21 +41,14 @@ const struct cmd_entry cmd_choose_buffer_entry = { cmd_choose_buffer_exec }; -struct cmd_choose_buffer_data { - struct client *client; - char *template; -}; - int cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; - struct cmd_choose_buffer_data *cdata; + struct window_choose_data *cdata; struct winlink *wl; struct paste_buffer *pb; - struct format_tree *ft; u_int idx; - char *line; const char *template; if (ctx->curclient == NULL) { @@ -77,77 +70,52 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) idx = 0; while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) { - ft = format_create(); - format_add(ft, "line", "%u", idx - 1); - format_paste_buffer(ft, pb); + cdata = window_choose_data_create(ctx); + if (args->argc != 0) + cdata->action = xstrdup(args->argv[0]); + else + cdata->action = xstrdup("paste-buffer -b '%%'"); - line = format_expand(ft, template); - window_choose_add(wl->window->active, idx - 1, "%s", line); + cdata->idx = idx - 1; + cdata->client->references++; - xfree(line); - format_free(ft); - } + cdata->ft_template = xstrdup(template); + format_add(cdata->ft, "line", "%u", idx - 1); + format_paste_buffer(cdata->ft, pb); - cdata = xmalloc(sizeof *cdata); - if (args->argc != 0) - cdata->template = xstrdup(args->argv[0]); - else - cdata->template = xstrdup("paste-buffer -b '%%'"); - cdata->client = ctx->curclient; - cdata->client->references++; + window_choose_add(wl->window->active, cdata); + } window_choose_ready(wl->window->active, - 0, cmd_choose_buffer_callback, cmd_choose_buffer_free, cdata); + 0, cmd_choose_buffer_callback, cmd_choose_buffer_free); return (0); } void -cmd_choose_buffer_callback(void *data, int idx) +cmd_choose_buffer_callback(struct window_choose_data *cdata) { - struct cmd_choose_buffer_data *cdata = data; - struct cmd_list *cmdlist; - struct cmd_ctx ctx; - char *template, *cause, tmp[16]; - - if (idx == -1) + if (cdata == NULL) return; if (cdata->client->flags & CLIENT_DEAD) return; - xsnprintf(tmp, sizeof tmp, "%u", idx); - template = cmd_template_replace(cdata->template, tmp, 1); - - if (cmd_string_parse(template, &cmdlist, &cause) != 0) { - if (cause != NULL) { - *cause = toupper((u_char) *cause); - status_message_set(cdata->client, "%s", cause); - xfree(cause); - } - xfree(template); - return; - } - xfree(template); - - 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); + xasprintf(&cdata->raw_format, "%u", cdata->idx); + window_choose_ctx(cdata); } void -cmd_choose_buffer_free(void *data) +cmd_choose_buffer_free(struct window_choose_data *data) { - struct cmd_choose_buffer_data *cdata = data; + struct window_choose_data *cdata = data; + + if (cdata == NULL) + return; cdata->client->references--; - xfree(cdata->template); + + xfree(cdata->ft_template); + xfree(cdata->action); + xfree(cdata->raw_format); xfree(cdata); } diff --git a/usr.bin/tmux/cmd-choose-client.c b/usr.bin/tmux/cmd-choose-client.c index 0c8c094e471..2e0ada2dfb5 100644 --- a/usr.bin/tmux/cmd-choose-client.c +++ b/usr.bin/tmux/cmd-choose-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-choose-client.c,v 1.7 2012/05/22 11:35:37 nicm Exp $ */ +/* $OpenBSD: cmd-choose-client.c,v 1.8 2012/06/25 14:08:55 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -28,8 +28,8 @@ int cmd_choose_client_exec(struct cmd *, struct cmd_ctx *); -void cmd_choose_client_callback(void *, int); -void cmd_choose_client_free(void *); +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,11 +50,9 @@ int cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; - struct cmd_choose_client_data *cdata; - struct format_tree *ft; + struct window_choose_data *cdata; struct winlink *wl; struct client *c; - char *line; const char *template; u_int i, idx, cur; @@ -81,83 +79,59 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) cur = idx; idx++; - ft = format_create(); - format_add(ft, "line", "%u", i); - format_session(ft, c->session); - format_client(ft, c); + cdata = window_choose_data_create(ctx); + if (args->argc != 0) + cdata->action = xstrdup(args->argv[0]); + else + cdata->action = xstrdup("detach-client -t '%%'"); - line = format_expand(ft, template); - window_choose_add(wl->window->active, i, "%s", line); - xfree(line); + cdata->idx = i; + cdata->client->references++; - format_free(ft); - } + cdata->ft_template = xstrdup(template); + format_add(cdata->ft, "line", "%u", i); + format_session(cdata->ft, c->session); + format_client(cdata->ft, c); - cdata = xmalloc(sizeof *cdata); - if (args->argc != 0) - cdata->template = xstrdup(args->argv[0]); - else - cdata->template = xstrdup("detach-client -t '%%'"); - cdata->client = ctx->curclient; - cdata->client->references++; + window_choose_add(wl->window->active, cdata); + } window_choose_ready(wl->window->active, - cur, cmd_choose_client_callback, cmd_choose_client_free, cdata); + cur, cmd_choose_client_callback, cmd_choose_client_free); return (0); } void -cmd_choose_client_callback(void *data, int idx) +cmd_choose_client_callback(struct window_choose_data *cdata) { - struct cmd_choose_client_data *cdata = data; - struct client *c; - struct cmd_list *cmdlist; - struct cmd_ctx ctx; - char *template, *cause; + struct client *c; - if (idx == -1) + if (cdata == NULL) return; if (cdata->client->flags & CLIENT_DEAD) return; - if ((u_int) idx > ARRAY_LENGTH(&clients) - 1) + if (cdata->idx > ARRAY_LENGTH(&clients) - 1) return; - c = ARRAY_ITEM(&clients, idx); + c = ARRAY_ITEM(&clients, cdata->idx); if (c == NULL || c->session == NULL) return; - template = cmd_template_replace(cdata->template, c->tty.path, 1); - - if (cmd_string_parse(template, &cmdlist, &cause) != 0) { - if (cause != NULL) { - *cause = toupper((u_char) *cause); - status_message_set(c, "%s", cause); - xfree(cause); - } - xfree(template); - return; - } - xfree(template); - - 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); + xasprintf(&cdata->raw_format, "%s", c->tty.path); + window_choose_ctx(cdata); } void -cmd_choose_client_free(void *data) +cmd_choose_client_free(struct window_choose_data *cdata) { - struct cmd_choose_client_data *cdata = data; + if (cdata == NULL) + return; cdata->client->references--; - xfree(cdata->template); + + xfree(cdata->ft_template); + xfree(cdata->action); + format_free(cdata->ft); xfree(cdata); } diff --git a/usr.bin/tmux/cmd-choose-session.c b/usr.bin/tmux/cmd-choose-session.c index 4de6f9ea8f6..78597f9f3ca 100644 --- a/usr.bin/tmux/cmd-choose-session.c +++ b/usr.bin/tmux/cmd-choose-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-choose-session.c,v 1.13 2012/05/22 11:35:37 nicm Exp $ */ +/* $OpenBSD: cmd-choose-session.c,v 1.14 2012/06/25 14:08:55 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -28,8 +28,8 @@ int cmd_choose_session_exec(struct cmd *, struct cmd_ctx *); -void cmd_choose_session_callback(void *, int); -void cmd_choose_session_free(void *); +void cmd_choose_session_callback(struct window_choose_data *); +void cmd_choose_session_free(struct window_choose_data *); const struct cmd_entry cmd_choose_session_entry = { "choose-session", NULL, @@ -41,21 +41,14 @@ const struct cmd_entry cmd_choose_session_entry = { cmd_choose_session_exec }; -struct cmd_choose_session_data { - struct client *client; - char *template; -}; - int cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; - struct cmd_choose_session_data *cdata; + struct window_choose_data *cdata; struct winlink *wl; struct session *s; - struct format_tree *ft; const char *template; - char *line; u_int idx, cur; if (ctx->curclient == NULL) { @@ -78,80 +71,58 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx) cur = idx; idx++; - ft = format_create(); - format_add(ft, "line", "%u", idx); - format_session(ft, s); + cdata = window_choose_data_create(ctx); + if (args->argc != 0) + cdata->action = xstrdup(args->argv[0]); + else + cdata->action = xstrdup("switch-client -t '%%'"); + cdata->idx = s->idx; - line = format_expand(ft, template); - window_choose_add(wl->window->active, s->idx, "%s", line); - xfree(line); + cdata->client->references++; + cdata->session->references++; - format_free(ft); - } + cdata->ft_template = xstrdup(template); + format_add(cdata->ft, "line", "%u", idx); + format_session(cdata->ft, s); - cdata = xmalloc(sizeof *cdata); - if (args->argc != 0) - cdata->template = xstrdup(args->argv[0]); - else - cdata->template = xstrdup("switch-client -t '%%'"); - cdata->client = ctx->curclient; - cdata->client->references++; + window_choose_add(wl->window->active, cdata); + } window_choose_ready(wl->window->active, - cur, cmd_choose_session_callback, cmd_choose_session_free, cdata); + cur, cmd_choose_session_callback, cmd_choose_session_free); return (0); } void -cmd_choose_session_callback(void *data, int idx) +cmd_choose_session_callback(struct window_choose_data *cdata) { - struct cmd_choose_session_data *cdata = data; - struct session *s; - struct cmd_list *cmdlist; - struct cmd_ctx ctx; - char *template, *cause; + struct session *s; - if (idx == -1) + if (cdata == NULL) return; if (cdata->client->flags & CLIENT_DEAD) return; - s = session_find_by_index(idx); + s = session_find_by_index(cdata->idx); if (s == NULL) return; - template = cmd_template_replace(cdata->template, s->name, 1); - - if (cmd_string_parse(template, &cmdlist, &cause) != 0) { - if (cause != NULL) { - *cause = toupper((u_char) *cause); - status_message_set(cdata->client, "%s", cause); - xfree(cause); - } - xfree(template); - return; - } - xfree(template); - - 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); + cdata->raw_format = xstrdup(s->name); + window_choose_ctx(cdata); } void -cmd_choose_session_free(void *data) +cmd_choose_session_free(struct window_choose_data *cdata) { - struct cmd_choose_session_data *cdata = data; + if (cdata == NULL) + return; cdata->client->references--; - xfree(cdata->template); + cdata->session->references--; + + xfree(cdata->ft_template); + xfree(cdata->action); + format_free(cdata->ft); xfree(cdata); } diff --git a/usr.bin/tmux/cmd-choose-window.c b/usr.bin/tmux/cmd-choose-window.c index cfcad5bb303..fbc4411860e 100644 --- a/usr.bin/tmux/cmd-choose-window.c +++ b/usr.bin/tmux/cmd-choose-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-choose-window.c,v 1.20 2012/05/29 08:15:45 nicm Exp $ */ +/* $OpenBSD: cmd-choose-window.c,v 1.21 2012/06/25 14:08:55 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -28,8 +28,8 @@ int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *); -void cmd_choose_window_callback(void *, int); -void cmd_choose_window_free(void *); +void cmd_choose_window_callback(struct window_choose_data *); +void cmd_choose_window_free(struct window_choose_data *); const struct cmd_entry cmd_choose_window_entry = { "choose-window", NULL, @@ -41,22 +41,14 @@ const struct cmd_entry cmd_choose_window_entry = { cmd_choose_window_exec }; -struct cmd_choose_window_data { - struct client *client; - struct session *session; - char *template; -}; - int cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; - struct cmd_choose_window_data *cdata; + struct window_choose_data *cdata; struct session *s; struct winlink *wl, *wm; - struct format_tree *ft; const char *template; - char *line; u_int idx, cur; if (ctx->curclient == NULL) { @@ -80,86 +72,59 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx) cur = idx; idx++; - ft = format_create(); - format_add(ft, "line", "%u", idx); - format_session(ft, s); - format_winlink(ft, s, wm); - format_window_pane(ft, wm->window->active); + cdata = window_choose_data_create(ctx); + if (args->argc != 0) + cdata->action = xstrdup(args->argv[0]); + else + cdata->action = xstrdup("select-window -t '%%'"); - line = format_expand(ft, template); - window_choose_add(wl->window->active, wm->idx, "%s", line); - - xfree(line); - format_free(ft); - } + cdata->idx = wm->idx; + cdata->client->references++; + cdata->session->references++; - cdata = xmalloc(sizeof *cdata); - if (args->argc != 0) - cdata->template = xstrdup(args->argv[0]); - else - cdata->template = xstrdup("select-window -t '%%'"); - cdata->session = s; - cdata->session->references++; - cdata->client = ctx->curclient; - cdata->client->references++; + cdata->ft_template = xstrdup(template); + format_add(cdata->ft, "line", "%u", idx); + format_session(cdata->ft, s); + format_winlink(cdata->ft, s, wm); + format_window_pane(cdata->ft, wm->window->active); + window_choose_add(wl->window->active, cdata); + } window_choose_ready(wl->window->active, - cur, cmd_choose_window_callback, cmd_choose_window_free, cdata); + cur, cmd_choose_window_callback, cmd_choose_window_free); return (0); } void -cmd_choose_window_callback(void *data, int idx) +cmd_choose_window_callback(struct window_choose_data *cdata) { - struct cmd_choose_window_data *cdata = data; - struct session *s = cdata->session; - struct cmd_list *cmdlist; - struct cmd_ctx ctx; - char *target, *template, *cause; + struct session *s; - if (idx == -1) - return; - if (!session_alive(s)) + if (cdata == NULL) return; if (cdata->client->flags & CLIENT_DEAD) return; - xasprintf(&target, "%s:%d", s->name, idx); - template = cmd_template_replace(cdata->template, target, 1); - xfree(target); - - if (cmd_string_parse(template, &cmdlist, &cause) != 0) { - if (cause != NULL) { - *cause = toupper((u_char) *cause); - status_message_set(cdata->client, "%s", cause); - xfree(cause); - } - xfree(template); + s = cdata->session; + if (!session_alive(s)) return; - } - xfree(template); - - 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); + xasprintf(&cdata->raw_format, "%s:%u", s->name, cdata->idx); + window_choose_ctx(cdata); } void -cmd_choose_window_free(void *data) +cmd_choose_window_free(struct window_choose_data *cdata) { - struct cmd_choose_window_data *cdata = data; + if (cdata == NULL) + return; cdata->session->references--; cdata->client->references--; - xfree(cdata->template); + + xfree(cdata->ft_template); + xfree(cdata->action); + format_free(cdata->ft); xfree(cdata); } diff --git a/usr.bin/tmux/cmd-find-window.c b/usr.bin/tmux/cmd-find-window.c index 0d8f726a905..76e7456d1d6 100644 --- a/usr.bin/tmux/cmd-find-window.c +++ b/usr.bin/tmux/cmd-find-window.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-find-window.c,v 1.14 2012/06/25 13:49:16 nicm Exp $ */ +/* $OpenBSD: cmd-find-window.c,v 1.15 2012/06/25 14:08:55 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -30,8 +30,8 @@ int cmd_find_window_exec(struct cmd *, struct cmd_ctx *); u_int cmd_find_window_match_flags(struct args *); -void cmd_find_window_callback(void *, int); -void cmd_find_window_free(void *); +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 @@ -53,10 +53,6 @@ const struct cmd_entry cmd_find_window_entry = { cmd_find_window_exec }; -struct cmd_find_window_data { - struct session *session; -}; - u_int cmd_find_window_match_flags(struct args *args) { @@ -81,15 +77,13 @@ int cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; - struct cmd_find_window_data *cdata; + struct window_choose_data *cdata; struct session *s; struct winlink *wl, *wm; struct window_pane *wp; - struct format_tree *ft; ARRAY_DECL(, u_int) list_idx; ARRAY_DECL(, char *) list_ctx; char *str, *sres, *sctx, *searchstr; - char *find_line; const char *template; u_int i, line, match_flags; @@ -172,29 +166,25 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) wm = winlink_find_by_index( &s->windows, ARRAY_ITEM(&list_idx, i)); - ft = format_create(); - format_add(ft, "line", "%u", i); - format_add(ft, "window_find_matches", "%s", - ARRAY_ITEM(&list_ctx, i)); - format_session(ft, s); - format_winlink(ft, s, wm); + cdata = window_choose_data_create(ctx); + cdata->idx = wm->idx; + cdata->client->references++; - find_line = format_expand(ft, template); - - window_choose_add(wl->window->active, wm->idx, "%s", find_line); + cdata->ft_template = xstrdup(template); + format_add(cdata->ft, "line", "%u", i); + format_add(cdata->ft, "window_find_matches", "%s", + ARRAY_ITEM(&list_ctx, i)); + format_session(cdata->ft, s); + format_winlink(cdata->ft, s, wm); - xfree(find_line); - format_free(ft); + window_choose_add(wl->window->active, cdata); } - cdata = xmalloc(sizeof *cdata); - cdata->session = s; - cdata->session->references++; - window_choose_ready(wl->window->active, - 0, cmd_find_window_callback, cmd_find_window_free, cdata); + 0, cmd_find_window_callback, cmd_find_window_free); out: + ARRAY_FREE(&list_idx); ARRAY_FREE(&list_ctx); @@ -202,27 +192,32 @@ out: } void -cmd_find_window_callback(void *data, int idx) +cmd_find_window_callback(struct window_choose_data *cdata) { - struct cmd_find_window_data *cdata = data; - struct session *s = cdata->session; + struct session *s; - if (idx == -1) + if (cdata == NULL) return; + + s = cdata->session; if (!session_alive(s)) return; - if (session_select(s, idx) == 0) { + if (session_select(s, cdata->idx) == 0) { server_redraw_session(s); recalculate_sizes(); } } void -cmd_find_window_free(void *data) +cmd_find_window_free(struct window_choose_data *cdata) { - struct cmd_find_window_data *cdata = data; + if (cdata == NULL) + return; cdata->session->references--; + + xfree(cdata->ft_template); + format_free(cdata->ft); xfree(cdata); } diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 1449f0175b5..cab0b5ca92c 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.342 2012/06/18 13:16:42 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.343 2012/06/25 14:08:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -846,6 +846,22 @@ struct window_mode { void (*timer)(struct window_pane *); }; +/* Structures for choose mode. */ +struct window_choose_data { + struct client *client; + struct session *session; + struct format_tree *ft; + char *ft_template; + char *raw_format; + char *action; + u_int idx; +}; + +struct window_choose_mode_item { + struct window_choose_data *wcd; + char *name; +}; + /* Child window structure. */ struct window_pane { u_int id; @@ -2121,10 +2137,14 @@ void window_copy_pageup(struct window_pane *); extern const struct window_mode window_choose_mode; void window_choose_vadd( struct window_pane *, int, const char *, va_list); -void printflike3 window_choose_add( - struct window_pane *, int, const char *, ...); +void window_choose_add(struct window_pane *, + struct window_choose_data *); void window_choose_ready(struct window_pane *, - u_int, void (*)(void *, int), void (*)(void *), void *); + 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 *); /* names.c */ void queue_window_name(struct window *); diff --git a/usr.bin/tmux/window-choose.c b/usr.bin/tmux/window-choose.c index 846748dfe1d..6a555193e2a 100644 --- a/usr.bin/tmux/window-choose.c +++ b/usr.bin/tmux/window-choose.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-choose.c,v 1.18 2012/04/23 22:40:47 nicm Exp $ */ +/* $OpenBSD: window-choose.c,v 1.19 2012/06/25 14:08:55 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -18,6 +18,7 @@ #include +#include #include #include "tmux.h" @@ -29,7 +30,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_fire_callback(struct window_pane *, int); +void window_choose_fire_callback( + struct window_pane *, struct window_choose_data *); void window_choose_redraw_screen(struct window_pane *); void window_choose_write_line( struct window_pane *, struct screen_write_ctx *, u_int); @@ -46,11 +48,6 @@ const struct window_mode window_choose_mode = { NULL, }; -struct window_choose_mode_item { - char *name; - int idx; -}; - struct window_choose_mode_data { struct screen screen; @@ -60,39 +57,30 @@ struct window_choose_mode_data { u_int top; u_int selected; - void (*callbackfn)(void *, int); - void (*freefn)(void *); - void *data; + void (*callbackfn)(struct window_choose_data *); + void (*freefn)(struct window_choose_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_vadd(struct window_pane *wp, int idx, const char *fmt, va_list ap) +window_choose_add(struct window_pane *wp, struct window_choose_data *wcd) { struct window_choose_mode_data *data = wp->modedata; struct window_choose_mode_item *item; ARRAY_EXPAND(&data->list, 1); item = &ARRAY_LAST(&data->list); - xvasprintf(&item->name, fmt, ap); - item->idx = idx; -} -void printflike3 -window_choose_add(struct window_pane *wp, int idx, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - window_choose_vadd(wp, idx, fmt, ap); - va_end(ap); + item->name = format_expand(wcd->ft, wcd->ft_template); + item->wcd = wcd; } void window_choose_ready(struct window_pane *wp, u_int cur, - void (*callbackfn)(void *, int), void (*freefn)(void *), void *cdata) + void (*callbackfn)(struct window_choose_data *), + void (*freefn)(struct window_choose_data *)) { struct window_choose_mode_data *data = wp->modedata; struct screen *s = &data->screen; @@ -103,7 +91,6 @@ window_choose_ready(struct window_pane *wp, u_int cur, data->callbackfn = callbackfn; data->freefn = freefn; - data->data = cdata; window_choose_redraw_screen(wp); } @@ -119,7 +106,6 @@ window_choose_init(struct window_pane *wp) data->callbackfn = NULL; data->freefn = NULL; - data->data = NULL; ARRAY_INIT(&data->list); data->top = 0; @@ -139,17 +125,36 @@ window_choose_init(struct window_pane *wp) return (s); } +struct window_choose_data * +window_choose_data_create(struct cmd_ctx *ctx) +{ + struct window_choose_data *wcd; + + wcd = xmalloc(sizeof *wcd); + wcd->ft = format_create(); + wcd->ft_template = NULL; + wcd->action = NULL; + wcd->raw_format = NULL; + wcd->client = ctx->curclient; + wcd->session = ctx->curclient->session; + wcd->idx = -1; + + return (wcd); +} + void window_choose_free(struct window_pane *wp) { struct window_choose_mode_data *data = wp->modedata; + struct window_choose_mode_item *item; u_int i; - if (data->freefn != NULL && data->data != NULL) - data->freefn(data->data); - - for (i = 0; i < ARRAY_LENGTH(&data->list); i++) - xfree(ARRAY_ITEM(&data->list, i).name); + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) { + item = &ARRAY_ITEM(&data->list, i); + if (data->freefn != NULL && item->wcd != NULL) + data->freefn(item->wcd); + xfree(item->name); + } ARRAY_FREE(&data->list); screen_free(&data->screen); @@ -171,7 +176,8 @@ window_choose_resize(struct window_pane *wp, u_int sx, u_int sy) } void -window_choose_fire_callback(struct window_pane *wp, int idx) +window_choose_fire_callback( + struct window_pane *wp, struct window_choose_data *wcd) { struct window_choose_mode_data *data = wp->modedata; const struct window_mode *oldmode; @@ -179,7 +185,7 @@ window_choose_fire_callback(struct window_pane *wp, int idx) oldmode = wp->mode; wp->mode = NULL; - data->callbackfn(data->data, idx); + data->callbackfn(wcd); wp->mode = oldmode; } @@ -199,12 +205,12 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) switch (mode_key_lookup(&data->mdata, key)) { case MODEKEYCHOICE_CANCEL: - window_choose_fire_callback(wp, -1); + 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->idx); + window_choose_fire_callback(wp, item->wcd); window_pane_reset_mode(wp); break; case MODEKEYCHOICE_UP: @@ -310,7 +316,7 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) data->selected = idx; item = &ARRAY_ITEM(&data->list, data->selected); - window_choose_fire_callback(wp, item->idx); + window_choose_fire_callback(wp, item->wcd); window_pane_reset_mode(wp); break; } @@ -339,7 +345,7 @@ window_choose_mouse( data->selected = idx; item = &ARRAY_ITEM(&data->list, data->selected); - window_choose_fire_callback(wp, item->idx); + window_choose_fire_callback(wp, item->wcd); window_pane_reset_mode(wp); } @@ -470,3 +476,37 @@ window_choose_scroll_down(struct window_pane *wp) window_choose_write_line(wp, &ctx, screen_size_y(s) - 2); screen_write_stop(&ctx); } + +void +window_choose_ctx(struct window_choose_data *cdata) +{ + struct cmd_ctx ctx; + struct cmd_list *cmdlist; + char *template, *cause; + + template = cmd_template_replace(cdata->action, + cdata->raw_format, 1); + + if (cmd_string_parse(template, &cmdlist, &cause) != 0) { + if (cause != NULL) { + *cause = toupper((u_char) *cause); + status_message_set(cdata->client, "%s", cause); + xfree(cause); + } + xfree(template); + return; + } + xfree(template); + + 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); +} -- cgit v1.2.3