mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-23 16:43:11 +01:00
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.
This commit is contained in:
parent
b9c873cdaa
commit
43355fa75c
157
cmd.c
157
cmd.c
@ -117,6 +117,9 @@ struct client *cmd_lookup_client(const char *);
|
|||||||
struct session *cmd_lookup_session(const char *, int *);
|
struct session *cmd_lookup_session(const char *, int *);
|
||||||
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
|
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
|
||||||
int cmd_lookup_index(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
|
int
|
||||||
cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
|
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;
|
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
|
||||||
@ -707,21 +709,9 @@ 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[0] == '-') {
|
else if (winptr[0] == '+' || winptr[0] == '-')
|
||||||
if (winptr[1] != '\0')
|
wl = cmd_find_window_offset(winptr, s, &ambiguous);
|
||||||
n = strtonum(winptr + 1, 1, INT_MAX, NULL);
|
else
|
||||||
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
|
|
||||||
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;
|
||||||
@ -739,20 +729,7 @@ no_colon:
|
|||||||
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[0] == '-') {
|
} else if (arg[0] == '+' || arg[0] == '-') {
|
||||||
if (arg[1] != '\0')
|
if ((wl = cmd_find_window_offset(arg, s, &ambiguous)) == NULL)
|
||||||
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)
|
|
||||||
goto lookup_session;
|
goto lookup_session;
|
||||||
} else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL)
|
} else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL)
|
||||||
goto lookup_session;
|
goto lookup_session;
|
||||||
@ -792,6 +769,26 @@ not_found:
|
|||||||
return (NULL);
|
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
|
* 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
|
* 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;
|
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
|
||||||
@ -855,19 +851,7 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
|
|||||||
goto not_found;
|
goto not_found;
|
||||||
idx = wl->idx;
|
idx = wl->idx;
|
||||||
} else if (winptr[0] == '+' || winptr[0] == '-') {
|
} else if (winptr[0] == '+' || winptr[0] == '-') {
|
||||||
if (winptr[1] != '\0')
|
if ((idx = cmd_find_index_offset(winptr, s, &ambiguous)) < 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)
|
|
||||||
goto invalid_index;
|
goto invalid_index;
|
||||||
} else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1)
|
} else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1)
|
||||||
goto invalid_index;
|
goto invalid_index;
|
||||||
@ -886,19 +870,7 @@ no_colon:
|
|||||||
goto not_found;
|
goto not_found;
|
||||||
idx = wl->idx;
|
idx = wl->idx;
|
||||||
} else if (arg[0] == '+' || arg[0] == '-') {
|
} else if (arg[0] == '+' || arg[0] == '-') {
|
||||||
if (arg[1] != '\0')
|
if ((idx = cmd_find_index_offset(arg, s, &ambiguous)) < 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)
|
|
||||||
goto lookup_session;
|
goto lookup_session;
|
||||||
} else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1)
|
} else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1)
|
||||||
goto lookup_session;
|
goto lookup_session;
|
||||||
@ -947,6 +919,32 @@ not_found:
|
|||||||
return (-2);
|
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
|
* 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 .,
|
* 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;
|
struct layout_cell *lc;
|
||||||
const char *period, *errstr;
|
const char *period, *errstr;
|
||||||
char *winptr, *paneptr;
|
char *winptr, *paneptr;
|
||||||
u_int idx, n = 1;
|
u_int idx;
|
||||||
|
|
||||||
/* Get the current session. */
|
/* Get the current session. */
|
||||||
if ((s = cmd_current_session(ctx)) == NULL) {
|
if ((s = cmd_current_session(ctx)) == NULL) {
|
||||||
@ -993,27 +991,9 @@ 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 if (paneptr[0] == '+' || paneptr[0] == '-') {
|
else if (paneptr[0] == '+' || paneptr[0] == '-')
|
||||||
if (paneptr[1] != '\0')
|
*wpp = cmd_find_pane_offset(paneptr, wl);
|
||||||
n = strtonum(paneptr + 1, 1, INT_MAX, NULL);
|
else {
|
||||||
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;
|
||||||
@ -1065,6 +1045,25 @@ error:
|
|||||||
return (NULL);
|
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. */
|
/* Replace the first %% or %idx in template by s. */
|
||||||
char *
|
char *
|
||||||
cmd_template_replace(char *template, const char *s, int idx)
|
cmd_template_replace(char *template, const char *s, int idx)
|
||||||
|
10
tmux.h
10
tmux.h
@ -1825,8 +1825,10 @@ 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_next_by_number(struct winlink *, struct session *,
|
||||||
struct winlink *winlink_previous_by_number(struct winlink *, int);
|
int);
|
||||||
|
struct winlink *winlink_previous_by_number(struct winlink *, struct session *,
|
||||||
|
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 *);
|
||||||
@ -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_resize(struct window *, u_int, u_int);
|
||||||
void window_remove_pane(struct window *, struct window_pane *);
|
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_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_pane_index(struct window *, struct window_pane *);
|
||||||
u_int window_count_panes(struct window *);
|
u_int window_count_panes(struct window *);
|
||||||
void window_destroy_panes(struct window *);
|
void window_destroy_panes(struct window *);
|
||||||
|
31
window.c
31
window.c
@ -173,22 +173,22 @@ winlink_previous(struct winlink *wl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct winlink *
|
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--) {
|
for (; n > 0; n--) {
|
||||||
if ((wl = RB_NEXT(winlinks, wwl, wl)) == NULL)
|
if ((wl = RB_NEXT(winlinks, wwl, wl)) == NULL)
|
||||||
break;
|
wl = RB_MIN(winlinks, &s->windows);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (wl);
|
return (wl);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct winlink *
|
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--) {
|
for (; n > 0; n--) {
|
||||||
if ((wl = RB_PREV(winlinks, wwl, wl)) == NULL)
|
if ((wl = RB_PREV(winlinks, wwl, wl)) == NULL)
|
||||||
break;
|
wl = RB_MAX(winlinks, &s->windows);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (wl);
|
return (wl);
|
||||||
@ -391,6 +391,29 @@ window_pane_at_index(struct window *w, u_int idx)
|
|||||||
return (NULL);
|
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
|
u_int
|
||||||
window_pane_index(struct window *w, struct window_pane *wp)
|
window_pane_index(struct window *w, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user