diff --git a/cmd-find.c b/cmd-find.c index 813bfbc9..959b7111 100644 --- a/cmd-find.c +++ b/cmd-find.c @@ -248,7 +248,11 @@ cmd_find_current_session_with_client(struct cmd_find_state *fs) { struct window_pane *wp; - /* If this is running in a pane, that's great. */ + /* + * If this is running in a pane, we can use that to limit the list of + * sessions to those containing that pane (we still use the current + * window in the best session). + */ if (fs->cmdq->client->tty.path != NULL) { RB_FOREACH(wp, window_pane_tree, &all_window_panes) { if (strcmp(wp->tty, fs->cmdq->client->tty.path) == 0) @@ -261,11 +265,8 @@ cmd_find_current_session_with_client(struct cmd_find_state *fs) if (wp == NULL) goto unknown_pane; - /* We now know the window and pane. */ + /* Find the best session and winlink containing this pane. */ fs->w = wp->window; - fs->wp = wp; - - /* Find the best session and winlink. */ if (cmd_find_best_session_with_window(fs) != 0) { if (wp != NULL) { /* @@ -277,6 +278,13 @@ cmd_find_current_session_with_client(struct cmd_find_state *fs) } return (-1); } + + /* Use the current window and pane from this session. */ + fs->wl = fs->s->curw; + fs->idx = fs->wl->idx; + fs->w = fs->wl->window; + fs->wp = fs->w->active; + return (0); unknown_pane: @@ -289,6 +297,7 @@ unknown_pane: fs->idx = fs->wl->idx; fs->w = fs->wl->window; fs->wp = fs->w->active; + return (0); } @@ -791,6 +800,67 @@ cmd_find_clear_state(struct cmd_find_state *fs, struct cmd_q *cmdq, int flags) fs->idx = -1; } +/* Check if a state if valid. */ +int +cmd_find_valid_state(struct cmd_find_state *fs) +{ + struct winlink *wl; + + if (fs->s == NULL || fs->wl == NULL || fs->w == NULL || fs->wp == NULL) + return (0); + + if (!session_alive(fs->s)) + return (0); + + RB_FOREACH(wl, winlinks, &fs->s->windows) { + if (wl->window == fs->w && wl == fs->wl) + break; + } + if (wl == NULL) + return (0); + + if (fs->w != fs->wl->window) + return (0); + + if (!window_has_pane(fs->w, fs->wp)) + return (0); + return (window_pane_visible(fs->wp)); +} + +/* Copy a state. */ +void +cmd_find_copy_state(struct cmd_find_state *dst, struct cmd_find_state *src) +{ + dst->s = src->s; + dst->wl = src->wl; + dst->idx = dst->wl->idx; + dst->w = dst->wl->window; + dst->wp = src->wp; +} + +/* Log the result. */ +void +cmd_find_log_state(const char *prefix, struct cmd_find_state *fs) +{ + if (fs->s != NULL) + log_debug("%s: s=$%u", prefix, fs->s->id); + else + log_debug("%s: s=none", prefix); + if (fs->wl != NULL) { + log_debug("%s: wl=%u %d w=@%u %s", prefix, fs->wl->idx, + fs->wl->window == fs->w, fs->w->id, fs->w->name); + } else + log_debug("%s: wl=none", prefix); + if (fs->wp != NULL) + log_debug("%s: wp=%%%u", prefix, fs->wp->id); + else + log_debug("%s: wp=none", prefix); + if (fs->idx != -1) + log_debug("%s: idx=%d", prefix, fs->idx); + else + log_debug("%s: idx=none", prefix); +} + /* * Split target into pieces and resolve for the given type. Fills in the given * state. Returns 0 on success or -1 on error. @@ -811,24 +881,22 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_q *cmdq, log_debug("%s: target %s, type %d", __func__, target, type); log_debug("%s: cmdq %p, flags %#x", __func__, cmdq, flags); - /* Find current state. */ - cmd_find_clear_state(¤t, cmdq, flags); - if (server_check_marked() && (flags & CMD_FIND_DEFAULT_MARKED)) { - current.s = marked_session; - current.wl = marked_winlink; - current.idx = current.wl->idx; - current.w = current.wl->window; - current.wp = marked_window_pane; - } - if (current.s == NULL && cmd_find_current_session(¤t) != 0) { - if (~flags & CMD_FIND_QUIET) - cmdq_error(cmdq, "no current session"); - goto error; - } - /* Clear new state. */ cmd_find_clear_state(fs, cmdq, flags); - fs->current = ¤t; + + /* Find current state. */ + fs->current = NULL; + if (server_check_marked() && (flags & CMD_FIND_DEFAULT_MARKED)) + fs->current = &marked_pane; + if (fs->current == NULL) { + cmd_find_clear_state(¤t, cmdq, flags); + if (cmd_find_current_session(¤t) != 0) { + if (~flags & CMD_FIND_QUIET) + cmdq_error(cmdq, "no current session"); + goto error; + } + fs->current = ¤t; + } /* An empty or NULL target is the current. */ if (target == NULL || *target == '\0') @@ -867,11 +935,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_q *cmdq, cmdq_error(cmdq, "no marked target"); goto error; } - fs->s = marked_session; - fs->wl = marked_winlink; - fs->idx = fs->wl->idx; - fs->w = fs->wl->window; - fs->wp = marked_window_pane; + cmd_find_copy_state(fs, &marked_pane); goto found; } @@ -1032,9 +1096,9 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_q *cmdq, current: /* Use the current session. */ + cmd_find_copy_state(fs, fs->current); if (flags & CMD_FIND_WINDOW_INDEX) - current.idx = -1; - memcpy(fs, ¤t, sizeof *fs); + fs->idx = -1; goto found; error: @@ -1067,29 +1131,6 @@ no_pane: goto error; } -/* Log the result. */ -void -cmd_find_log_state(const char *prefix, struct cmd_find_state *fs) -{ - if (fs->s != NULL) - log_debug("%s: s=$%u", prefix, fs->s->id); - else - log_debug("%s: s=none", prefix); - if (fs->wl != NULL) { - log_debug("%s: wl=%u %d w=@%u %s", prefix, fs->wl->idx, - fs->wl->window == fs->w, fs->w->id, fs->w->name); - } else - log_debug("%s: wl=none", prefix); - if (fs->wp != NULL) - log_debug("%s: wp=%%%u", prefix, fs->wp->id); - else - log_debug("%s: wp=none", prefix); - if (fs->idx != -1) - log_debug("%s: idx=%d", prefix, fs->idx); - else - log_debug("%s: idx=none", prefix); -} - /* Find the target client or report an error and return NULL. */ struct client * cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet) diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 08796e5d..4abe2473 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -39,7 +39,7 @@ const struct cmd_entry cmd_list_keys_entry = { .args = { "t:T:", 0, 0 }, .usage = "[-t mode-table] [-T key-table]", - .flags = 0, + .flags = CMD_STARTSERVER, .exec = cmd_list_keys_exec }; @@ -50,7 +50,7 @@ const struct cmd_entry cmd_list_commands_entry = { .args = { "", 0, 0 }, .usage = "", - .flags = 0, + .flags = CMD_STARTSERVER, .exec = cmd_list_keys_exec }; diff --git a/cmd-select-pane.c b/cmd-select-pane.c index 7652f608..6ebe753c 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -94,13 +94,13 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq) if (args_has(args, 'm') || args_has(args, 'M')) { if (args_has(args, 'm') && !window_pane_visible(wp)) return (CMD_RETURN_NORMAL); - lastwp = marked_window_pane; + lastwp = marked_pane.wp; if (args_has(args, 'M') || server_is_marked(s, wl, wp)) server_clear_marked(); else server_set_marked(s, wl, wp); - markedwp = marked_window_pane; + markedwp = marked_pane.wp; if (lastwp != NULL) { server_redraw_window_borders(lastwp->window); diff --git a/screen-redraw.c b/screen-redraw.c index fd4536d0..9958d04a 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -331,9 +331,9 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top) continue; active = screen_redraw_check_is(i, j, type, w, w->active, wp); - if (server_is_marked(s, s->curw, marked_window_pane) && + if (server_is_marked(s, s->curw, marked_pane.wp) && screen_redraw_check_is(i, j, type, w, - marked_window_pane, wp)) { + marked_pane.wp, wp)) { if (active) tty_attributes(tty, &m_active_gc, NULL); else diff --git a/server.c b/server.c index c4a7789f..cc0fe889 100644 --- a/server.c +++ b/server.c @@ -40,18 +40,14 @@ * Main server functions. */ -struct clients clients; +struct clients clients; -struct tmuxproc *server_proc; -int server_fd; -int server_exit; -struct event server_ev_accept; +struct tmuxproc *server_proc; +int server_fd; +int server_exit; +struct event server_ev_accept; -struct session *marked_session; -struct winlink *marked_winlink; -struct window *marked_window; -struct window_pane *marked_window_pane; -struct layout_cell *marked_layout_cell; +struct cmd_find_state marked_pane; int server_create_socket(void); int server_loop(void); @@ -67,22 +63,18 @@ void server_child_stopped(pid_t, int); void server_set_marked(struct session *s, struct winlink *wl, struct window_pane *wp) { - marked_session = s; - marked_winlink = wl; - marked_window = wl->window; - marked_window_pane = wp; - marked_layout_cell = wp->layout_cell; + cmd_find_clear_state(&marked_pane, NULL, 0); + marked_pane.s = s; + marked_pane.wl = wl; + marked_pane.w = wl->window; + marked_pane.wp = wp; } /* Clear marked pane. */ void server_clear_marked(void) { - marked_session = NULL; - marked_winlink = NULL; - marked_window = NULL; - marked_window_pane = NULL; - marked_layout_cell = NULL; + cmd_find_clear_state(&marked_pane, NULL, 0); } /* Is this the marked pane? */ @@ -91,9 +83,9 @@ server_is_marked(struct session *s, struct winlink *wl, struct window_pane *wp) { if (s == NULL || wl == NULL || wp == NULL) return (0); - if (marked_session != s || marked_winlink != wl) + if (marked_pane.s != s || marked_pane.wl != wl) return (0); - if (marked_window_pane != wp) + if (marked_pane.wp != wp) return (0); return (server_check_marked()); } @@ -102,25 +94,7 @@ server_is_marked(struct session *s, struct winlink *wl, struct window_pane *wp) int server_check_marked(void) { - struct winlink *wl; - - if (marked_window_pane == NULL) - return (0); - if (marked_layout_cell != marked_window_pane->layout_cell) - return (0); - - if (!session_alive(marked_session)) - return (0); - RB_FOREACH(wl, winlinks, &marked_session->windows) { - if (wl->window == marked_window && wl == marked_winlink) - break; - } - if (wl == NULL) - return (0); - - if (!window_has_pane(marked_window, marked_window_pane)) - return (0); - return (window_pane_visible(marked_window_pane)); + return (cmd_find_valid_state(&marked_pane)); } /* Create server socket. */ diff --git a/tmux.h b/tmux.h index 9694c4dc..e12a758d 100644 --- a/tmux.h +++ b/tmux.h @@ -1768,6 +1768,9 @@ int cmd_find_target(struct cmd_find_state *, struct cmd_q *, struct client *cmd_find_client(struct cmd_q *, const char *, int); void cmd_find_clear_state(struct cmd_find_state *, struct cmd_q *, int); +int cmd_find_valid_state(struct cmd_find_state *); +void cmd_find_copy_state(struct cmd_find_state *, + struct cmd_find_state *); void cmd_find_log_state(const char *, struct cmd_find_state *); /* cmd.c */ @@ -1846,9 +1849,7 @@ void alerts_check_session(struct session *); /* server.c */ extern struct tmuxproc *server_proc; extern struct clients clients; -extern struct session *marked_session; -extern struct winlink *marked_winlink; -extern struct window_pane *marked_window_pane; +extern struct cmd_find_state marked_pane; void server_set_marked(struct session *, struct winlink *, struct window_pane *); void server_clear_marked(void); diff --git a/window.c b/window.c index 78f944c5..f412da64 100644 --- a/window.c +++ b/window.c @@ -567,7 +567,7 @@ window_add_pane(struct window *w, u_int hlimit) void window_lost_pane(struct window *w, struct window_pane *wp) { - if (wp == marked_window_pane) + if (wp == marked_pane.wp) server_clear_marked(); if (wp == w->active) { @@ -690,7 +690,7 @@ window_printable_flags(struct session *s, struct winlink *wl) flags[pos++] = '*'; if (wl == TAILQ_FIRST(&s->lastw)) flags[pos++] = '-'; - if (server_check_marked() && wl == marked_winlink) + if (server_check_marked() && wl == marked_pane.wl) flags[pos++] = 'M'; if (wl->window->flags & WINDOW_ZOOMED) flags[pos++] = 'Z';