xref: /minix3/external/bsd/tmux/dist/cmd-select-window.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1 /* Id */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <stdlib.h>
22 
23 #include "tmux.h"
24 
25 /*
26  * Select window by index.
27  */
28 
29 void		 cmd_select_window_key_binding(struct cmd *, int);
30 enum cmd_retval	 cmd_select_window_exec(struct cmd *, struct cmd_q *);
31 
32 const struct cmd_entry cmd_select_window_entry = {
33 	"select-window", "selectw",
34 	"lnpTt:", 0, 0,
35 	"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
36 	0,
37 	cmd_select_window_key_binding,
38 	cmd_select_window_exec
39 };
40 
41 const struct cmd_entry cmd_next_window_entry = {
42 	"next-window", "next",
43 	"at:", 0, 0,
44 	"[-a] " CMD_TARGET_SESSION_USAGE,
45 	0,
46 	cmd_select_window_key_binding,
47 	cmd_select_window_exec
48 };
49 
50 const struct cmd_entry cmd_previous_window_entry = {
51 	"previous-window", "prev",
52 	"at:", 0, 0,
53 	"[-a] " CMD_TARGET_SESSION_USAGE,
54 	0,
55 	cmd_select_window_key_binding,
56 	cmd_select_window_exec
57 };
58 
59 const struct cmd_entry cmd_last_window_entry = {
60 	"last-window", "last",
61 	"t:", 0, 0,
62 	CMD_TARGET_SESSION_USAGE,
63 	0,
64 	NULL,
65 	cmd_select_window_exec
66 };
67 
68 void
cmd_select_window_key_binding(struct cmd * self,int key)69 cmd_select_window_key_binding(struct cmd *self, int key)
70 {
71 	char	tmp[16];
72 
73 	self->args = args_create(0);
74 	if (key >= '0' && key <= '9') {
75 		xsnprintf(tmp, sizeof tmp, ":%d", key - '0');
76 		args_set(self->args, 't', tmp);
77 	}
78 	if (key == ('n' | KEYC_ESCAPE) || key == ('p' | KEYC_ESCAPE))
79 		args_set(self->args, 'a', NULL);
80 }
81 
82 enum cmd_retval
cmd_select_window_exec(struct cmd * self,struct cmd_q * cmdq)83 cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
84 {
85 	struct args	*args = self->args;
86 	struct winlink	*wl;
87 	struct session	*s;
88 	int		 next, previous, last, activity;
89 
90 	next = self->entry == &cmd_next_window_entry;
91 	if (args_has(self->args, 'n'))
92 		next = 1;
93 	previous = self->entry == &cmd_previous_window_entry;
94 	if (args_has(self->args, 'p'))
95 		previous = 1;
96 	last = self->entry == &cmd_last_window_entry;
97 	if (args_has(self->args, 'l'))
98 		last = 1;
99 
100 	if (next || previous || last) {
101 		s = cmd_find_session(cmdq, args_get(args, 't'), 0);
102 		if (s == NULL)
103 			return (CMD_RETURN_ERROR);
104 
105 		activity = args_has(self->args, 'a');
106 		if (next) {
107 			if (session_next(s, activity) != 0) {
108 				cmdq_error(cmdq, "no next window");
109 				return (CMD_RETURN_ERROR);
110 			}
111 		} else if (previous) {
112 			if (session_previous(s, activity) != 0) {
113 				cmdq_error(cmdq, "no previous window");
114 				return (CMD_RETURN_ERROR);
115 			}
116 		} else {
117 			if (session_last(s) != 0) {
118 				cmdq_error(cmdq, "no last window");
119 				return (CMD_RETURN_ERROR);
120 			}
121 		}
122 
123 		server_redraw_session(s);
124 	} else {
125 		wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
126 		if (wl == NULL)
127 			return (CMD_RETURN_ERROR);
128 
129 		/*
130 		 * If -T and select-window is invoked on same window as
131 		 * current, switch to previous window.
132 		 */
133 		if (args_has(self->args, 'T') && wl == s->curw) {
134 			if (session_last(s) != 0) {
135 				cmdq_error(cmdq, "no last window");
136 				return (-1);
137 			}
138 			server_redraw_session(s);
139 		} else if (session_select(s, wl->idx) == 0)
140 			server_redraw_session(s);
141 	}
142 	recalculate_sizes();
143 
144 	return (CMD_RETURN_NORMAL);
145 }
146