mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	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:
		@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								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 *);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user