mirror of
https://github.com/tmux/tmux.git
synced 2026-08-03 14:08:59 +00:00
Back out select-layout multiple windows.
This commit is contained in:
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
23
tmux.1
23
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
|
||||
|
||||
Reference in New Issue
Block a user