summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2012-06-25 14:27:25 +0000
committerNicholas Marriott <nicm@openbsd.org>2012-06-25 14:27:25 +0000
commit67b926cf3c77737e3b40c9d70c38314ac19ba105 (patch)
tree70e11d99991264920f3a063dc4cdccb37522202f
parent5b6f78186c63a19e213eb8597efe69277556e038 (diff)
Provide common helper function for adding windows and sessions to choose
lists and expand %% in command before using it rather than at callback time. From Thomas Adam.
-rw-r--r--cmd-choose-buffer.c22
-rw-r--r--cmd-choose-client.c17
-rw-r--r--cmd-choose-session.c34
-rw-r--r--cmd-choose-window.c31
-rw-r--r--tmux.h14
-rw-r--r--window-choose.c66
6 files changed, 110 insertions, 74 deletions
diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c
index edef4d46..0baa0a28 100644
--- a/cmd-choose-buffer.c
+++ b/cmd-choose-buffer.c
@@ -48,8 +48,9 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_choose_data *cdata;
struct winlink *wl;
struct paste_buffer *pb;
- u_int idx;
+ char *action, *action_data;
const char *template;
+ u_int idx;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
@@ -68,14 +69,14 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
+ if (args->argc != 0)
+ action = xstrdup(args->argv[0]);
+ else
+ action = xstrdup("paste-buffer -b '%%'");
+
idx = 0;
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
cdata = window_choose_data_create(ctx);
- if (args->argc != 0)
- cdata->action = xstrdup(args->argv[0]);
- else
- cdata->action = xstrdup("paste-buffer -b '%%'");
-
cdata->idx = idx - 1;
cdata->client->references++;
@@ -83,8 +84,13 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
format_add(cdata->ft, "line", "%u", idx - 1);
format_paste_buffer(cdata->ft, pb);
+ xasprintf(&action_data, "%u", idx - 1);
+ cdata->command = cmd_template_replace(action, action_data, 1);
+ xfree(action_data);
+
window_choose_add(wl->window->active, cdata);
}
+ xfree(action);
window_choose_ready(wl->window->active,
0, cmd_choose_buffer_callback, cmd_choose_buffer_free);
@@ -100,7 +106,6 @@ cmd_choose_buffer_callback(struct window_choose_data *cdata)
if (cdata->client->flags & CLIENT_DEAD)
return;
- xasprintf(&cdata->raw_format, "%u", cdata->idx);
window_choose_ctx(cdata);
}
@@ -114,8 +119,7 @@ cmd_choose_buffer_free(struct window_choose_data *data)
cdata->client->references--;
+ xfree(cdata->command);
xfree(cdata->ft_template);
- xfree(cdata->action);
- xfree(cdata->raw_format);
xfree(cdata);
}
diff --git a/cmd-choose-client.c b/cmd-choose-client.c
index d12fc241..fd6b2128 100644
--- a/cmd-choose-client.c
+++ b/cmd-choose-client.c
@@ -54,6 +54,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl;
struct client *c;
const char *template;
+ char *action;
u_int i, idx, cur;
if (ctx->curclient == NULL) {
@@ -70,6 +71,11 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((template = args_get(args, 'F')) == NULL)
template = DEFAULT_CLIENT_TEMPLATE;
+ if (args->argc != 0)
+ action = xstrdup(args->argv[0]);
+ else
+ action = xstrdup("detach-client -t '%%'");
+
cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
@@ -80,11 +86,6 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
idx++;
cdata = window_choose_data_create(ctx);
- if (args->argc != 0)
- cdata->action = xstrdup(args->argv[0]);
- else
- cdata->action = xstrdup("detach-client -t '%%'");
-
cdata->idx = i;
cdata->client->references++;
@@ -93,8 +94,11 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
format_session(cdata->ft, c->session);
format_client(cdata->ft, c);
+ cdata->command = cmd_template_replace(action, c->tty.path, 1);
+
window_choose_add(wl->window->active, cdata);
}
+ xfree(action);
window_choose_ready(wl->window->active,
cur, cmd_choose_client_callback, cmd_choose_client_free);
@@ -118,7 +122,6 @@ cmd_choose_client_callback(struct window_choose_data *cdata)
if (c == NULL || c->session == NULL)
return;
- xasprintf(&cdata->raw_format, "%s", c->tty.path);
window_choose_ctx(cdata);
}
@@ -131,7 +134,7 @@ cmd_choose_client_free(struct window_choose_data *cdata)
cdata->client->references--;
xfree(cdata->ft_template);
- xfree(cdata->action);
+ xfree(cdata->command);
format_free(cdata->ft);
xfree(cdata);
}
diff --git a/cmd-choose-session.c b/cmd-choose-session.c
index b26d9d8f..2f30c309 100644
--- a/cmd-choose-session.c
+++ b/cmd-choose-session.c
@@ -45,9 +45,9 @@ int
cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
- struct window_choose_data *cdata;
struct winlink *wl;
struct session *s;
+ char *action;
const char *template;
u_int idx, cur;
@@ -65,28 +65,21 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((template = args_get(args, 'F')) == NULL)
template = DEFAULT_SESSION_TEMPLATE;
+ if (args->argc != 0)
+ action = xstrdup(args->argv[0]);
+ else
+ action = xstrdup("switch-client -t '%%'");
+
cur = idx = 0;
RB_FOREACH(s, sessions, &sessions) {
if (s == ctx->curclient->session)
cur = idx;
idx++;
- 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;
-
- cdata->client->references++;
- cdata->session->references++;
-
- cdata->ft_template = xstrdup(template);
- format_add(cdata->ft, "line", "%u", idx);
- format_session(cdata->ft, s);
-
- window_choose_add(wl->window->active, cdata);
+ window_choose_add_session(wl->window->active,
+ ctx, s, template, action, idx);
}
+ xfree(action);
window_choose_ready(wl->window->active,
cur, cmd_choose_session_callback, cmd_choose_session_free);
@@ -97,18 +90,11 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
void
cmd_choose_session_callback(struct window_choose_data *cdata)
{
- struct session *s;
-
if (cdata == NULL)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
- s = session_find_by_index(cdata->idx);
- if (s == NULL)
- return;
-
- cdata->raw_format = xstrdup(s->name);
window_choose_ctx(cdata);
}
@@ -121,8 +107,8 @@ cmd_choose_session_free(struct window_choose_data *cdata)
cdata->client->references--;
cdata->session->references--;
+ xfree(cdata->command);
xfree(cdata->ft_template);
- xfree(cdata->action);
format_free(cdata->ft);
xfree(cdata);
}
diff --git a/cmd-choose-window.c b/cmd-choose-window.c
index 4ccb7c02..3c8831eb 100644
--- a/cmd-choose-window.c
+++ b/cmd-choose-window.c
@@ -45,10 +45,10 @@ int
cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
- struct window_choose_data *cdata;
struct session *s;
struct winlink *wl, *wm;
const char *template;
+ char *action;
u_int idx, cur;
if (ctx->curclient == NULL) {
@@ -66,30 +66,22 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((template = args_get(args, 'F')) == NULL)
template = DEFAULT_WINDOW_TEMPLATE " \"#{pane_title}\"";
+ if (args->argc != 0)
+ action = xstrdup(args->argv[0]);
+ else
+ action = xstrdup("select-window -t '%%'");
+
cur = idx = 0;
RB_FOREACH(wm, winlinks, &s->windows) {
if (wm == s->curw)
cur = idx;
idx++;
- cdata = window_choose_data_create(ctx);
- if (args->argc != 0)
- cdata->action = xstrdup(args->argv[0]);
- else
- cdata->action = xstrdup("select-window -t '%%'");
-
- cdata->idx = wm->idx;
- cdata->client->references++;
- cdata->session->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_add_window(wl->window->active, ctx, s, wm,
+ template, action, idx);
}
+ xfree(action);
+
window_choose_ready(wl->window->active,
cur, cmd_choose_window_callback, cmd_choose_window_free);
@@ -110,7 +102,6 @@ cmd_choose_window_callback(struct window_choose_data *cdata)
if (!session_alive(s))
return;
- xasprintf(&cdata->raw_format, "%s:%u", s->name, cdata->idx);
window_choose_ctx(cdata);
}
@@ -124,7 +115,7 @@ cmd_choose_window_free(struct window_choose_data *cdata)
cdata->client->references--;
xfree(cdata->ft_template);
- xfree(cdata->action);
+ xfree(cdata->command);
format_free(cdata->ft);
xfree(cdata);
}
diff --git a/tmux.h b/tmux.h
index a27b56ad..f4e953c3 100644
--- a/tmux.h
+++ b/tmux.h
@@ -852,8 +852,7 @@ struct window_choose_data {
struct session *session;
struct format_tree *ft;
char *ft_template;
- char *raw_format;
- char *action;
+ char *command;
u_int idx;
};
@@ -2135,16 +2134,19 @@ void window_copy_pageup(struct window_pane *);
/* window-choose.c */
extern const struct window_mode window_choose_mode;
-void window_choose_vadd(
- struct window_pane *, int, const char *, va_list);
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 *);
+struct window_choose_data *window_choose_data_create(struct cmd_ctx *);
void window_choose_ctx(struct window_choose_data *);
+struct window_choose_data *window_choose_add_window(struct window_pane *,
+ struct cmd_ctx *, 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 *,
+ char *, u_int);
/* names.c */
void queue_window_name(struct window *);
diff --git a/window-choose.c b/window-choose.c
index a21db699..ed951661 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -133,8 +133,7 @@ window_choose_data_create(struct cmd_ctx *ctx)
wcd = xmalloc(sizeof *wcd);
wcd->ft = format_create();
wcd->ft_template = NULL;
- wcd->action = NULL;
- wcd->raw_format = NULL;
+ wcd->command = NULL;
wcd->client = ctx->curclient;
wcd->session = ctx->curclient->session;
wcd->idx = -1;
@@ -482,21 +481,22 @@ window_choose_ctx(struct window_choose_data *cdata)
{
struct cmd_ctx ctx;
struct cmd_list *cmdlist;
- char *template, *cause;
+ char *cause;
- template = cmd_template_replace(cdata->action,
- cdata->raw_format, 1);
+ /* The command template will have already been replaced. But if it's
+ * NULL, bail here.
+ */
+ if (cdata->command == NULL)
+ return;
- if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
+ if (cmd_string_parse(cdata->command, &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;
@@ -510,3 +510,53 @@ window_choose_ctx(struct window_choose_data *cdata)
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)
+{
+ struct window_choose_data *wcd;
+
+ wcd = window_choose_data_create(ctx);
+ wcd->idx = s->idx;
+ wcd->command = cmd_template_replace(action, s->name, 1);
+ wcd->ft_template = xstrdup(template);
+ format_add(wcd->ft, "line", "%u", idx);
+ format_session(wcd->ft, s);
+
+ wcd->client->references++;
+ wcd->session->references++;
+
+ window_choose_add(wp, wcd);
+
+ return (wcd);
+}
+
+struct window_choose_data *
+window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx,
+ 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);
+ xfree(action_data);
+
+ wcd->idx = wl->idx;
+ 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++;
+
+ window_choose_add(wp, wcd);
+
+ return (wcd);
+}