xref: /minix/external/bsd/tmux/dist/cmd-new-window.c (revision 9f988b79)
1 /* $Id: cmd-new-window.c,v 1.1.1.2 2011/08/17 18:40:04 jmmv Exp $ */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5  *
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.
9  *
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.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <stdlib.h>
22 
23 #include "tmux.h"
24 
25 /*
26  * Create a new window.
27  */
28 
29 int	cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
30 
31 const struct cmd_entry cmd_new_window_entry = {
32 	"new-window", "neww",
33 	"adkn:Pt:", 0, 1,
34 	"[-adk] [-n window-name] [-t target-window] [command]",
35 	0,
36 	NULL,
37 	NULL,
38 	cmd_new_window_exec
39 };
40 
41 int
42 cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
43 {
44 	struct args	*args = self->args;
45 	struct session	*s;
46 	struct winlink	*wl;
47 	char		*cmd, *cwd, *cause;
48 	int		 idx, last, detached;
49 
50 	if (args_has(args, 'a')) {
51 		wl = cmd_find_window(ctx, args_get(args, 't'), &s);
52 		if (wl == NULL)
53 			return (-1);
54 		idx = wl->idx + 1;
55 
56 		/* Find the next free index. */
57 		for (last = idx; last < INT_MAX; last++) {
58 			if (winlink_find_by_index(&s->windows, last) == NULL)
59 				break;
60 		}
61 		if (last == INT_MAX) {
62 			ctx->error(ctx, "no free window indexes");
63 			return (-1);
64 		}
65 
66 		/* Move everything from last - 1 to idx up a bit. */
67 		for (; last > idx; last--) {
68 			wl = winlink_find_by_index(&s->windows, last - 1);
69 			server_link_window(s, wl, s, last, 0, 0, NULL);
70 			server_unlink_window(s, wl);
71 		}
72 	} else {
73 		if ((idx = cmd_find_index(ctx, args_get(args, 't'), &s)) == -2)
74 			return (-1);
75 	}
76 	detached = args_has(args, 'd');
77 
78 	wl = NULL;
79 	if (idx != -1)
80 		wl = winlink_find_by_index(&s->windows, idx);
81 	if (wl != NULL && args_has(args, 'k')) {
82 		/*
83 		 * Can't use session_detach as it will destroy session if this
84 		 * makes it empty.
85 		 */
86 		wl->flags &= ~WINLINK_ALERTFLAGS;
87 		winlink_stack_remove(&s->lastw, wl);
88 		winlink_remove(&s->windows, wl);
89 
90 		/* Force select/redraw if current. */
91 		if (wl == s->curw) {
92 			detached = 0;
93 			s->curw = NULL;
94 		}
95 	}
96 
97 	if (args->argc == 0)
98 		cmd = options_get_string(&s->options, "default-command");
99 	else
100 		cmd = args->argv[0];
101 	cwd = options_get_string(&s->options, "default-path");
102 	if (*cwd == '\0') {
103 		if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
104 			cwd = ctx->cmdclient->cwd;
105 		else
106 			cwd = s->cwd;
107 	}
108 
109 	if (idx == -1)
110 		idx = -1 - options_get_number(&s->options, "base-index");
111 	wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause);
112 	if (wl == NULL) {
113 		ctx->error(ctx, "create window failed: %s", cause);
114 		xfree(cause);
115 		return (-1);
116 	}
117 	if (!detached) {
118 		session_select(s, wl->idx);
119 		server_redraw_session_group(s);
120 	} else
121 		server_status_session_group(s);
122 
123 	if (args_has(args, 'P'))
124 		ctx->print(ctx, "%s:%u", s->name, wl->idx);
125 	return (0);
126 }
127