=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/cmd.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- src/usr.bin/tmux/cmd.c 2010/06/21 21:44:09 1.42 +++ src/usr.bin/tmux/cmd.c 2010/07/14 18:37:49 1.43 @@ -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 @@ -117,6 +117,9 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; @@ -1063,6 +1043,25 @@ error: xfree(winptr); 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. */