xref: /netbsd-src/external/bsd/tmux/dist/cmd-switch-client.c (revision 6db267571823ee3b0a1d61478df085a087f2e990)
15494e770Schristos /* $OpenBSD$ */
2698d5317Sjmmv 
3698d5317Sjmmv /*
4ed4e6cd4Schristos  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5698d5317Sjmmv  *
6698d5317Sjmmv  * Permission to use, copy, modify, and distribute this software for any
7698d5317Sjmmv  * purpose with or without fee is hereby granted, provided that the above
8698d5317Sjmmv  * copyright notice and this permission notice appear in all copies.
9698d5317Sjmmv  *
10698d5317Sjmmv  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11698d5317Sjmmv  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12698d5317Sjmmv  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13698d5317Sjmmv  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14698d5317Sjmmv  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15698d5317Sjmmv  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16698d5317Sjmmv  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17698d5317Sjmmv  */
18698d5317Sjmmv 
19698d5317Sjmmv #include <sys/types.h>
20698d5317Sjmmv 
21698d5317Sjmmv #include <stdlib.h>
22698d5317Sjmmv #include <string.h>
23698d5317Sjmmv 
24698d5317Sjmmv #include "tmux.h"
25698d5317Sjmmv 
26698d5317Sjmmv /*
27698d5317Sjmmv  * Switch client to a different session.
28698d5317Sjmmv  */
29698d5317Sjmmv 
304e179ddaSchristos static enum cmd_retval	cmd_switch_client_exec(struct cmd *,
314e179ddaSchristos 			    struct cmdq_item *);
32698d5317Sjmmv 
33698d5317Sjmmv const struct cmd_entry cmd_switch_client_entry = {
34ed4e6cd4Schristos 	.name = "switch-client",
35ed4e6cd4Schristos 	.alias = "switchc",
36ed4e6cd4Schristos 
37*6db26757Swiz 	.args = { "lc:EFnpt:rT:Z", 0, 0, NULL },
38aa83ff61Schristos 	.usage = "[-ElnprZ] [-c target-client] [-t target-session] "
39ed4e6cd4Schristos 		 "[-T key-table]",
40ed4e6cd4Schristos 
41c9ad075bSchristos 	/* -t is special */
42ed4e6cd4Schristos 
439fb66d81Schristos 	.flags = CMD_READONLY|CMD_CLIENT_CFLAG,
44ed4e6cd4Schristos 	.exec = cmd_switch_client_exec
45698d5317Sjmmv };
46698d5317Sjmmv 
474e179ddaSchristos static enum cmd_retval
cmd_switch_client_exec(struct cmd * self,struct cmdq_item * item)484e179ddaSchristos cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
49698d5317Sjmmv {
509fb66d81Schristos 	struct args		*args = cmd_get_args(self);
519fb66d81Schristos 	struct cmd_find_state	*current = cmdq_get_current(item);
529fb66d81Schristos 	struct cmd_find_state	 target;
53c9ad075bSchristos 	const char		*tflag = args_get(args, 't');
54c9ad075bSchristos 	enum cmd_find_type	 type;
55c9ad075bSchristos 	int			 flags;
569fb66d81Schristos 	struct client		*tc = cmdq_get_target_client(item);
57c9ad075bSchristos 	struct session		*s;
58c9ad075bSchristos 	struct winlink		*wl;
59aa83ff61Schristos 	struct window		*w;
60ed4e6cd4Schristos 	struct window_pane	*wp;
614e179ddaSchristos 	const char		*tablename;
625494e770Schristos 	struct key_table	*table;
63698d5317Sjmmv 
646483eba0Schristos 	if (tflag != NULL && tflag[strcspn(tflag, ":.%")] != '\0') {
65c9ad075bSchristos 		type = CMD_FIND_PANE;
66c9ad075bSchristos 		flags = 0;
67c9ad075bSchristos 	} else {
68c9ad075bSchristos 		type = CMD_FIND_SESSION;
69c9ad075bSchristos 		flags = CMD_FIND_PREFER_UNATTACHED;
70c9ad075bSchristos 	}
719fb66d81Schristos 	if (cmd_find_target(&target, item, tflag, type, flags) != 0)
72c9ad075bSchristos 		return (CMD_RETURN_ERROR);
739fb66d81Schristos 	s = target.s;
749fb66d81Schristos 	wl = target.wl;
759fb66d81Schristos 	wp = target.wp;
76c9ad075bSchristos 
779fb66d81Schristos 	if (args_has(args, 'r')) {
789fb66d81Schristos 		if (tc->flags & CLIENT_READONLY)
799fb66d81Schristos 			tc->flags &= ~(CLIENT_READONLY|CLIENT_IGNORESIZE);
809fb66d81Schristos 		else
819fb66d81Schristos 			tc->flags |= (CLIENT_READONLY|CLIENT_IGNORESIZE);
829fb66d81Schristos 	}
835494e770Schristos 
845494e770Schristos 	tablename = args_get(args, 'T');
855494e770Schristos 	if (tablename != NULL) {
865494e770Schristos 		table = key_bindings_get_table(tablename, 0);
875494e770Schristos 		if (table == NULL) {
884e179ddaSchristos 			cmdq_error(item, "table %s doesn't exist", tablename);
895494e770Schristos 			return (CMD_RETURN_ERROR);
905494e770Schristos 		}
915494e770Schristos 		table->references++;
929fb66d81Schristos 		key_bindings_unref_table(tc->keytable);
939fb66d81Schristos 		tc->keytable = table;
94ed4e6cd4Schristos 		return (CMD_RETURN_NORMAL);
95928fc495Schristos 	}
96928fc495Schristos 
97d530c4d0Sjmmv 	if (args_has(args, 'n')) {
989fb66d81Schristos 		if ((s = session_next_session(tc->session)) == NULL) {
994e179ddaSchristos 			cmdq_error(item, "can't find next session");
100928fc495Schristos 			return (CMD_RETURN_ERROR);
101698d5317Sjmmv 		}
102d530c4d0Sjmmv 	} else if (args_has(args, 'p')) {
1039fb66d81Schristos 		if ((s = session_previous_session(tc->session)) == NULL) {
1044e179ddaSchristos 			cmdq_error(item, "can't find previous session");
105928fc495Schristos 			return (CMD_RETURN_ERROR);
106698d5317Sjmmv 		}
107d530c4d0Sjmmv 	} else if (args_has(args, 'l')) {
1089fb66d81Schristos 		if (tc->last_session != NULL && session_alive(tc->last_session))
1099fb66d81Schristos 			s = tc->last_session;
110ed4e6cd4Schristos 		else
111ed4e6cd4Schristos 			s = NULL;
112698d5317Sjmmv 		if (s == NULL) {
1134e179ddaSchristos 			cmdq_error(item, "can't find last session");
114928fc495Schristos 			return (CMD_RETURN_ERROR);
115698d5317Sjmmv 		}
116928fc495Schristos 	} else {
1179fb66d81Schristos 		if (cmdq_get_client(item) == NULL)
118928fc495Schristos 			return (CMD_RETURN_NORMAL);
1199fb66d81Schristos 		if (wl != NULL && wp != NULL && wp != wl->window->active) {
1209fb66d81Schristos 			w = wl->window;
1219fb66d81Schristos 			if (window_push_zoom(w, 0, args_has(args, 'Z')))
122aa83ff61Schristos 				server_redraw_window(w);
123aa83ff61Schristos 			window_redraw_active_switch(w, wp);
124aa83ff61Schristos 			window_set_active_pane(w, wp, 1);
125aa83ff61Schristos 			if (window_pop_zoom(w))
126aa83ff61Schristos 				server_redraw_window(w);
127ef36e747Schristos 		}
128aa83ff61Schristos 		if (wl != NULL) {
129c9ad075bSchristos 			session_set_current(s, wl);
1309fb66d81Schristos 			cmd_find_from_session(current, s, 0);
131928fc495Schristos 		}
132928fc495Schristos 	}
133698d5317Sjmmv 
1344e179ddaSchristos 	if (!args_has(args, 'E'))
1359fb66d81Schristos 		environ_update(s->options, tc->environ, s->environ);
1365494e770Schristos 
137*6db26757Swiz 	server_client_set_session(tc, s);
1389fb66d81Schristos 	if (~cmdq_get_flags(item) & CMDQ_STATE_REPEAT)
1399fb66d81Schristos 		server_client_set_key_table(tc, NULL);
140698d5317Sjmmv 
141928fc495Schristos 	return (CMD_RETURN_NORMAL);
142698d5317Sjmmv }
143