15494e770Schristos /* $OpenBSD$ */
2698d5317Sjmmv
3698d5317Sjmmv /*
4ed4e6cd4Schristos * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
5698d5317Sjmmv *
6698d5317Sjmmv * Permission to use, copy, modify, and distribute this software for any
7698d5317Sjmmv * purpose with or without fee is hereby granted, provided that the above
8698d5317Sjmmv * copyright notice and this permission notice appear in all copies.
9698d5317Sjmmv *
10698d5317Sjmmv * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11698d5317Sjmmv * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12698d5317Sjmmv * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13698d5317Sjmmv * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14698d5317Sjmmv * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15698d5317Sjmmv * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16698d5317Sjmmv * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17698d5317Sjmmv */
18698d5317Sjmmv
19698d5317Sjmmv #include <sys/types.h>
20698d5317Sjmmv
218f3b9483Schristos #include <stdlib.h>
22ef36e747Schristos #include <string.h>
238f3b9483Schristos
24698d5317Sjmmv #include "tmux.h"
25698d5317Sjmmv
26698d5317Sjmmv /*
27698d5317Sjmmv * Select pane.
28698d5317Sjmmv */
29698d5317Sjmmv
304e179ddaSchristos static enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmdq_item *);
31698d5317Sjmmv
32698d5317Sjmmv const struct cmd_entry cmd_select_pane_entry = {
33ed4e6cd4Schristos .name = "select-pane",
34ed4e6cd4Schristos .alias = "selectp",
35ed4e6cd4Schristos
366db26757Swiz .args = { "DdegLlMmP:RT:t:UZ", 0, 0, NULL }, /* -P and -g deprecated */
37aa83ff61Schristos .usage = "[-DdeLlMmRUZ] [-T title] " CMD_TARGET_PANE_USAGE,
38ed4e6cd4Schristos
39c9ad075bSchristos .target = { 't', CMD_FIND_PANE, 0 },
40ed4e6cd4Schristos
41ed4e6cd4Schristos .flags = 0,
42ed4e6cd4Schristos .exec = cmd_select_pane_exec
43d530c4d0Sjmmv };
44d530c4d0Sjmmv
45d530c4d0Sjmmv const struct cmd_entry cmd_last_pane_entry = {
46ed4e6cd4Schristos .name = "last-pane",
47ed4e6cd4Schristos .alias = "lastp",
48ed4e6cd4Schristos
496db26757Swiz .args = { "det:Z", 0, 0, NULL },
50aa83ff61Schristos .usage = "[-deZ] " CMD_TARGET_WINDOW_USAGE,
51ed4e6cd4Schristos
52c9ad075bSchristos .target = { 't', CMD_FIND_WINDOW, 0 },
53ed4e6cd4Schristos
54ed4e6cd4Schristos .flags = 0,
55ed4e6cd4Schristos .exec = cmd_select_pane_exec
56698d5317Sjmmv };
57698d5317Sjmmv
58ef36e747Schristos static void
cmd_select_pane_redraw(struct window * w)59ef36e747Schristos cmd_select_pane_redraw(struct window *w)
60ef36e747Schristos {
61ef36e747Schristos struct client *c;
62ef36e747Schristos
63ef36e747Schristos /*
64ef36e747Schristos * Redraw entire window if it is bigger than the client (the
65ef36e747Schristos * offset may change), otherwise just draw borders.
66ef36e747Schristos */
67ef36e747Schristos
68ef36e747Schristos TAILQ_FOREACH(c, &clients, entry) {
69ef36e747Schristos if (c->session == NULL || (c->flags & CLIENT_CONTROL))
70ef36e747Schristos continue;
71ef36e747Schristos if (c->session->curw->window == w && tty_window_bigger(&c->tty))
72ef36e747Schristos server_redraw_client(c);
73ef36e747Schristos else {
74ef36e747Schristos if (c->session->curw->window == w)
75ef36e747Schristos c->flags |= CLIENT_REDRAWBORDERS;
76ef36e747Schristos if (session_has(c->session, w))
77ef36e747Schristos c->flags |= CLIENT_REDRAWSTATUS;
78ef36e747Schristos }
79ef36e747Schristos
80ef36e747Schristos }
81ef36e747Schristos }
82ef36e747Schristos
834e179ddaSchristos static enum cmd_retval
cmd_select_pane_exec(struct cmd * self,struct cmdq_item * item)844e179ddaSchristos cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
85698d5317Sjmmv {
869fb66d81Schristos struct args *args = cmd_get_args(self);
879fb66d81Schristos const struct cmd_entry *entry = cmd_get_entry(self);
889fb66d81Schristos struct cmd_find_state *current = cmdq_get_current(item);
899fb66d81Schristos struct cmd_find_state *target = cmdq_get_target(item);
909fb66d81Schristos struct client *c = cmdq_get_client(item);
919fb66d81Schristos struct winlink *wl = target->wl;
92ed4e6cd4Schristos struct window *w = wl->window;
939fb66d81Schristos struct session *s = target->s;
949fb66d81Schristos struct window_pane *wp = target->wp, *activewp, *lastwp, *markedwp;
959fb66d81Schristos struct options *oo = wp->options;
969fb66d81Schristos char *title;
975494e770Schristos const char *style;
986483eba0Schristos struct options_entry *o;
99698d5317Sjmmv
1009fb66d81Schristos if (entry == &cmd_last_pane_entry || args_has(args, 'l')) {
101*c23f9150Swiz /*
102*c23f9150Swiz * Check for no last pane found in case the other pane was
103*c23f9150Swiz * spawned without being visited (for example split-window -d).
104*c23f9150Swiz */
105*c23f9150Swiz lastwp = TAILQ_FIRST(&w->last_panes);
1068f3b9483Schristos if (lastwp == NULL && window_count_panes(w) == 2) {
1078f3b9483Schristos lastwp = TAILQ_PREV(w->active, window_panes, entry);
1088f3b9483Schristos if (lastwp == NULL)
1098f3b9483Schristos lastwp = TAILQ_NEXT(w->active, entry);
1108f3b9483Schristos }
111c9ad075bSchristos if (lastwp == NULL) {
1124e179ddaSchristos cmdq_error(item, "no last pane");
113928fc495Schristos return (CMD_RETURN_ERROR);
114698d5317Sjmmv }
1159fb66d81Schristos if (args_has(args, 'e')) {
116c9ad075bSchristos lastwp->flags &= ~PANE_INPUTOFF;
1179fb66d81Schristos server_redraw_window_borders(lastwp->window);
1189fb66d81Schristos server_status_window(lastwp->window);
1199fb66d81Schristos } else if (args_has(args, 'd')) {
120c9ad075bSchristos lastwp->flags |= PANE_INPUTOFF;
1219fb66d81Schristos server_redraw_window_borders(lastwp->window);
1229fb66d81Schristos server_status_window(lastwp->window);
1239fb66d81Schristos } else {
1249fb66d81Schristos if (window_push_zoom(w, 0, args_has(args, 'Z')))
125aa83ff61Schristos server_redraw_window(w);
126c9ad075bSchristos window_redraw_active_switch(w, lastwp);
1276483eba0Schristos if (window_set_active_pane(w, lastwp, 1)) {
128c9ad075bSchristos cmd_find_from_winlink(current, wl, 0);
129ef36e747Schristos cmd_select_pane_redraw(w);
1305494e770Schristos }
131aa83ff61Schristos if (window_pop_zoom(w))
132aa83ff61Schristos server_redraw_window(w);
1335494e770Schristos }
134928fc495Schristos return (CMD_RETURN_NORMAL);
135d530c4d0Sjmmv }
136d530c4d0Sjmmv
1375494e770Schristos if (args_has(args, 'm') || args_has(args, 'M')) {
1385494e770Schristos if (args_has(args, 'm') && !window_pane_visible(wp))
1395494e770Schristos return (CMD_RETURN_NORMAL);
1409fb66d81Schristos if (server_check_marked())
141ed4e6cd4Schristos lastwp = marked_pane.wp;
1429fb66d81Schristos else
1439fb66d81Schristos lastwp = NULL;
1445494e770Schristos
1455494e770Schristos if (args_has(args, 'M') || server_is_marked(s, wl, wp))
1465494e770Schristos server_clear_marked();
1475494e770Schristos else
1485494e770Schristos server_set_marked(s, wl, wp);
149ed4e6cd4Schristos markedwp = marked_pane.wp;
1505494e770Schristos
1515494e770Schristos if (lastwp != NULL) {
1526db26757Swiz lastwp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
1535494e770Schristos server_redraw_window_borders(lastwp->window);
1545494e770Schristos server_status_window(lastwp->window);
1555494e770Schristos }
1565494e770Schristos if (markedwp != NULL) {
1576db26757Swiz markedwp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
1585494e770Schristos server_redraw_window_borders(markedwp->window);
1595494e770Schristos server_status_window(markedwp->window);
1605494e770Schristos }
1615494e770Schristos return (CMD_RETURN_NORMAL);
1625494e770Schristos }
1635494e770Schristos
1649fb66d81Schristos style = args_get(args, 'P');
1659fb66d81Schristos if (style != NULL) {
1669fb66d81Schristos o = options_set_string(oo, "window-style", 0, "%s", style);
1676483eba0Schristos if (o == NULL) {
1684e179ddaSchristos cmdq_error(item, "bad style: %s", style);
169928fc495Schristos return (CMD_RETURN_ERROR);
170d530c4d0Sjmmv }
1719fb66d81Schristos options_set_string(oo, "window-active-style", 0, "%s", style);
1726483eba0Schristos wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
1735494e770Schristos }
1749fb66d81Schristos if (args_has(args, 'g')) {
1759fb66d81Schristos cmdq_print(item, "%s", options_get_string(oo, "window-style"));
1765494e770Schristos return (CMD_RETURN_NORMAL);
1775494e770Schristos }
178d530c4d0Sjmmv
1799fb66d81Schristos if (args_has(args, 'L')) {
1809fb66d81Schristos window_push_zoom(w, 0, 1);
181698d5317Sjmmv wp = window_pane_find_left(wp);
182aa83ff61Schristos window_pop_zoom(w);
1839fb66d81Schristos } else if (args_has(args, 'R')) {
1849fb66d81Schristos window_push_zoom(w, 0, 1);
185698d5317Sjmmv wp = window_pane_find_right(wp);
186aa83ff61Schristos window_pop_zoom(w);
1879fb66d81Schristos } else if (args_has(args, 'U')) {
1889fb66d81Schristos window_push_zoom(w, 0, 1);
189698d5317Sjmmv wp = window_pane_find_up(wp);
190aa83ff61Schristos window_pop_zoom(w);
1919fb66d81Schristos } else if (args_has(args, 'D')) {
1929fb66d81Schristos window_push_zoom(w, 0, 1);
193698d5317Sjmmv wp = window_pane_find_down(wp);
194aa83ff61Schristos window_pop_zoom(w);
195ed4e6cd4Schristos }
1965494e770Schristos if (wp == NULL)
1975494e770Schristos return (CMD_RETURN_NORMAL);
1985494e770Schristos
1999fb66d81Schristos if (args_has(args, 'e')) {
2005494e770Schristos wp->flags &= ~PANE_INPUTOFF;
2019fb66d81Schristos server_redraw_window_borders(wp->window);
202c9ad075bSchristos server_status_window(wp->window);
2039fb66d81Schristos return (CMD_RETURN_NORMAL);
2049fb66d81Schristos }
2059fb66d81Schristos if (args_has(args, 'd')) {
2069fb66d81Schristos wp->flags |= PANE_INPUTOFF;
2079fb66d81Schristos server_redraw_window_borders(wp->window);
2089fb66d81Schristos server_status_window(wp->window);
2098f3b9483Schristos return (CMD_RETURN_NORMAL);
210c9ad075bSchristos }
211c9ad075bSchristos
2129fb66d81Schristos if (args_has(args, 'T')) {
2139fb66d81Schristos title = format_single_from_target(item, args_get(args, 'T'));
2149fb66d81Schristos if (screen_set_title(&wp->base, title)) {
2159fb66d81Schristos notify_pane("pane-title-changed", wp);
2169fb66d81Schristos server_redraw_window_borders(wp->window);
2179fb66d81Schristos server_status_window(wp->window);
2189fb66d81Schristos }
2199fb66d81Schristos free(title);
2205494e770Schristos return (CMD_RETURN_NORMAL);
2219fb66d81Schristos }
2229fb66d81Schristos
2239fb66d81Schristos if (c != NULL && c->session != NULL && (c->flags & CLIENT_ACTIVEPANE))
2249fb66d81Schristos activewp = server_client_get_pane(c);
2259fb66d81Schristos else
2269fb66d81Schristos activewp = w->active;
2279fb66d81Schristos if (wp == activewp)
2289fb66d81Schristos return (CMD_RETURN_NORMAL);
2299fb66d81Schristos if (window_push_zoom(w, 0, args_has(args, 'Z')))
230aa83ff61Schristos server_redraw_window(w);
2315494e770Schristos window_redraw_active_switch(w, wp);
2329fb66d81Schristos if (c != NULL && c->session != NULL && (c->flags & CLIENT_ACTIVEPANE))
2339fb66d81Schristos server_client_set_pane(c, wp);
2349fb66d81Schristos else if (window_set_active_pane(w, wp, 1))
235c9ad075bSchristos cmd_find_from_winlink_pane(current, wl, wp, 0);
2366483eba0Schristos cmdq_insert_hook(s, item, current, "after-select-pane");
237ef36e747Schristos cmd_select_pane_redraw(w);
238aa83ff61Schristos if (window_pop_zoom(w))
239aa83ff61Schristos server_redraw_window(w);
240698d5317Sjmmv
241928fc495Schristos return (CMD_RETURN_NORMAL);
242698d5317Sjmmv }
243