Annotation of embedaddon/tmux/cmd-new-window.c, revision 1.1.1.1
1.1 misho 1: /* $OpenBSD$ */
2:
3: /*
4: * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
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 <errno.h>
22: #include <fcntl.h>
23: #include <stdlib.h>
24: #include <string.h>
25: #include <unistd.h>
26:
27: #include "tmux.h"
28:
29: /*
30: * Create a new window.
31: */
32:
33: #define NEW_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
34:
35: static enum cmd_retval cmd_new_window_exec(struct cmd *, struct cmdq_item *);
36:
37: const struct cmd_entry cmd_new_window_entry = {
38: .name = "new-window",
39: .alias = "neww",
40:
41: .args = { "ac:dF:kn:Pt:", 0, -1 },
42: .usage = "[-adkP] [-c start-directory] [-F format] [-n window-name] "
43: CMD_TARGET_WINDOW_USAGE " [command]",
44:
45: .tflag = CMD_WINDOW_INDEX,
46:
47: .flags = 0,
48: .exec = cmd_new_window_exec
49: };
50:
51: static enum cmd_retval
52: cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
53: {
54: struct args *args = self->args;
55: struct session *s = item->state.tflag.s;
56: struct winlink *wl = item->state.tflag.wl;
57: struct client *c = item->state.c;
58: int idx = item->state.tflag.idx;
59: const char *cmd, *path, *template, *cwd, *to_free;
60: char **argv, *cause, *cp;
61: int argc, detached;
62: struct environ_entry *envent;
63: struct cmd_find_state fs;
64:
65: if (args_has(args, 'a')) {
66: if ((idx = winlink_shuffle_up(s, wl)) == -1) {
67: cmdq_error(item, "no free window indexes");
68: return (CMD_RETURN_ERROR);
69: }
70: }
71: detached = args_has(args, 'd');
72:
73: if (args->argc == 0) {
74: cmd = options_get_string(s->options, "default-command");
75: if (cmd != NULL && *cmd != '\0') {
76: argc = 1;
77: argv = (char **)&cmd;
78: } else {
79: argc = 0;
80: argv = NULL;
81: }
82: } else {
83: argc = args->argc;
84: argv = args->argv;
85: }
86:
87: path = NULL;
88: if (item->client != NULL && item->client->session == NULL)
89: envent = environ_find(item->client->environ, "PATH");
90: else
91: envent = environ_find(s->environ, "PATH");
92: if (envent != NULL)
93: path = envent->value;
94:
95: to_free = NULL;
96: if (args_has(args, 'c')) {
97: cwd = args_get(args, 'c');
98: to_free = cwd = format_single(item, cwd, c, s, NULL, NULL);
99: } else if (item->client != NULL && item->client->session == NULL)
100: cwd = item->client->cwd;
101: else
102: cwd = s->cwd;
103:
104: wl = NULL;
105: if (idx != -1)
106: wl = winlink_find_by_index(&s->windows, idx);
107: if (wl != NULL && args_has(args, 'k')) {
108: /*
109: * Can't use session_detach as it will destroy session if this
110: * makes it empty.
111: */
112: notify_session_window("window-unlinked", s, wl->window);
113: wl->flags &= ~WINLINK_ALERTFLAGS;
114: winlink_stack_remove(&s->lastw, wl);
115: winlink_remove(&s->windows, wl);
116:
117: /* Force select/redraw if current. */
118: if (wl == s->curw) {
119: detached = 0;
120: s->curw = NULL;
121: }
122: }
123:
124: if (idx == -1)
125: idx = -1 - options_get_number(s->options, "base-index");
126: wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
127: &cause);
128: if (wl == NULL) {
129: cmdq_error(item, "create window failed: %s", cause);
130: free(cause);
131: goto error;
132: }
133: if (!detached) {
134: session_select(s, wl->idx);
135: server_redraw_session_group(s);
136: } else
137: server_status_session_group(s);
138:
139: if (args_has(args, 'P')) {
140: if ((template = args_get(args, 'F')) == NULL)
141: template = NEW_WINDOW_TEMPLATE;
142: cp = format_single(item, template, c, s, wl, NULL);
143: cmdq_print(item, "%s", cp);
144: free(cp);
145: }
146:
147: if (to_free != NULL)
148: free((void *)to_free);
149:
150: cmd_find_from_winlink(&fs, s, wl);
151: hooks_insert(s->hooks, item, &fs, "after-new-window");
152:
153: return (CMD_RETURN_NORMAL);
154:
155: error:
156: if (to_free != NULL)
157: free((void *)to_free);
158: return (CMD_RETURN_ERROR);
159: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>