diff options
Diffstat (limited to 'cmd.c')
-rw-r--r-- | cmd.c | 937 |
1 files changed, 2 insertions, 935 deletions
@@ -115,24 +115,6 @@ const struct cmd_entry *cmd_table[] = { NULL }; -ARRAY_DECL(client_list, struct client *); -ARRAY_DECL(sessionslist, struct session *); - -int cmd_session_better(struct session *, struct session *, int); -struct session *cmd_choose_session_list(struct sessionslist *); -struct session *cmd_choose_session(int); -struct client *cmd_choose_client(struct client_list *); -struct client *cmd_lookup_client(const char *); -struct session *cmd_lookup_session(struct cmd_q *, 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_lookup_winlink_windowid(struct session *, const char *); -struct session *cmd_window_session(struct cmd_q *, struct window *, - struct winlink **); -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) { @@ -331,183 +313,6 @@ cmd_print(struct cmd *cmd, char *buf, size_t len) return (off); } -/* - * Figure out the current session. Use: 1) the current session, if the command - * context has one; 2) the most recently used session containing the pty of the - * calling client, if any; 3) the session specified in the TMUX variable from - * the environment (as passed from the client); 4) the most recently used - * session from all sessions. - */ -struct session * -cmd_current_session(struct cmd_q *cmdq, int prefer_unattached) -{ - struct client *c = cmdq->client; - struct session *s; - struct sessionslist ss; - struct winlink *wl; - struct window_pane *wp; - const char *path; - int found; - - /* Try the queue session. */ - if (c != NULL && c->session != NULL) - return (c->session); - - /* - * If the name of the calling client's pty is known, build a list of - * the sessions that contain it and if any choose either the first or - * the newest. - */ - path = c == NULL ? NULL : c->tty.path; - if (path != NULL) { - ARRAY_INIT(&ss); - RB_FOREACH(s, sessions, &sessions) { - found = 0; - RB_FOREACH(wl, winlinks, &s->windows) { - TAILQ_FOREACH(wp, &wl->window->panes, entry) { - if (strcmp(wp->tty, path) == 0) { - found = 1; - break; - } - } - if (found) - break; - } - if (found) - ARRAY_ADD(&ss, s); - } - - s = cmd_choose_session_list(&ss); - ARRAY_FREE(&ss); - if (s != NULL) - return (s); - } - - return (cmd_choose_session(prefer_unattached)); -} - -/* Is this session better? */ -int -cmd_session_better(struct session *s, struct session *best, - int prefer_unattached) -{ - if (best == NULL) - return (1); - if (prefer_unattached) { - if (!(best->flags & SESSION_UNATTACHED) && - (s->flags & SESSION_UNATTACHED)) - return (1); - else if ((best->flags & SESSION_UNATTACHED) && - !(s->flags & SESSION_UNATTACHED)) - return (0); - } - return (timercmp(&s->activity_time, &best->activity_time, >)); -} - -/* - * Find the most recently used session, preferring unattached if the flag is - * set. - */ -struct session * -cmd_choose_session(int prefer_unattached) -{ - struct session *s, *best; - - best = NULL; - RB_FOREACH(s, sessions, &sessions) { - if (cmd_session_better(s, best, prefer_unattached)) - best = s; - } - return (best); -} - -/* Find the most recently used session from a list. */ -struct session * -cmd_choose_session_list(struct sessionslist *ss) -{ - struct session *s, *sbest; - struct timeval *tv = NULL; - u_int i; - - sbest = NULL; - for (i = 0; i < ARRAY_LENGTH(ss); i++) { - if ((s = ARRAY_ITEM(ss, i)) == NULL) - continue; - - if (tv == NULL || timercmp(&s->activity_time, tv, >)) { - sbest = s; - tv = &s->activity_time; - } - } - - return (sbest); -} - -/* - * Find the current client. First try the current client if set, then pick the - * most recently used of the clients attached to the current session if any, - * then of all clients. - */ -struct client * -cmd_current_client(struct cmd_q *cmdq) -{ - struct session *s; - struct client *c; - struct client_list cc; - - if (cmdq->client != NULL && cmdq->client->session != NULL) - return (cmdq->client); - - /* - * No current client set. Find the current session and return the - * newest of its clients. - */ - s = cmd_current_session(cmdq, 0); - if (s != NULL && !(s->flags & SESSION_UNATTACHED)) { - ARRAY_INIT(&cc); - TAILQ_FOREACH(c, &clients, entry) { - if (s == c->session) - ARRAY_ADD(&cc, c); - } - - c = cmd_choose_client(&cc); - ARRAY_FREE(&cc); - if (c != NULL) - return (c); - } - - ARRAY_INIT(&cc); - TAILQ_FOREACH(c, &clients, entry) - ARRAY_ADD(&cc, c); - c = cmd_choose_client(&cc); - ARRAY_FREE(&cc); - return (c); -} - -/* Choose the most recently used client from a list. */ -struct client * -cmd_choose_client(struct client_list *cc) -{ - struct client *c, *cbest; - struct timeval *tv = NULL; - u_int i; - - cbest = NULL; - for (i = 0; i < ARRAY_LENGTH(cc); i++) { - if ((c = ARRAY_ITEM(cc, i)) == NULL) - continue; - if (c->session == NULL) - continue; - - if (tv == NULL || timercmp(&c->activity_time, tv, >)) { - cbest = c; - tv = &c->activity_time; - } - } - - return (cbest); -} - /* Adjust current mouse position for a pane. */ int cmd_mouse_at(struct window_pane *wp, struct mouse_event *m, u_int *xp, @@ -559,7 +364,8 @@ cmd_mouse_window(struct mouse_event *m, struct session **sp) /* Get current mouse pane if any. */ struct window_pane * -cmd_mouse_pane(struct mouse_event *m, struct session **sp, struct winlink **wlp) +cmd_mouse_pane(struct mouse_event *m, struct session **sp, + struct winlink **wlp) { struct winlink *wl; struct window_pane *wp; @@ -576,745 +382,6 @@ cmd_mouse_pane(struct mouse_event *m, struct session **sp, struct winlink **wlp) return (wp); } -/* Find the target client or report an error and return NULL. */ -struct client * -cmd_find_client(struct cmd_q *cmdq, const char *arg, int quiet) -{ - struct client *c; - char *tmparg; - size_t arglen; - - /* A NULL argument means the current client. */ - if (arg == NULL) { - c = cmd_current_client(cmdq); - if (c == NULL && !quiet) - cmdq_error(cmdq, "no clients"); - return (c); - } - tmparg = xstrdup(arg); - - /* Trim a single trailing colon if any. */ - arglen = strlen(tmparg); - if (arglen != 0 && tmparg[arglen - 1] == ':') - tmparg[arglen - 1] = '\0'; - - /* Find the client, if any. */ - c = cmd_lookup_client(tmparg); - - /* If no client found, report an error. */ - if (c == NULL && !quiet) - cmdq_error(cmdq, "client not found: %s", tmparg); - - free(tmparg); - return (c); -} - -/* - * Lookup a client by device path. Either of a full match and a match without a - * leading _PATH_DEV ("/dev/") is accepted. - */ -struct client * -cmd_lookup_client(const char *name) -{ - struct client *c; - const char *path; - - TAILQ_FOREACH(c, &clients, entry) { - if (c->session == NULL || c->tty.path == NULL) - continue; - path = c->tty.path; - - /* Check for exact matches. */ - if (strcmp(name, path) == 0) - return (c); - - /* Check without leading /dev if present. */ - if (strncmp(path, _PATH_DEV, (sizeof _PATH_DEV) - 1) != 0) - continue; - if (strcmp(name, path + (sizeof _PATH_DEV) - 1) == 0) - return (c); - } - - return (NULL); -} - -/* Lookup a session by name. If no session is found, NULL is returned. */ -struct session * -cmd_lookup_session(struct cmd_q *cmdq, const char *name, int *ambiguous) -{ - struct session *s, *sfound; - struct window *w; - struct window_pane *wp; - - *ambiguous = 0; - - /* Look for $id first. */ - if ((s = session_find_by_id_str(name)) != NULL) - return (s); - - /* Try as pane or window id. */ - if ((wp = window_pane_find_by_id_str(name)) != NULL) - return (cmd_window_session(cmdq, wp->window, NULL)); - if ((w = window_find_by_id_str(name)) != NULL) - return (cmd_window_session(cmdq, w, NULL)); - - /* - * Look for matches. First look for exact matches - session names must - * be unique so an exact match can't be ambigious and can just be - * returned. - */ - if ((s = session_find(name)) != NULL) - return (s); - - /* - * Otherwise look for partial matches, returning early if it is found to - * be ambiguous. - */ - sfound = NULL; - RB_FOREACH(s, sessions, &sessions) { - if (strncmp(name, s->name, strlen(name)) == 0 || - fnmatch(name, s->name, 0) == 0) { - if (sfound != NULL) { - *ambiguous = 1; - return (NULL); - } - sfound = s; - } - } - return (sfound); -} - -/* - * 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 - * idx if the window index is a valid number but there is no window with that - * index. - */ -struct winlink * -cmd_lookup_window(struct session *s, const char *name, int *ambiguous) -{ - struct winlink *wl, *wlfound; - struct window *w; - struct window_pane *wp; - const char *errstr; - u_int idx; - - *ambiguous = 0; - - /* Try as pane or window id. */ - if ((wl = cmd_lookup_winlink_windowid(s, name)) != NULL) - return (wl); - - /* Lookup as pane or window id. */ - if ((wp = window_pane_find_by_id_str(name)) != NULL) { - wl = winlink_find_by_window(&s->windows, wp->window); - if (wl != NULL) - return (wl); - } - if ((w = window_find_by_id_str(name)) != NULL) { - wl = winlink_find_by_window(&s->windows, w); - if (wl != NULL) - return (wl); - } - - /* First see if this is a valid window index in this session. */ - idx = strtonum(name, 0, INT_MAX, &errstr); - if (errstr == NULL) { - if ((wl = winlink_find_by_index(&s->windows, idx)) != NULL) - return (wl); - } - - /* Look for exact matches, error if more than one. */ - wlfound = NULL; - RB_FOREACH(wl, winlinks, &s->windows) { - if (strcmp(name, wl->window->name) == 0) { - if (wlfound != NULL) { - *ambiguous = 1; - return (NULL); - } - wlfound = wl; - } - } - if (wlfound != NULL) - return (wlfound); - - /* Now look for pattern matches, again error if multiple. */ - wlfound = NULL; - RB_FOREACH(wl, winlinks, &s->windows) { - if (strncmp(name, wl->window->name, strlen(name)) == 0 || - fnmatch(name, wl->window->name, 0) == 0) { - if (wlfound != NULL) { - *ambiguous = 1; - return (NULL); - } - wlfound = wl; - } - } - if (wlfound != NULL) - return (wlfound); - - return (NULL); -} - -/* - * Find a window index - if the window doesn't exist, check if it is a - * potential index and return it anyway. - */ -int -cmd_lookup_index(struct session *s, const char *name, int *ambiguous) -{ - struct winlink *wl; - const char *errstr; - u_int idx; - - idx = strtonum(name, 0, INT_MAX, &errstr); - if (errstr == NULL) - return (idx); - - if ((wl = cmd_lookup_window(s, name, ambiguous)) != NULL) - return (wl->idx); - if (*ambiguous) - return (-1); - - return (-1); -} - -/* Lookup window id in a session. An initial @ means a window id. */ -struct winlink * -cmd_lookup_winlink_windowid(struct session *s, const char *arg) -{ - const char *errstr; - u_int windowid; - - if (*arg != '@') - return (NULL); - - windowid = strtonum(arg + 1, 0, UINT_MAX, &errstr); - if (errstr != NULL) - return (NULL); - return (winlink_find_by_window_id(&s->windows, windowid)); -} - -/* Find session and winlink for window. */ -struct session * -cmd_window_session(struct cmd_q *cmdq, struct window *w, struct winlink **wlp) -{ - struct session *s; - struct sessionslist ss; - struct winlink *wl; - - /* If this window is in the current session, return that winlink. */ - s = cmd_current_session(cmdq, 0); - if (s != NULL) { - wl = winlink_find_by_window(&s->windows, w); - if (wl != NULL) { - if (wlp != NULL) - *wlp = wl; - return (s); - } - } - - /* Otherwise choose from all sessions with this window. */ - ARRAY_INIT(&ss); - RB_FOREACH(s, sessions, &sessions) { - if (winlink_find_by_window(&s->windows, w) != NULL) - ARRAY_ADD(&ss, s); - } - s = cmd_choose_session_list(&ss); - ARRAY_FREE(&ss); - if (wlp != NULL) - *wlp = winlink_find_by_window(&s->windows, w); - return (s); -} - -/* Find the target session or report an error and return NULL. */ -struct session * -cmd_find_session(struct cmd_q *cmdq, const char *arg, int prefer_unattached) -{ - struct session *s; - struct client *c; - char *tmparg; - size_t arglen; - int ambiguous; - - /* A NULL argument means the current session. */ - if (arg == NULL) { - if ((s = cmd_current_session(cmdq, prefer_unattached)) == NULL) - cmdq_error(cmdq, "can't establish current session"); - return (s); - } - - /* Trim a single trailing colon if any. */ - tmparg = xstrdup(arg); - arglen = strlen(tmparg); - if (arglen != 0 && tmparg[arglen - 1] == ':') - tmparg[arglen - 1] = '\0'; - - /* An empty session name is the current session. */ - if (*tmparg == '\0') { - free(tmparg); - if ((s = cmd_current_session(cmdq, prefer_unattached)) == NULL) - cmdq_error(cmdq, "can't establish current session"); - return (s); - } - - /* Find the session, if any. */ - s = cmd_lookup_session(cmdq, tmparg, &ambiguous); - - /* If it doesn't, try to match it as a client. */ - if (s == NULL && (c = cmd_lookup_client(tmparg)) != NULL) - s = c->session; - - /* If no session found, report an error. */ - if (s == NULL) { - if (ambiguous) - cmdq_error(cmdq, "more than one session: %s", tmparg); - else - cmdq_error(cmdq, "session not found: %s", tmparg); - } - - free(tmparg); - return (s); -} - -/* Find the target session and window or report an error and return NULL. */ -struct winlink * -cmd_find_window(struct cmd_q *cmdq, const char *arg, struct session **sp) -{ - struct session *s; - struct winlink *wl; - const char *winptr; - char *sessptr = NULL; - int ambiguous = 0; - - /* - * Find the current session. There must always be a current session, if - * it can't be found, report an error. - */ - if ((s = cmd_current_session(cmdq, 0)) == NULL) { - cmdq_error(cmdq, "can't establish current session"); - return (NULL); - } - - /* A NULL argument means the current session and window. */ - if (arg == NULL) { - if (sp != NULL) - *sp = s; - return (s->curw); - } - - /* Time to look at the argument. If it is empty, that is an error. */ - if (*arg == '\0') - goto not_found; - - /* Find the separating colon and split into window and session. */ - winptr = strchr(arg, ':'); - if (winptr == NULL) - goto no_colon; - winptr++; /* skip : */ - sessptr = xstrdup(arg); - *strchr(sessptr, ':') = '\0'; - - /* Try to lookup the session if present. */ - if (*sessptr != '\0') { - if ((s = cmd_lookup_session(cmdq, sessptr, &ambiguous)) == NULL) - goto no_session; - } - if (sp != NULL) - *sp = s; - - /* - * Then work out the window. An empty string is the current window, - * otherwise try special cases then to look it up in the session. - */ - if (*winptr == '\0') - wl = s->curw; - else if (winptr[0] == '!' && winptr[1] == '\0') - wl = TAILQ_FIRST(&s->lastw); - else if (winptr[0] == '^' && winptr[1] == '\0') - wl = RB_MIN(winlinks, &s->windows); - else if (winptr[0] == '$' && winptr[1] == '\0') - wl = RB_MAX(winlinks, &s->windows); - 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; - - if (sessptr != NULL) - free(sessptr); - return (wl); - -no_colon: - /* - * No colon in the string, first try special cases, then as a window - * and lastly as a session. - */ - if (arg[0] == '=' && arg[1] == '\0') { - if ((wl = cmd_mouse_window(&cmdq->item->mouse, &s)) == NULL) { - cmdq_error(cmdq, "no mouse target"); - goto error; - } - } else if (arg[0] == '!' && arg[1] == '\0') { - if ((wl = TAILQ_FIRST(&s->lastw)) == NULL) - goto not_found; - } else if (arg[0] == '+' || arg[0] == '-') { - 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; - - if (sp != NULL) - *sp = s; - - return (wl); - -lookup_session: - if (ambiguous) - goto not_found; - if (*arg != '\0' && - (s = cmd_lookup_session(cmdq, arg, &ambiguous)) == NULL) - goto no_session; - - if (sp != NULL) - *sp = s; - - return (s->curw); - -no_session: - if (ambiguous) - cmdq_error(cmdq, "multiple sessions: %s", arg); - else - cmdq_error(cmdq, "session not found: %s", arg); - goto error; - -not_found: - if (ambiguous) - cmdq_error(cmdq, "multiple windows: %s", arg); - else - cmdq_error(cmdq, "window not found: %s", arg); - goto error; - -error: - free(sessptr); - 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 - * used when parsing an argument for a window target that may not exist (for - * example if it is going to be created). - */ -int -cmd_find_index(struct cmd_q *cmdq, const char *arg, struct session **sp) -{ - struct session *s; - struct winlink *wl; - const char *winptr; - char *sessptr = NULL; - int idx, ambiguous = 0; - - /* - * Find the current session. There must always be a current session, if - * it can't be found, report an error. - */ - if ((s = cmd_current_session(cmdq, 0)) == NULL) { - cmdq_error(cmdq, "can't establish current session"); - return (-2); - } - - /* A NULL argument means the current session and "no window" (-1). */ - if (arg == NULL) { - if (sp != NULL) - *sp = s; - return (-1); - } - - /* Time to look at the argument. If it is empty, that is an error. */ - if (*arg == '\0') - goto not_found; - - /* Find the separating colon. If none, assume the current session. */ - winptr = strchr(arg, ':'); - if (winptr == NULL) - goto no_colon; - winptr++; /* skip : */ - sessptr = xstrdup(arg); - *strchr(sessptr, ':') = '\0'; - - /* Try to lookup the session if present. */ - if (sessptr != NULL && *sessptr != '\0') { - if ((s = cmd_lookup_session(cmdq, sessptr, &ambiguous)) == NULL) - goto no_session; - } - if (sp != NULL) - *sp = s; - - /* - * Then work out the window. An empty string is a new window otherwise - * try to look it up in the session. - */ - if (*winptr == '\0') - idx = -1; - else if (winptr[0] == '!' && winptr[1] == '\0') { - if ((wl = TAILQ_FIRST(&s->lastw)) == NULL) - goto not_found; - idx = wl->idx; - } else if (winptr[0] == '+' || winptr[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; - - free(sessptr); - return (idx); - -no_colon: - /* - * No colon in the string, first try special cases, then as a window - * and lastly as a session. - */ - if (arg[0] == '!' && arg[1] == '\0') { - if ((wl = TAILQ_FIRST(&s->lastw)) == NULL) - goto not_found; - idx = wl->idx; - } else if (arg[0] == '+' || arg[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; - - if (sp != NULL) - *sp = s; - - return (idx); - -lookup_session: - if (ambiguous) - goto not_found; - if (*arg != '\0' && - (s = cmd_lookup_session(cmdq, arg, &ambiguous)) == NULL) - goto no_session; - - if (sp != NULL) - *sp = s; - - return (-1); - -no_session: - if (ambiguous) - cmdq_error(cmdq, "multiple sessions: %s", arg); - else - cmdq_error(cmdq, "session not found: %s", arg); - free(sessptr); - return (-2); - -invalid_index: - if (ambiguous) - goto not_found; - cmdq_error(cmdq, "invalid index: %s", arg); - - free(sessptr); - return (-2); - -not_found: - if (ambiguous) - cmdq_error(cmdq, "multiple windows: %s", arg); - else - cmdq_error(cmdq, "window not found: %s", arg); - free(sessptr); - 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 ., - * such as mysession:mywindow.0. - */ -struct winlink * -cmd_find_pane(struct cmd_q *cmdq, - const char *arg, struct session **sp, struct window_pane **wpp) -{ - struct session *s; - struct winlink *wl; - const char *period, *errstr; - char *winptr, *paneptr; - u_int idx; - - /* Get the current session. */ - if ((s = cmd_current_session(cmdq, 0)) == NULL) { - cmdq_error(cmdq, "can't establish current session"); - return (NULL); - } - if (sp != NULL) - *sp = s; - - /* A NULL argument means the current session, window and pane. */ - if (arg == NULL) { - *wpp = s->curw->window->active; - return (s->curw); - } - - /* Lookup as pane id. */ - if ((*wpp = window_pane_find_by_id_str(arg)) != NULL) { - s = cmd_window_session(cmdq, (*wpp)->window, &wl); - if (sp != NULL) - *sp = s; - return (wl); - } - - /* Look for a separating period. */ - if ((period = strrchr(arg, '.')) == NULL) - goto no_period; - - /* Pull out the window part and parse it. */ - winptr = xstrdup(arg); - winptr[period - arg] = '\0'; - if (*winptr == '\0') - wl = s->curw; - else if ((wl = cmd_find_window(cmdq, winptr, sp)) == NULL) - goto error; - - /* Find the pane section and look it up. */ - paneptr = winptr + (period - arg) + 1; - if (*paneptr == '\0') - *wpp = wl->window->active; - else if (paneptr[0] == '+' || paneptr[0] == '-') - *wpp = cmd_find_pane_offset(paneptr, wl); - else if (paneptr[0] == '!' && paneptr[1] == '\0') { - if (wl->window->last == NULL) { - cmdq_error(cmdq, "no last pane"); - goto error; - } - *wpp = wl->window->last; - } else { - idx = strtonum(paneptr, 0, INT_MAX, &errstr); - if (errstr != NULL) - goto lookup_string; - *wpp = window_pane_at_index(wl->window, idx); - if (*wpp == NULL) - goto lookup_string; - } - - free(winptr); - return (wl); - -lookup_string: - /* Try pane string description. */ - if ((*wpp = window_find_string(wl->window, paneptr)) == NULL) { - cmdq_error(cmdq, "can't find pane: %s", paneptr); - goto error; - } - - free(winptr); - return (wl); - -no_period: - /* Check mouse event. */ - if (arg[0] == '=' && arg[1] == '\0') { - *wpp = cmd_mouse_pane(&cmdq->item->mouse, &s, &wl); - if (*wpp == NULL) { - cmdq_error(cmdq, "no mouse target"); - return (NULL); - } - if (sp != NULL) - *sp = s; - return (wl); - } - - /* Try as a pane number alone. */ - idx = strtonum(arg, 0, INT_MAX, &errstr); - if (errstr != NULL) - goto lookup_window; - - /* Try index in the current session and window. */ - if ((*wpp = window_pane_at_index(s->curw->window, idx)) == NULL) - goto lookup_window; - - return (s->curw); - -lookup_window: - /* Try pane string description. */ - if ((*wpp = window_find_string(s->curw->window, arg)) != NULL) - return (s->curw); - - /* Try as a window and use the active pane. */ - if ((wl = cmd_find_window(cmdq, arg, sp)) != NULL) - *wpp = wl->window->active; - return (wl); - -error: - free(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. */ char * cmd_template_replace(const char *template, const char *s, int idx) |