4 * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
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>
30 static enum cmd_retval
cmd_select_pane_exec(struct cmd
*, struct cmdq_item
*);
32 const struct cmd_entry cmd_select_pane_entry
= {
33 .name
= "select-pane",
36 .args
= { "DdegLlMmP:RT:t:UZ", 0, 0, NULL
}, /* -P and -g deprecated */
37 .usage
= "[-DdeLlMmRUZ] [-T title] " CMD_TARGET_PANE_USAGE
,
39 .target
= { 't', CMD_FIND_PANE
, 0 },
42 .exec
= cmd_select_pane_exec
45 const struct cmd_entry cmd_last_pane_entry
= {
49 .args
= { "det:Z", 0, 0, NULL
},
50 .usage
= "[-deZ] " CMD_TARGET_WINDOW_USAGE
,
52 .target
= { 't', CMD_FIND_WINDOW
, 0 },
55 .exec
= cmd_select_pane_exec
59 cmd_select_pane_redraw(struct window
*w
)
64 * Redraw entire window if it is bigger than the client (the
65 * offset may change), otherwise just draw borders.
68 TAILQ_FOREACH(c
, &clients
, entry
) {
69 if (c
->session
== NULL
|| (c
->flags
& CLIENT_CONTROL
))
71 if (c
->session
->curw
->window
== w
&& tty_window_bigger(&c
->tty
))
72 server_redraw_client(c
);
74 if (c
->session
->curw
->window
== w
)
75 c
->flags
|= CLIENT_REDRAWBORDERS
;
76 if (session_has(c
->session
, w
))
77 c
->flags
|= CLIENT_REDRAWSTATUS
;
83 static enum cmd_retval
84 cmd_select_pane_exec(struct cmd
*self
, struct cmdq_item
*item
)
86 struct args
*args
= cmd_get_args(self
);
87 const struct cmd_entry
*entry
= cmd_get_entry(self
);
88 struct cmd_find_state
*current
= cmdq_get_current(item
);
89 struct cmd_find_state
*target
= cmdq_get_target(item
);
90 struct client
*c
= cmdq_get_client(item
);
91 struct winlink
*wl
= target
->wl
;
92 struct window
*w
= wl
->window
;
93 struct session
*s
= target
->s
;
94 struct window_pane
*wp
= target
->wp
, *activewp
, *lastwp
, *markedwp
;
95 struct options
*oo
= wp
->options
;
98 struct options_entry
*o
;
100 if (entry
== &cmd_last_pane_entry
|| args_has(args
, 'l')) {
102 * Check for no last pane found in case the other pane was
103 * spawned without being visited (for example split-window -d).
105 lastwp
= TAILQ_FIRST(&w
->last_panes
);
106 if (lastwp
== NULL
&& window_count_panes(w
) == 2) {
107 lastwp
= TAILQ_PREV(w
->active
, window_panes
, entry
);
109 lastwp
= TAILQ_NEXT(w
->active
, entry
);
111 if (lastwp
== NULL
) {
112 cmdq_error(item
, "no last pane");
113 return (CMD_RETURN_ERROR
);
115 if (args_has(args
, 'e')) {
116 lastwp
->flags
&= ~PANE_INPUTOFF
;
117 server_redraw_window_borders(lastwp
->window
);
118 server_status_window(lastwp
->window
);
119 } else if (args_has(args
, 'd')) {
120 lastwp
->flags
|= PANE_INPUTOFF
;
121 server_redraw_window_borders(lastwp
->window
);
122 server_status_window(lastwp
->window
);
124 if (window_push_zoom(w
, 0, args_has(args
, 'Z')))
125 server_redraw_window(w
);
126 window_redraw_active_switch(w
, lastwp
);
127 if (window_set_active_pane(w
, lastwp
, 1)) {
128 cmd_find_from_winlink(current
, wl
, 0);
129 cmd_select_pane_redraw(w
);
131 if (window_pop_zoom(w
))
132 server_redraw_window(w
);
134 return (CMD_RETURN_NORMAL
);
137 if (args_has(args
, 'm') || args_has(args
, 'M')) {
138 if (args_has(args
, 'm') && !window_pane_visible(wp
))
139 return (CMD_RETURN_NORMAL
);
140 if (server_check_marked())
141 lastwp
= marked_pane
.wp
;
145 if (args_has(args
, 'M') || server_is_marked(s
, wl
, wp
))
146 server_clear_marked();
148 server_set_marked(s
, wl
, wp
);
149 markedwp
= marked_pane
.wp
;
151 if (lastwp
!= NULL
) {
152 lastwp
->flags
|= (PANE_REDRAW
|PANE_STYLECHANGED
);
153 server_redraw_window_borders(lastwp
->window
);
154 server_status_window(lastwp
->window
);
156 if (markedwp
!= NULL
) {
157 markedwp
->flags
|= (PANE_REDRAW
|PANE_STYLECHANGED
);
158 server_redraw_window_borders(markedwp
->window
);
159 server_status_window(markedwp
->window
);
161 return (CMD_RETURN_NORMAL
);
164 style
= args_get(args
, 'P');
166 o
= options_set_string(oo
, "window-style", 0, "%s", style
);
168 cmdq_error(item
, "bad style: %s", style
);
169 return (CMD_RETURN_ERROR
);
171 options_set_string(oo
, "window-active-style", 0, "%s", style
);
172 wp
->flags
|= (PANE_REDRAW
|PANE_STYLECHANGED
);
174 if (args_has(args
, 'g')) {
175 cmdq_print(item
, "%s", options_get_string(oo
, "window-style"));
176 return (CMD_RETURN_NORMAL
);
179 if (args_has(args
, 'L')) {
180 window_push_zoom(w
, 0, 1);
181 wp
= window_pane_find_left(wp
);
183 } else if (args_has(args
, 'R')) {
184 window_push_zoom(w
, 0, 1);
185 wp
= window_pane_find_right(wp
);
187 } else if (args_has(args
, 'U')) {
188 window_push_zoom(w
, 0, 1);
189 wp
= window_pane_find_up(wp
);
191 } else if (args_has(args
, 'D')) {
192 window_push_zoom(w
, 0, 1);
193 wp
= window_pane_find_down(wp
);
197 return (CMD_RETURN_NORMAL
);
199 if (args_has(args
, 'e')) {
200 wp
->flags
&= ~PANE_INPUTOFF
;
201 server_redraw_window_borders(wp
->window
);
202 server_status_window(wp
->window
);
203 return (CMD_RETURN_NORMAL
);
205 if (args_has(args
, 'd')) {
206 wp
->flags
|= PANE_INPUTOFF
;
207 server_redraw_window_borders(wp
->window
);
208 server_status_window(wp
->window
);
209 return (CMD_RETURN_NORMAL
);
212 if (args_has(args
, 'T')) {
213 title
= format_single_from_target(item
, args_get(args
, 'T'));
214 if (screen_set_title(&wp
->base
, title
)) {
215 notify_pane("pane-title-changed", wp
);
216 server_redraw_window_borders(wp
->window
);
217 server_status_window(wp
->window
);
220 return (CMD_RETURN_NORMAL
);
223 if (c
!= NULL
&& c
->session
!= NULL
&& (c
->flags
& CLIENT_ACTIVEPANE
))
224 activewp
= server_client_get_pane(c
);
226 activewp
= w
->active
;
228 return (CMD_RETURN_NORMAL
);
229 if (window_push_zoom(w
, 0, args_has(args
, 'Z')))
230 server_redraw_window(w
);
231 window_redraw_active_switch(w
, wp
);
232 if (c
!= NULL
&& c
->session
!= NULL
&& (c
->flags
& CLIENT_ACTIVEPANE
))
233 server_client_set_pane(c
, wp
);
234 else if (window_set_active_pane(w
, wp
, 1))
235 cmd_find_from_winlink_pane(current
, wl
, wp
, 0);
236 cmdq_insert_hook(s
, item
, current
, "after-select-pane");
237 cmd_select_pane_redraw(w
);
238 if (window_pop_zoom(w
))
239 server_redraw_window(w
);
241 return (CMD_RETURN_NORMAL
);