1 | /* $OpenBSD$ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2007 Nicholas Marriott <[email protected]> |
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 | static enum cmd_retval cmd_select_window_exec(struct cmd *, |
30 | struct cmdq_item *); |
31 | |
32 | const struct cmd_entry cmd_select_window_entry = { |
33 | .name = "select-window" , |
34 | .alias = "selectw" , |
35 | |
36 | .args = { "lnpTt:" , 0, 0 }, |
37 | .usage = "[-lnpT] " CMD_TARGET_WINDOW_USAGE, |
38 | |
39 | .target = { 't', CMD_FIND_WINDOW, 0 }, |
40 | |
41 | .flags = 0, |
42 | .exec = cmd_select_window_exec |
43 | }; |
44 | |
45 | const struct cmd_entry cmd_next_window_entry = { |
46 | .name = "next-window" , |
47 | .alias = "next" , |
48 | |
49 | .args = { "at:" , 0, 0 }, |
50 | .usage = "[-a] " CMD_TARGET_SESSION_USAGE, |
51 | |
52 | .target = { 't', CMD_FIND_SESSION, 0 }, |
53 | |
54 | .flags = 0, |
55 | .exec = cmd_select_window_exec |
56 | }; |
57 | |
58 | const struct cmd_entry cmd_previous_window_entry = { |
59 | .name = "previous-window" , |
60 | .alias = "prev" , |
61 | |
62 | .args = { "at:" , 0, 0 }, |
63 | .usage = "[-a] " CMD_TARGET_SESSION_USAGE, |
64 | |
65 | .target = { 't', CMD_FIND_SESSION, 0 }, |
66 | |
67 | .flags = 0, |
68 | .exec = cmd_select_window_exec |
69 | }; |
70 | |
71 | const struct cmd_entry cmd_last_window_entry = { |
72 | .name = "last-window" , |
73 | .alias = "last" , |
74 | |
75 | .args = { "t:" , 0, 0 }, |
76 | .usage = CMD_TARGET_SESSION_USAGE, |
77 | |
78 | .target = { 't', CMD_FIND_SESSION, 0 }, |
79 | |
80 | .flags = 0, |
81 | .exec = cmd_select_window_exec |
82 | }; |
83 | |
84 | static enum cmd_retval |
85 | cmd_select_window_exec(struct cmd *self, struct cmdq_item *item) |
86 | { |
87 | struct cmd_find_state *current = &item->shared->current; |
88 | struct winlink *wl = item->target.wl; |
89 | struct session *s = item->target.s; |
90 | int next, previous, last, activity; |
91 | |
92 | next = self->entry == &cmd_next_window_entry; |
93 | if (args_has(self->args, 'n')) |
94 | next = 1; |
95 | previous = self->entry == &cmd_previous_window_entry; |
96 | if (args_has(self->args, 'p')) |
97 | previous = 1; |
98 | last = self->entry == &cmd_last_window_entry; |
99 | if (args_has(self->args, 'l')) |
100 | last = 1; |
101 | |
102 | if (next || previous || last) { |
103 | activity = args_has(self->args, 'a'); |
104 | if (next) { |
105 | if (session_next(s, activity) != 0) { |
106 | cmdq_error(item, "no next window" ); |
107 | return (CMD_RETURN_ERROR); |
108 | } |
109 | } else if (previous) { |
110 | if (session_previous(s, activity) != 0) { |
111 | cmdq_error(item, "no previous window" ); |
112 | return (CMD_RETURN_ERROR); |
113 | } |
114 | } else { |
115 | if (session_last(s) != 0) { |
116 | cmdq_error(item, "no last window" ); |
117 | return (CMD_RETURN_ERROR); |
118 | } |
119 | } |
120 | cmd_find_from_session(current, s, 0); |
121 | server_redraw_session(s); |
122 | cmdq_insert_hook(s, item, current, "after-select-window" ); |
123 | } else { |
124 | /* |
125 | * If -T and select-window is invoked on same window as |
126 | * current, switch to previous window. |
127 | */ |
128 | if (args_has(self->args, 'T') && wl == s->curw) { |
129 | if (session_last(s) != 0) { |
130 | cmdq_error(item, "no last window" ); |
131 | return (-1); |
132 | } |
133 | if (current->s == s) |
134 | cmd_find_from_session(current, s, 0); |
135 | server_redraw_session(s); |
136 | } else if (session_select(s, wl->idx) == 0) { |
137 | cmd_find_from_session(current, s, 0); |
138 | server_redraw_session(s); |
139 | } |
140 | cmdq_insert_hook(s, item, current, "after-select-window" ); |
141 | } |
142 | recalculate_sizes(); |
143 | |
144 | return (CMD_RETURN_NORMAL); |
145 | } |
146 | |