mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-22 16:13:58 +01:00
Merge pane number into the target specification for pane commands. Instead of
using -p index, a target pane is now addressed with the normal -t window form but suffixed with a period and a pane index, for example :0.2 or mysess:mywin.1. An unadorned number such as -t 1 is tried as a pane index in the current window, if that fails the same rules are followed as for a target window and the current pane in that window used. As a side-effect this now means that swap-pane can swap panes between different windows. Note that this changes the syntax of the break-pane, clear-history, kill-pane, resize-pane, select-pane and swap-pane commands.
This commit is contained in:
parent
a87228b4ff
commit
071494d8fa
@ -30,39 +30,30 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
|
||||
|
||||
const struct cmd_entry cmd_break_pane_entry = {
|
||||
"break-pane", "breakp",
|
||||
CMD_PANE_WINDOW_USAGE " [-d]",
|
||||
CMD_TARGET_PANE_USAGE " [-d]",
|
||||
0, CMD_CHFLAG('d'),
|
||||
cmd_pane_init,
|
||||
cmd_pane_parse,
|
||||
cmd_target_init,
|
||||
cmd_target_parse,
|
||||
cmd_break_pane_exec,
|
||||
cmd_pane_free,
|
||||
cmd_pane_print
|
||||
cmd_target_free,
|
||||
cmd_target_print
|
||||
};
|
||||
|
||||
int
|
||||
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_pane_data *data = self->data;
|
||||
struct cmd_target_data *data = self->data;
|
||||
struct winlink *wl;
|
||||
struct session *s;
|
||||
struct window_pane *wp;
|
||||
struct window *w;
|
||||
char *cause;
|
||||
|
||||
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
|
||||
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
|
||||
return (-1);
|
||||
if (data->pane == -1)
|
||||
wp = wl->window->active;
|
||||
else {
|
||||
wp = window_pane_at_index(wl->window, data->pane);
|
||||
if (wp == NULL) {
|
||||
ctx->error(ctx, "no pane: %d", data->pane);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (window_count_panes(wl->window) == 1) {
|
||||
ctx->error(ctx, "can't break pane: %d", data->pane);
|
||||
ctx->error(ctx, "can't break with only one pane");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -28,34 +28,25 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
|
||||
|
||||
const struct cmd_entry cmd_clear_history_entry = {
|
||||
"clear-history", "clearhist",
|
||||
CMD_PANE_WINDOW_USAGE,
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0, 0,
|
||||
cmd_pane_init,
|
||||
cmd_pane_parse,
|
||||
cmd_target_init,
|
||||
cmd_target_parse,
|
||||
cmd_clear_history_exec,
|
||||
cmd_pane_free,
|
||||
cmd_pane_print
|
||||
cmd_target_free,
|
||||
cmd_target_print
|
||||
};
|
||||
|
||||
int
|
||||
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_pane_data *data = self->data;
|
||||
struct cmd_target_data *data = self->data;
|
||||
struct winlink *wl;
|
||||
struct window_pane *wp;
|
||||
struct grid *gd;
|
||||
|
||||
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
|
||||
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
|
||||
return (-1);
|
||||
if (data->pane == -1)
|
||||
wp = wl->window->active;
|
||||
else {
|
||||
wp = window_pane_at_index(wl->window, data->pane);
|
||||
if (wp == NULL) {
|
||||
ctx->error(ctx, "no pane: %d", data->pane);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
gd = wp->base.grid;
|
||||
|
||||
grid_move_lines(gd, 0, gd->hsize, gd->sy);
|
||||
|
@ -467,93 +467,3 @@ cmd_option_print(struct cmd *self, char *buf, size_t len)
|
||||
off += xsnprintf(buf + off, len - off, " %s", data->value);
|
||||
return (off);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_pane_init(struct cmd *self, unused int key)
|
||||
{
|
||||
struct cmd_pane_data *data;
|
||||
|
||||
self->data = data = xmalloc(sizeof *data);
|
||||
data->chflags = 0;
|
||||
data->target = NULL;
|
||||
data->arg = NULL;
|
||||
data->pane = -1;
|
||||
}
|
||||
|
||||
int
|
||||
cmd_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||
{
|
||||
struct cmd_pane_data *data;
|
||||
const struct cmd_entry *entry = self->entry;
|
||||
int opt, n;
|
||||
const char *errstr;
|
||||
|
||||
/* Don't use the entry version since it may be dependent on key. */
|
||||
cmd_pane_init(self, 0);
|
||||
data = self->data;
|
||||
|
||||
while ((opt = cmd_getopt(argc, argv, "p:t:", entry->chflags)) != -1) {
|
||||
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
|
||||
continue;
|
||||
switch (opt) {
|
||||
case 'p':
|
||||
if (data->pane == -1) {
|
||||
n = strtonum(optarg, 0, INT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
xasprintf(cause, "pane %s", errstr);
|
||||
goto error;
|
||||
}
|
||||
data->pane = n;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (data->target == NULL)
|
||||
data->target = xstrdup(optarg);
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
|
||||
goto usage;
|
||||
return (0);
|
||||
|
||||
usage:
|
||||
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
|
||||
|
||||
error:
|
||||
self->entry->free(self);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_pane_free(struct cmd *self)
|
||||
{
|
||||
struct cmd_pane_data *data = self->data;
|
||||
|
||||
if (data->target != NULL)
|
||||
xfree(data->target);
|
||||
if (data->arg != NULL)
|
||||
xfree(data->arg);
|
||||
xfree(data);
|
||||
}
|
||||
|
||||
size_t
|
||||
cmd_pane_print(struct cmd *self, char *buf, size_t len)
|
||||
{
|
||||
struct cmd_pane_data *data = self->data;
|
||||
size_t off = 0;
|
||||
|
||||
off += xsnprintf(buf, len, "%s", self->entry->name);
|
||||
if (data == NULL)
|
||||
return (off);
|
||||
off += cmd_print_flags(buf, len, off, data->chflags);
|
||||
if (off < len && data->target != NULL)
|
||||
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
|
||||
if (off < len && data->arg != NULL)
|
||||
off += cmd_prarg(buf + off, len - off, " ", data->arg);
|
||||
return (off);
|
||||
}
|
||||
|
@ -30,33 +30,24 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
|
||||
|
||||
const struct cmd_entry cmd_kill_pane_entry = {
|
||||
"kill-pane", "killp",
|
||||
CMD_PANE_WINDOW_USAGE,
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0, 0,
|
||||
cmd_pane_init,
|
||||
cmd_pane_parse,
|
||||
cmd_target_init,
|
||||
cmd_target_parse,
|
||||
cmd_kill_pane_exec,
|
||||
cmd_pane_free,
|
||||
cmd_pane_print
|
||||
cmd_target_free,
|
||||
cmd_target_print
|
||||
};
|
||||
|
||||
int
|
||||
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_pane_data *data = self->data;
|
||||
struct cmd_target_data *data = self->data;
|
||||
struct winlink *wl;
|
||||
struct window_pane *wp;
|
||||
|
||||
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
|
||||
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
|
||||
return (-1);
|
||||
if (data->pane == -1)
|
||||
wp = wl->window->active;
|
||||
else {
|
||||
wp = window_pane_at_index(wl->window, data->pane);
|
||||
if (wp == NULL) {
|
||||
ctx->error(ctx, "no pane: %d", data->pane);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (window_count_panes(wl->window) == 1) {
|
||||
/* Only one pane, kill the window. */
|
||||
|
@ -31,22 +31,22 @@ int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
|
||||
|
||||
const struct cmd_entry cmd_resize_pane_entry = {
|
||||
"resize-pane", "resizep",
|
||||
CMD_PANE_WINDOW_USAGE "[-DU] [adjustment]",
|
||||
"[-DU] " CMD_TARGET_PANE_USAGE " [adjustment]",
|
||||
CMD_ARG01,
|
||||
CMD_CHFLAG('D')|CMD_CHFLAG('L')|CMD_CHFLAG('R')|CMD_CHFLAG('U'),
|
||||
cmd_resize_pane_init,
|
||||
cmd_pane_parse,
|
||||
cmd_target_parse,
|
||||
cmd_resize_pane_exec,
|
||||
cmd_pane_free,
|
||||
cmd_pane_print
|
||||
cmd_target_free,
|
||||
cmd_target_print
|
||||
};
|
||||
|
||||
void
|
||||
cmd_resize_pane_init(struct cmd *self, int key)
|
||||
{
|
||||
struct cmd_pane_data *data;
|
||||
struct cmd_target_data *data;
|
||||
|
||||
cmd_pane_init(self, key);
|
||||
cmd_target_init(self, key);
|
||||
data = self->data;
|
||||
|
||||
if (key == (KEYC_UP | KEYC_CTRL))
|
||||
@ -79,23 +79,14 @@ cmd_resize_pane_init(struct cmd *self, int key)
|
||||
int
|
||||
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_pane_data *data = self->data;
|
||||
struct cmd_target_data *data = self->data;
|
||||
struct winlink *wl;
|
||||
const char *errstr;
|
||||
struct window_pane *wp;
|
||||
u_int adjust;
|
||||
|
||||
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
|
||||
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
|
||||
return (-1);
|
||||
if (data->pane == -1)
|
||||
wp = wl->window->active;
|
||||
else {
|
||||
wp = window_pane_at_index(wl->window, data->pane);
|
||||
if (wp == NULL) {
|
||||
ctx->error(ctx, "no pane: %d", data->pane);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->arg == NULL)
|
||||
adjust = 1;
|
||||
|
@ -28,36 +28,27 @@ int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
|
||||
|
||||
const struct cmd_entry cmd_select_pane_entry = {
|
||||
"select-pane", "selectp",
|
||||
CMD_PANE_WINDOW_USAGE,
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0, 0,
|
||||
cmd_pane_init,
|
||||
cmd_pane_parse,
|
||||
cmd_target_init,
|
||||
cmd_target_parse,
|
||||
cmd_select_pane_exec,
|
||||
cmd_pane_free,
|
||||
cmd_pane_print
|
||||
cmd_target_free,
|
||||
cmd_target_print
|
||||
};
|
||||
|
||||
int
|
||||
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_pane_data *data = self->data;
|
||||
struct cmd_target_data *data = self->data;
|
||||
struct winlink *wl;
|
||||
struct window_pane *wp;
|
||||
|
||||
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
|
||||
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
|
||||
return (-1);
|
||||
if (data->pane == -1)
|
||||
wp = wl->window->active;
|
||||
else {
|
||||
wp = window_pane_at_index(wl->window, data->pane);
|
||||
if (wp == NULL) {
|
||||
ctx->error(ctx, "no pane: %d", data->pane);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!window_pane_visible(wp)) {
|
||||
ctx->error(ctx, "pane %d is not visible", data->pane);
|
||||
ctx->error(ctx, "pane not visible: %s", data->target);
|
||||
return (-1);
|
||||
}
|
||||
window_set_active_pane(wl->window, wp);
|
||||
|
259
cmd-swap-pane.c
259
cmd-swap-pane.c
@ -26,191 +26,93 @@
|
||||
* Swap two panes.
|
||||
*/
|
||||
|
||||
int cmd_swap_pane_parse(struct cmd *, int, char **, char **);
|
||||
int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
|
||||
void cmd_swap_pane_free(struct cmd *);
|
||||
void cmd_swap_pane_init(struct cmd *, int);
|
||||
size_t cmd_swap_pane_print(struct cmd *, char *, size_t);
|
||||
|
||||
struct cmd_swap_pane_data {
|
||||
char *target;
|
||||
int src;
|
||||
int dst;
|
||||
int flag_detached;
|
||||
int flag_up;
|
||||
int flag_down;
|
||||
};
|
||||
int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
|
||||
|
||||
const struct cmd_entry cmd_swap_pane_entry = {
|
||||
"swap-pane", "swapp",
|
||||
"[-dDU] [-t target-window] [-p src-index] [-q dst-index]",
|
||||
0, 0,
|
||||
"[-dDU] " CMD_SRCDST_PANE_USAGE,
|
||||
0, CMD_CHFLAG('d')|CMD_CHFLAG('D')|CMD_CHFLAG('U'),
|
||||
cmd_swap_pane_init,
|
||||
cmd_swap_pane_parse,
|
||||
cmd_srcdst_parse,
|
||||
cmd_swap_pane_exec,
|
||||
cmd_swap_pane_free,
|
||||
cmd_swap_pane_print
|
||||
cmd_srcdst_free,
|
||||
cmd_srcdst_print
|
||||
};
|
||||
|
||||
void
|
||||
cmd_swap_pane_init(struct cmd *self, int key)
|
||||
{
|
||||
struct cmd_swap_pane_data *data;
|
||||
struct cmd_target_data *data;
|
||||
|
||||
self->data = data = xmalloc(sizeof *data);
|
||||
data->target = NULL;
|
||||
data->src = -1;
|
||||
data->dst = -1;
|
||||
data->flag_detached = 0;
|
||||
data->flag_up = 0;
|
||||
data->flag_down = 0;
|
||||
|
||||
switch (key) {
|
||||
case '{':
|
||||
data->flag_up = 1;
|
||||
break;
|
||||
case '}':
|
||||
data->flag_down = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||
{
|
||||
struct cmd_swap_pane_data *data;
|
||||
int opt, n;
|
||||
const char *errstr;
|
||||
|
||||
self->entry->init(self, 0);
|
||||
cmd_srcdst_init(self, key);
|
||||
data = self->data;
|
||||
|
||||
while ((opt = getopt(argc, argv, "dDt:p:q:U")) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
data->flag_detached = 1;
|
||||
break;
|
||||
case 'D':
|
||||
data->flag_up = 0;
|
||||
data->flag_down = 1;
|
||||
data->dst = -1;
|
||||
break;
|
||||
case 't':
|
||||
if (data->target == NULL)
|
||||
data->target = xstrdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
if (data->src == -1) {
|
||||
n = strtonum(optarg, 0, INT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
xasprintf(cause, "src %s", errstr);
|
||||
goto error;
|
||||
}
|
||||
data->src = n;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
if (data->dst == -1) {
|
||||
n = strtonum(optarg, 0, INT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
xasprintf(cause, "dst %s", errstr);
|
||||
goto error;
|
||||
}
|
||||
data->dst = n;
|
||||
}
|
||||
data->flag_up = 0;
|
||||
data->flag_down = 0;
|
||||
break;
|
||||
case 'U':
|
||||
data->flag_up = 1;
|
||||
data->flag_down = 0;
|
||||
data->dst = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc != 0)
|
||||
goto usage;
|
||||
|
||||
return (0);
|
||||
|
||||
usage:
|
||||
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
|
||||
|
||||
error:
|
||||
self->entry->free(self);
|
||||
return (-1);
|
||||
if (key == '{')
|
||||
data->chflags |= CMD_CHFLAG('U');
|
||||
else if (key == '}')
|
||||
data->chflags |= CMD_CHFLAG('D');
|
||||
}
|
||||
|
||||
int
|
||||
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
{
|
||||
struct cmd_swap_pane_data *data = self->data;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct window_pane *tmp_wp, *src_wp, *dst_wp;
|
||||
struct layout_cell *lc;
|
||||
u_int sx, sy, xoff, yoff;
|
||||
struct cmd_srcdst_data *data = self->data;
|
||||
struct winlink *src_wl, *dst_wl;
|
||||
struct window *src_w, *dst_w;
|
||||
struct window_pane *tmp_wp, *src_wp, *dst_wp;
|
||||
struct layout_cell *src_lc, *dst_lc;
|
||||
u_int sx, sy, xoff, yoff;
|
||||
|
||||
if (data == NULL)
|
||||
return (0);
|
||||
|
||||
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
|
||||
if ((dst_wl = cmd_find_pane(ctx, data->dst, NULL, &dst_wp)) == NULL)
|
||||
return (-1);
|
||||
w = wl->window;
|
||||
dst_w = dst_wl->window;
|
||||
|
||||
if (data->src == -1)
|
||||
src_wp = w->active;
|
||||
else {
|
||||
src_wp = window_pane_at_index(w, data->src);
|
||||
if (src_wp == NULL) {
|
||||
ctx->error(ctx, "no pane: %d", data->src);
|
||||
if (data->src == NULL) {
|
||||
src_wl = dst_wl;
|
||||
src_w = dst_w;
|
||||
if (data->chflags & CMD_CHFLAG('D')) {
|
||||
src_wp = TAILQ_NEXT(dst_wp, entry);
|
||||
if (src_wp == NULL)
|
||||
src_wp = TAILQ_FIRST(&dst_w->panes);
|
||||
} else if (data->chflags & CMD_CHFLAG('U')) {
|
||||
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
|
||||
if (src_wp == NULL)
|
||||
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
|
||||
} else
|
||||
return (0);
|
||||
} else {
|
||||
src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp);
|
||||
if (src_wl == NULL)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (data->dst == -1)
|
||||
dst_wp = w->active;
|
||||
else {
|
||||
dst_wp = window_pane_at_index(w, data->dst);
|
||||
if (dst_wp == NULL) {
|
||||
ctx->error(ctx, "no pane: %d", data->dst);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (data->dst == -1 && data->flag_up) {
|
||||
if ((dst_wp = TAILQ_PREV(src_wp, window_panes, entry)) == NULL)
|
||||
dst_wp = TAILQ_LAST(&w->panes, window_panes);
|
||||
}
|
||||
if (data->dst == -1 && data->flag_down) {
|
||||
if ((dst_wp = TAILQ_NEXT(src_wp, entry)) == NULL)
|
||||
dst_wp = TAILQ_FIRST(&w->panes);
|
||||
src_w = src_wl->window;
|
||||
}
|
||||
|
||||
if (src_wp == dst_wp)
|
||||
return (0);
|
||||
|
||||
tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
|
||||
TAILQ_REMOVE(&w->panes, dst_wp, entry);
|
||||
TAILQ_REPLACE(&w->panes, src_wp, dst_wp, entry);
|
||||
TAILQ_REMOVE(&dst_w->panes, dst_wp, entry);
|
||||
TAILQ_REPLACE(&src_w->panes, src_wp, dst_wp, entry);
|
||||
if (tmp_wp == src_wp)
|
||||
tmp_wp = dst_wp;
|
||||
if (tmp_wp == NULL)
|
||||
TAILQ_INSERT_HEAD(&w->panes, src_wp, entry);
|
||||
TAILQ_INSERT_HEAD(&dst_w->panes, src_wp, entry);
|
||||
else
|
||||
TAILQ_INSERT_AFTER(&w->panes, tmp_wp, src_wp, entry);
|
||||
TAILQ_INSERT_AFTER(&dst_w->panes, tmp_wp, src_wp, entry);
|
||||
|
||||
lc = src_wp->layout_cell;
|
||||
src_wp->layout_cell = dst_wp->layout_cell;
|
||||
if (src_wp->layout_cell != NULL)
|
||||
src_wp->layout_cell->wp = src_wp;
|
||||
dst_wp->layout_cell = lc;
|
||||
if (dst_wp->layout_cell != NULL)
|
||||
dst_wp->layout_cell->wp = dst_wp;
|
||||
src_lc = src_wp->layout_cell;
|
||||
dst_lc = dst_wp->layout_cell;
|
||||
src_lc->wp = dst_wp;
|
||||
dst_wp->layout_cell = src_lc;
|
||||
dst_lc->wp = src_wp;
|
||||
src_wp->layout_cell = dst_lc;
|
||||
|
||||
src_wp->window = dst_w;
|
||||
dst_wp->window = src_w;
|
||||
|
||||
sx = src_wp->sx; sy = src_wp->sy;
|
||||
xoff = src_wp->xoff; yoff = src_wp->yoff;
|
||||
@ -219,51 +121,24 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||
dst_wp->xoff = xoff; dst_wp->yoff = yoff;
|
||||
window_pane_resize(dst_wp, sx, sy);
|
||||
|
||||
if (!data->flag_detached) {
|
||||
tmp_wp = dst_wp;
|
||||
if (!window_pane_visible(tmp_wp))
|
||||
tmp_wp = src_wp;
|
||||
window_set_active_pane(w, tmp_wp);
|
||||
if (!(data->chflags & CMD_CHFLAG('d'))) {
|
||||
if (src_w != dst_w) {
|
||||
window_set_active_pane(src_w, dst_wp);
|
||||
window_set_active_pane(dst_w, src_wp);
|
||||
} else {
|
||||
tmp_wp = dst_wp;
|
||||
if (!window_pane_visible(tmp_wp))
|
||||
tmp_wp = src_wp;
|
||||
window_set_active_pane(src_w, tmp_wp);
|
||||
}
|
||||
} else {
|
||||
if (src_w->active == src_wp)
|
||||
window_set_active_pane(src_w, dst_wp);
|
||||
if (dst_w->active == dst_wp)
|
||||
window_set_active_pane(dst_w, src_wp);
|
||||
}
|
||||
server_redraw_window(w);
|
||||
server_redraw_window(src_w);
|
||||
server_redraw_window(dst_w);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
cmd_swap_pane_free(struct cmd *self)
|
||||
{
|
||||
struct cmd_swap_pane_data *data = self->data;
|
||||
|
||||
if (data->target != NULL)
|
||||
xfree(data->target);
|
||||
xfree(data);
|
||||
}
|
||||
|
||||
size_t
|
||||
cmd_swap_pane_print(struct cmd *self, char *buf, size_t len)
|
||||
{
|
||||
struct cmd_swap_pane_data *data = self->data;
|
||||
size_t off = 0;
|
||||
|
||||
off += xsnprintf(buf, len, "%s", self->entry->name);
|
||||
if (data == NULL)
|
||||
return (off);
|
||||
if (off < len &&
|
||||
(data->flag_down || data->flag_up || data->flag_detached)) {
|
||||
off += xsnprintf(buf + off, len - off, " -");
|
||||
if (off < len && data->flag_detached)
|
||||
off += xsnprintf(buf + off, len - off, "d");
|
||||
if (off < len && data->flag_up)
|
||||
off += xsnprintf(buf + off, len - off, "D");
|
||||
if (off < len && data->flag_down)
|
||||
off += xsnprintf(buf + off, len - off, "U");
|
||||
}
|
||||
if (off < len && data->target != NULL)
|
||||
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
|
||||
if (off < len && data->src != -1)
|
||||
off += xsnprintf(buf + off, len - off, " -p %d", data->src);
|
||||
if (off < len && data->dst != -1)
|
||||
off += xsnprintf(buf + off, len - off, " -q %d", data->dst);
|
||||
return (off);
|
||||
}
|
||||
|
85
cmd.c
85
cmd.c
@ -771,3 +771,88 @@ not_found:
|
||||
xfree(sessptr);
|
||||
return (-2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the target session, window and pane number or report an error and
|
||||
* return NULL. The pane number is separated from the session:window by a .,
|
||||
* such as mysession:mywindow.0.
|
||||
*/
|
||||
struct winlink *
|
||||
cmd_find_pane(struct cmd_ctx *ctx,
|
||||
const char *arg, struct session **sp, struct window_pane **wpp)
|
||||
{
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
const char *period;
|
||||
char *winptr, *paneptr;
|
||||
const char *errstr;
|
||||
u_int idx;
|
||||
|
||||
/* Get the current session. */
|
||||
if ((s = cmd_current_session(ctx)) == NULL) {
|
||||
ctx->error(ctx, "can't establish current session");
|
||||
return (NULL);
|
||||
}
|
||||
if (sp != NULL)
|
||||
*sp = s;
|
||||
|
||||
/* A NULL argument means the current session, window and pane. */
|
||||
if (arg == NULL) {
|
||||
*wpp = s->curw->window->active;
|
||||
return (s->curw);
|
||||
}
|
||||
|
||||
/* Look for a separating period. */
|
||||
if ((period = strrchr(arg, '.')) == NULL)
|
||||
goto no_period;
|
||||
|
||||
/* Pull out the window part and parse it. */
|
||||
winptr = xstrdup(arg);
|
||||
winptr[period - arg] = '\0';
|
||||
if (*winptr == '\0')
|
||||
wl = s->curw;
|
||||
else if ((wl = cmd_find_window(ctx, winptr, sp)) == NULL)
|
||||
goto error;
|
||||
|
||||
/* Find the pane section and look it up. */
|
||||
paneptr = winptr + (period - arg) + 1;
|
||||
if (*paneptr == '\0')
|
||||
*wpp = wl->window->active;
|
||||
else {
|
||||
idx = strtonum(paneptr, 0, INT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
ctx->error(ctx, "pane %s: %s", errstr, paneptr);
|
||||
goto error;
|
||||
}
|
||||
*wpp = window_pane_at_index(wl->window, idx);
|
||||
if (*wpp == NULL) {
|
||||
ctx->error(ctx, "no such pane: %u", idx);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
xfree(winptr);
|
||||
return (wl);
|
||||
|
||||
no_period:
|
||||
/* Try as a pane number alone. */
|
||||
idx = strtonum(arg, 0, INT_MAX, &errstr);
|
||||
if (errstr != NULL)
|
||||
goto lookup_window;
|
||||
|
||||
/* Try index in the current session and window. */
|
||||
if ((*wpp = window_pane_at_index(s->curw->window, idx)) == NULL)
|
||||
goto lookup_window;
|
||||
|
||||
return (s->curw);
|
||||
|
||||
lookup_window:
|
||||
/* Try as a window and use the active pane. */
|
||||
if ((wl = cmd_find_window(ctx, arg, sp)) != NULL)
|
||||
*wpp = wl->window->active;
|
||||
return (wl);
|
||||
|
||||
error:
|
||||
xfree(winptr);
|
||||
return (NULL);
|
||||
}
|
||||
|
69
tmux.1
69
tmux.1
@ -534,9 +534,10 @@ Most commands accept the optional
|
||||
argument with one of
|
||||
.Ar target-client ,
|
||||
.Ar target-session
|
||||
.Ar target-window ,
|
||||
or
|
||||
.Ar target-window .
|
||||
These specify the client, session or window which a command should affect.
|
||||
.Ar target-pane .
|
||||
These specify the client, session, window or pane which a command should affect.
|
||||
.Ar target-client
|
||||
is the name of the
|
||||
.Xr pty 4
|
||||
@ -598,6 +599,19 @@ When the argument does not contain a colon,
|
||||
first attempts to parse it as window; if that fails, an attempt is made to
|
||||
match a session.
|
||||
.Pp
|
||||
.Ar target-pane
|
||||
takes a similar form to
|
||||
.Ar target-window
|
||||
but with the optional addition of a period followed by a pane index, for
|
||||
example: mysession:mywindow.1.
|
||||
If the pane index is omitted, the currently active pane in the specified
|
||||
window is used.
|
||||
If neither a colon nor period appears,
|
||||
.Nm
|
||||
first attempts to use the argument as a pane index; if that fails, it is looked
|
||||
up as for
|
||||
.Ar target-window .
|
||||
.Pp
|
||||
Multiple commands may be specified together as part of a
|
||||
.Em command sequence .
|
||||
Each command should be separated by spaces and a semicolon;
|
||||
@ -687,12 +701,12 @@ To view the default bindings and possible commands, see the
|
||||
command.
|
||||
.It Xo Ic break-pane
|
||||
.Op Fl d
|
||||
.Op Fl p Ar pane-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
.D1 (alias: Ic breakp )
|
||||
Break the current pane off from its containing window to make it the only pane
|
||||
in a new window.
|
||||
Break
|
||||
.Ar target-pane
|
||||
off from its containing window to make it the only pane in a new window.
|
||||
If
|
||||
.Fl d
|
||||
is given, the new window does not become the current window.
|
||||
@ -711,8 +725,7 @@ attached to the current client may be selected interactively from a list.
|
||||
This command works only from inside
|
||||
.Nm .
|
||||
.It Xo Ic clear-history
|
||||
.Op Fl p Ar pane-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
.D1 (alias: Ic clearhist )
|
||||
Remove and free the history for the specified pane.
|
||||
@ -782,8 +795,7 @@ Display a message (see the
|
||||
option below)
|
||||
in the status line.
|
||||
.It Xo Ic down-pane
|
||||
.Op Fl p Ar pane-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
.D1 (alias: Ic downp )
|
||||
Move down a pane.
|
||||
@ -818,8 +830,7 @@ if
|
||||
.Ar shell-command
|
||||
returns success.
|
||||
.It Xo Ic kill-pane
|
||||
.Op Fl p Ar pane-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
.D1 (alias: Ic killp )
|
||||
Destroy the given pane.
|
||||
@ -1058,8 +1069,7 @@ if specified, to
|
||||
.Ar new-name .
|
||||
.It Xo Ic resize-pane
|
||||
.Op Fl DLRU
|
||||
.Op Fl p Ar pane-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl t Ar target-pane
|
||||
.Op Ar adjustment
|
||||
.Xc
|
||||
.D1 (alias: Ic resizep )
|
||||
@ -1130,12 +1140,11 @@ If
|
||||
.Ar layout-name
|
||||
is not given, the last layout used (if any) is reapplied.
|
||||
.It Xo Ic select-pane
|
||||
.Op Fl p Ar pane-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
.D1 (alias: Ic selectp )
|
||||
Make pane
|
||||
.Ar pane-index
|
||||
.Ar target-pane
|
||||
the active pane in window
|
||||
.Ar target-window .
|
||||
.It Xo Ic select-prompt
|
||||
@ -1297,11 +1306,9 @@ Whether a key repeats may be set when it is bound using the
|
||||
.Fl r
|
||||
flag to
|
||||
.Ic bind-key .
|
||||
Repeat is enabled for the default keys of the
|
||||
.Ic resize-pane-up
|
||||
and
|
||||
.Ic resize-pane-down
|
||||
commands.
|
||||
Repeat is enabled for the default keys bound to the
|
||||
.Ic resize-pane
|
||||
command.
|
||||
.It Xo Ic set-remain-on-exit
|
||||
.Op Ic on | Ic off
|
||||
.Xc
|
||||
@ -1659,19 +1666,18 @@ Suspend a client by sending
|
||||
(tty stop).
|
||||
.It Xo Ic swap-pane
|
||||
.Op Fl dDU
|
||||
.Op Fl p Ar src-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl q Ar dst-index
|
||||
.Op Fl s Ar src-pane
|
||||
.Op Fl t Ar dst-pane
|
||||
.Xc
|
||||
.D1 (alias: Ic swapp )
|
||||
Swap two panes within a window.
|
||||
Swap two panes.
|
||||
If
|
||||
.Fl U
|
||||
is used, the pane is swapped with the pane above (before it numerically);
|
||||
is used and no source pane is specified with
|
||||
.Fl s ,
|
||||
.Ar dst-pane is swapped with the previous pane (before it numerically);
|
||||
.Fl D
|
||||
swaps with the pane below (the next numerically); or
|
||||
.Ar dst-index
|
||||
may be give to swap with a specific pane.
|
||||
swaps with the next pane (after it numerically).
|
||||
.It Xo Ic swap-window
|
||||
.Op Fl d
|
||||
.Op Fl s Ar src-window
|
||||
@ -1733,8 +1739,7 @@ if
|
||||
is specified and the window is linked to only one session, it is unlinked and
|
||||
destroyed.
|
||||
.It Xo Ic up-pane
|
||||
.Op Fl p Ar pane-index
|
||||
.Op Fl t Ar target-window
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
.D1 (alias: Ic upp )
|
||||
Move up a pane.
|
||||
|
20
tmux.h
20
tmux.h
@ -1023,13 +1023,6 @@ struct cmd_option_data {
|
||||
char *value;
|
||||
};
|
||||
|
||||
struct cmd_pane_data {
|
||||
uint64_t chflags;
|
||||
char *target;
|
||||
char *arg;
|
||||
int pane;
|
||||
};
|
||||
|
||||
/* Key binding. */
|
||||
struct key_binding {
|
||||
int key;
|
||||
@ -1222,6 +1215,8 @@ struct winlink *cmd_find_window(
|
||||
struct cmd_ctx *, const char *, struct session **);
|
||||
int cmd_find_index(
|
||||
struct cmd_ctx *, const char *, struct session **);
|
||||
struct winlink *cmd_find_pane(struct cmd_ctx *,
|
||||
const char *, struct session **, struct window_pane **);
|
||||
extern const struct cmd_entry *cmd_table[];
|
||||
extern const struct cmd_entry cmd_attach_session_entry;
|
||||
extern const struct cmd_entry cmd_bind_key_entry;
|
||||
@ -1307,6 +1302,7 @@ int cmd_string_parse(const char *, struct cmd_list **, char **);
|
||||
|
||||
/* cmd-generic.c */
|
||||
size_t cmd_prarg(char *, size_t, const char *, char *);
|
||||
#define CMD_TARGET_PANE_USAGE "[-t target-pane]"
|
||||
#define CMD_TARGET_WINDOW_USAGE "[-t target-window]"
|
||||
#define CMD_TARGET_SESSION_USAGE "[-t target-session]"
|
||||
#define CMD_TARGET_CLIENT_USAGE "[-t target-client]"
|
||||
@ -1314,6 +1310,7 @@ void cmd_target_init(struct cmd *, int);
|
||||
int cmd_target_parse(struct cmd *, int, char **, char **);
|
||||
void cmd_target_free(struct cmd *);
|
||||
size_t cmd_target_print(struct cmd *, char *, size_t);
|
||||
#define CMD_SRCDST_PANE_USAGE "[-s src-pane] [-t dst-pane]"
|
||||
#define CMD_SRCDST_WINDOW_USAGE "[-s src-window] [-t dst-window]"
|
||||
#define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]"
|
||||
#define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]"
|
||||
@ -1321,6 +1318,7 @@ void cmd_srcdst_init(struct cmd *, int);
|
||||
int cmd_srcdst_parse(struct cmd *, int, char **, char **);
|
||||
void cmd_srcdst_free(struct cmd *);
|
||||
size_t cmd_srcdst_print(struct cmd *, char *, size_t);
|
||||
#define CMD_BUFFER_PANE_USAGE "[-b buffer-index] [-t target-pane]"
|
||||
#define CMD_BUFFER_WINDOW_USAGE "[-b buffer-index] [-t target-window]"
|
||||
#define CMD_BUFFER_SESSION_USAGE "[-b buffer-index] [-t target-session]"
|
||||
#define CMD_BUFFER_CLIENT_USAGE "[-b buffer-index] [-t target-client]"
|
||||
@ -1328,6 +1326,7 @@ void cmd_buffer_init(struct cmd *, int);
|
||||
int cmd_buffer_parse(struct cmd *, int, char **, char **);
|
||||
void cmd_buffer_free(struct cmd *);
|
||||
size_t cmd_buffer_print(struct cmd *, char *, size_t);
|
||||
#define CMD_OPTION_PANE_USAGE "[-gu] [-t target-pane] option [value]"
|
||||
#define CMD_OPTION_WINDOW_USAGE "[-gu] [-t target-window] option [value]"
|
||||
#define CMD_OPTION_SESSION_USAGE "[-gu] [-t target-session] option [value]"
|
||||
#define CMD_OPTION_CLIENT_USAGE "[-gu] [-t target-client] option [value]"
|
||||
@ -1335,13 +1334,6 @@ void cmd_option_init(struct cmd *, int);
|
||||
int cmd_option_parse(struct cmd *, int, char **, char **);
|
||||
void cmd_option_free(struct cmd *);
|
||||
size_t cmd_option_print(struct cmd *, char *, size_t);
|
||||
#define CMD_PANE_WINDOW_USAGE "[-t target-window] [-p pane-index]"
|
||||
#define CMD_PANE_SESSION_USAGE "[-t target-session] [-p pane-index]"
|
||||
#define CMD_PANE_CLIENT_USAGE "[-t target-client] [-p pane-index]"
|
||||
void cmd_pane_init(struct cmd *, int);
|
||||
int cmd_pane_parse(struct cmd *, int, char **, char **);
|
||||
void cmd_pane_free(struct cmd *);
|
||||
size_t cmd_pane_print(struct cmd *, char *, size_t);
|
||||
|
||||
/* client.c */
|
||||
int client_init(char *, struct client_ctx *, int, int);
|
||||
|
Loading…
Reference in New Issue
Block a user