mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add choose-tree command to show windows and sessions in the same
list. Change choose-window and -session to use the same code. From Thomas Adam.
This commit is contained in:
		
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							@@ -12,8 +12,7 @@ SRCS=	arguments.c \
 | 
				
			|||||||
	cmd-capture-pane.c \
 | 
						cmd-capture-pane.c \
 | 
				
			||||||
	cmd-choose-buffer.c \
 | 
						cmd-choose-buffer.c \
 | 
				
			||||||
	cmd-choose-client.c \
 | 
						cmd-choose-client.c \
 | 
				
			||||||
	cmd-choose-session.c \
 | 
						cmd-choose-tree.c \
 | 
				
			||||||
	cmd-choose-window.c \
 | 
					 | 
				
			||||||
	cmd-clear-history.c \
 | 
						cmd-clear-history.c \
 | 
				
			||||||
	cmd-clock-mode.c \
 | 
						cmd-clock-mode.c \
 | 
				
			||||||
	cmd-command-prompt.c \
 | 
						cmd-command-prompt.c \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,114 +0,0 @@
 | 
				
			|||||||
/* $OpenBSD$ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
					 | 
				
			||||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
					 | 
				
			||||||
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
					 | 
				
			||||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <ctype.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "tmux.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Enter choice mode to choose a session.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int	cmd_choose_session_exec(struct cmd *, struct cmd_ctx *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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,
 | 
					 | 
				
			||||||
	"F:t:", 0, 1,
 | 
					 | 
				
			||||||
	CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
 | 
					 | 
				
			||||||
	0,
 | 
					 | 
				
			||||||
	NULL,
 | 
					 | 
				
			||||||
	NULL,
 | 
					 | 
				
			||||||
	cmd_choose_session_exec
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct args			*args = self->args;
 | 
					 | 
				
			||||||
	struct winlink			*wl;
 | 
					 | 
				
			||||||
	struct session			*s;
 | 
					 | 
				
			||||||
	char				*action;
 | 
					 | 
				
			||||||
	const char			*template;
 | 
					 | 
				
			||||||
	u_int			 	 idx, cur;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ctx->curclient == NULL) {
 | 
					 | 
				
			||||||
		ctx->error(ctx, "must be run interactively");
 | 
					 | 
				
			||||||
		return (-1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
 | 
					 | 
				
			||||||
		return (-1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
 | 
					 | 
				
			||||||
		return (0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
cmd_choose_session_callback(struct window_choose_data *cdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (cdata == NULL)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	if (cdata->client->flags & CLIENT_DEAD)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	window_choose_ctx(cdata);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
cmd_choose_session_free(struct window_choose_data *cdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (cdata == NULL)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cdata->client->references--;
 | 
					 | 
				
			||||||
	cdata->session->references--;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	xfree(cdata->command);
 | 
					 | 
				
			||||||
	xfree(cdata->ft_template);
 | 
					 | 
				
			||||||
	format_free(cdata->ft);
 | 
					 | 
				
			||||||
	xfree(cdata);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										251
									
								
								cmd-choose-tree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								cmd-choose-tree.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,251 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CMD_CHOOSE_TREE_WINDOW_ACTION "select-window -t '%%'"
 | 
				
			||||||
 | 
					#define CMD_CHOOSE_TREE_SESSION_ACTION "switch-client -t '%%'"
 | 
				
			||||||
 | 
					#define CMD_CHOOSE_TREE_WINDOW_TEMPLATE \
 | 
				
			||||||
 | 
					    DEFAULT_WINDOW_TEMPLATE " \"#{pane_title}\""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enter choice mode to choose a session and/or window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_choose_tree_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_choose_tree_callback(struct window_choose_data *);
 | 
				
			||||||
 | 
					void	cmd_choose_tree_free(struct window_choose_data *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_choose_tree_entry = {
 | 
				
			||||||
 | 
						"choose-tree", NULL,
 | 
				
			||||||
 | 
						"S:W:swb:c:t:", 0, 1,
 | 
				
			||||||
 | 
						"[-SW] [-s format] [-w format ] [-b session template] " \
 | 
				
			||||||
 | 
						"[-c window template] " CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_choose_tree_exec
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_choose_session_entry = {
 | 
				
			||||||
 | 
						"choose-session", NULL,
 | 
				
			||||||
 | 
						"F:t:", 0, 1,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_choose_tree_exec
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_choose_window_entry = {
 | 
				
			||||||
 | 
						"choose-window", NULL,
 | 
				
			||||||
 | 
						"F:t:", 0, 1,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_choose_tree_exec
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct args			*args = self->args;
 | 
				
			||||||
 | 
						struct winlink			*wl, *wm;
 | 
				
			||||||
 | 
						struct session			*s, *s2;
 | 
				
			||||||
 | 
						struct tty			*tty;
 | 
				
			||||||
 | 
						struct window_choose_data	*wcd = NULL;
 | 
				
			||||||
 | 
						const char			*ses_template, *win_template;
 | 
				
			||||||
 | 
						char				*final_win_action, *final_win_template;
 | 
				
			||||||
 | 
						const char			*ses_action, *win_action;
 | 
				
			||||||
 | 
						u_int				 cur_win, idx_ses, win_ses;
 | 
				
			||||||
 | 
						u_int				 wflag, sflag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ses_template = win_template = NULL;
 | 
				
			||||||
 | 
						ses_action = win_action = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->curclient == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "must be run interactively");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s = ctx->curclient->session;
 | 
				
			||||||
 | 
						tty = &ctx->curclient->tty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Sort out which command this is. */
 | 
				
			||||||
 | 
						wflag = sflag = 0;
 | 
				
			||||||
 | 
						if (self->entry == &cmd_choose_session_entry) {
 | 
				
			||||||
 | 
							sflag = 1;
 | 
				
			||||||
 | 
							if ((ses_template = args_get(args, 'F')) == NULL)
 | 
				
			||||||
 | 
								ses_template = DEFAULT_SESSION_TEMPLATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (args->argc != 0)
 | 
				
			||||||
 | 
								ses_action = args->argv[0];
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ses_action = CMD_CHOOSE_TREE_SESSION_ACTION;
 | 
				
			||||||
 | 
						} else if (self->entry == &cmd_choose_window_entry) {
 | 
				
			||||||
 | 
							wflag = 1;
 | 
				
			||||||
 | 
							if ((win_template = args_get(args, 'F')) == NULL)
 | 
				
			||||||
 | 
								win_template = CMD_CHOOSE_TREE_WINDOW_TEMPLATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (args->argc != 0)
 | 
				
			||||||
 | 
								win_action = args->argv[0];
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								win_action = CMD_CHOOSE_TREE_WINDOW_ACTION;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wflag = args_has(args, 'w');
 | 
				
			||||||
 | 
							sflag = args_has(args, 's');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((ses_action = args_get(args, 'b')) == NULL)
 | 
				
			||||||
 | 
								ses_action = CMD_CHOOSE_TREE_SESSION_ACTION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((win_action = args_get(args, 'c')) == NULL)
 | 
				
			||||||
 | 
								win_action = CMD_CHOOSE_TREE_WINDOW_ACTION;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((ses_template = args_get(args, 'S')) == NULL)
 | 
				
			||||||
 | 
								ses_template = DEFAULT_SESSION_TEMPLATE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((win_template = args_get(args, 'W')) == NULL)
 | 
				
			||||||
 | 
								win_template = CMD_CHOOSE_TREE_WINDOW_TEMPLATE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If not asking for windows and sessions, assume no "-ws" given and
 | 
				
			||||||
 | 
						 * hence display the entire tree outright.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!wflag && !sflag)
 | 
				
			||||||
 | 
							wflag = sflag = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If we're drawing in tree mode, including sessions, then pad the
 | 
				
			||||||
 | 
						 * window template, otherwise just render the windows as a flat list
 | 
				
			||||||
 | 
						 * without any padding.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (wflag && sflag)
 | 
				
			||||||
 | 
							xasprintf(&final_win_template, "    --> %s", win_template);
 | 
				
			||||||
 | 
						else if (wflag)
 | 
				
			||||||
 | 
							final_win_template = xstrdup(win_template);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							final_win_template = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						idx_ses = cur_win = -1;
 | 
				
			||||||
 | 
						RB_FOREACH(s2, sessions, &sessions) {
 | 
				
			||||||
 | 
							idx_ses++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If we're just choosing windows, jump straight there. Note
 | 
				
			||||||
 | 
							 * that this implies the current session, so only choose
 | 
				
			||||||
 | 
							 * windows when the session matches this one.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (wflag && !sflag) {
 | 
				
			||||||
 | 
								if (s != s2)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								goto windows_only;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wcd = window_choose_add_session(wl->window->active,
 | 
				
			||||||
 | 
								ctx, s2, ses_template, (char *)ses_action, idx_ses);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* If we're just choosing sessions, skip choosing windows. */
 | 
				
			||||||
 | 
							if (sflag && !wflag) {
 | 
				
			||||||
 | 
								if (s == s2)
 | 
				
			||||||
 | 
									cur_win = idx_ses;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					windows_only:
 | 
				
			||||||
 | 
							win_ses = -1;
 | 
				
			||||||
 | 
							RB_FOREACH(wm, winlinks, &s2->windows) {
 | 
				
			||||||
 | 
								win_ses++;
 | 
				
			||||||
 | 
								if (sflag && wflag)
 | 
				
			||||||
 | 
									idx_ses++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (wm == s2->curw && s == s2) {
 | 
				
			||||||
 | 
									if (wflag && !sflag) {
 | 
				
			||||||
 | 
										/*
 | 
				
			||||||
 | 
										 * Then we're only counting windows.
 | 
				
			||||||
 | 
										 * So remember which is the current
 | 
				
			||||||
 | 
										 * window in the list.
 | 
				
			||||||
 | 
										 */
 | 
				
			||||||
 | 
										cur_win = win_ses;
 | 
				
			||||||
 | 
									} else
 | 
				
			||||||
 | 
										cur_win = idx_ses;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								xasprintf(&final_win_action, "%s ; %s", win_action,
 | 
				
			||||||
 | 
									wcd ? wcd->command : "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								window_choose_add_window(wl->window->active,
 | 
				
			||||||
 | 
									ctx, s2, wm, final_win_template,
 | 
				
			||||||
 | 
									final_win_action, idx_ses);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								xfree(final_win_action);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If we're just drawing windows, don't consider moving on to
 | 
				
			||||||
 | 
							 * other sessions as we only list windows in this session.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (wflag && !sflag)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (final_win_template != NULL)
 | 
				
			||||||
 | 
							xfree(final_win_template);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_choose_ready(wl->window->active, cur_win,
 | 
				
			||||||
 | 
							cmd_choose_tree_callback, cmd_choose_tree_free);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_choose_tree_callback(struct window_choose_data *cdata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (cdata == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cdata->client->flags & CLIENT_DEAD)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_choose_ctx(cdata);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_choose_tree_free(struct window_choose_data *cdata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						cdata->session->references--;
 | 
				
			||||||
 | 
						cdata->client->references--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(cdata->ft_template);
 | 
				
			||||||
 | 
						xfree(cdata->command);
 | 
				
			||||||
 | 
						format_free(cdata->ft);
 | 
				
			||||||
 | 
						xfree(cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,121 +0,0 @@
 | 
				
			|||||||
/* $OpenBSD$ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
					 | 
				
			||||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
					 | 
				
			||||||
 * copyright notice and this permission notice appear in all copies.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
					 | 
				
			||||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
					 | 
				
			||||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
					 | 
				
			||||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
					 | 
				
			||||||
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
					 | 
				
			||||||
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
					 | 
				
			||||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <sys/types.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <ctype.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "tmux.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Enter choice mode to choose a window.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int	cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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,
 | 
					 | 
				
			||||||
	"F:t:", 0, 1,
 | 
					 | 
				
			||||||
	CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
 | 
					 | 
				
			||||||
	0,
 | 
					 | 
				
			||||||
	NULL,
 | 
					 | 
				
			||||||
	NULL,
 | 
					 | 
				
			||||||
	cmd_choose_window_exec
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct args			*args = self->args;
 | 
					 | 
				
			||||||
	struct session			*s;
 | 
					 | 
				
			||||||
	struct winlink			*wl, *wm;
 | 
					 | 
				
			||||||
	const char			*template;
 | 
					 | 
				
			||||||
	char				*action;
 | 
					 | 
				
			||||||
	u_int			 	 idx, cur;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ctx->curclient == NULL) {
 | 
					 | 
				
			||||||
		ctx->error(ctx, "must be run interactively");
 | 
					 | 
				
			||||||
		return (-1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s = ctx->curclient->session;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
 | 
					 | 
				
			||||||
		return (-1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
 | 
					 | 
				
			||||||
		return (0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
cmd_choose_window_callback(struct window_choose_data *cdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct session	*s;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (cdata == NULL)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	if (cdata->client->flags & CLIENT_DEAD)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s = cdata->session;
 | 
					 | 
				
			||||||
	if (!session_alive(s))
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	window_choose_ctx(cdata);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
cmd_choose_window_free(struct window_choose_data *cdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (cdata == NULL)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cdata->session->references--;
 | 
					 | 
				
			||||||
	cdata->client->references--;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	xfree(cdata->ft_template);
 | 
					 | 
				
			||||||
	xfree(cdata->command);
 | 
					 | 
				
			||||||
	format_free(cdata->ft);
 | 
					 | 
				
			||||||
	xfree(cdata);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								cmd.c
									
									
									
									
									
								
							@@ -36,6 +36,7 @@ const struct cmd_entry *cmd_table[] = {
 | 
				
			|||||||
	&cmd_choose_buffer_entry,
 | 
						&cmd_choose_buffer_entry,
 | 
				
			||||||
	&cmd_choose_client_entry,
 | 
						&cmd_choose_client_entry,
 | 
				
			||||||
	&cmd_choose_session_entry,
 | 
						&cmd_choose_session_entry,
 | 
				
			||||||
 | 
						&cmd_choose_tree_entry,
 | 
				
			||||||
	&cmd_choose_window_entry,
 | 
						&cmd_choose_window_entry,
 | 
				
			||||||
	&cmd_clear_history_entry,
 | 
						&cmd_clear_history_entry,
 | 
				
			||||||
	&cmd_clock_mode_entry,
 | 
						&cmd_clock_mode_entry,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -147,7 +147,7 @@ key_bindings_init(void)
 | 
				
			|||||||
		{ 'p', 			  0, &cmd_previous_window_entry },
 | 
							{ 'p', 			  0, &cmd_previous_window_entry },
 | 
				
			||||||
		{ 'q',			  0, &cmd_display_panes_entry },
 | 
							{ 'q',			  0, &cmd_display_panes_entry },
 | 
				
			||||||
		{ 'r', 			  0, &cmd_refresh_client_entry },
 | 
							{ 'r', 			  0, &cmd_refresh_client_entry },
 | 
				
			||||||
		{ 's', 			  0, &cmd_choose_session_entry },
 | 
							{ 's', 			  0, &cmd_choose_tree_entry },
 | 
				
			||||||
		{ 't', 			  0, &cmd_clock_mode_entry },
 | 
							{ 't', 			  0, &cmd_clock_mode_entry },
 | 
				
			||||||
		{ 'u',			  1, &cmd_select_layout_entry },
 | 
							{ 'u',			  1, &cmd_select_layout_entry },
 | 
				
			||||||
		{ 'w', 			  0, &cmd_choose_window_entry },
 | 
							{ 'w', 			  0, &cmd_choose_window_entry },
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										62
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								tmux.1
									
									
									
									
									
								
							@@ -1090,6 +1090,68 @@ section.
 | 
				
			|||||||
This command works only from inside
 | 
					This command works only from inside
 | 
				
			||||||
.Nm .
 | 
					.Nm .
 | 
				
			||||||
.It Xo
 | 
					.It Xo
 | 
				
			||||||
 | 
					.Ic choose-tree
 | 
				
			||||||
 | 
					.Op Fl s
 | 
				
			||||||
 | 
					.Op Fl w
 | 
				
			||||||
 | 
					.Op Fl b Ar session-template
 | 
				
			||||||
 | 
					.Op Fl c Ar window-template
 | 
				
			||||||
 | 
					.Op Fl S Ar format
 | 
				
			||||||
 | 
					.Op Fl W Ar format
 | 
				
			||||||
 | 
					.Op Fl t Ar target-window
 | 
				
			||||||
 | 
					.Xc
 | 
				
			||||||
 | 
					Put a window into tree choice mode, where either sessions or windows may be
 | 
				
			||||||
 | 
					selected interactively from a list.
 | 
				
			||||||
 | 
					By default, windows belonging to a session are indented to show their
 | 
				
			||||||
 | 
					relationship to a session.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					Note that the
 | 
				
			||||||
 | 
					.Ic choose-window
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Ic choose-session
 | 
				
			||||||
 | 
					commands are wrappers around
 | 
				
			||||||
 | 
					.Ic choose-tree .
 | 
				
			||||||
 | 
					.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl s
 | 
				
			||||||
 | 
					is given, will show sessions.
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl w
 | 
				
			||||||
 | 
					is given, will show windows.
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl b
 | 
				
			||||||
 | 
					is given, will override the default session command.
 | 
				
			||||||
 | 
					Note that
 | 
				
			||||||
 | 
					.Ql %%
 | 
				
			||||||
 | 
					can be used, and will be replaced with the session name.
 | 
				
			||||||
 | 
					The default option if not specified is "switch-client -t '%%'".
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl c
 | 
				
			||||||
 | 
					is given, will override the default window command.
 | 
				
			||||||
 | 
					Note that
 | 
				
			||||||
 | 
					.Ql %%
 | 
				
			||||||
 | 
					can be used, and will be replaced with the session name and window index.
 | 
				
			||||||
 | 
					This command will run
 | 
				
			||||||
 | 
					.Ar session-template
 | 
				
			||||||
 | 
					before it.
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl S
 | 
				
			||||||
 | 
					is given will display the specified format instead of the default session
 | 
				
			||||||
 | 
					format.
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl W
 | 
				
			||||||
 | 
					is given will display the specified format instead of the default window
 | 
				
			||||||
 | 
					format.
 | 
				
			||||||
 | 
					For the meaning of the
 | 
				
			||||||
 | 
					.Fl s
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					.Fl w
 | 
				
			||||||
 | 
					options, see the
 | 
				
			||||||
 | 
					.Sx FORMATS
 | 
				
			||||||
 | 
					section.
 | 
				
			||||||
 | 
					This command only works from inside
 | 
				
			||||||
 | 
					.Nm .
 | 
				
			||||||
 | 
					.It Xo
 | 
				
			||||||
.Ic choose-window
 | 
					.Ic choose-window
 | 
				
			||||||
.Op Fl F Ar format
 | 
					.Op Fl F Ar format
 | 
				
			||||||
.Op Fl t Ar target-window
 | 
					.Op Fl t Ar target-window
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1664,6 +1664,7 @@ extern const struct cmd_entry cmd_capture_pane_entry;
 | 
				
			|||||||
extern const struct cmd_entry cmd_choose_buffer_entry;
 | 
					extern const struct cmd_entry cmd_choose_buffer_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_choose_client_entry;
 | 
					extern const struct cmd_entry cmd_choose_client_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_choose_session_entry;
 | 
					extern const struct cmd_entry cmd_choose_session_entry;
 | 
				
			||||||
 | 
					extern const struct cmd_entry cmd_choose_tree_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_choose_window_entry;
 | 
					extern const struct cmd_entry cmd_choose_window_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_clear_history_entry;
 | 
					extern const struct cmd_entry cmd_clear_history_entry;
 | 
				
			||||||
extern const struct cmd_entry cmd_clock_mode_entry;
 | 
					extern const struct cmd_entry cmd_clock_mode_entry;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user