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>
26 * Create a new window.
29 int cmd_new_window_parse(struct cmd
*, int, char **, char **);
30 int cmd_new_window_exec(struct cmd
*, struct cmd_ctx
*);
31 void cmd_new_window_free(struct cmd
*);
32 void cmd_new_window_init(struct cmd
*, int);
33 size_t cmd_new_window_print(struct cmd
*, char *, size_t);
35 struct cmd_new_window_data
{
39 int flag_insert_after
;
44 const struct cmd_entry cmd_new_window_entry
= {
46 "[-adk] [-n window-name] [-t target-window] [command]",
57 cmd_new_window_init(struct cmd
*self
, unused
int arg
)
59 struct cmd_new_window_data
*data
;
61 self
->data
= data
= xmalloc(sizeof *data
);
65 data
->flag_insert_after
= 0;
66 data
->flag_detached
= 0;
71 cmd_new_window_parse(struct cmd
*self
, int argc
, char **argv
, char **cause
)
73 struct cmd_new_window_data
*data
;
76 self
->entry
->init(self
, KEYC_NONE
);
79 while ((opt
= getopt(argc
, argv
, "adkt:n:")) != -1) {
82 data
->flag_insert_after
= 1;
85 data
->flag_detached
= 1;
91 if (data
->target
== NULL
)
92 data
->target
= xstrdup(optarg
);
95 if (data
->name
== NULL
)
96 data
->name
= xstrdup(optarg
);
104 if (argc
!= 0 && argc
!= 1)
108 data
->cmd
= xstrdup(argv
[0]);
113 xasprintf(cause
, "usage: %s %s", self
->entry
->name
, self
->entry
->usage
);
115 self
->entry
->free(self
);
120 cmd_new_window_exec(struct cmd
*self
, struct cmd_ctx
*ctx
)
122 struct cmd_new_window_data
*data
= self
->data
;
125 char *cmd
, *cwd
, *cause
;
131 if (data
->flag_insert_after
) {
132 if ((wl
= cmd_find_window(ctx
, data
->target
, &s
)) == NULL
)
136 /* Find the next free index. */
137 for (last
= idx
; last
< INT_MAX
; last
++) {
138 if (winlink_find_by_index(&s
->windows
, last
) == NULL
)
141 if (last
== INT_MAX
) {
142 ctx
->error(ctx
, "no free window indexes");
146 /* Move everything from last - 1 to idx up a bit. */
147 for (; last
> idx
; last
--) {
148 wl
= winlink_find_by_index(&s
->windows
, last
- 1);
149 server_link_window(s
, wl
, s
, last
, 0, 0, NULL
);
150 server_unlink_window(s
, wl
);
153 if ((idx
= cmd_find_index(ctx
, data
->target
, &s
)) == -2)
159 wl
= winlink_find_by_index(&s
->windows
, idx
);
160 if (wl
!= NULL
&& data
->flag_kill
) {
162 * Can't use session_detach as it will destroy session if this
165 session_alert_cancel(s
, wl
);
166 winlink_stack_remove(&s
->lastw
, wl
);
167 winlink_remove(&s
->windows
, wl
);
169 /* Force select/redraw if current. */
171 data
->flag_detached
= 0;
178 cmd
= options_get_string(&s
->options
, "default-command");
179 if (ctx
->cmdclient
== NULL
|| ctx
->cmdclient
->cwd
== NULL
)
180 cwd
= options_get_string(&s
->options
, "default-path");
182 cwd
= ctx
->cmdclient
->cwd
;
185 idx
= -1 - options_get_number(&s
->options
, "base-index");
186 wl
= session_new(s
, data
->name
, cmd
, cwd
, idx
, &cause
);
188 ctx
->error(ctx
, "create window failed: %s", cause
);
192 if (!data
->flag_detached
) {
193 session_select(s
, wl
->idx
);
194 server_redraw_session_group(s
);
196 server_status_session_group(s
);
202 cmd_new_window_free(struct cmd
*self
)
204 struct cmd_new_window_data
*data
= self
->data
;
206 if (data
->target
!= NULL
)
208 if (data
->name
!= NULL
)
210 if (data
->cmd
!= NULL
)
216 cmd_new_window_print(struct cmd
*self
, char *buf
, size_t len
)
218 struct cmd_new_window_data
*data
= self
->data
;
221 off
+= xsnprintf(buf
, len
, "%s", self
->entry
->name
);
224 if (off
< len
&& data
->flag_detached
)
225 off
+= xsnprintf(buf
+ off
, len
- off
, " -d");
226 if (off
< len
&& data
->target
!= NULL
)
227 off
+= cmd_prarg(buf
+ off
, len
- off
, " -t ", data
->target
);
228 if (off
< len
&& data
->name
!= NULL
)
229 off
+= cmd_prarg(buf
+ off
, len
- off
, " -n ", data
->name
);
230 if (off
< len
&& data
->cmd
!= NULL
)
231 off
+= cmd_prarg(buf
+ off
, len
- off
, " ", data
->cmd
);