summaryrefslogtreecommitdiffstats
path: root/cmd.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2009-07-30 13:45:56 +0000
committerNicholas Marriott <nicm@openbsd.org>2009-07-30 13:45:56 +0000
commit071494d8faff83287088bbdcc38db1414c0123b9 (patch)
tree1f5caa38dbc76cf1ece9c51e63de2a8f25ddee2c /cmd.c
parenta87228b4ff85087600b0a077cb88b41506a60ff1 (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 'cmd.c')
-rw-r--r--cmd.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/cmd.c b/cmd.c
index 820521d0..31b80b50 100644
--- a/cmd.c
+++ b/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);
+}