mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add -n and -p flags to switch-client to move to the next and previous
session (yes, it doesn't match window/pane, but so what, nor does switch-client). Based on a diff long ago from "edsouza".
This commit is contained in:
		@@ -27,6 +27,7 @@
 | 
				
			|||||||
 * Switch client to a different session.
 | 
					 * Switch client to a different session.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_switch_client_init(struct cmd *, int);
 | 
				
			||||||
int	cmd_switch_client_parse(struct cmd *, int, char **, char **);
 | 
					int	cmd_switch_client_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
int	cmd_switch_client_exec(struct cmd *, struct cmd_ctx *);
 | 
					int	cmd_switch_client_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
void	cmd_switch_client_free(struct cmd *);
 | 
					void	cmd_switch_client_free(struct cmd *);
 | 
				
			||||||
@@ -35,28 +36,50 @@ size_t	cmd_switch_client_print(struct cmd *, char *, size_t);
 | 
				
			|||||||
struct cmd_switch_client_data {
 | 
					struct cmd_switch_client_data {
 | 
				
			||||||
	char	*name;
 | 
						char	*name;
 | 
				
			||||||
	char	*target;
 | 
						char	*target;
 | 
				
			||||||
 | 
						int	 flag_next;
 | 
				
			||||||
 | 
						int	 flag_previous;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct cmd_entry cmd_switch_client_entry = {
 | 
					const struct cmd_entry cmd_switch_client_entry = {
 | 
				
			||||||
	"switch-client", "switchc",
 | 
						"switch-client", "switchc",
 | 
				
			||||||
	"[-c target-client] [-t target-session]",
 | 
						"[-np] [-c target-client] [-t target-session]",
 | 
				
			||||||
	0, "",
 | 
						0, "",
 | 
				
			||||||
	NULL,
 | 
						cmd_switch_client_init,
 | 
				
			||||||
	cmd_switch_client_parse,
 | 
						cmd_switch_client_parse,
 | 
				
			||||||
	cmd_switch_client_exec,
 | 
						cmd_switch_client_exec,
 | 
				
			||||||
	cmd_switch_client_free,
 | 
						cmd_switch_client_free,
 | 
				
			||||||
	cmd_switch_client_print
 | 
						cmd_switch_client_print
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_switch_client_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_switch_client_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->name = NULL;
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->flag_next = 0;
 | 
				
			||||||
 | 
						data->flag_previous = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case '(':
 | 
				
			||||||
 | 
							data->flag_previous = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ')':
 | 
				
			||||||
 | 
							data->flag_next = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
					cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cmd_switch_client_data	*data;
 | 
						struct cmd_switch_client_data	*data;
 | 
				
			||||||
	int				 opt;
 | 
						int				 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	self->data = data = xmalloc(sizeof *data);
 | 
						self->entry->init(self, KEYC_NONE);
 | 
				
			||||||
	data->name = NULL;
 | 
						data = self->data;
 | 
				
			||||||
	data->target = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((opt = getopt(argc, argv, "c:t:")) != -1) {
 | 
						while ((opt = getopt(argc, argv, "c:t:")) != -1) {
 | 
				
			||||||
		switch (opt) {
 | 
							switch (opt) {
 | 
				
			||||||
@@ -65,9 +88,21 @@ cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			|||||||
				data->name = xstrdup(optarg);
 | 
									data->name = xstrdup(optarg);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 't':
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->flag_next || data->flag_previous)
 | 
				
			||||||
 | 
									goto usage;
 | 
				
			||||||
			if (data->target == NULL)
 | 
								if (data->target == NULL)
 | 
				
			||||||
				data->target = xstrdup(optarg);
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case 'n':
 | 
				
			||||||
 | 
								if (data->flag_previous || data->target != NULL)
 | 
				
			||||||
 | 
									goto usage;
 | 
				
			||||||
 | 
								data->flag_next = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'p':
 | 
				
			||||||
 | 
								if (data->flag_next || data->target != NULL)
 | 
				
			||||||
 | 
									goto usage;
 | 
				
			||||||
 | 
								data->flag_next = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			goto usage;
 | 
								goto usage;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -98,9 +133,22 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ((c = cmd_find_client(ctx, data->name)) == NULL)
 | 
						if ((c = cmd_find_client(ctx, data->name)) == NULL)
 | 
				
			||||||
		return (-1);
 | 
							return (-1);
 | 
				
			||||||
	if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
					 | 
				
			||||||
		return (-1);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flag_next) {
 | 
				
			||||||
 | 
							if ((s = session_next_session(c->session)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "can't find next session");
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (data->flag_previous) {
 | 
				
			||||||
 | 
							if ((s = session_previous_session(c->session)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "can't find previous session");
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							s = cmd_find_session(ctx, data->target);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
	c->session = s;
 | 
						c->session = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	recalculate_sizes();
 | 
						recalculate_sizes();
 | 
				
			||||||
@@ -130,6 +178,10 @@ cmd_switch_client_print(struct cmd *self, char *buf, size_t len)
 | 
				
			|||||||
	off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
	if (data == NULL)
 | 
						if (data == NULL)
 | 
				
			||||||
		return (off);
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->flag_next)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "%s", " -n");
 | 
				
			||||||
 | 
						if (off < len && data->flag_previous)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "%s", " -p");
 | 
				
			||||||
	if (off < len && data->name != NULL)
 | 
						if (off < len && data->name != NULL)
 | 
				
			||||||
		off += cmd_prarg(buf + off, len - off, " -c ", data->name);
 | 
							off += cmd_prarg(buf + off, len - off, " -c ", data->name);
 | 
				
			||||||
	if (off < len && data->target != NULL)
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -108,6 +108,8 @@ key_bindings_init(void)
 | 
				
			|||||||
		{ '#', 			  0, &cmd_list_buffers_entry },
 | 
							{ '#', 			  0, &cmd_list_buffers_entry },
 | 
				
			||||||
		{ '%', 			  0, &cmd_split_window_entry },
 | 
							{ '%', 			  0, &cmd_split_window_entry },
 | 
				
			||||||
		{ '&', 			  0, &cmd_confirm_before_entry },
 | 
							{ '&', 			  0, &cmd_confirm_before_entry },
 | 
				
			||||||
 | 
							{ '(',                    0, &cmd_switch_client_entry },
 | 
				
			||||||
 | 
							{ ')',                    0, &cmd_switch_client_entry },
 | 
				
			||||||
		{ ',', 			  0, &cmd_command_prompt_entry },
 | 
							{ ',', 			  0, &cmd_command_prompt_entry },
 | 
				
			||||||
		{ '-', 			  0, &cmd_delete_buffer_entry },
 | 
							{ '-', 			  0, &cmd_delete_buffer_entry },
 | 
				
			||||||
		{ '.', 			  0, &cmd_command_prompt_entry },
 | 
							{ '.', 			  0, &cmd_command_prompt_entry },
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										42
									
								
								session.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								session.c
									
									
									
									
									
								
							@@ -169,6 +169,48 @@ session_index(struct session *s, u_int *i)
 | 
				
			|||||||
	return (-1);
 | 
						return (-1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Find the next usable session. */
 | 
				
			||||||
 | 
					struct session *
 | 
				
			||||||
 | 
					session_next_session(struct session *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session *s2;
 | 
				
			||||||
 | 
						u_int		i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ARRAY_LENGTH(&sessions) == 0 || session_index(s, &i) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							if (i == ARRAY_LENGTH(&sessions) - 1)
 | 
				
			||||||
 | 
								i = 0;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								i++;
 | 
				
			||||||
 | 
							s2 = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
						} while (s2 == NULL || s2->flags & SESSION_DEAD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (s2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Find the previous usable session. */
 | 
				
			||||||
 | 
					struct session *
 | 
				
			||||||
 | 
					session_previous_session(struct session *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session *s2;
 | 
				
			||||||
 | 
						u_int		i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ARRAY_LENGTH(&sessions) == 0 || session_index(s, &i) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							if (i == 0)
 | 
				
			||||||
 | 
								i = ARRAY_LENGTH(&sessions) - 1;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								i--;
 | 
				
			||||||
 | 
							s2 = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
						} while (s2 == NULL || s2->flags & SESSION_DEAD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (s2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Create a new window on a session. */
 | 
					/* Create a new window on a session. */
 | 
				
			||||||
struct winlink *
 | 
					struct winlink *
 | 
				
			||||||
session_new(struct session *s,
 | 
					session_new(struct session *s,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							@@ -660,6 +660,7 @@ Suspend a client by sending
 | 
				
			|||||||
.Dv SIGTSTP
 | 
					.Dv SIGTSTP
 | 
				
			||||||
(tty stop).
 | 
					(tty stop).
 | 
				
			||||||
.It Xo Ic switch-client
 | 
					.It Xo Ic switch-client
 | 
				
			||||||
 | 
					.Op Fl np
 | 
				
			||||||
.Op Fl c Ar target-client
 | 
					.Op Fl c Ar target-client
 | 
				
			||||||
.Op Fl t Ar target-session
 | 
					.Op Fl t Ar target-session
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
@@ -668,6 +669,11 @@ Switch the current session for client
 | 
				
			|||||||
.Ar target-client
 | 
					.Ar target-client
 | 
				
			||||||
to
 | 
					to
 | 
				
			||||||
.Ar target-session .
 | 
					.Ar target-session .
 | 
				
			||||||
 | 
					If
 | 
				
			||||||
 | 
					.Fl n
 | 
				
			||||||
 | 
					or
 | 
				
			||||||
 | 
					.Fl p
 | 
				
			||||||
 | 
					is used, the client is moved to the next or previous session respectively.
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Sh WINDOWS AND PANES
 | 
					.Sh WINDOWS AND PANES
 | 
				
			||||||
A
 | 
					A
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1965,6 +1965,8 @@ struct session	*session_create(const char *, const char *, const char *,
 | 
				
			|||||||
		     char **);
 | 
							     char **);
 | 
				
			||||||
void		 session_destroy(struct session *);
 | 
					void		 session_destroy(struct session *);
 | 
				
			||||||
int		 session_index(struct session *, u_int *);
 | 
					int		 session_index(struct session *, u_int *);
 | 
				
			||||||
 | 
					struct session	*session_next_session(struct session *);
 | 
				
			||||||
 | 
					struct session	*session_previous_session(struct session *);
 | 
				
			||||||
struct winlink	*session_new(struct session *,
 | 
					struct winlink	*session_new(struct session *,
 | 
				
			||||||
		     const char *, const char *, const char *, int, char **);
 | 
							     const char *, const char *, const char *, int, char **);
 | 
				
			||||||
struct winlink	*session_attach(
 | 
					struct winlink	*session_attach(
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user