Sync OpenBSD patchset 725:

Extend the -t:+ and -t:- window targets for next and previous window to
accept an offset such as -t:+2. From Tiago Cunha.
This commit is contained in:
Tiago Cunha 2010-06-22 23:29:05 +00:00
parent 47b335dee7
commit 8d3b726396
4 changed files with 164 additions and 69 deletions

189
cmd.c
View File

@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.139 2010-05-14 14:33:39 tcunha Exp $ */ /* $Id: cmd.c,v 1.140 2010-06-22 23:29:05 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -537,7 +537,7 @@ cmd_lookup_session(const char *name, int *ambiguous)
/* /*
* Lookup a window or return -1 if not found or ambigious. First try as an * Lookup a window or return -1 if not found or ambigious. First try as an
* index and if invalid, use fnmatch or leading prefix. Return NULL but fill in * index and if invalid, use fnmatch or leading prefix. Return NULL but fill in
* idx if the window index is a valid number but there is now window with that * idx if the window index is a valid number but there is no window with that
* index. * index.
*/ */
struct winlink * struct winlink *
@ -659,6 +659,7 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
const char *winptr; const char *winptr;
char *sessptr = NULL; char *sessptr = NULL;
int ambiguous = 0; int ambiguous = 0;
int n = 1;
/* /*
* Find the current session. There must always be a current session, if * Find the current session. There must always be a current session, if
@ -704,11 +705,21 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
wl = s->curw; wl = s->curw;
else if (winptr[0] == '!' && winptr[1] == '\0') else if (winptr[0] == '!' && winptr[1] == '\0')
wl = TAILQ_FIRST(&s->lastw); wl = TAILQ_FIRST(&s->lastw);
else if (winptr[0] == '+' && winptr[1] == '\0') else if (winptr[0] == '+' || winptr[0] == '-') {
wl = winlink_next(s->curw); if (winptr[1] != '\0')
else if (winptr[0] == '-' && winptr[1] == '\0') n = strtonum(winptr + 1, 1, INT_MAX, NULL);
wl = winlink_previous(s->curw); if (n == 0)
else 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
wl = cmd_lookup_window(s, winptr, &ambiguous); wl = cmd_lookup_window(s, winptr, &ambiguous);
if (wl == NULL) if (wl == NULL)
goto not_found; goto not_found;
@ -725,25 +736,41 @@ no_colon:
if (arg[0] == '!' && arg[1] == '\0') { if (arg[0] == '!' && arg[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL) if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found; goto not_found;
} else if (arg[0] == '+' && arg[1] == '\0') { } else if (arg[0] == '+' || arg[0] == '-') {
if ((wl = winlink_next(s->curw)) == NULL) if (arg[1] != '\0')
goto not_found; n = strtonum(arg + 1, 1, INT_MAX, NULL);
} else if (arg[0] == '-' && arg[1] == '\0') { if (n == 0)
if ((wl = winlink_previous(s->curw)) == NULL) wl = cmd_lookup_window(s, arg, &ambiguous);
goto not_found; else {
} else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) { if (arg[0] == '+')
if (ambiguous) wl = winlink_next_by_number(s->curw, n);
goto not_found; else
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL) wl = winlink_previous_by_number(s->curw, n);
goto no_session; /* Search by name before giving up. */
wl = s->curw; if (wl == NULL)
} wl = cmd_lookup_window(s, arg, &ambiguous);
}
if (wl == NULL)
goto lookup_session;
} else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL)
goto lookup_session;
if (sp != NULL) if (sp != NULL)
*sp = s; *sp = s;
return (wl); return (wl);
lookup_session:
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
if (sp != NULL)
*sp = s;
return (s->curw);
no_session: no_session:
if (ambiguous) if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg); ctx->error(ctx, "multiple sessions: %s", arg);
@ -777,6 +804,7 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
const char *winptr; const char *winptr;
char *sessptr = NULL; char *sessptr = NULL;
int idx, ambiguous = 0; int idx, ambiguous = 0;
int n = 1;
/* /*
* Find the current session. There must always be a current session, if * Find the current session. There must always be a current session, if
@ -824,20 +852,23 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL) if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found; goto not_found;
idx = wl->idx; idx = wl->idx;
} else if (winptr[0] == '+' && winptr[1] == '\0') { } else if (winptr[0] == '+' || winptr[0] == '-') {
if (s->curw->idx == INT_MAX) if (winptr[1] != '\0')
goto not_found; n = strtonum(winptr + 1, 1, INT_MAX, NULL);
idx = s->curw->idx + 1; if (winptr[0] == '+' && s->curw->idx == INT_MAX)
} else if (winptr[0] == '-' && winptr[1] == '\0') { idx = cmd_lookup_index(s, winptr, &ambiguous);
if (s->curw->idx == 0) else if (winptr[0] == '-' && s->curw->idx == 0)
goto not_found; idx = cmd_lookup_index(s, winptr, &ambiguous);
idx = s->curw->idx - 1; else if (n == 0)
} else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) { idx = cmd_lookup_index(s, winptr, &ambiguous);
if (ambiguous) else if (winptr[0] == '+')
goto not_found; idx = s->curw->idx + n;
ctx->error(ctx, "invalid index: %s", arg); else
idx = -2; idx = s->curw->idx - n;
} if (idx < 0)
goto invalid_index;
} else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1)
goto invalid_index;
if (sessptr != NULL) if (sessptr != NULL)
xfree(sessptr); xfree(sessptr);
@ -852,27 +883,40 @@ no_colon:
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL) if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found; goto not_found;
idx = wl->idx; idx = wl->idx;
} else if (arg[0] == '+' && arg[1] == '\0') { } else if (arg[0] == '+' || arg[0] == '-') {
if (s->curw->idx == INT_MAX) if (arg[1] != '\0')
goto not_found; n = strtonum(arg + 1, 1, INT_MAX, NULL);
idx = s->curw->idx + 1; if (arg[0] == '+' && s->curw->idx == INT_MAX)
} else if (arg[0] == '-' && arg[1] == '\0') { idx = cmd_lookup_index(s, arg, &ambiguous);
if (s->curw->idx == 0) else if (arg[0] == '-' && s->curw->idx == 0)
goto not_found; idx = cmd_lookup_index(s, arg, &ambiguous);
idx = s->curw->idx - 1; else if (n == 0)
} else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) { idx = cmd_lookup_index(s, arg, &ambiguous);
if (ambiguous) else if (arg[0] == '+')
goto not_found; idx = s->curw->idx + n;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL) else
goto no_session; idx = s->curw->idx - n;
idx = -1; if (idx < 0)
} goto lookup_session;
} else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1)
goto lookup_session;
if (sp != NULL) if (sp != NULL)
*sp = s; *sp = s;
return (idx); return (idx);
lookup_session:
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
if (sp != NULL)
*sp = s;
return (-1);
no_session: no_session:
if (ambiguous) if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg); ctx->error(ctx, "multiple sessions: %s", arg);
@ -882,6 +926,15 @@ no_session:
xfree(sessptr); xfree(sessptr);
return (-2); return (-2);
invalid_index:
if (ambiguous)
goto not_found;
ctx->error(ctx, "invalid index: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (-2);
not_found: not_found:
if (ambiguous) if (ambiguous)
ctx->error(ctx, "multiple windows: %s", arg); ctx->error(ctx, "multiple windows: %s", arg);
@ -906,7 +959,7 @@ cmd_find_pane(struct cmd_ctx *ctx,
struct layout_cell *lc; struct layout_cell *lc;
const char *period, *errstr; const char *period, *errstr;
char *winptr, *paneptr; char *winptr, *paneptr;
u_int idx; u_int idx, n = 1;
/* Get the current session. */ /* Get the current session. */
if ((s = cmd_current_session(ctx)) == NULL) { if ((s = cmd_current_session(ctx)) == NULL) {
@ -938,7 +991,27 @@ cmd_find_pane(struct cmd_ctx *ctx,
paneptr = winptr + (period - arg) + 1; paneptr = winptr + (period - arg) + 1;
if (*paneptr == '\0') if (*paneptr == '\0')
*wpp = wl->window->active; *wpp = wl->window->active;
else { 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 {
idx = strtonum(paneptr, 0, INT_MAX, &errstr); idx = strtonum(paneptr, 0, INT_MAX, &errstr);
if (errstr != NULL) if (errstr != NULL)
goto lookup_string; goto lookup_string;
@ -951,20 +1024,6 @@ cmd_find_pane(struct cmd_ctx *ctx,
return (wl); return (wl);
lookup_string: lookup_string:
/* Try as next or previous pane. */
if (paneptr[0] == '+' && paneptr[1] == '\0') {
*wpp = TAILQ_NEXT(wl->window->active, entry);
if (*wpp == NULL)
*wpp = TAILQ_FIRST(&wl->window->panes);
return (wl);
}
if (paneptr[0] == '-' && paneptr[1] == '\0') {
*wpp = TAILQ_PREV(wl->window->active, window_panes, entry);
if (*wpp == NULL)
*wpp = TAILQ_LAST(&wl->window->panes, window_panes);
return (wl);
}
/* Try pane string description. */ /* Try pane string description. */
if ((lc = layout_find_string(wl->window, paneptr)) == NULL) { if ((lc = layout_find_string(wl->window, paneptr)) == NULL) {
ctx->error(ctx, "can't find pane: %s", paneptr); ctx->error(ctx, "can't find pane: %s", paneptr);

16
tmux.1
View File

@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.258 2010-06-15 20:24:52 tcunha Exp $ .\" $Id: tmux.1,v 1.259 2010-06-22 23:29:05 tcunha Exp $
.\" .\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\" .\"
@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: June 14 2010 $ .Dd $Mdocdate: June 21 2010 $
.Dt TMUX 1 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@ -428,6 +428,18 @@ One of the strings
.Em bottom-right .Em bottom-right
may be used instead of a pane index. may be used instead of a pane index.
.Pp .Pp
The special characters
.Ql +
and
.Ql -
may be followed by an offset, for example:
.Bd -literal -offset indent
select-window -t:+2
.Ed
.Pp
When dealing with a session that doesn't contain sequential window indexes,
they will be correctly skipped.
.Pp
.Ar shell-command .Ar shell-command
arguments are arguments are
.Xr sh 1 .Xr sh 1

4
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.562 2010-06-22 23:26:18 tcunha Exp $ */ /* $Id: tmux.h,v 1.563 2010-06-22 23:29:05 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1798,6 +1798,8 @@ struct winlink *winlink_add(struct winlinks *, struct window *, int);
void winlink_remove(struct winlinks *, struct winlink *); void winlink_remove(struct winlinks *, struct winlink *);
struct winlink *winlink_next(struct winlink *); struct winlink *winlink_next(struct winlink *);
struct winlink *winlink_previous(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);
void winlink_stack_push(struct winlink_stack *, struct winlink *); void winlink_stack_push(struct winlink_stack *, struct winlink *);
void winlink_stack_remove(struct winlink_stack *, struct winlink *); void winlink_stack_remove(struct winlink_stack *, struct winlink *);
int window_index(struct window *, u_int *); int window_index(struct window *, u_int *);

View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.132 2010-05-22 21:56:04 micahcowan Exp $ */ /* $Id: window.c,v 1.133 2010-06-22 23:29:05 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -170,6 +170,28 @@ winlink_previous(struct winlink *wl)
return (RB_PREV(winlinks, wwl, wl)); return (RB_PREV(winlinks, wwl, wl));
} }
struct winlink *
winlink_next_by_number(struct winlink *wl, int n)
{
for (; n > 0; n--) {
if ((wl = RB_NEXT(winlinks, wwl, wl)) == NULL)
break;
}
return (wl);
}
struct winlink *
winlink_previous_by_number(struct winlink *wl, int n)
{
for (; n > 0; n--) {
if ((wl = RB_PREV(winlinks, wwl, wl)) == NULL)
break;
}
return (wl);
}
void void
winlink_stack_push(struct winlink_stack *stack, struct winlink *wl) winlink_stack_push(struct winlink_stack *stack, struct winlink *wl)
{ {