Sync OpenBSD patchset 1143:

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.
This commit is contained in:
Tiago Cunha 2012-07-04 11:03:20 +00:00
parent 5761712799
commit 7e02d2f459
6 changed files with 110 additions and 74 deletions

View File

@ -48,8 +48,9 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_choose_data *cdata; struct window_choose_data *cdata;
struct winlink *wl; struct winlink *wl;
struct paste_buffer *pb; struct paste_buffer *pb;
u_int idx; char *action, *action_data;
const char *template; const char *template;
u_int idx;
if (ctx->curclient == NULL) { if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively"); 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) if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0); return (0);
if (args->argc != 0)
action = xstrdup(args->argv[0]);
else
action = xstrdup("paste-buffer -b '%%'");
idx = 0; idx = 0;
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) { while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
cdata = window_choose_data_create(ctx); 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->idx = idx - 1;
cdata->client->references++; 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_add(cdata->ft, "line", "%u", idx - 1);
format_paste_buffer(cdata->ft, pb); 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); window_choose_add(wl->window->active, cdata);
} }
xfree(action);
window_choose_ready(wl->window->active, window_choose_ready(wl->window->active,
0, cmd_choose_buffer_callback, cmd_choose_buffer_free); 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) if (cdata->client->flags & CLIENT_DEAD)
return; return;
xasprintf(&cdata->raw_format, "%u", cdata->idx);
window_choose_ctx(cdata); window_choose_ctx(cdata);
} }
@ -114,8 +119,7 @@ cmd_choose_buffer_free(struct window_choose_data *data)
cdata->client->references--; cdata->client->references--;
xfree(cdata->command);
xfree(cdata->ft_template); xfree(cdata->ft_template);
xfree(cdata->action);
xfree(cdata->raw_format);
xfree(cdata); xfree(cdata);
} }

View File

@ -54,6 +54,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl; struct winlink *wl;
struct client *c; struct client *c;
const char *template; const char *template;
char *action;
u_int i, idx, cur; u_int i, idx, cur;
if (ctx->curclient == NULL) { 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) if ((template = args_get(args, 'F')) == NULL)
template = DEFAULT_CLIENT_TEMPLATE; template = DEFAULT_CLIENT_TEMPLATE;
if (args->argc != 0)
action = xstrdup(args->argv[0]);
else
action = xstrdup("detach-client -t '%%'");
cur = idx = 0; cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
@ -80,11 +86,6 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
idx++; idx++;
cdata = window_choose_data_create(ctx); 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->idx = i;
cdata->client->references++; 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_session(cdata->ft, c->session);
format_client(cdata->ft, c); format_client(cdata->ft, c);
cdata->command = cmd_template_replace(action, c->tty.path, 1);
window_choose_add(wl->window->active, cdata); window_choose_add(wl->window->active, cdata);
} }
xfree(action);
window_choose_ready(wl->window->active, window_choose_ready(wl->window->active,
cur, cmd_choose_client_callback, cmd_choose_client_free); 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) if (c == NULL || c->session == NULL)
return; return;
xasprintf(&cdata->raw_format, "%s", c->tty.path);
window_choose_ctx(cdata); window_choose_ctx(cdata);
} }
@ -131,7 +134,7 @@ cmd_choose_client_free(struct window_choose_data *cdata)
cdata->client->references--; cdata->client->references--;
xfree(cdata->ft_template); xfree(cdata->ft_template);
xfree(cdata->action); xfree(cdata->command);
format_free(cdata->ft); format_free(cdata->ft);
xfree(cdata); xfree(cdata);
} }

View File

@ -45,9 +45,9 @@ int
cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct window_choose_data *cdata;
struct winlink *wl; struct winlink *wl;
struct session *s; struct session *s;
char *action;
const char *template; const char *template;
u_int idx, cur; 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) if ((template = args_get(args, 'F')) == NULL)
template = DEFAULT_SESSION_TEMPLATE; template = DEFAULT_SESSION_TEMPLATE;
if (args->argc != 0)
action = xstrdup(args->argv[0]);
else
action = xstrdup("switch-client -t '%%'");
cur = idx = 0; cur = idx = 0;
RB_FOREACH(s, sessions, &sessions) { RB_FOREACH(s, sessions, &sessions) {
if (s == ctx->curclient->session) if (s == ctx->curclient->session)
cur = idx; cur = idx;
idx++; idx++;
cdata = window_choose_data_create(ctx); window_choose_add_session(wl->window->active,
if (args->argc != 0) ctx, s, template, action, idx);
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);
} }
xfree(action);
window_choose_ready(wl->window->active, window_choose_ready(wl->window->active,
cur, cmd_choose_session_callback, cmd_choose_session_free); 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 void
cmd_choose_session_callback(struct window_choose_data *cdata) cmd_choose_session_callback(struct window_choose_data *cdata)
{ {
struct session *s;
if (cdata == NULL) if (cdata == NULL)
return; return;
if (cdata->client->flags & CLIENT_DEAD) if (cdata->client->flags & CLIENT_DEAD)
return; return;
s = session_find_by_index(cdata->idx);
if (s == NULL)
return;
cdata->raw_format = xstrdup(s->name);
window_choose_ctx(cdata); window_choose_ctx(cdata);
} }
@ -121,8 +107,8 @@ cmd_choose_session_free(struct window_choose_data *cdata)
cdata->client->references--; cdata->client->references--;
cdata->session->references--; cdata->session->references--;
xfree(cdata->command);
xfree(cdata->ft_template); xfree(cdata->ft_template);
xfree(cdata->action);
format_free(cdata->ft); format_free(cdata->ft);
xfree(cdata); xfree(cdata);
} }

View File

@ -45,10 +45,10 @@ int
cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct window_choose_data *cdata;
struct session *s; struct session *s;
struct winlink *wl, *wm; struct winlink *wl, *wm;
const char *template; const char *template;
char *action;
u_int idx, cur; u_int idx, cur;
if (ctx->curclient == NULL) { 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) if ((template = args_get(args, 'F')) == NULL)
template = DEFAULT_WINDOW_TEMPLATE " \"#{pane_title}\""; template = DEFAULT_WINDOW_TEMPLATE " \"#{pane_title}\"";
if (args->argc != 0)
action = xstrdup(args->argv[0]);
else
action = xstrdup("select-window -t '%%'");
cur = idx = 0; cur = idx = 0;
RB_FOREACH(wm, winlinks, &s->windows) { RB_FOREACH(wm, winlinks, &s->windows) {
if (wm == s->curw) if (wm == s->curw)
cur = idx; cur = idx;
idx++; idx++;
cdata = window_choose_data_create(ctx); window_choose_add_window(wl->window->active, ctx, s, wm,
if (args->argc != 0) template, action, idx);
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);
} }
xfree(action);
window_choose_ready(wl->window->active, window_choose_ready(wl->window->active,
cur, cmd_choose_window_callback, cmd_choose_window_free); 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)) if (!session_alive(s))
return; return;
xasprintf(&cdata->raw_format, "%s:%u", s->name, cdata->idx);
window_choose_ctx(cdata); window_choose_ctx(cdata);
} }
@ -124,7 +115,7 @@ cmd_choose_window_free(struct window_choose_data *cdata)
cdata->client->references--; cdata->client->references--;
xfree(cdata->ft_template); xfree(cdata->ft_template);
xfree(cdata->action); xfree(cdata->command);
format_free(cdata->ft); format_free(cdata->ft);
xfree(cdata); xfree(cdata);
} }

14
tmux.h
View File

@ -848,8 +848,7 @@ struct window_choose_data {
struct session *session; struct session *session;
struct format_tree *ft; struct format_tree *ft;
char *ft_template; char *ft_template;
char *raw_format; char *command;
char *action;
u_int idx; u_int idx;
}; };
@ -2131,16 +2130,19 @@ void window_copy_pageup(struct window_pane *);
/* window-choose.c */ /* window-choose.c */
extern const struct window_mode window_choose_mode; 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 *, void window_choose_add(struct window_pane *,
struct window_choose_data *); struct window_choose_data *);
void window_choose_ready(struct window_pane *, void window_choose_ready(struct window_pane *,
u_int, void (*)(struct window_choose_data *), u_int, void (*)(struct window_choose_data *),
void (*)(struct window_choose_data *)); void (*)(struct window_choose_data *));
struct window_choose_data *window_choose_data_create( struct window_choose_data *window_choose_data_create(struct cmd_ctx *);
struct cmd_ctx *);
void window_choose_ctx(struct window_choose_data *); 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 */ /* names.c */
void queue_window_name(struct window *); void queue_window_name(struct window *);

View File

@ -133,8 +133,7 @@ window_choose_data_create(struct cmd_ctx *ctx)
wcd = xmalloc(sizeof *wcd); wcd = xmalloc(sizeof *wcd);
wcd->ft = format_create(); wcd->ft = format_create();
wcd->ft_template = NULL; wcd->ft_template = NULL;
wcd->action = NULL; wcd->command = NULL;
wcd->raw_format = NULL;
wcd->client = ctx->curclient; wcd->client = ctx->curclient;
wcd->session = ctx->curclient->session; wcd->session = ctx->curclient->session;
wcd->idx = -1; wcd->idx = -1;
@ -482,21 +481,22 @@ window_choose_ctx(struct window_choose_data *cdata)
{ {
struct cmd_ctx ctx; struct cmd_ctx ctx;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
char *template, *cause; char *cause;
template = cmd_template_replace(cdata->action, /* The command template will have already been replaced. But if it's
cdata->raw_format, 1); * 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) { if (cause != NULL) {
*cause = toupper((u_char) *cause); *cause = toupper((u_char) *cause);
status_message_set(cdata->client, "%s", cause); status_message_set(cdata->client, "%s", cause);
xfree(cause); xfree(cause);
} }
xfree(template);
return; return;
} }
xfree(template);
ctx.msgdata = NULL; ctx.msgdata = NULL;
ctx.curclient = cdata->client; ctx.curclient = cdata->client;
@ -510,3 +510,53 @@ window_choose_ctx(struct window_choose_data *cdata)
cmd_list_exec(cmdlist, &ctx); cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist); 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);
}