Sync OpenBSD patchset 200:

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.
pull/1/head
Tiago Cunha 2009-07-30 20:45:20 +00:00
parent ec1396c9ee
commit 1650b8552f
10 changed files with 243 additions and 421 deletions

View File

@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-break-pane.c,v 1.7 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -30,39 +30,30 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_break_pane_entry = { const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp", "break-pane", "breakp",
CMD_PANE_WINDOW_USAGE " [-d]", CMD_TARGET_PANE_USAGE " [-d]",
0, CMD_CHFLAG('d'), 0, CMD_CHFLAG('d'),
cmd_pane_init, cmd_target_init,
cmd_pane_parse, cmd_target_parse,
cmd_break_pane_exec, cmd_break_pane_exec,
cmd_pane_free, cmd_target_free,
cmd_pane_print cmd_target_print
}; };
int int
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) 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 winlink *wl;
struct session *s; struct session *s;
struct window_pane *wp; struct window_pane *wp;
struct window *w; struct window *w;
char *cause; 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); 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) { 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); return (-1);
} }

View File

@ -1,4 +1,4 @@
/* $Id: cmd-clear-history.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-clear-history.c,v 1.6 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -28,34 +28,25 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = { const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist", "clear-history", "clearhist",
CMD_PANE_WINDOW_USAGE, CMD_TARGET_PANE_USAGE,
0, 0, 0, 0,
cmd_pane_init, cmd_target_init,
cmd_pane_parse, cmd_target_parse,
cmd_clear_history_exec, cmd_clear_history_exec,
cmd_pane_free, cmd_target_free,
cmd_pane_print cmd_target_print
}; };
int int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx) 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 winlink *wl;
struct window_pane *wp; struct window_pane *wp;
struct grid *gd; 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); 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; gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy); grid_move_lines(gd, 0, gd->hsize, gd->sy);

View File

@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.31 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-generic.c,v 1.32 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -467,93 +467,3 @@ cmd_option_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf + off, len - off, " %s", data->value); off += xsnprintf(buf + off, len - off, " %s", data->value);
return (off); 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);
}

View File

@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.11 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-kill-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -30,33 +30,24 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = { const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp", "kill-pane", "killp",
CMD_PANE_WINDOW_USAGE, CMD_TARGET_PANE_USAGE,
0, 0, 0, 0,
cmd_pane_init, cmd_target_init,
cmd_pane_parse, cmd_target_parse,
cmd_kill_pane_exec, cmd_kill_pane_exec,
cmd_pane_free, cmd_target_free,
cmd_pane_print cmd_target_print
}; };
int int
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx) 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 winlink *wl;
struct window_pane *wp; 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); 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) { if (window_count_panes(wl->window) == 1) {
/* Only one pane, kill the window. */ /* Only one pane, kill the window. */

View File

@ -1,4 +1,4 @@
/* $Id: cmd-resize-pane.c,v 1.11 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-resize-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -31,22 +31,22 @@ int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = { const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep", "resize-pane", "resizep",
CMD_PANE_WINDOW_USAGE "[-DU] [adjustment]", "[-DU] " CMD_TARGET_PANE_USAGE " [adjustment]",
CMD_ARG01, CMD_ARG01,
CMD_CHFLAG('D')|CMD_CHFLAG('L')|CMD_CHFLAG('R')|CMD_CHFLAG('U'), CMD_CHFLAG('D')|CMD_CHFLAG('L')|CMD_CHFLAG('R')|CMD_CHFLAG('U'),
cmd_resize_pane_init, cmd_resize_pane_init,
cmd_pane_parse, cmd_target_parse,
cmd_resize_pane_exec, cmd_resize_pane_exec,
cmd_pane_free, cmd_target_free,
cmd_pane_print cmd_target_print
}; };
void void
cmd_resize_pane_init(struct cmd *self, int key) 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; data = self->data;
if (key == (KEYC_UP | KEYC_CTRL)) if (key == (KEYC_UP | KEYC_CTRL))
@ -79,23 +79,14 @@ cmd_resize_pane_init(struct cmd *self, int key)
int int
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) 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; struct winlink *wl;
const char *errstr; const char *errstr;
struct window_pane *wp; struct window_pane *wp;
u_int adjust; 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); 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) if (data->arg == NULL)
adjust = 1; adjust = 1;

View File

@ -1,4 +1,4 @@
/* $Id: cmd-select-pane.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-select-pane.c,v 1.10 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -28,36 +28,27 @@ int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = { const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp", "select-pane", "selectp",
CMD_PANE_WINDOW_USAGE, CMD_TARGET_PANE_USAGE,
0, 0, 0, 0,
cmd_pane_init, cmd_target_init,
cmd_pane_parse, cmd_target_parse,
cmd_select_pane_exec, cmd_select_pane_exec,
cmd_pane_free, cmd_target_free,
cmd_pane_print cmd_target_print
}; };
int int
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx) 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 winlink *wl;
struct window_pane *wp; 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); 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)) { 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); return (-1);
} }
window_set_active_pane(wl->window, wp); window_set_active_pane(wl->window, wp);

View File

@ -1,4 +1,4 @@
/* $Id: cmd-swap-pane.c,v 1.11 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-swap-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -26,191 +26,93 @@
* Swap two panes. * 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); void cmd_swap_pane_init(struct cmd *, int);
size_t cmd_swap_pane_print(struct cmd *, char *, size_t); int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
struct cmd_swap_pane_data {
char *target;
int src;
int dst;
int flag_detached;
int flag_up;
int flag_down;
};
const struct cmd_entry cmd_swap_pane_entry = { const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp", "swap-pane", "swapp",
"[-dDU] [-t target-window] [-p src-index] [-q dst-index]", "[-dDU] " CMD_SRCDST_PANE_USAGE,
0, 0, 0, CMD_CHFLAG('d')|CMD_CHFLAG('D')|CMD_CHFLAG('U'),
cmd_swap_pane_init, cmd_swap_pane_init,
cmd_swap_pane_parse, cmd_srcdst_parse,
cmd_swap_pane_exec, cmd_swap_pane_exec,
cmd_swap_pane_free, cmd_srcdst_free,
cmd_swap_pane_print cmd_srcdst_print
}; };
void void
cmd_swap_pane_init(struct cmd *self, int key) 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); cmd_srcdst_init(self, key);
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);
data = self->data; data = self->data;
while ((opt = getopt(argc, argv, "dDt:p:q:U")) != -1) { if (key == '{')
switch (opt) { data->chflags |= CMD_CHFLAG('U');
case 'd': else if (key == '}')
data->flag_detached = 1; data->chflags |= CMD_CHFLAG('D');
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);
} }
int int
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_swap_pane_data *data = self->data; struct cmd_srcdst_data *data = self->data;
struct winlink *wl; struct winlink *src_wl, *dst_wl;
struct window *w; struct window *src_w, *dst_w;
struct window_pane *tmp_wp, *src_wp, *dst_wp; struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *lc; struct layout_cell *src_lc, *dst_lc;
u_int sx, sy, xoff, yoff; u_int sx, sy, xoff, yoff;
if (data == NULL) if (data == NULL)
return (0); 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); return (-1);
w = wl->window; dst_w = dst_wl->window;
if (data->src == -1) if (data->src == NULL) {
src_wp = w->active; src_wl = dst_wl;
else { src_w = dst_w;
src_wp = window_pane_at_index(w, data->src); if (data->chflags & CMD_CHFLAG('D')) {
if (src_wp == NULL) { src_wp = TAILQ_NEXT(dst_wp, entry);
ctx->error(ctx, "no pane: %d", data->src); 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); return (-1);
} src_w = src_wl->window;
}
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);
} }
if (src_wp == dst_wp) if (src_wp == dst_wp)
return (0); return (0);
tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry); tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
TAILQ_REMOVE(&w->panes, dst_wp, entry); TAILQ_REMOVE(&dst_w->panes, dst_wp, entry);
TAILQ_REPLACE(&w->panes, src_wp, dst_wp, entry); TAILQ_REPLACE(&src_w->panes, src_wp, dst_wp, entry);
if (tmp_wp == src_wp) if (tmp_wp == src_wp)
tmp_wp = dst_wp; tmp_wp = dst_wp;
if (tmp_wp == NULL) if (tmp_wp == NULL)
TAILQ_INSERT_HEAD(&w->panes, src_wp, entry); TAILQ_INSERT_HEAD(&dst_w->panes, src_wp, entry);
else 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_lc = src_wp->layout_cell;
src_wp->layout_cell = dst_wp->layout_cell; dst_lc = dst_wp->layout_cell;
if (src_wp->layout_cell != NULL) src_lc->wp = dst_wp;
src_wp->layout_cell->wp = src_wp; dst_wp->layout_cell = src_lc;
dst_wp->layout_cell = lc; dst_lc->wp = src_wp;
if (dst_wp->layout_cell != NULL) src_wp->layout_cell = dst_lc;
dst_wp->layout_cell->wp = dst_wp;
src_wp->window = dst_w;
dst_wp->window = src_w;
sx = src_wp->sx; sy = src_wp->sy; sx = src_wp->sx; sy = src_wp->sy;
xoff = src_wp->xoff; yoff = src_wp->yoff; 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; dst_wp->xoff = xoff; dst_wp->yoff = yoff;
window_pane_resize(dst_wp, sx, sy); window_pane_resize(dst_wp, sx, sy);
if (!data->flag_detached) { if (!(data->chflags & CMD_CHFLAG('d'))) {
tmp_wp = dst_wp; if (src_w != dst_w) {
if (!window_pane_visible(tmp_wp)) window_set_active_pane(src_w, dst_wp);
tmp_wp = src_wp; window_set_active_pane(dst_w, src_wp);
window_set_active_pane(w, tmp_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); 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);
}

87
cmd.c
View File

@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.110 2009-07-30 20:26:20 tcunha Exp $ */ /* $Id: cmd.c,v 1.111 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -770,3 +770,88 @@ not_found:
xfree(sessptr); xfree(sessptr);
return (-2); 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);
}

71
tmux.1
View File

@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.137 2009-07-30 20:33:29 tcunha Exp $ .\" $Id: tmux.1,v 1.138 2009-07-30 20:45:20 tcunha Exp $
.\" .\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\" .\"
@ -534,9 +534,10 @@ Most commands accept the optional
argument with one of argument with one of
.Ar target-client , .Ar target-client ,
.Ar target-session .Ar target-session
.Ar target-window ,
or or
.Ar target-window . .Ar target-pane .
These specify the client, session or window which a command should affect. These specify the client, session, window or pane which a command should affect.
.Ar target-client .Ar target-client
is the name of the is the name of the
.Xr pty 4 .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 first attempts to parse it as window; if that fails, an attempt is made to
match a session. match a session.
.Pp .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 Multiple commands may be specified together as part of a
.Em command sequence . .Em command sequence .
Each command should be separated by spaces and a semicolon; 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. command.
.It Xo Ic break-pane .It Xo Ic break-pane
.Op Fl d .Op Fl d
.Op Fl p Ar pane-index .Op Fl t Ar target-pane
.Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic breakp ) .D1 (alias: Ic breakp )
Break the current pane off from its containing window to make it the only pane Break
in a new window. .Ar target-pane
off from its containing window to make it the only pane in a new window.
If If
.Fl d .Fl d
is given, the new window does not become the current window. 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 This command works only from inside
.Nm . .Nm .
.It Xo Ic clear-history .It Xo Ic clear-history
.Op Fl p Ar pane-index .Op Fl t Ar target-pane
.Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic clearhist ) .D1 (alias: Ic clearhist )
Remove and free the history for the specified pane. Remove and free the history for the specified pane.
@ -782,8 +795,7 @@ Display a message (see the
option below) option below)
in the status line. in the status line.
.It Xo Ic down-pane .It Xo Ic down-pane
.Op Fl p Ar pane-index .Op Fl t Ar target-pane
.Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic downp ) .D1 (alias: Ic downp )
Move down a pane. Move down a pane.
@ -818,8 +830,7 @@ if
.Ar shell-command .Ar shell-command
returns success. returns success.
.It Xo Ic kill-pane .It Xo Ic kill-pane
.Op Fl p Ar pane-index .Op Fl t Ar target-pane
.Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic killp ) .D1 (alias: Ic killp )
Destroy the given pane. Destroy the given pane.
@ -1058,8 +1069,7 @@ if specified, to
.Ar new-name . .Ar new-name .
.It Xo Ic resize-pane .It Xo Ic resize-pane
.Op Fl DLRU .Op Fl DLRU
.Op Fl p Ar pane-index .Op Fl t Ar target-pane
.Op Fl t Ar target-window
.Op Ar adjustment .Op Ar adjustment
.Xc .Xc
.D1 (alias: Ic resizep ) .D1 (alias: Ic resizep )
@ -1130,12 +1140,11 @@ If
.Ar layout-name .Ar layout-name
is not given, the last layout used (if any) is reapplied. is not given, the last layout used (if any) is reapplied.
.It Xo Ic select-pane .It Xo Ic select-pane
.Op Fl p Ar pane-index .Op Fl t Ar target-pane
.Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic selectp ) .D1 (alias: Ic selectp )
Make pane Make pane
.Ar pane-index .Ar target-pane
the active pane in window the active pane in window
.Ar target-window . .Ar target-window .
.It Xo Ic select-prompt .It Xo Ic select-prompt
@ -1297,11 +1306,9 @@ Whether a key repeats may be set when it is bound using the
.Fl r .Fl r
flag to flag to
.Ic bind-key . .Ic bind-key .
Repeat is enabled for the default keys of the Repeat is enabled for the default keys bound to the
.Ic resize-pane-up .Ic resize-pane
and command.
.Ic resize-pane-down
commands.
.It Xo Ic set-remain-on-exit .It Xo Ic set-remain-on-exit
.Op Ic on | Ic off .Op Ic on | Ic off
.Xc .Xc
@ -1659,19 +1666,18 @@ Suspend a client by sending
(tty stop). (tty stop).
.It Xo Ic swap-pane .It Xo Ic swap-pane
.Op Fl dDU .Op Fl dDU
.Op Fl p Ar src-index .Op Fl s Ar src-pane
.Op Fl t Ar target-window .Op Fl t Ar dst-pane
.Op Fl q Ar dst-index
.Xc .Xc
.D1 (alias: Ic swapp ) .D1 (alias: Ic swapp )
Swap two panes within a window. Swap two panes.
If If
.Fl U .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 .Fl D
swaps with the pane below (the next numerically); or swaps with the next pane (after it numerically).
.Ar dst-index
may be give to swap with a specific pane.
.It Xo Ic swap-window .It Xo Ic swap-window
.Op Fl d .Op Fl d
.Op Fl s Ar src-window .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 is specified and the window is linked to only one session, it is unlinked and
destroyed. destroyed.
.It Xo Ic up-pane .It Xo Ic up-pane
.Op Fl p Ar pane-index .Op Fl t Ar target-pane
.Op Fl t Ar target-window
.Xc .Xc
.D1 (alias: Ic upp ) .D1 (alias: Ic upp )
Move up a pane. Move up a pane.

22
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.399 2009-07-30 20:21:55 tcunha Exp $ */ /* $Id: tmux.h,v 1.400 2009-07-30 20:45:20 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1022,13 +1022,6 @@ struct cmd_option_data {
char *value; char *value;
}; };
struct cmd_pane_data {
uint64_t chflags;
char *target;
char *arg;
int pane;
};
/* Key binding. */ /* Key binding. */
struct key_binding { struct key_binding {
int key; int key;
@ -1221,6 +1214,8 @@ struct winlink *cmd_find_window(
struct cmd_ctx *, const char *, struct session **); struct cmd_ctx *, const char *, struct session **);
int cmd_find_index( int cmd_find_index(
struct cmd_ctx *, const char *, struct session **); 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_table[];
extern const struct cmd_entry cmd_attach_session_entry; extern const struct cmd_entry cmd_attach_session_entry;
extern const struct cmd_entry cmd_bind_key_entry; extern const struct cmd_entry cmd_bind_key_entry;
@ -1306,6 +1301,7 @@ int cmd_string_parse(const char *, struct cmd_list **, char **);
/* cmd-generic.c */ /* cmd-generic.c */
size_t cmd_prarg(char *, size_t, const char *, char *); 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_WINDOW_USAGE "[-t target-window]"
#define CMD_TARGET_SESSION_USAGE "[-t target-session]" #define CMD_TARGET_SESSION_USAGE "[-t target-session]"
#define CMD_TARGET_CLIENT_USAGE "[-t target-client]" #define CMD_TARGET_CLIENT_USAGE "[-t target-client]"
@ -1313,6 +1309,7 @@ void cmd_target_init(struct cmd *, int);
int cmd_target_parse(struct cmd *, int, char **, char **); int cmd_target_parse(struct cmd *, int, char **, char **);
void cmd_target_free(struct cmd *); void cmd_target_free(struct cmd *);
size_t cmd_target_print(struct cmd *, char *, size_t); 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_WINDOW_USAGE "[-s src-window] [-t dst-window]"
#define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]" #define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]"
#define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]" #define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]"
@ -1320,6 +1317,7 @@ void cmd_srcdst_init(struct cmd *, int);
int cmd_srcdst_parse(struct cmd *, int, char **, char **); int cmd_srcdst_parse(struct cmd *, int, char **, char **);
void cmd_srcdst_free(struct cmd *); void cmd_srcdst_free(struct cmd *);
size_t cmd_srcdst_print(struct cmd *, char *, size_t); 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_WINDOW_USAGE "[-b buffer-index] [-t target-window]"
#define CMD_BUFFER_SESSION_USAGE "[-b buffer-index] [-t target-session]" #define CMD_BUFFER_SESSION_USAGE "[-b buffer-index] [-t target-session]"
#define CMD_BUFFER_CLIENT_USAGE "[-b buffer-index] [-t target-client]" #define CMD_BUFFER_CLIENT_USAGE "[-b buffer-index] [-t target-client]"
@ -1327,6 +1325,7 @@ void cmd_buffer_init(struct cmd *, int);
int cmd_buffer_parse(struct cmd *, int, char **, char **); int cmd_buffer_parse(struct cmd *, int, char **, char **);
void cmd_buffer_free(struct cmd *); void cmd_buffer_free(struct cmd *);
size_t cmd_buffer_print(struct cmd *, char *, size_t); 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_WINDOW_USAGE "[-gu] [-t target-window] option [value]"
#define CMD_OPTION_SESSION_USAGE "[-gu] [-t target-session] option [value]" #define CMD_OPTION_SESSION_USAGE "[-gu] [-t target-session] option [value]"
#define CMD_OPTION_CLIENT_USAGE "[-gu] [-t target-client] option [value]" #define CMD_OPTION_CLIENT_USAGE "[-gu] [-t target-client] option [value]"
@ -1334,13 +1333,6 @@ void cmd_option_init(struct cmd *, int);
int cmd_option_parse(struct cmd *, int, char **, char **); int cmd_option_parse(struct cmd *, int, char **, char **);
void cmd_option_free(struct cmd *); void cmd_option_free(struct cmd *);
size_t cmd_option_print(struct cmd *, char *, size_t); 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 */ /* client.c */
int client_init(char *, struct client_ctx *, int, int); int client_init(char *, struct client_ctx *, int, int);