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