4 * Copyright (c) 2009 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>
28 * Split a window (add a new pane).
31 int cmd_split_window_parse(struct cmd
*, int, char **, char **);
32 int cmd_split_window_exec(struct cmd
*, struct cmd_ctx
*);
33 void cmd_split_window_free(struct cmd
*);
34 void cmd_split_window_init(struct cmd
*, int);
35 size_t cmd_split_window_print(struct cmd
*, char *, size_t);
37 struct cmd_split_window_data
{
46 const struct cmd_entry cmd_split_window_entry
= {
47 "split-window", "splitw",
48 "[-dhv] [-p percentage|-l size] [-t target-pane] [command]",
50 cmd_split_window_init
,
51 cmd_split_window_parse
,
52 cmd_split_window_exec
,
53 cmd_split_window_free
,
54 cmd_split_window_print
58 cmd_split_window_init(struct cmd
*self
, int key
)
60 struct cmd_split_window_data
*data
;
62 self
->data
= data
= xmalloc(sizeof *data
);
65 data
->flag_detached
= 0;
66 data
->flag_horizontal
= 0;
67 data
->percentage
= -1;
72 data
->flag_horizontal
= 1;
75 data
->flag_horizontal
= 0;
81 cmd_split_window_parse(struct cmd
*self
, int argc
, char **argv
, char **cause
)
83 struct cmd_split_window_data
*data
;
87 self
->entry
->init(self
, KEYC_NONE
);
90 while ((opt
= getopt(argc
, argv
, "dhl:p:t:v")) != -1) {
93 data
->flag_detached
= 1;
96 data
->flag_horizontal
= 1;
99 if (data
->target
== NULL
)
100 data
->target
= xstrdup(optarg
);
103 if (data
->percentage
!= -1 || data
->size
!= -1)
105 data
->size
= strtonum(optarg
, 1, INT_MAX
, &errstr
);
106 if (errstr
!= NULL
) {
107 xasprintf(cause
, "size %s", errstr
);
112 if (data
->size
!= -1 || data
->percentage
!= -1)
114 data
->percentage
= strtonum(optarg
, 1, 100, &errstr
);
115 if (errstr
!= NULL
) {
116 xasprintf(cause
, "percentage %s", errstr
);
121 data
->flag_horizontal
= 0;
129 if (argc
!= 0 && argc
!= 1)
133 data
->cmd
= xstrdup(argv
[0]);
138 xasprintf(cause
, "usage: %s %s", self
->entry
->name
, self
->entry
->usage
);
141 self
->entry
->free(self
);
146 cmd_split_window_exec(struct cmd
*self
, struct cmd_ctx
*ctx
)
148 struct cmd_split_window_data
*data
= self
->data
;
152 struct window_pane
*wp
, *new_wp
= NULL
;
154 char *cmd
, *cwd
, *cause
;
158 enum layout_type type
;
159 struct layout_cell
*lc
;
161 if ((wl
= cmd_find_pane(ctx
, data
->target
, &s
, &wp
)) == NULL
)
166 environ_copy(&global_environ
, &env
);
167 environ_copy(&s
->environ
, &env
);
168 server_fill_environ(s
, &env
);
172 cmd
= options_get_string(&s
->options
, "default-command");
173 if (ctx
->cmdclient
== NULL
|| ctx
->cmdclient
->cwd
== NULL
)
174 cwd
= options_get_string(&s
->options
, "default-path");
176 cwd
= ctx
->cmdclient
->cwd
;
178 type
= LAYOUT_TOPBOTTOM
;
179 if (data
->flag_horizontal
)
180 type
= LAYOUT_LEFTRIGHT
;
183 if (data
->size
!= -1)
185 else if (data
->percentage
!= -1) {
186 if (type
== LAYOUT_TOPBOTTOM
)
187 size
= (wp
->sy
* data
->percentage
) / 100;
189 size
= (wp
->sx
* data
->percentage
) / 100;
191 hlimit
= options_get_number(&s
->options
, "history-limit");
193 shell
= options_get_string(&s
->options
, "default-shell");
194 if (*shell
== '\0' || areshell(shell
))
195 shell
= _PATH_BSHELL
;
197 if ((lc
= layout_split_pane(wp
, type
, size
)) == NULL
) {
198 cause
= xstrdup("pane too small");
201 new_wp
= window_add_pane(w
, hlimit
);
202 if (window_pane_spawn(
203 new_wp
, cmd
, shell
, cwd
, &env
, s
->tio
, &cause
) != 0)
205 layout_assign_pane(lc
, new_wp
);
207 server_redraw_window(w
);
209 if (!data
->flag_detached
) {
210 window_set_active_pane(w
, new_wp
);
211 session_select(s
, wl
->idx
);
212 server_redraw_session(s
);
214 server_status_session(s
);
222 window_remove_pane(w
, new_wp
);
223 ctx
->error(ctx
, "create pane failed: %s", cause
);
229 cmd_split_window_free(struct cmd
*self
)
231 struct cmd_split_window_data
*data
= self
->data
;
233 if (data
->target
!= NULL
)
235 if (data
->cmd
!= NULL
)
241 cmd_split_window_print(struct cmd
*self
, char *buf
, size_t len
)
243 struct cmd_split_window_data
*data
= self
->data
;
246 off
+= xsnprintf(buf
, len
, "%s", self
->entry
->name
);
249 if (off
< len
&& data
->flag_detached
)
250 off
+= xsnprintf(buf
+ off
, len
- off
, " -d");
251 if (off
< len
&& data
->flag_horizontal
)
252 off
+= xsnprintf(buf
+ off
, len
- off
, " -h");
253 if (off
< len
&& data
->size
> 0)
254 off
+= xsnprintf(buf
+ off
, len
- off
, " -l %d", data
->size
);
255 if (off
< len
&& data
->percentage
> 0) {
257 buf
+ off
, len
- off
, " -p %d", data
->percentage
);
259 if (off
< len
&& data
->target
!= NULL
)
260 off
+= cmd_prarg(buf
+ off
, len
- off
, " -t ", data
->target
);
261 if (off
< len
&& data
->cmd
!= NULL
)
262 off
+= cmd_prarg(buf
+ off
, len
- off
, " ", data
->cmd
);