xref: /openbsd-src/usr.bin/tmux/cmd-select-window.c (revision 3447b427c1ffcf379e7fc14b9e25cce4fa75a963)
1 /* $OpenBSD: cmd-select-window.c,v 1.13 2015/12/13 14:32:38 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 	CMD_WINDOW_T,
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 	CMD_SESSION_T,
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 	CMD_SESSION_T,
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 	CMD_SESSION_T,
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 winlink	*wl = cmdq->state.tflag.wl;
67 	struct session	*s = cmdq->state.tflag.s;
68 	int		 next, previous, last, activity;
69 
70 	next = self->entry == &cmd_next_window_entry;
71 	if (args_has(self->args, 'n'))
72 		next = 1;
73 	previous = self->entry == &cmd_previous_window_entry;
74 	if (args_has(self->args, 'p'))
75 		previous = 1;
76 	last = self->entry == &cmd_last_window_entry;
77 	if (args_has(self->args, 'l'))
78 		last = 1;
79 
80 	if (next || previous || last) {
81 		activity = args_has(self->args, 'a');
82 		if (next) {
83 			if (session_next(s, activity) != 0) {
84 				cmdq_error(cmdq, "no next window");
85 				return (CMD_RETURN_ERROR);
86 			}
87 		} else if (previous) {
88 			if (session_previous(s, activity) != 0) {
89 				cmdq_error(cmdq, "no previous window");
90 				return (CMD_RETURN_ERROR);
91 			}
92 		} else {
93 			if (session_last(s) != 0) {
94 				cmdq_error(cmdq, "no last window");
95 				return (CMD_RETURN_ERROR);
96 			}
97 		}
98 
99 		server_redraw_session(s);
100 	} else {
101 		/*
102 		 * If -T and select-window is invoked on same window as
103 		 * current, switch to previous window.
104 		 */
105 		if (args_has(self->args, 'T') && wl == s->curw) {
106 			if (session_last(s) != 0) {
107 				cmdq_error(cmdq, "no last window");
108 				return (-1);
109 			}
110 			server_redraw_session(s);
111 		} else if (session_select(s, wl->idx) == 0)
112 			server_redraw_session(s);
113 	}
114 	recalculate_sizes();
115 
116 	return (CMD_RETURN_NORMAL);
117 }
118