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>
26 * Break pane off into a window.
29 #define BREAK_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
31 static enum cmd_retval
cmd_break_pane_exec(struct cmd
*, struct cmdq_item
*);
33 const struct cmd_entry cmd_break_pane_entry
= {
37 .args
= { "abdPF:n:s:t:", 0, 0, NULL
},
38 .usage
= "[-abdP] [-F format] [-n window-name] [-s src-pane] "
41 .source
= { 's', CMD_FIND_PANE
, 0 },
42 .target
= { 't', CMD_FIND_WINDOW
, CMD_FIND_WINDOW_INDEX
},
45 .exec
= cmd_break_pane_exec
48 static enum cmd_retval
49 cmd_break_pane_exec(struct cmd
*self
, struct cmdq_item
*item
)
51 struct args
*args
= cmd_get_args(self
);
52 struct cmd_find_state
*current
= cmdq_get_current(item
);
53 struct cmd_find_state
*target
= cmdq_get_target(item
);
54 struct cmd_find_state
*source
= cmdq_get_source(item
);
55 struct client
*tc
= cmdq_get_target_client(item
);
56 struct winlink
*wl
= source
->wl
;
57 struct session
*src_s
= source
->s
;
58 struct session
*dst_s
= target
->s
;
59 struct window_pane
*wp
= source
->wp
;
60 struct window
*w
= wl
->window
;
61 char *name
, *cause
, *cp
;
62 int idx
= target
->idx
, before
;
65 before
= args_has(args
, 'b');
66 if (args_has(args
, 'a') || before
) {
67 if (target
->wl
!= NULL
)
68 idx
= winlink_shuffle_up(dst_s
, target
->wl
, before
);
70 idx
= winlink_shuffle_up(dst_s
, dst_s
->curw
, before
);
72 return (CMD_RETURN_ERROR
);
74 server_unzoom_window(w
);
76 if (window_count_panes(w
) == 1) {
77 if (server_link_window(src_s
, wl
, dst_s
, idx
, 0,
78 !args_has(args
, 'd'), &cause
) != 0) {
79 cmdq_error(item
, "%s", cause
);
81 return (CMD_RETURN_ERROR
);
83 if (args_has(args
, 'n')) {
84 window_set_name(w
, args_get(args
, 'n'));
85 options_set_number(w
->options
, "automatic-rename", 0);
87 server_unlink_window(src_s
, wl
);
88 return (CMD_RETURN_NORMAL
);
90 if (idx
!= -1 && winlink_find_by_index(&dst_s
->windows
, idx
) != NULL
) {
91 cmdq_error(item
, "index in use: %d", idx
);
92 return (CMD_RETURN_ERROR
);
95 TAILQ_REMOVE(&w
->panes
, wp
, entry
);
96 server_client_remove_pane(wp
);
97 window_lost_pane(w
, wp
);
98 layout_close_pane(wp
);
100 w
= wp
->window
= window_create(w
->sx
, w
->sy
, w
->xpixel
, w
->ypixel
);
101 options_set_parent(wp
->options
, w
->options
);
102 wp
->flags
|= PANE_STYLECHANGED
;
103 TAILQ_INSERT_HEAD(&w
->panes
, wp
, entry
);
107 if (!args_has(args
, 'n')) {
108 name
= default_window_name(w
);
109 window_set_name(w
, name
);
112 window_set_name(w
, args_get(args
, 'n'));
113 options_set_number(w
->options
, "automatic-rename", 0);
117 wp
->flags
|= PANE_CHANGED
;
120 idx
= -1 - options_get_number(dst_s
->options
, "base-index");
121 wl
= session_attach(dst_s
, w
, idx
, &cause
); /* can't fail */
122 if (!args_has(args
, 'd')) {
123 session_select(dst_s
, wl
->idx
);
124 cmd_find_from_session(current
, dst_s
, 0);
127 server_redraw_session(src_s
);
129 server_redraw_session(dst_s
);
130 server_status_session_group(src_s
);
132 server_status_session_group(dst_s
);
134 if (args_has(args
, 'P')) {
135 if ((template = args_get(args
, 'F')) == NULL
)
136 template = BREAK_PANE_TEMPLATE
;
137 cp
= format_single(item
, template, tc
, dst_s
, wl
, wp
);
138 cmdq_print(item
, "%s", cp
);
141 return (CMD_RETURN_NORMAL
);