From 6036bdd06cba9fa500098f1f17983d62955b24e5 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 19 Jul 2009 13:21:40 +0000 Subject: Improved layout code. Each window now has a tree of layout cells associated with it. In this tree, each node is either a horizontal or vertical cell containing a list of other cells running from left-to-right or top-to-bottom, or a leaf cell which is associated with a pane. The major functional changes are: - panes may now be split arbitrarily both horizontally (splitw -h, C-b %) and vertically (splitw -v, C-b "); - panes may be resized both horizontally and vertically (resizep -L/-R/-U/-D, bound to C-b left/right/up/down and C-b M-left/right/up/down); - layouts are now applied and then may be modified by resizing or splitting panes, rather than being fixed and reapplied when the window is resized or panes are added; - manual-vertical layout is no longer necessary, and active-only layout is gone (but may return in future); - the main-pane layouts now reduce the size of the main pane to fit all panes if possible. Thanks to all who tested. --- cmd-split-window.c | 97 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 33 deletions(-) (limited to 'cmd-split-window.c') diff --git a/cmd-split-window.c b/cmd-split-window.c index 74d28313..f1b21d51 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -39,13 +39,14 @@ struct cmd_split_window_data { char *target; char *cmd; int flag_detached; + int flag_horizontal; int percentage; - int lines; + int size; }; const struct cmd_entry cmd_split_window_entry = { "split-window", "splitw", - "[-d] [-p percentage|-l lines] [-t target-window] [command]", + "[-dhv] [-p percentage|-l size] [-t target-window] [command]", 0, 0, cmd_split_window_init, cmd_split_window_parse, @@ -57,7 +58,7 @@ const struct cmd_entry cmd_split_window_entry = { }; void -cmd_split_window_init(struct cmd *self, unused int arg) +cmd_split_window_init(struct cmd *self, int key) { struct cmd_split_window_data *data; @@ -65,50 +66,63 @@ cmd_split_window_init(struct cmd *self, unused int arg) data->target = NULL; data->cmd = NULL; data->flag_detached = 0; + data->flag_horizontal = 0; data->percentage = -1; - data->lines = -1; + data->size = -1; + + switch (key) { + case '%': + data->flag_horizontal = 1; + break; + case '"': + data->flag_horizontal = 0; + break; + } } int cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_split_window_data *data; - int opt, n; + int opt; const char *errstr; self->entry->init(self, 0); data = self->data; - while ((opt = getopt(argc, argv, "dl:p:t:")) != -1) { + while ((opt = getopt(argc, argv, "dhl:p:t:v")) != -1) { switch (opt) { case 'd': data->flag_detached = 1; break; + case 'h': + data->flag_horizontal = 1; + break; case 't': if (data->target == NULL) data->target = xstrdup(optarg); break; case 'l': - if (data->percentage == -1 && data->lines == -1) { - n = strtonum(optarg, 1, INT_MAX, &errstr); - if (errstr != NULL) { - xasprintf(cause, "lines %s", errstr); - goto error; - } - data->lines = n; + if (data->percentage != -1 || data->size != -1) + break; + data->size = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr != NULL) { + xasprintf(cause, "size %s", errstr); + goto error; } break; case 'p': - if (data->lines == -1 && data->percentage == -1) { - n = strtonum(optarg, 1, 100, &errstr); - if (errstr != NULL) { - xasprintf( - cause, "percentage %s", errstr); - goto error; - } - data->percentage = n; + if (data->size != -1 || data->percentage != -1) + break; + data->percentage = strtonum(optarg, 1, 100, &errstr); + if (errstr != NULL) { + xasprintf(cause, "percentage %s", errstr); + goto error; } break; + case 'v': + data->flag_horizontal = 0; + break; default: goto usage; } @@ -142,7 +156,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx) const char **env; char *cmd, *cwd, *cause; u_int hlimit; - int lines; + int size; + enum layout_type type; if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return (-1); @@ -158,19 +173,27 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx) else cwd = ctx->cmdclient->cwd; - lines = -1; - if (data->lines != -1) - lines = data->lines; + size = -1; + if (data->size != -1) + size = data->size; else if (data->percentage != -1) - lines = (w->active->sy * data->percentage) / 100; - + size = (w->active->sy * data->percentage) / 100; hlimit = options_get_number(&s->options, "history-limit"); - wp = window_add_pane(w, lines, cmd, cwd, env, hlimit, &cause); - if (wp == NULL) { - ctx->error(ctx, "create pane failed: %s", cause); - xfree(cause); - return (-1); + + type = LAYOUT_TOPBOTTOM; + if (data->flag_horizontal) + type = LAYOUT_LEFTRIGHT; + + wp = window_add_pane(w, hlimit, &cause); + if (wp == NULL) + goto error; + if (window_pane_spawn(wp, cmd, cwd, env, &cause) != 0) + goto error; + if (layout_split_pane(w->active, type, size, wp) != 0) { + cause = xstrdup("pane too small"); + goto error; } + server_redraw_window(w); if (!data->flag_detached) { @@ -179,9 +202,15 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx) server_redraw_session(s); } else server_status_session(s); - layout_refresh(w, 0); return (0); + +error: + if (wp != NULL) + window_remove_pane(w, wp); + ctx->error(ctx, "create pane failed: %s", cause); + xfree(cause); + return (-1); } void @@ -228,6 +257,8 @@ cmd_split_window_print(struct cmd *self, char *buf, size_t len) return (off); if (off < len && data->flag_detached) off += xsnprintf(buf + off, len - off, " -d"); + if (off < len && data->flag_horizontal) + off += xsnprintf(buf + off, len - off, " -h"); if (off < len && data->target != NULL) off += cmd_prarg(buf + off, len - off, " -t ", data->target); if (off < len && data->cmd != NULL) -- cgit v1.2.3