diff --git a/cmd-select-layout.c b/cmd-select-layout.c index c4b989c55..4a1f6bed2 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -18,7 +18,6 @@ #include -#include #include #include @@ -30,14 +29,6 @@ static enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmdq_item *); -static enum cmd_retval cmd_select_layout_exec_multiple(struct cmdq_item *, - const char *); - -struct cmd_select_layout_record { - struct window *w; - char *layout; - struct layout_prepared *prepared; -}; const struct cmd_entry cmd_select_layout_entry = { .name = "select-layout", @@ -78,121 +69,6 @@ const struct cmd_entry cmd_previous_layout_entry = { .exec = cmd_select_layout_exec }; -static void -cmd_select_layout_free_records(struct cmd_select_layout_record *records, - u_int nrecords) -{ - u_int i; - - for (i = 0; i < nrecords; i++) { - free(records[i].layout); - layout_free_prepared(records[i].prepared); - } - free(records); -} - -/* Apply a list of @window-id:layout records. */ -static enum cmd_retval -cmd_select_layout_exec_multiple(struct cmdq_item *item, const char *input) -{ - struct cmd_select_layout_record *records = NULL; - struct window *w; - const char *ptr = input, *idstart, *idend; - const char *layoutstart, *layoutend; - char *id, *cause, *oldlayout; - u_int i, nrecords = 0; - - for (;;) { - while (*ptr != '\0' && isspace((u_char)*ptr)) - ptr++; - if (*ptr == '\0') - break; - if (*ptr != '@') - goto invalid; - - idstart = ptr++; - if (!isdigit((u_char)*ptr)) - goto invalid; - while (isdigit((u_char)*ptr)) - ptr++; - idend = ptr; - while (*ptr != '\0' && isspace((u_char)*ptr)) - ptr++; - if (*ptr++ != ':') - goto invalid; - - id = xstrndup(idstart, idend - idstart); - w = window_find_by_id_str(id); - if (w == NULL) { - cmdq_error(item, "unknown window: %s", id); - free(id); - goto fail; - } - free(id); - for (i = 0; i < nrecords; i++) { - if (records[i].w == w) { - cmdq_error(item, "duplicate window: @%u", w->id); - goto fail; - } - } - - layoutstart = ptr; - while (*ptr != '\0' && *ptr != '@') - ptr++; - layoutend = ptr; - while (layoutend != layoutstart && - isspace((u_char)layoutend[-1])) - layoutend--; - if (layoutend == layoutstart) - goto invalid; - - records = xreallocarray(records, nrecords + 1, - sizeof *records); - records[nrecords].w = w; - records[nrecords].layout = xstrndup(layoutstart, - layoutend - layoutstart); - records[nrecords].prepared = NULL; - nrecords++; - } - if (nrecords == 0) - goto invalid; - - /* Validate every record before changing any window. */ - for (i = 0; i < nrecords; i++) { - records[i].prepared = layout_prepare(records[i].w, - records[i].layout, &cause); - if (records[i].prepared == NULL) { - cmdq_error(item, "@%u: %s", records[i].w->id, cause); - free(cause); - goto fail; - } - } - - for (i = 0; i < nrecords; i++) { - w = records[i].w; - server_unzoom_window(w); - oldlayout = w->old_layout; - w->old_layout = layout_dump(w, w->layout_root); - layout_apply_prepared(w, records[i].prepared); - records[i].prepared = NULL; - free(oldlayout); - } - recalculate_sizes(); - for (i = 0; i < nrecords; i++) { - server_redraw_window(records[i].w); - notify_window("window-layout-changed", records[i].w); - } - - cmd_select_layout_free_records(records, nrecords); - return (CMD_RETURN_NORMAL); - -invalid: - cmdq_error(item, "invalid multiple-window layout"); -fail: - cmd_select_layout_free_records(records, nrecords); - return (CMD_RETURN_ERROR); -} - static enum cmd_retval cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item) { @@ -205,21 +81,16 @@ cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item) const char *layoutname; char *oldlayout, *cause; int next, previous, layout; - const char *ptr; if (cmd_get_entry(self) == &cmd_select_layout_entry && args_count(args) != 0 && !args_has(args, 'E') && !args_has(args, 'n') && !args_has(args, 'o') && !args_has(args, 'p')) { - ptr = args_string(args, 0); - while (*ptr != '\0' && isspace((u_char)*ptr)) - ptr++; - if (*ptr == '@') - return (cmd_select_layout_exec_multiple(item, ptr)); - if (layout_set_lookup(ptr) == -1) { - prepared = layout_prepare(w, ptr, &cause); + layoutname = args_string(args, 0); + if (layout_set_lookup(layoutname) == -1) { + prepared = layout_prepare(w, layoutname, &cause); if (prepared == NULL) { - cmdq_error(item, "%s: %s", cause, ptr); + cmdq_error(item, "%s: %s", cause, layoutname); free(cause); return (CMD_RETURN_ERROR); } diff --git a/layout-custom.c b/layout-custom.c index ada162055..f8c666965 100644 --- a/layout-custom.c +++ b/layout-custom.c @@ -76,10 +76,6 @@ * used when all match the target window, tree order is used when none match, * and a partial match is rejected. Surplus cells are removed from the end when * the target has fewer panes; a target with more panes is rejected. - * - * cmd-select-layout.c also accepts multiple window records in this form: - * - * @window-id:layout [@window-id:layout ...] */ #define LAYOUT_STRING_MAX 8192 diff --git a/regress/layout-custom.sh b/regress/layout-custom.sh index 757a32359..715882cb9 100755 --- a/regress/layout-custom.sh +++ b/regress/layout-custom.sh @@ -338,26 +338,17 @@ sleep 0.5 $TMUX new-session -d -x 80 -y 24 || exit 1 $TMUX split-window -h || fail "split-window failed" -# Multiple @window-id:layout records may be applied in one command. The -# newline produced by list-windows is insignificant whitespace. +# select-layout changes only the window selected by -t. A window ID is not +# accepted as part of the layout argument. $TMUX new-window -d -n second || fail "second window failed" -$TMUX split-window -d -h -t @1 || fail "second window split failed" -layouts=$($TMUX list-windows -F '#{window_id}:#{window_layout}') -$TMUX select-layout "$layouts" || fail "multiple-window layout was rejected" -must_equal "$($TMUX list-windows -F '#{window_id}:#{window_layout}')" \ - "$layouts" -compact=$(printf %s "$layouts" | tr -d '\n') -$TMUX select-layout "$compact" || fail "compact multiple-window layout failed" - -# All records are validated before any window is changed. -before=$($TMUX display-message -p -t @0 '#{window_width}x#{window_height}') -must_fail $TMUX select-layout "@0:$reported@1:0000," -must_equal "$($TMUX display-message -p -t @0 '#{window_width}x#{window_height}')" \ - "$before" -must_fail $TMUX select-layout '@0' -must_fail $TMUX select-layout '@0:' -must_fail $TMUX select-layout "@0:$legacy@0:$legacy" -must_fail $TMUX select-layout "@999999:$legacy" +$TMUX split-window -v -t @1 || fail "second window split failed" +first=$($TMUX display-message -p -t @0 '#{window_layout}') +second=$($TMUX display-message -p -t @1 '#{window_layout}') +$TMUX select-layout -t @1 even-horizontal || fail "target layout failed" +must_equal "$($TMUX display-message -p -t @0 '#{window_layout}')" "$first" +[ "$($TMUX display-message -p -t @1 '#{window_layout}')" != "$second" ] || \ + fail "target window layout did not change" +must_fail $TMUX select-layout "@0:$first" # Add floating panes and verify exact z-order, semicolon output and zoom state. $TMUX kill-server 2>/dev/null diff --git a/tmux.1 b/tmux.1 index 9117c73d6..117c71644 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3447,16 +3447,6 @@ The format is described under In control mode, the old form is used unless the client has the .Ql new\-window\-layouts flag. -.Pp -Layouts for multiple windows may be produced in a form suitable for -.Ic select\-layout -using -.Fl F . -For example, they may be captured and reapplied directly: -.Bd -literal -offset indent -$ layouts=\[dq]$(tmux list\-windows \-F \[aq]#{window_id}:#{window_layout}\[aq])\[dq] -$ tmux select\-layout \[dq]$layouts\[dq] -.Ed .Tg movep .It Xo Ic move\-pane .Op Fl bdfhMv @@ -4008,17 +3998,8 @@ uses for the layout in its default output. .Pp A layout description is a snapshot, not a complete saved session. -It rearranges existing panes and windows but does not create panes or windows. -.Pp -Layouts for multiple windows may be prefixed by their window IDs and joined: -.Bd -literal -offset indent -window-layouts = @window-id:layout [@window-id:layout ...] -.Ed -.Pp -Whitespace, including newlines, may appear between the window records. -Each window layout retains its own checksum and version prefix. -All records are checked before any window is changed. -Unknown or duplicate window IDs are rejected. +It rearranges existing panes in the target window but does not create panes or +windows. .Tg selectp .It Xo Ic select\-pane .Op Fl DdeLlMmRUZ