Annotation of src/usr.bin/tmux/cmd-new-window.c, Revision 1.10
1.10 ! nicm 1: /* $OpenBSD: cmd-new-window.c,v 1.9 2009/11/13 19:53:29 nicm Exp $ */
1.1 nicm 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_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);
34:
35: struct cmd_new_window_data {
36: char *target;
37: char *name;
38: char *cmd;
39: int flag_detached;
40: int flag_kill;
41: };
42:
43: const struct cmd_entry cmd_new_window_entry = {
44: "new-window", "neww",
45: "[-dk] [-n window-name] [-t target-window] [command]",
1.9 nicm 46: 0, "",
1.1 nicm 47: cmd_new_window_init,
48: cmd_new_window_parse,
49: cmd_new_window_exec,
50: cmd_new_window_free,
51: cmd_new_window_print
52: };
53:
1.10 ! nicm 54: /* ARGSUSED */
1.1 nicm 55: void
56: cmd_new_window_init(struct cmd *self, unused int arg)
57: {
58: struct cmd_new_window_data *data;
59:
60: self->data = data = xmalloc(sizeof *data);
61: data->target = NULL;
62: data->name = NULL;
63: data->cmd = NULL;
64: data->flag_detached = 0;
65: data->flag_kill = 0;
66: }
67:
68: int
69: cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause)
70: {
71: struct cmd_new_window_data *data;
72: int opt;
73:
1.7 nicm 74: self->entry->init(self, KEYC_NONE);
1.1 nicm 75: data = self->data;
76:
77: while ((opt = getopt(argc, argv, "dkt:n:")) != -1) {
78: switch (opt) {
79: case 'd':
80: data->flag_detached = 1;
81: break;
82: case 'k':
83: data->flag_kill = 1;
84: break;
85: case 't':
86: if (data->target == NULL)
87: data->target = xstrdup(optarg);
88: break;
89: case 'n':
90: if (data->name == NULL)
91: data->name = xstrdup(optarg);
92: break;
93: default:
94: goto usage;
95: }
96: }
97: argc -= optind;
98: argv += optind;
99: if (argc != 0 && argc != 1)
100: goto usage;
101:
102: if (argc == 1)
103: data->cmd = xstrdup(argv[0]);
104:
105: return (0);
106:
107: usage:
108: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
109:
110: self->entry->free(self);
111: return (-1);
112: }
113:
114: int
115: cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
116: {
117: struct cmd_new_window_data *data = self->data;
118: struct session *s;
119: struct winlink *wl;
120: char *cmd, *cwd, *cause;
121: int idx;
122:
123: if (data == NULL)
124: return (0);
125:
1.3 nicm 126: if ((idx = cmd_find_index(ctx, data->target, &s)) == -2)
1.1 nicm 127: return (-1);
128:
129: wl = NULL;
130: if (idx != -1)
131: wl = winlink_find_by_index(&s->windows, idx);
132: if (wl != NULL) {
133: if (data->flag_kill) {
134: /*
135: * Can't use session_detach as it will destroy session
136: * if this makes it empty.
137: */
138: session_alert_cancel(s, wl);
139: winlink_stack_remove(&s->lastw, wl);
140: winlink_remove(&s->windows, wl);
141:
142: /* Force select/redraw if current. */
143: if (wl == s->curw) {
144: data->flag_detached = 0;
145: s->curw = NULL;
146: }
147: }
148: }
149:
150: cmd = data->cmd;
151: if (cmd == NULL)
152: cmd = options_get_string(&s->options, "default-command");
153: if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
1.2 nicm 154: cwd = options_get_string(&s->options, "default-path");
1.1 nicm 155: else
156: cwd = ctx->cmdclient->cwd;
157:
1.6 nicm 158: if (idx == -1)
159: idx = -1 - options_get_number(&s->options, "base-index");
1.1 nicm 160: wl = session_new(s, data->name, cmd, cwd, idx, &cause);
161: if (wl == NULL) {
162: ctx->error(ctx, "create window failed: %s", cause);
163: xfree(cause);
164: return (-1);
165: }
166: if (!data->flag_detached) {
167: session_select(s, wl->idx);
1.8 nicm 168: server_redraw_session_group(s);
169: } else
170: server_status_session_group(s);
1.1 nicm 171:
172: return (0);
173: }
174:
175: void
176: cmd_new_window_free(struct cmd *self)
177: {
178: struct cmd_new_window_data *data = self->data;
179:
180: if (data->target != NULL)
181: xfree(data->target);
182: if (data->name != NULL)
183: xfree(data->name);
184: if (data->cmd != NULL)
185: xfree(data->cmd);
186: xfree(data);
187: }
188:
189: size_t
190: cmd_new_window_print(struct cmd *self, char *buf, size_t len)
191: {
192: struct cmd_new_window_data *data = self->data;
193: size_t off = 0;
194:
195: off += xsnprintf(buf, len, "%s", self->entry->name);
196: if (data == NULL)
197: return (off);
198: if (off < len && data->flag_detached)
199: off += xsnprintf(buf + off, len - off, " -d");
200: if (off < len && data->target != NULL)
201: off += cmd_prarg(buf + off, len - off, " -t ", data->target);
202: if (off < len && data->name != NULL)
203: off += cmd_prarg(buf + off, len - off, " -n ", data->name);
204: if (off < len && data->cmd != NULL)
205: off += cmd_prarg(buf + off, len - off, " ", data->cmd);
206: return (off);
207: }