diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-30 13:45:57 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-30 13:45:57 +0000 |
commit | a4a0375c140fd7522a48e4b1809f29dca5224051 (patch) | |
tree | 0faffaa284757c9a67646630ce43cbbd4eec3483 /usr.bin | |
parent | d7f1f0ac003199ab73991b716bf4a7742b3f4c22 (diff) |
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.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tmux/cmd-break-pane.c | 27 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-clear-history.c | 25 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-generic.c | 92 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-kill-pane.c | 25 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-resize-pane.c | 27 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-select-pane.c | 27 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-swap-pane.c | 265 | ||||
-rw-r--r-- | usr.bin/tmux/cmd.c | 87 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 71 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 22 |
10 files changed, 245 insertions, 423 deletions
diff --git a/usr.bin/tmux/cmd-break-pane.c b/usr.bin/tmux/cmd-break-pane.c index edf2fbf8b87..af754f5ddc7 100644 --- a/usr.bin/tmux/cmd-break-pane.c +++ b/usr.bin/tmux/cmd-break-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-break-pane.c,v 1.4 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-break-pane.c,v 1.5 2009/07/30 13:45:56 nicm Exp $ */ /* * 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 = { "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); } diff --git a/usr.bin/tmux/cmd-clear-history.c b/usr.bin/tmux/cmd-clear-history.c index 922fe25a4fa..3a57bcda72c 100644 --- a/usr.bin/tmux/cmd-clear-history.c +++ b/usr.bin/tmux/cmd-clear-history.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-clear-history.c,v 1.4 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-clear-history.c,v 1.5 2009/07/30 13:45:56 nicm Exp $ */ /* * 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 = { "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); diff --git a/usr.bin/tmux/cmd-generic.c b/usr.bin/tmux/cmd-generic.c index 9eff797b4ff..9fb49993c3c 100644 --- a/usr.bin/tmux/cmd-generic.c +++ b/usr.bin/tmux/cmd-generic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-generic.c,v 1.4 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-generic.c,v 1.5 2009/07/30 13:45:56 nicm Exp $ */ /* * 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); 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); -} diff --git a/usr.bin/tmux/cmd-kill-pane.c b/usr.bin/tmux/cmd-kill-pane.c index c63125ce962..cda85b40e2e 100644 --- a/usr.bin/tmux/cmd-kill-pane.c +++ b/usr.bin/tmux/cmd-kill-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-kill-pane.c,v 1.5 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-kill-pane.c,v 1.6 2009/07/30 13:45:56 nicm Exp $ */ /* * 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 = { "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. */ diff --git a/usr.bin/tmux/cmd-resize-pane.c b/usr.bin/tmux/cmd-resize-pane.c index a494e44aec4..3c284a23a4e 100644 --- a/usr.bin/tmux/cmd-resize-pane.c +++ b/usr.bin/tmux/cmd-resize-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-resize-pane.c,v 1.5 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-resize-pane.c,v 1.6 2009/07/30 13:45:56 nicm Exp $ */ /* * 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 = { "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; diff --git a/usr.bin/tmux/cmd-select-pane.c b/usr.bin/tmux/cmd-select-pane.c index 5e7d3509150..b72c173dc7d 100644 --- a/usr.bin/tmux/cmd-select-pane.c +++ b/usr.bin/tmux/cmd-select-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-select-pane.c,v 1.6 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-select-pane.c,v 1.7 2009/07/30 13:45:56 nicm Exp $ */ /* * 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 = { "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); diff --git a/usr.bin/tmux/cmd-swap-pane.c b/usr.bin/tmux/cmd-swap-pane.c index 7d5437516d8..20c153a0e2c 100644 --- a/usr.bin/tmux/cmd-swap-pane.c +++ b/usr.bin/tmux/cmd-swap-pane.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-swap-pane.c,v 1.7 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-swap-pane.c,v 1.8 2009/07/30 13:45:56 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -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; - - 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; + struct cmd_target_data *data; - 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; - - 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); - 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); + dst_w = dst_wl->window; + + 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 && 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); - - 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; + TAILQ_INSERT_AFTER(&dst_w->panes, tmp_wp, src_wp, entry); + + 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); -} diff --git a/usr.bin/tmux/cmd.c b/usr.bin/tmux/cmd.c index 34de0f97ab6..6e172d70ae2 100644 --- a/usr.bin/tmux/cmd.c +++ b/usr.bin/tmux/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.11 2009/07/29 17:03:16 nicm Exp $ */ +/* $OpenBSD: cmd.c,v 1.12 2009/07/30 13:45:56 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -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); +} diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 0b44ce47326..5cb90728ca4 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.51 2009/07/30 13:31:22 jmc Exp $ +.\" $OpenBSD: tmux.1,v 1.52 2009/07/30 13:45:56 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" @@ -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. diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 806b9f91f11..17c48dc7677 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.64 2009/07/29 14:17:26 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.65 2009/07/30 13:45:56 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -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); |