Fix detach -a by skipping clients where the session is NULL.
[tmux-openbsd.git] / cmd-select-window.c
blob744bdf7735248a0ac827b72ba2546cc286b02e47
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
21 #include <stdlib.h>
23 #include "tmux.h"
26 * Select window by index.
29 void cmd_select_window_key_binding(struct cmd *, int);
30 enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_q *);
32 const struct cmd_entry cmd_select_window_entry = {
33 "select-window", "selectw",
34 "lnpTt:", 0, 0,
35 "[-lnpT] " CMD_TARGET_WINDOW_USAGE,
37 cmd_select_window_key_binding,
38 cmd_select_window_exec
41 const struct cmd_entry cmd_next_window_entry = {
42 "next-window", "next",
43 "at:", 0, 0,
44 "[-a] " CMD_TARGET_SESSION_USAGE,
46 cmd_select_window_key_binding,
47 cmd_select_window_exec
50 const struct cmd_entry cmd_previous_window_entry = {
51 "previous-window", "prev",
52 "at:", 0, 0,
53 "[-a] " CMD_TARGET_SESSION_USAGE,
55 cmd_select_window_key_binding,
56 cmd_select_window_exec
59 const struct cmd_entry cmd_last_window_entry = {
60 "last-window", "last",
61 "t:", 0, 0,
62 CMD_TARGET_SESSION_USAGE,
64 NULL,
65 cmd_select_window_exec
68 void
69 cmd_select_window_key_binding(struct cmd *self, int key)
71 char tmp[16];
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);
78 if (key == ('n' | KEYC_ESCAPE) || key == ('p' | KEYC_ESCAPE))
79 args_set(self->args, 'a', NULL);
82 enum cmd_retval
83 cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
85 struct args *args = self->args;
86 struct winlink *wl;
87 struct session *s;
88 int next, previous, last, activity;
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;
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);
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);
111 } else if (previous) {
112 if (session_previous(s, activity) != 0) {
113 cmdq_error(cmdq, "no previous window");
114 return (CMD_RETURN_ERROR);
116 } else {
117 if (session_last(s) != 0) {
118 cmdq_error(cmdq, "no last window");
119 return (CMD_RETURN_ERROR);
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);
130 * If -T and select-window is invoked on same window as
131 * current, switch to previous window.
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);
138 server_redraw_session(s);
139 } else if (session_select(s, wl->idx) == 0)
140 server_redraw_session(s);
142 recalculate_sizes();
144 return (CMD_RETURN_NORMAL);