Make pane/window wrapping more logical (so with 10 windows, +10 from
authornicm <nicm@openbsd.org>
Wed, 14 Jul 2010 18:37:49 +0000 (18:37 +0000)
committernicm <nicm@openbsd.org>
Wed, 14 Jul 2010 18:37:49 +0000 (18:37 +0000)
window 5 stays in the same place), and tidy the code. From Tiago Cunha.

usr.bin/tmux/cmd.c
usr.bin/tmux/tmux.h
usr.bin/tmux/window.c

index 667e26a..68077ac 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd.c,v 1.42 2010/06/21 21:44:09 nicm Exp $ */
+/* $OpenBSD: cmd.c,v 1.43 2010/07/14 18:37:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -117,6 +117,9 @@ struct client       *cmd_lookup_client(const char *);
 struct session *cmd_lookup_session(const char *, int *);
 struct winlink *cmd_lookup_window(struct session *, const char *, int *);
 int             cmd_lookup_index(struct session *, const char *, int *);
+struct winlink *cmd_find_window_offset(const char *, struct session *, int *);
+int             cmd_find_index_offset(const char *, struct session *, int *);
+struct window_pane     *cmd_find_pane_offset(const char *, struct winlink *);
 
 int
 cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
@@ -661,7 +664,6 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
        const char      *winptr;
        char            *sessptr = NULL;
        int              ambiguous = 0;
-       int              n = 1;
 
        /*
         * Find the current session. There must always be a current session, if
@@ -707,21 +709,9 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
                wl = s->curw;
        else if (winptr[0] == '!' && winptr[1] == '\0')
                wl = TAILQ_FIRST(&s->lastw);
-       else if (winptr[0] == '+' || winptr[0] == '-') {
-               if (winptr[1] != '\0')
-                       n = strtonum(winptr + 1, 1, INT_MAX, NULL);
-               if (n == 0)
-                       wl = cmd_lookup_window(s, winptr, &ambiguous);
-               else {
-                       if (winptr[0] == '+')
-                               wl = winlink_next_by_number(s->curw, n);
-                       else
-                               wl = winlink_previous_by_number(s->curw, n);
-                       /* Search by name before giving up. */
-                       if (wl == NULL)
-                               wl = cmd_lookup_window(s, winptr, &ambiguous);
-               }
-       } else
+       else if (winptr[0] == '+' || winptr[0] == '-')
+               wl = cmd_find_window_offset(winptr, s, &ambiguous);
+       else
                wl = cmd_lookup_window(s, winptr, &ambiguous);
        if (wl == NULL)
                goto not_found;
@@ -739,20 +729,7 @@ no_colon:
                if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
                        goto not_found;
        } else if (arg[0] == '+' || arg[0] == '-') {
-               if (arg[1] != '\0')
-                       n = strtonum(arg + 1, 1, INT_MAX, NULL);
-               if (n == 0)
-                       wl = cmd_lookup_window(s, arg, &ambiguous);
-               else {
-                       if (arg[0] == '+')
-                               wl = winlink_next_by_number(s->curw, n);
-                       else
-                               wl = winlink_previous_by_number(s->curw, n);
-                       /* Search by name before giving up. */
-                       if (wl == NULL)
-                               wl = cmd_lookup_window(s, arg, &ambiguous);
-               }
-               if (wl == NULL)
+               if ((wl = cmd_find_window_offset(arg, s, &ambiguous)) == NULL)
                        goto lookup_session;
        } else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL)
                goto lookup_session;
@@ -792,6 +769,26 @@ not_found:
        return (NULL);
 }
 
+struct winlink *
+cmd_find_window_offset(const char *winptr, struct session *s, int *ambiguous)
+{
+       struct winlink  *wl;
+       int              offset = 1;
+
+       if (winptr[1] != '\0')
+               offset = strtonum(winptr + 1, 1, INT_MAX, NULL);
+       if (offset == 0)
+               wl = cmd_lookup_window(s, winptr, ambiguous);
+       else {
+               if (winptr[0] == '+')
+                       wl = winlink_next_by_number(s->curw, s, offset);
+               else
+                       wl = winlink_previous_by_number(s->curw, s, offset);
+       }
+
+       return (wl);
+}
+
 /*
  * Find the target session and window index, whether or not it exists in the
  * session. Return -2 on error or -1 if no window index is specified. This is
@@ -806,7 +803,6 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
        const char      *winptr;
        char            *sessptr = NULL;
        int              idx, ambiguous = 0;
-       int              n = 1;
 
        /*
         * Find the current session. There must always be a current session, if
@@ -855,19 +851,7 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
                        goto not_found;
                idx = wl->idx;
        } else if (winptr[0] == '+' || winptr[0] == '-') {
-               if (winptr[1] != '\0')
-                       n = strtonum(winptr + 1, 1, INT_MAX, NULL);
-               if (winptr[0] == '+' && s->curw->idx == INT_MAX)
-                       idx = cmd_lookup_index(s, winptr, &ambiguous);
-               else if (winptr[0] == '-' && s->curw->idx == 0)
-                       idx = cmd_lookup_index(s, winptr, &ambiguous);
-               else if (n == 0)
-                       idx = cmd_lookup_index(s, winptr, &ambiguous);
-               else if (winptr[0] == '+')
-                       idx = s->curw->idx + n;
-               else
-                       idx = s->curw->idx - n;
-               if (idx < 0)
+               if ((idx = cmd_find_index_offset(winptr, s, &ambiguous)) < 0)
                        goto invalid_index;
        } else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1)
                goto invalid_index;
@@ -886,19 +870,7 @@ no_colon:
                        goto not_found;
                idx = wl->idx;
        } else if (arg[0] == '+' || arg[0] == '-') {
-               if (arg[1] != '\0')
-                       n = strtonum(arg + 1, 1, INT_MAX, NULL);
-               if (arg[0] == '+' && s->curw->idx == INT_MAX)
-                       idx = cmd_lookup_index(s, arg, &ambiguous);
-               else if (arg[0] == '-' && s->curw->idx == 0)
-                       idx = cmd_lookup_index(s, arg, &ambiguous);
-               else if (n == 0)
-                       idx = cmd_lookup_index(s, arg, &ambiguous);
-               else if (arg[0] == '+')
-                       idx = s->curw->idx + n;
-               else
-                       idx = s->curw->idx - n;
-               if (idx < 0)
+               if ((idx = cmd_find_index_offset(arg, s, &ambiguous)) < 0)
                        goto lookup_session;
        } else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1)
                goto lookup_session;
@@ -947,6 +919,32 @@ not_found:
        return (-2);
 }
 
+int
+cmd_find_index_offset(const char *winptr, struct session *s, int *ambiguous)
+{
+       int     idx, offset = 1;
+
+       if (winptr[1] != '\0')
+               offset = strtonum(winptr + 1, 1, INT_MAX, NULL);
+       if (offset == 0)
+               idx = cmd_lookup_index(s, winptr, ambiguous);
+       else {
+               if (winptr[0] == '+') {
+                       if (s->curw->idx == INT_MAX)
+                               idx = cmd_lookup_index(s, winptr, ambiguous);
+                       else
+                               idx = s->curw->idx + offset;
+               } else {
+                       if (s->curw->idx == 0)
+                               idx = cmd_lookup_index(s, winptr, ambiguous);
+                       else
+                               idx = s->curw->idx - offset;
+               }
+       }
+
+       return (idx);
+}
+
 /*
  * 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 .,
@@ -961,7 +959,7 @@ cmd_find_pane(struct cmd_ctx *ctx,
        struct layout_cell      *lc;
        const char              *period, *errstr;
        char                    *winptr, *paneptr;
-       u_int                    idx, n = 1;
+       u_int                    idx;
 
        /* Get the current session. */
        if ((s = cmd_current_session(ctx)) == NULL) {
@@ -993,27 +991,9 @@ cmd_find_pane(struct cmd_ctx *ctx,
        paneptr = winptr + (period - arg) + 1;
        if (*paneptr == '\0')
                *wpp = wl->window->active;
-       else if (paneptr[0] == '+' || paneptr[0] == '-') {
-               if (paneptr[1] != '\0')
-                       n = strtonum(paneptr + 1, 1, INT_MAX, NULL);
-               idx = window_pane_index(wl->window, wl->window->active);
-               if (paneptr[0] == '+' && idx == INT_MAX)
-                       *wpp = TAILQ_FIRST(&wl->window->panes);
-               else if (paneptr[0] == '-' && idx == 0)
-                       *wpp = TAILQ_LAST(&wl->window->panes, window_panes);
-               else if (n == 0)
-                       *wpp = wl->window->active;
-               else if (paneptr[0] == '+')
-                       *wpp = window_pane_at_index(wl->window, idx + n);
-               else
-                       *wpp = window_pane_at_index(wl->window, idx - n);
-               if (paneptr[0] == '+' && *wpp == NULL)
-                       *wpp = TAILQ_FIRST(&wl->window->panes);
-               else if (paneptr[0] == '-' && *wpp == NULL)
-                       *wpp = TAILQ_LAST(&wl->window->panes, window_panes);
-               else if (*wpp == NULL)
-                       goto error;
-       } else {
+       else if (paneptr[0] == '+' || paneptr[0] == '-')
+               *wpp = cmd_find_pane_offset(paneptr, wl);
+       else {
                idx = strtonum(paneptr, 0, INT_MAX, &errstr);
                if (errstr != NULL)
                        goto lookup_string;
@@ -1065,6 +1045,25 @@ error:
        return (NULL);
 }
 
+struct window_pane *
+cmd_find_pane_offset(const char *paneptr, struct winlink *wl)
+{
+       struct window           *w = wl->window;
+       struct window_pane      *wp = w->active;
+       u_int                    offset = 1;
+
+       if (paneptr[1] != '\0')
+               offset = strtonum(paneptr + 1, 1, INT_MAX, NULL);
+       if (offset > 0) {
+               if (paneptr[0] == '+')
+                       wp = window_pane_next_by_number(w, wp, offset);
+               else
+                       wp = window_pane_previous_by_number(w, wp, offset);
+       }
+
+       return (wp);
+}
+
 /* Replace the first %% or %idx in template by s. */
 char *
 cmd_template_replace(char *template, const char *s, int idx)
index 66b952c..aad791c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.234 2010/07/11 17:06:45 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.235 2010/07/14 18:37:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1825,8 +1825,10 @@ struct winlink   *winlink_add(struct winlinks *, struct window *, int);
 void            winlink_remove(struct winlinks *, struct winlink *);
 struct winlink *winlink_next(struct winlink *);
 struct winlink *winlink_previous(struct winlink *);
-struct winlink *winlink_next_by_number(struct winlink *, int);
-struct winlink *winlink_previous_by_number(struct winlink *, int);
+struct winlink *winlink_next_by_number(struct winlink *, struct session *,
+                    int);
+struct winlink *winlink_previous_by_number(struct winlink *, struct session *,
+                    int);
 void            winlink_stack_push(struct winlink_stack *, struct winlink *);
 void            winlink_stack_remove(struct winlink_stack *, struct winlink *);
 int             window_index(struct window *, u_int *);
@@ -1841,6 +1843,10 @@ struct window_pane *window_add_pane(struct window *, u_int);
 void            window_resize(struct window *, u_int, u_int);
 void            window_remove_pane(struct window *, struct window_pane *);
 struct window_pane *window_pane_at_index(struct window *, u_int);
+struct window_pane *window_pane_next_by_number(struct window *,
+                       struct window_pane *, u_int);
+struct window_pane *window_pane_previous_by_number(struct window *,
+                       struct window_pane *, u_int);
 u_int           window_pane_index(struct window *, struct window_pane *);
 u_int           window_count_panes(struct window *);
 void            window_destroy_panes(struct window *);
index 48e4e64..cfb0c20 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window.c,v 1.52 2010/06/21 01:46:36 nicm Exp $ */
+/* $OpenBSD: window.c,v 1.53 2010/07/14 18:37:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -173,22 +173,22 @@ winlink_previous(struct winlink *wl)
 }
 
 struct winlink *
-winlink_next_by_number(struct winlink *wl, int n)
+winlink_next_by_number(struct winlink *wl, struct session *s, int n)
 {
        for (; n > 0; n--) {
                if ((wl = RB_NEXT(winlinks, wwl, wl)) == NULL)
-                       break;
+                       wl = RB_MIN(winlinks, &s->windows);
        }
 
        return (wl);
 }
 
 struct winlink *
-winlink_previous_by_number(struct winlink *wl, int n)
+winlink_previous_by_number(struct winlink *wl, struct session *s, int n)
 {
        for (; n > 0; n--) {
                if ((wl = RB_PREV(winlinks, wwl, wl)) == NULL)
-                       break;
+                       wl = RB_MAX(winlinks, &s->windows);
        }
 
        return (wl);
@@ -391,6 +391,29 @@ window_pane_at_index(struct window *w, u_int idx)
        return (NULL);
 }
 
+struct window_pane *
+window_pane_next_by_number(struct window *w, struct window_pane *wp, u_int n)
+{
+       for (; n > 0; n--) {
+               if ((wp = TAILQ_NEXT(wp, entry)) == NULL)
+                       wp = TAILQ_FIRST(&w->panes);
+       }
+
+       return (wp);
+}
+
+struct window_pane *
+window_pane_previous_by_number(struct window *w, struct window_pane *wp,
+    u_int n)
+{
+       for (; n > 0; n--) {
+               if ((wp = TAILQ_PREV(wp, window_panes, entry)) == NULL)
+                       wp = TAILQ_LAST(&w->panes, window_panes);
+       }
+
+       return (wp);
+}
+
 u_int
 window_pane_index(struct window *w, struct window_pane *wp)
 {