1 /* $OpenBSD$ */
2
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
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 .name = "select-window",
33 .alias = "selectw",
34
35 .args = { "lnpTt:", 0, 0 },
36 .usage = "[-lnpT] " CMD_TARGET_WINDOW_USAGE,
37
38 .tflag = CMD_WINDOW,
39
40 .flags = 0,
41 .exec = cmd_select_window_exec
42 };
43
44 const struct cmd_entry cmd_next_window_entry = {
45 .name = "next-window",
46 .alias = "next",
47
48 .args = { "at:", 0, 0 },
49 .usage = "[-a] " CMD_TARGET_SESSION_USAGE,
50
51 .tflag = CMD_SESSION,
52
53 .flags = 0,
54 .exec = cmd_select_window_exec
55 };
56
57 const struct cmd_entry cmd_previous_window_entry = {
58 .name = "previous-window",
59 .alias = "prev",
60
61 .args = { "at:", 0, 0 },
62 .usage = "[-a] " CMD_TARGET_SESSION_USAGE,
63
64 .tflag = CMD_SESSION,
65
66 .flags = 0,
67 .exec = cmd_select_window_exec
68 };
69
70 const struct cmd_entry cmd_last_window_entry = {
71 .name = "last-window",
72 .alias = "last",
73
74 .args = { "t:", 0, 0 },
75 .usage = CMD_TARGET_SESSION_USAGE,
76
77 .tflag = CMD_SESSION,
78
79 .flags = 0,
80 .exec = cmd_select_window_exec
81 };
82
83 enum cmd_retval
cmd_select_window_exec(struct cmd * self,struct cmd_q * cmdq)84 cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
85 {
86 struct winlink *wl = cmdq->state.tflag.wl;
87 struct session *s = cmdq->state.tflag.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 activity = args_has(self->args, 'a');
102 if (next) {
103 if (session_next(s, activity) != 0) {
104 cmdq_error(cmdq, "no next window");
105 return (CMD_RETURN_ERROR);
106 }
107 } else if (previous) {
108 if (session_previous(s, activity) != 0) {
109 cmdq_error(cmdq, "no previous window");
110 return (CMD_RETURN_ERROR);
111 }
112 } else {
113 if (session_last(s) != 0) {
114 cmdq_error(cmdq, "no last window");
115 return (CMD_RETURN_ERROR);
116 }
117 }
118
119 server_redraw_session(s);
120 } else {
121 /*
122 * If -T and select-window is invoked on same window as
123 * current, switch to previous window.
124 */
125 if (args_has(self->args, 'T') && wl == s->curw) {
126 if (session_last(s) != 0) {
127 cmdq_error(cmdq, "no last window");
128 return (-1);
129 }
130 server_redraw_session(s);
131 } else if (session_select(s, wl->idx) == 0)
132 server_redraw_session(s);
133 }
134 recalculate_sizes();
135
136 return (CMD_RETURN_NORMAL);
137 }
138