From 385f8052714931a7f438da985f27921026059b92 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 14 Jul 2010 18:37:49 +0000 Subject: [PATCH] Make pane/window wrapping more logical (so with 10 windows, +10 from window 5 stays in the same place), and tidy the code. From Tiago Cunha. --- usr.bin/tmux/cmd.c | 159 +++++++++++++++++++++--------------------- usr.bin/tmux/tmux.h | 12 +++- usr.bin/tmux/window.c | 33 +++++++-- 3 files changed, 116 insertions(+), 88 deletions(-) diff --git a/usr.bin/tmux/cmd.c b/usr.bin/tmux/cmd.c index 667e26ad262..68077acf865 100644 --- a/usr.bin/tmux/cmd.c +++ b/usr.bin/tmux/cmd.c @@ -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 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) diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 66b952c263d..aad791c6ff0 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -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 @@ -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 *); diff --git a/usr.bin/tmux/window.c b/usr.bin/tmux/window.c index 48e4e645ab5..cfb0c200902 100644 --- a/usr.bin/tmux/window.c +++ b/usr.bin/tmux/window.c @@ -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 @@ -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) { -- 2.20.1