xref: /openbsd/usr.bin/tmux/cmd-select-window.c (revision cecf84d4)
1 /* $OpenBSD: cmd-select-window.c,v 1.12 2014/10/20 22:29:25 nicm Exp $ */
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 enum cmd_retval	 cmd_select_window_exec(struct cmd *, struct cmd_q *);
30 
31 const struct cmd_entry cmd_select_window_entry = {
32 	"select-window", "selectw",
33 	"lnpTt:", 0, 0,
34 	"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
35 	0,
36 	cmd_select_window_exec
37 };
38 
39 const struct cmd_entry cmd_next_window_entry = {
40 	"next-window", "next",
41 	"at:", 0, 0,
42 	"[-a] " CMD_TARGET_SESSION_USAGE,
43 	0,
44 	cmd_select_window_exec
45 };
46 
47 const struct cmd_entry cmd_previous_window_entry = {
48 	"previous-window", "prev",
49 	"at:", 0, 0,
50 	"[-a] " CMD_TARGET_SESSION_USAGE,
51 	0,
52 	cmd_select_window_exec
53 };
54 
55 const struct cmd_entry cmd_last_window_entry = {
56 	"last-window", "last",
57 	"t:", 0, 0,
58 	CMD_TARGET_SESSION_USAGE,
59 	0,
60 	cmd_select_window_exec
61 };
62 
63 enum cmd_retval
64 cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
65 {
66 	struct args	*args = self->args;
67 	struct winlink	*wl;
68 	struct session	*s;
69 	int		 next, previous, last, activity;
70 
71 	next = self->entry == &cmd_next_window_entry;
72 	if (args_has(self->args, 'n'))
73 		next = 1;
74 	previous = self->entry == &cmd_previous_window_entry;
75 	if (args_has(self->args, 'p'))
76 		previous = 1;
77 	last = self->entry == &cmd_last_window_entry;
78 	if (args_has(self->args, 'l'))
79 		last = 1;
80 
81 	if (next || previous || last) {
82 		s = cmd_find_session(cmdq, args_get(args, 't'), 0);
83 		if (s == NULL)
84 			return (CMD_RETURN_ERROR);
85 
86 		activity = args_has(self->args, 'a');
87 		if (next) {
88 			if (session_next(s, activity) != 0) {
89 				cmdq_error(cmdq, "no next window");
90 				return (CMD_RETURN_ERROR);
91 			}
92 		} else if (previous) {
93 			if (session_previous(s, activity) != 0) {
94 				cmdq_error(cmdq, "no previous window");
95 				return (CMD_RETURN_ERROR);
96 			}
97 		} else {
98 			if (session_last(s) != 0) {
99 				cmdq_error(cmdq, "no last window");
100 				return (CMD_RETURN_ERROR);
101 			}
102 		}
103 
104 		server_redraw_session(s);
105 	} else {
106 		wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
107 		if (wl == NULL)
108 			return (CMD_RETURN_ERROR);
109 
110 		/*
111 		 * If -T and select-window is invoked on same window as
112 		 * current, switch to previous window.
113 		 */
114 		if (args_has(self->args, 'T') && wl == s->curw) {
115 			if (session_last(s) != 0) {
116 				cmdq_error(cmdq, "no last window");
117 				return (-1);
118 			}
119 			server_redraw_session(s);
120 		} else if (session_select(s, wl->idx) == 0)
121 			server_redraw_session(s);
122 	}
123 	recalculate_sizes();
124 
125 	return (CMD_RETURN_NORMAL);
126 }
127