Annotation of src/usr.bin/tmux/cmd-split-window.c, Revision 1.3
1.3 ! nicm 1: /* $OpenBSD: cmd-split-window.c,v 1.2 2009/06/25 06:48:23 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 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: #include <unistd.h>
23:
24: #include "tmux.h"
25:
26: /*
27: * Split a window (add a new pane).
28: */
29:
30: int cmd_split_window_parse(struct cmd *, int, char **, char **);
31: int cmd_split_window_exec(struct cmd *, struct cmd_ctx *);
32: void cmd_split_window_send(struct cmd *, struct buffer *);
33: void cmd_split_window_recv(struct cmd *, struct buffer *);
34: void cmd_split_window_free(struct cmd *);
35: void cmd_split_window_init(struct cmd *, int);
36: size_t cmd_split_window_print(struct cmd *, char *, size_t);
37:
38: struct cmd_split_window_data {
39: char *target;
40: char *cmd;
41: int flag_detached;
42: int percentage;
43: int lines;
44: };
45:
46: const struct cmd_entry cmd_split_window_entry = {
47: "split-window", "splitw",
48: "[-d] [-p percentage|-l lines] [-t target-window] [command]",
49: 0,
50: cmd_split_window_init,
51: cmd_split_window_parse,
52: cmd_split_window_exec,
53: cmd_split_window_send,
54: cmd_split_window_recv,
55: cmd_split_window_free,
56: cmd_split_window_print
57: };
58:
59: void
60: cmd_split_window_init(struct cmd *self, unused int arg)
61: {
62: struct cmd_split_window_data *data;
63:
64: self->data = data = xmalloc(sizeof *data);
65: data->target = NULL;
66: data->cmd = NULL;
67: data->flag_detached = 0;
68: data->percentage = -1;
69: data->lines = -1;
70: }
71:
72: int
73: cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
74: {
75: struct cmd_split_window_data *data;
76: int opt, n;
77: const char *errstr;
78:
79: self->entry->init(self, 0);
80: data = self->data;
81:
82: while ((opt = getopt(argc, argv, "dl:p:t:")) != -1) {
83: switch (opt) {
84: case 'd':
85: data->flag_detached = 1;
86: break;
87: case 't':
88: if (data->target == NULL)
89: data->target = xstrdup(optarg);
90: break;
91: case 'l':
92: if (data->percentage == -1 && data->lines == -1) {
93: n = strtonum(optarg, 1, INT_MAX, &errstr);
94: if (errstr != NULL) {
95: xasprintf(cause, "lines %s", errstr);
96: goto error;
97: }
98: data->lines = n;
99: }
100: break;
101: case 'p':
102: if (data->lines == -1 && data->percentage == -1) {
103: n = strtonum(optarg, 1, 100, &errstr);
104: if (errstr != NULL) {
105: xasprintf(
106: cause, "percentage %s", errstr);
107: goto error;
108: }
109: data->percentage = n;
110: }
111: break;
112: default:
113: goto usage;
114: }
115: }
116: argc -= optind;
117: argv += optind;
118: if (argc != 0 && argc != 1)
119: goto usage;
120:
121: if (argc == 1)
122: data->cmd = xstrdup(argv[0]);
123:
124: return (0);
125:
126: usage:
127: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
128:
129: error:
130: self->entry->free(self);
131: return (-1);
132: }
133:
134: int
135: cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
136: {
137: struct cmd_split_window_data *data = self->data;
138: struct session *s;
139: struct winlink *wl;
140: struct window *w;
141: struct window_pane *wp;
142: const char **env;
143: char *cmd, *cwd, *cause;
1.2 nicm 144: u_int hlimit;
145: int lines;
1.1 nicm 146:
147: if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
148: return (-1);
149: w = wl->window;
150:
151: env = server_fill_environ(s);
152:
153: cmd = data->cmd;
154: if (cmd == NULL)
155: cmd = options_get_string(&s->options, "default-command");
156: if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
1.3 ! nicm 157: cwd = options_get_string(&s->options, "default-path");
1.1 nicm 158: else
159: cwd = ctx->cmdclient->cwd;
160:
161: lines = -1;
162: if (data->lines != -1)
163: lines = data->lines;
164: else if (data->percentage != -1)
165: lines = (w->active->sy * data->percentage) / 100;
166:
167: hlimit = options_get_number(&s->options, "history-limit");
168: wp = window_add_pane(w, lines, cmd, cwd, env, hlimit, &cause);
169: if (wp == NULL) {
170: ctx->error(ctx, "create pane failed: %s", cause);
171: xfree(cause);
172: return (-1);
173: }
174: server_redraw_window(w);
175:
176: if (!data->flag_detached) {
177: window_set_active_pane(w, wp);
178: session_select(s, wl->idx);
179: server_redraw_session(s);
180: } else
181: server_status_session(s);
182: layout_refresh(w, 0);
183:
184: return (0);
185: }
186:
187: void
188: cmd_split_window_send(struct cmd *self, struct buffer *b)
189: {
190: struct cmd_split_window_data *data = self->data;
191:
192: buffer_write(b, data, sizeof *data);
193: cmd_send_string(b, data->target);
194: cmd_send_string(b, data->cmd);
195: }
196:
197: void
198: cmd_split_window_recv(struct cmd *self, struct buffer *b)
199: {
200: struct cmd_split_window_data *data;
201:
202: self->data = data = xmalloc(sizeof *data);
203: buffer_read(b, data, sizeof *data);
204: data->target = cmd_recv_string(b);
205: data->cmd = cmd_recv_string(b);
206: }
207:
208: void
209: cmd_split_window_free(struct cmd *self)
210: {
211: struct cmd_split_window_data *data = self->data;
212:
213: if (data->target != NULL)
214: xfree(data->target);
215: if (data->cmd != NULL)
216: xfree(data->cmd);
217: xfree(data);
218: }
219:
220: size_t
221: cmd_split_window_print(struct cmd *self, char *buf, size_t len)
222: {
223: struct cmd_split_window_data *data = self->data;
224: size_t off = 0;
225:
226: off += xsnprintf(buf, len, "%s", self->entry->name);
227: if (data == NULL)
228: return (off);
229: if (off < len && data->flag_detached)
230: off += xsnprintf(buf + off, len - off, " -d");
231: if (off < len && data->target != NULL)
232: off += cmd_prarg(buf + off, len - off, " -t ", data->target);
233: if (off < len && data->cmd != NULL)
234: off += cmd_prarg(buf + off, len - off, " ", data->cmd);
235: return (off);
236: }