mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 01:34:18 +00:00 
			
		
		
		
	Make the cmd_find_* functions more obvious when looking for a client,
rather than having it inside other functions. Should be no change to the way targets are resolved just yet.
This commit is contained in:
		
							
								
								
									
										350
									
								
								cmd-find.c
									
									
									
									
									
								
							
							
						
						
									
										350
									
								
								cmd-find.c
									
									
									
									
									
								
							@@ -27,19 +27,12 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
static struct session *cmd_find_try_TMUX(struct client *, struct window *);
 | 
			
		||||
static int	cmd_find_client_better(struct client *, struct client *);
 | 
			
		||||
static struct client *cmd_find_best_client(struct client **, u_int);
 | 
			
		||||
static int	cmd_find_session_better(struct session *, struct session *,
 | 
			
		||||
		    int);
 | 
			
		||||
static struct session *cmd_find_best_session(struct session **, u_int, int);
 | 
			
		||||
static int	cmd_find_best_session_with_window(struct cmd_find_state *);
 | 
			
		||||
static int	cmd_find_best_winlink_with_window(struct cmd_find_state *);
 | 
			
		||||
 | 
			
		||||
static int	cmd_find_current_session_with_client(struct cmd_find_state *);
 | 
			
		||||
static int	cmd_find_current_session(struct cmd_find_state *);
 | 
			
		||||
static struct client *cmd_find_current_client(struct cmdq_item *);
 | 
			
		||||
 | 
			
		||||
static const char *cmd_find_map_table(const char *[][2], const char *);
 | 
			
		||||
 | 
			
		||||
static int	cmd_find_get_session(struct cmd_find_state *, const char *);
 | 
			
		||||
@@ -84,13 +77,12 @@ static const char *cmd_find_pane_table[][2] = {
 | 
			
		||||
 | 
			
		||||
/* Get session from TMUX if present. */
 | 
			
		||||
static struct session *
 | 
			
		||||
cmd_find_try_TMUX(struct client *c, struct window *w)
 | 
			
		||||
cmd_find_try_TMUX(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct environ_entry	*envent;
 | 
			
		||||
	char			 tmp[256];
 | 
			
		||||
	long long		 pid;
 | 
			
		||||
	u_int			 session;
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
 | 
			
		||||
	envent = environ_find(c->environ, "TMUX");
 | 
			
		||||
	if (envent == NULL)
 | 
			
		||||
@@ -100,13 +92,8 @@ cmd_find_try_TMUX(struct client *c, struct window *w)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	if (pid != getpid())
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	log_debug("client %p TMUX is %s (session @%u)", c, envent->value,
 | 
			
		||||
	    session);
 | 
			
		||||
 | 
			
		||||
	s = session_find_by_id(session);
 | 
			
		||||
	if (s == NULL || (w != NULL && !session_has(s, w)))
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	return (s);
 | 
			
		||||
	log_debug("client %p TMUX %s (session @%u)", c, envent->value, session);
 | 
			
		||||
	return (session_find_by_id(session));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Is this client better? */
 | 
			
		||||
@@ -118,29 +105,24 @@ cmd_find_client_better(struct client *c, struct client *than)
 | 
			
		||||
	return (timercmp(&c->activity_time, &than->activity_time, >));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find best client from a list, or all if list is NULL. */
 | 
			
		||||
/* Find best client for session. */
 | 
			
		||||
static struct client *
 | 
			
		||||
cmd_find_best_client(struct client **clist, u_int csize)
 | 
			
		||||
cmd_find_best_client(struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c_loop, *c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	if (s->flags & SESSION_UNATTACHED)
 | 
			
		||||
		s = NULL;
 | 
			
		||||
 | 
			
		||||
	c = NULL;
 | 
			
		||||
	if (clist != NULL) {
 | 
			
		||||
		for (i = 0; i < csize; i++) {
 | 
			
		||||
			if (clist[i]->session == NULL)
 | 
			
		||||
				continue;
 | 
			
		||||
			if (cmd_find_client_better(clist[i], c))
 | 
			
		||||
				c = clist[i];
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
	TAILQ_FOREACH(c_loop, &clients, entry) {
 | 
			
		||||
		if (c_loop->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (s != NULL && c_loop->session != s)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (cmd_find_client_better(c_loop, c))
 | 
			
		||||
			c = c_loop;
 | 
			
		||||
	}
 | 
			
		||||
	}
 | 
			
		||||
	return (c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -192,12 +174,6 @@ cmd_find_best_session_with_window(struct cmd_find_state *fs)
 | 
			
		||||
	u_int		  ssize;
 | 
			
		||||
	struct session	 *s;
 | 
			
		||||
 | 
			
		||||
	if (fs->item != NULL && fs->item->client != NULL) {
 | 
			
		||||
		fs->s = cmd_find_try_TMUX(fs->item->client, fs->w);
 | 
			
		||||
		if (fs->s != NULL)
 | 
			
		||||
			return (cmd_find_best_winlink_with_window(fs));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ssize = 0;
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
		if (!session_has(s, fs->w))
 | 
			
		||||
@@ -245,146 +221,6 @@ cmd_find_best_winlink_with_window(struct cmd_find_state *fs)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find current session when we have an unattached client. */
 | 
			
		||||
static int
 | 
			
		||||
cmd_find_current_session_with_client(struct cmd_find_state *fs)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * 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->item != NULL) {
 | 
			
		||||
		RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
 | 
			
		||||
			if (strcmp(wp->tty, fs->item->client->ttyname) == 0)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	} else
 | 
			
		||||
		wp = NULL;
 | 
			
		||||
 | 
			
		||||
	/* Not running in a pane. We know nothing. Find the best session. */
 | 
			
		||||
	if (wp == NULL)
 | 
			
		||||
		goto unknown_pane;
 | 
			
		||||
 | 
			
		||||
	/* Find the best session and winlink containing this pane. */
 | 
			
		||||
	fs->w = wp->window;
 | 
			
		||||
	if (cmd_find_best_session_with_window(fs) != 0) {
 | 
			
		||||
		if (wp != NULL) {
 | 
			
		||||
			/*
 | 
			
		||||
			 * The window may have been destroyed but the pane
 | 
			
		||||
			 * still on all_window_panes due to something else
 | 
			
		||||
			 * holding a reference.
 | 
			
		||||
			 */
 | 
			
		||||
			goto unknown_pane;
 | 
			
		||||
		}
 | 
			
		||||
		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:
 | 
			
		||||
	fs->s = NULL;
 | 
			
		||||
	if (fs->item != NULL)
 | 
			
		||||
		fs->s = cmd_find_try_TMUX(fs->item->client, NULL);
 | 
			
		||||
	if (fs->s == NULL)
 | 
			
		||||
		fs->s = cmd_find_best_session(NULL, 0, fs->flags);
 | 
			
		||||
	if (fs->s == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	fs->wl = fs->s->curw;
 | 
			
		||||
	fs->idx = fs->wl->idx;
 | 
			
		||||
	fs->w = fs->wl->window;
 | 
			
		||||
	fs->wp = fs->w->active;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Work out the best current state. If this function succeeds, the state is
 | 
			
		||||
 * guaranteed to be completely filled in.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
cmd_find_current_session(struct cmd_find_state *fs)
 | 
			
		||||
{
 | 
			
		||||
	/* If we know the current client, use it. */
 | 
			
		||||
	if (fs->item != NULL && fs->item->client != NULL) {
 | 
			
		||||
		log_debug("%s: have client %p%s", __func__, fs->item->client,
 | 
			
		||||
		    fs->item->client->session == NULL ? "" : " (with session)");
 | 
			
		||||
		if (fs->item->client->session == NULL)
 | 
			
		||||
			return (cmd_find_current_session_with_client(fs));
 | 
			
		||||
		fs->s = fs->item->client->session;
 | 
			
		||||
		fs->wl = fs->s->curw;
 | 
			
		||||
		fs->idx = fs->wl->idx;
 | 
			
		||||
		fs->w = fs->wl->window;
 | 
			
		||||
		fs->wp = fs->w->active;
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* We know nothing, find the best session and client. */
 | 
			
		||||
	fs->s = cmd_find_best_session(NULL, 0, fs->flags);
 | 
			
		||||
	if (fs->s == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	fs->wl = fs->s->curw;
 | 
			
		||||
	fs->idx = fs->wl->idx;
 | 
			
		||||
	fs->w = fs->wl->window;
 | 
			
		||||
	fs->wp = fs->w->active;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Work out the best current client. */
 | 
			
		||||
static struct client *
 | 
			
		||||
cmd_find_current_client(struct cmdq_item *item)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_find_state	 current;
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
	struct client		*c, **clist = NULL;
 | 
			
		||||
	u_int		 	 csize;
 | 
			
		||||
 | 
			
		||||
	/* If the queue client has a session, use it. */
 | 
			
		||||
	if (item->client != NULL && item->client->session != NULL) {
 | 
			
		||||
		log_debug("%s: using item %p client %p", __func__, item,
 | 
			
		||||
		    item->client);
 | 
			
		||||
		return (item->client);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Otherwise find the current session. */
 | 
			
		||||
	cmd_find_clear_state(¤t, item, 0);
 | 
			
		||||
	if (cmd_find_current_session(¤t) != 0)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
 | 
			
		||||
	/* If it is attached, find the best of it's clients. */
 | 
			
		||||
	s = current.s;
 | 
			
		||||
	log_debug("%s: current session $%u %s", __func__, s->id, s->name);
 | 
			
		||||
	if (~s->flags & SESSION_UNATTACHED) {
 | 
			
		||||
		csize = 0;
 | 
			
		||||
		TAILQ_FOREACH(c, &clients, entry) {
 | 
			
		||||
			if (c->session != s)
 | 
			
		||||
				continue;
 | 
			
		||||
			clist = xreallocarray(clist, csize + 1, sizeof *clist);
 | 
			
		||||
			clist[csize++] = c;
 | 
			
		||||
		}
 | 
			
		||||
		if (csize != 0) {
 | 
			
		||||
			c = cmd_find_best_client(clist, csize);
 | 
			
		||||
			if (c != NULL) {
 | 
			
		||||
				free(clist);
 | 
			
		||||
				return (c);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		free(clist);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Otherwise pick best of all clients. */
 | 
			
		||||
	return (cmd_find_best_client(NULL, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Maps string in table. */
 | 
			
		||||
static const char *
 | 
			
		||||
cmd_find_map_table(const char *table[][2], const char *s)
 | 
			
		||||
@@ -797,18 +633,16 @@ cmd_find_get_pane_with_window(struct cmd_find_state *fs, const char *pane)
 | 
			
		||||
 | 
			
		||||
/* Clear state. */
 | 
			
		||||
void
 | 
			
		||||
cmd_find_clear_state(struct cmd_find_state *fs, struct cmdq_item *item,
 | 
			
		||||
    int flags)
 | 
			
		||||
cmd_find_clear_state(struct cmd_find_state *fs, int flags)
 | 
			
		||||
{
 | 
			
		||||
	memset(fs, 0, sizeof *fs);
 | 
			
		||||
 | 
			
		||||
	fs->item = item;
 | 
			
		||||
	fs->flags = flags;
 | 
			
		||||
 | 
			
		||||
	fs->idx = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check if state is empty/ */
 | 
			
		||||
/* Check if state is empty. */
 | 
			
		||||
int
 | 
			
		||||
cmd_find_empty_state(struct cmd_find_state *fs)
 | 
			
		||||
{
 | 
			
		||||
@@ -882,7 +716,7 @@ cmd_find_log_state(const char *prefix, struct cmd_find_state *fs)
 | 
			
		||||
void
 | 
			
		||||
cmd_find_from_session(struct cmd_find_state *fs, struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	fs->s = s;
 | 
			
		||||
	fs->wl = fs->s->curw;
 | 
			
		||||
@@ -896,7 +730,7 @@ cmd_find_from_session(struct cmd_find_state *fs, struct session *s)
 | 
			
		||||
void
 | 
			
		||||
cmd_find_from_winlink(struct cmd_find_state *fs, struct winlink *wl)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	fs->s = wl->session;
 | 
			
		||||
	fs->wl = wl;
 | 
			
		||||
@@ -911,7 +745,7 @@ int
 | 
			
		||||
cmd_find_from_session_window(struct cmd_find_state *fs, struct session *s,
 | 
			
		||||
    struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	fs->s = s;
 | 
			
		||||
	fs->w = w;
 | 
			
		||||
@@ -927,7 +761,7 @@ cmd_find_from_session_window(struct cmd_find_state *fs, struct session *s,
 | 
			
		||||
int
 | 
			
		||||
cmd_find_from_window(struct cmd_find_state *fs, struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	fs->w = w;
 | 
			
		||||
	if (cmd_find_best_session_with_window(fs) != 0)
 | 
			
		||||
@@ -945,7 +779,7 @@ void
 | 
			
		||||
cmd_find_from_winlink_pane(struct cmd_find_state *fs, struct winlink *wl,
 | 
			
		||||
    struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	fs->s = wl->session;
 | 
			
		||||
	fs->wl = wl;
 | 
			
		||||
@@ -970,17 +804,126 @@ cmd_find_from_pane(struct cmd_find_state *fs, struct window_pane *wp)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find current state. */
 | 
			
		||||
/* Find state from nothing. */
 | 
			
		||||
int
 | 
			
		||||
cmd_find_current(struct cmd_find_state *fs, struct cmdq_item *item, int flags)
 | 
			
		||||
cmd_find_from_nothing(struct cmd_find_state *fs)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, item, flags);
 | 
			
		||||
	if (cmd_find_current_session(fs) != 0) {
 | 
			
		||||
		if (~flags & CMD_FIND_QUIET)
 | 
			
		||||
			cmdq_error(item, "no current session");
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	fs->s = cmd_find_best_session(NULL, 0, fs->flags);
 | 
			
		||||
	if (fs->s == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	fs->wl = fs->s->curw;
 | 
			
		||||
	fs->idx = fs->wl->idx;
 | 
			
		||||
	fs->w = fs->wl->window;
 | 
			
		||||
	fs->wp = fs->w->active;
 | 
			
		||||
 | 
			
		||||
	cmd_find_log_state(__func__, fs);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find state from mouse. */
 | 
			
		||||
int
 | 
			
		||||
cmd_find_from_mouse(struct cmd_find_state *fs, struct mouse_event *m)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	if (!m->valid)
 | 
			
		||||
		return (-1);
 | 
			
		||||
 | 
			
		||||
	fs->wp = cmd_mouse_pane(m, &fs->s, &fs->wl);
 | 
			
		||||
	if (fs->wp == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	fs->w = fs->wl->window;
 | 
			
		||||
 | 
			
		||||
	cmd_find_log_state(__func__, fs);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find state from client. */
 | 
			
		||||
int
 | 
			
		||||
cmd_find_from_client(struct cmd_find_state *fs, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
	struct winlink		*wl;
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
 | 
			
		||||
	/* If no client, treat as from nothing. */
 | 
			
		||||
	if (c == NULL)
 | 
			
		||||
		return (cmd_find_from_nothing(fs));
 | 
			
		||||
 | 
			
		||||
	/* If this is an attached client, all done. */
 | 
			
		||||
	if (c->session != NULL) {
 | 
			
		||||
		cmd_find_from_session(fs, c->session);
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If this is an unattached client running in a pane, we can use that
 | 
			
		||||
	 * to limit the list of sessions to those containing that pane.
 | 
			
		||||
	 */
 | 
			
		||||
	RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
 | 
			
		||||
		if (strcmp(wp->tty, c->ttyname) == 0)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	if (wp == NULL)
 | 
			
		||||
		goto unknown_pane;
 | 
			
		||||
 | 
			
		||||
	/* If we have a session in TMUX, see if it has this pane. */
 | 
			
		||||
	s = cmd_find_try_TMUX(c);
 | 
			
		||||
	if (s != NULL) {
 | 
			
		||||
		RB_FOREACH(wl, winlinks, &s->windows) {
 | 
			
		||||
			if (window_has_pane(wl->window, wp))
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		if (wl != NULL) {
 | 
			
		||||
			fs->s = s;
 | 
			
		||||
			fs->wl = s->curw; /* use active session */
 | 
			
		||||
			fs->w = fs->wl->window;
 | 
			
		||||
			fs->wp = fs->w->active; /* use active pane */
 | 
			
		||||
 | 
			
		||||
			cmd_find_log_state(__func__, fs);
 | 
			
		||||
			return (0);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Don't have a session, or it doesn't have this pane. Try all
 | 
			
		||||
	 * sessions.
 | 
			
		||||
	 */
 | 
			
		||||
	fs->w = wp->window;
 | 
			
		||||
	if (cmd_find_best_session_with_window(fs) != 0) {
 | 
			
		||||
		if (wp != NULL) {
 | 
			
		||||
			/*
 | 
			
		||||
			 * The window may have been destroyed but the pane
 | 
			
		||||
			 * still on all_window_panes due to something else
 | 
			
		||||
			 * holding a reference.
 | 
			
		||||
			 */
 | 
			
		||||
			goto unknown_pane;
 | 
			
		||||
		}
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	fs->wl = fs->s->curw;
 | 
			
		||||
	fs->w = fs->wl->window;
 | 
			
		||||
	fs->wp = fs->w->active; /* use active pane */
 | 
			
		||||
 | 
			
		||||
	cmd_find_log_state(__func__, fs);
 | 
			
		||||
	return (0);
 | 
			
		||||
 | 
			
		||||
unknown_pane:
 | 
			
		||||
	/*
 | 
			
		||||
	 * We're not running in a known pane, but maybe this client has TMUX
 | 
			
		||||
	 * in the environment. That'd give us a session.
 | 
			
		||||
	 */
 | 
			
		||||
	s = cmd_find_try_TMUX(c);
 | 
			
		||||
	if (s != NULL) {
 | 
			
		||||
		cmd_find_from_session(fs, s);
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Otherwise we need to guess. */
 | 
			
		||||
	return (cmd_find_from_nothing(fs));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -988,11 +931,11 @@ cmd_find_current(struct cmd_find_state *fs, struct cmdq_item *item, int flags)
 | 
			
		||||
 * state. Returns 0 on success or -1 on error.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
cmd_find_target(struct cmd_find_state *fs, struct cmd_find_state *current,
 | 
			
		||||
    struct cmdq_item *item, const char *target, enum cmd_find_type type,
 | 
			
		||||
    int flags)
 | 
			
		||||
cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item,
 | 
			
		||||
    const char *target, enum cmd_find_type type, int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct mouse_event	*m;
 | 
			
		||||
	struct cmd_find_state	 current;
 | 
			
		||||
	char			*colon, *period, *copy = NULL;
 | 
			
		||||
	const char		*session, *window, *pane;
 | 
			
		||||
	int			 window_only = 0, pane_only = 0;
 | 
			
		||||
@@ -1005,7 +948,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_find_state *current,
 | 
			
		||||
	log_debug("%s: item %p, flags %#x", __func__, item, flags);
 | 
			
		||||
 | 
			
		||||
	/* Clear new state. */
 | 
			
		||||
	cmd_find_clear_state(fs, item, flags);
 | 
			
		||||
	cmd_find_clear_state(fs, flags);
 | 
			
		||||
 | 
			
		||||
	/* Find current state. */
 | 
			
		||||
	if (server_check_marked() && (flags & CMD_FIND_DEFAULT_MARKED)) {
 | 
			
		||||
@@ -1014,10 +957,11 @@ cmd_find_target(struct cmd_find_state *fs, struct cmd_find_state *current,
 | 
			
		||||
	} else if (cmd_find_valid_state(&item->shared->current)) {
 | 
			
		||||
		fs->current = &item->shared->current;
 | 
			
		||||
		log_debug("%s: current is from queue", __func__);
 | 
			
		||||
	} else {
 | 
			
		||||
		fs->current = current;
 | 
			
		||||
		log_debug("%s: current is from argument", __func__);
 | 
			
		||||
	}
 | 
			
		||||
	} else if (cmd_find_from_client(¤t, item->client) == 0) {
 | 
			
		||||
		fs->current = ¤t;
 | 
			
		||||
		log_debug("%s: current is from client", __func__);
 | 
			
		||||
	} else
 | 
			
		||||
		return (-1);
 | 
			
		||||
	if (!cmd_find_empty_state(fs->current) &&
 | 
			
		||||
	    !cmd_find_valid_state(fs->current))
 | 
			
		||||
		fatalx("invalid current find state");
 | 
			
		||||
@@ -1264,12 +1208,20 @@ struct client *
 | 
			
		||||
cmd_find_client(struct cmdq_item *item, const char *target, int quiet)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	char		*copy;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
 | 
			
		||||
	/* A NULL argument means the current client. */
 | 
			
		||||
	if (item != NULL && target == NULL) {
 | 
			
		||||
		c = cmd_find_current_client(item);
 | 
			
		||||
	if (target == NULL) {
 | 
			
		||||
		c = NULL;
 | 
			
		||||
		if (item->client != NULL && item->client->session != NULL)
 | 
			
		||||
			c = item->client;
 | 
			
		||||
		else {
 | 
			
		||||
			s = cmd_find_best_session(NULL, 0, CMD_FIND_QUIET);
 | 
			
		||||
			if (s != NULL)
 | 
			
		||||
				c = cmd_find_best_client(s);
 | 
			
		||||
		}
 | 
			
		||||
		if (c == NULL && !quiet)
 | 
			
		||||
			cmdq_error(item, "no current client");
 | 
			
		||||
		log_debug("%s: no target, return %p", __func__, c);
 | 
			
		||||
 
 | 
			
		||||
@@ -216,11 +216,12 @@ cmdq_fire_command(struct cmdq_item *item)
 | 
			
		||||
		name = cmd->entry->name;
 | 
			
		||||
		if (cmd_find_valid_state(&item->state.tflag))
 | 
			
		||||
			fsp = &item->state.tflag;
 | 
			
		||||
		else {
 | 
			
		||||
			if (cmd_find_current(&fs, item, CMD_FIND_QUIET) != 0)
 | 
			
		||||
				goto out;
 | 
			
		||||
		else if (cmd_find_valid_state(&item->shared->current))
 | 
			
		||||
			fsp = &item->shared->current;
 | 
			
		||||
		else if (cmd_find_from_client(&fs, item->client) == 0)
 | 
			
		||||
			fsp = &fs;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			goto out;
 | 
			
		||||
		hooks_insert(fsp->s->hooks, item, fsp, "after-%s", name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@ cmd_run_shell_print(struct job *job, const char *msg)
 | 
			
		||||
			cmdq_print(cdata->item, "%s", msg);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if (cmd_find_current (&fs, NULL, CMD_FIND_QUIET) != 0)
 | 
			
		||||
		if (cmd_find_from_nothing(&fs) != 0)
 | 
			
		||||
			return;
 | 
			
		||||
		wp = fs.wp;
 | 
			
		||||
		if (wp == NULL)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								cmd.c
									
									
									
									
									
								
							@@ -454,7 +454,6 @@ cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag,
 | 
			
		||||
{
 | 
			
		||||
	int			 targetflags, error;
 | 
			
		||||
	struct cmd_find_state	*fs = NULL;
 | 
			
		||||
	struct cmd_find_state	 current;
 | 
			
		||||
 | 
			
		||||
	if (flag == CMD_NONE ||
 | 
			
		||||
	    flag == CMD_CLIENT ||
 | 
			
		||||
@@ -511,15 +510,6 @@ cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag,
 | 
			
		||||
	}
 | 
			
		||||
	log_debug("%s: flag %c %d %#x", __func__, c, flag, targetflags);
 | 
			
		||||
 | 
			
		||||
	error = cmd_find_current(¤t, item, targetflags);
 | 
			
		||||
	if (error != 0) {
 | 
			
		||||
		if (~targetflags & CMD_FIND_QUIET)
 | 
			
		||||
			return (-1);
 | 
			
		||||
		cmd_find_clear_state(¤t, NULL, 0);
 | 
			
		||||
	}
 | 
			
		||||
	if (!cmd_find_empty_state(¤t) && !cmd_find_valid_state(¤t))
 | 
			
		||||
		fatalx("invalid current state");
 | 
			
		||||
 | 
			
		||||
	switch (flag) {
 | 
			
		||||
	case CMD_NONE:
 | 
			
		||||
	case CMD_CLIENT:
 | 
			
		||||
@@ -529,14 +519,14 @@ cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag,
 | 
			
		||||
	case CMD_SESSION_CANFAIL:
 | 
			
		||||
	case CMD_SESSION_PREFERUNATTACHED:
 | 
			
		||||
	case CMD_SESSION_WITHPANE:
 | 
			
		||||
		error = cmd_find_target(fs, ¤t, item, target,
 | 
			
		||||
		    CMD_FIND_SESSION, targetflags);
 | 
			
		||||
		error = cmd_find_target(fs, item, target, CMD_FIND_SESSION,
 | 
			
		||||
		    targetflags);
 | 
			
		||||
		if (error != 0)
 | 
			
		||||
			goto error;
 | 
			
		||||
		break;
 | 
			
		||||
	case CMD_MOVEW_R:
 | 
			
		||||
		error = cmd_find_target(fs, ¤t, item, target,
 | 
			
		||||
		    CMD_FIND_SESSION, CMD_FIND_QUIET);
 | 
			
		||||
		error = cmd_find_target(fs, item, target, CMD_FIND_SESSION,
 | 
			
		||||
		    CMD_FIND_QUIET);
 | 
			
		||||
		if (error == 0)
 | 
			
		||||
			break;
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
@@ -544,16 +534,16 @@ cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag,
 | 
			
		||||
	case CMD_WINDOW_CANFAIL:
 | 
			
		||||
	case CMD_WINDOW_MARKED:
 | 
			
		||||
	case CMD_WINDOW_INDEX:
 | 
			
		||||
		error = cmd_find_target(fs, ¤t, item, target,
 | 
			
		||||
		    CMD_FIND_WINDOW, targetflags);
 | 
			
		||||
		error = cmd_find_target(fs, item, target, CMD_FIND_WINDOW,
 | 
			
		||||
		    targetflags);
 | 
			
		||||
		if (error != 0)
 | 
			
		||||
			goto error;
 | 
			
		||||
		break;
 | 
			
		||||
	case CMD_PANE:
 | 
			
		||||
	case CMD_PANE_CANFAIL:
 | 
			
		||||
	case CMD_PANE_MARKED:
 | 
			
		||||
		error = cmd_find_target(fs, ¤t, item, target,
 | 
			
		||||
		    CMD_FIND_PANE, targetflags);
 | 
			
		||||
		error = cmd_find_target(fs, item, target, CMD_FIND_PANE,
 | 
			
		||||
		    targetflags);
 | 
			
		||||
		if (error != 0)
 | 
			
		||||
			goto error;
 | 
			
		||||
		break;
 | 
			
		||||
@@ -565,7 +555,7 @@ cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag,
 | 
			
		||||
error:
 | 
			
		||||
	if (~targetflags & CMD_FIND_QUIET)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	cmd_find_clear_state(fs, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(fs, 0);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -584,8 +574,8 @@ cmd_prepare_state(struct cmd *cmd, struct cmdq_item *item)
 | 
			
		||||
	free(tmp);
 | 
			
		||||
 | 
			
		||||
	state->c = NULL;
 | 
			
		||||
	cmd_find_clear_state(&state->tflag, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(&state->sflag, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(&state->tflag, 0);
 | 
			
		||||
	cmd_find_clear_state(&state->sflag, 0);
 | 
			
		||||
 | 
			
		||||
	flag = cmd->entry->cflag;
 | 
			
		||||
	if (flag == CMD_NONE) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								notify.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								notify.c
									
									
									
									
									
								
							@@ -44,9 +44,9 @@ notify_hook(struct cmdq_item *item, struct notify_entry *ne)
 | 
			
		||||
	struct session		*s = ne->session;
 | 
			
		||||
	struct window		*w = ne->window;
 | 
			
		||||
 | 
			
		||||
	cmd_find_clear_state(&fs, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(&fs, 0);
 | 
			
		||||
	if (cmd_find_empty_state(&ne->fs) || !cmd_find_valid_state(&ne->fs))
 | 
			
		||||
		cmd_find_current(&fs, item, CMD_FIND_QUIET);
 | 
			
		||||
		cmd_find_from_nothing(&fs);
 | 
			
		||||
	else
 | 
			
		||||
		cmd_find_copy_state(&fs, &ne->fs);
 | 
			
		||||
 | 
			
		||||
@@ -164,10 +164,7 @@ notify_client(const char *name, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_find_state	fs;
 | 
			
		||||
 | 
			
		||||
	if (c->session != NULL)
 | 
			
		||||
		cmd_find_from_session(&fs, c->session);
 | 
			
		||||
	else
 | 
			
		||||
		cmd_find_current(&fs, NULL, CMD_FIND_QUIET);
 | 
			
		||||
	cmd_find_from_client(&fs, c);
 | 
			
		||||
	notify_add(name, &fs, c, NULL, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -179,7 +176,7 @@ notify_session(const char *name, struct session *s)
 | 
			
		||||
	if (session_alive(s))
 | 
			
		||||
		cmd_find_from_session(&fs, s);
 | 
			
		||||
	else
 | 
			
		||||
		cmd_find_current(&fs, NULL, CMD_FIND_QUIET);
 | 
			
		||||
		cmd_find_from_nothing(&fs);
 | 
			
		||||
	notify_add(name, &fs, NULL, s, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								server.c
									
									
									
									
									
								
							@@ -63,7 +63,7 @@ static void	server_child_stopped(pid_t, int);
 | 
			
		||||
void
 | 
			
		||||
server_set_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(&marked_pane, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(&marked_pane, 0);
 | 
			
		||||
	marked_pane.s = s;
 | 
			
		||||
	marked_pane.wl = wl;
 | 
			
		||||
	marked_pane.w = wl->window;
 | 
			
		||||
@@ -74,7 +74,7 @@ server_set_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
 | 
			
		||||
void
 | 
			
		||||
server_clear_marked(void)
 | 
			
		||||
{
 | 
			
		||||
	cmd_find_clear_state(&marked_pane, NULL, 0);
 | 
			
		||||
	cmd_find_clear_state(&marked_pane, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Is this the marked pane? */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1145,7 +1145,6 @@ enum cmd_find_type {
 | 
			
		||||
	CMD_FIND_SESSION,
 | 
			
		||||
};
 | 
			
		||||
struct cmd_find_state {
 | 
			
		||||
	struct cmdq_item	*item;
 | 
			
		||||
	int			 flags;
 | 
			
		||||
	struct cmd_find_state	*current;
 | 
			
		||||
 | 
			
		||||
@@ -1730,14 +1729,10 @@ long long	 args_strtonum(struct args *, u_char, long long, long long,
 | 
			
		||||
		     char **);
 | 
			
		||||
 | 
			
		||||
/* cmd-find.c */
 | 
			
		||||
int		 cmd_find_current(struct cmd_find_state *, struct cmdq_item *,
 | 
			
		||||
		     int);
 | 
			
		||||
int		 cmd_find_target(struct cmd_find_state *,
 | 
			
		||||
		     struct cmd_find_state *, struct cmdq_item *, const char *,
 | 
			
		||||
		     enum cmd_find_type, int);
 | 
			
		||||
int		 cmd_find_target(struct cmd_find_state *, struct cmdq_item *,
 | 
			
		||||
		     const char *, enum cmd_find_type, int);
 | 
			
		||||
struct client	*cmd_find_client(struct cmdq_item *, const char *, int);
 | 
			
		||||
void		 cmd_find_clear_state(struct cmd_find_state *,
 | 
			
		||||
		     struct cmdq_item *, int);
 | 
			
		||||
void		 cmd_find_clear_state(struct cmd_find_state *, int);
 | 
			
		||||
int		 cmd_find_empty_state(struct cmd_find_state *);
 | 
			
		||||
int		 cmd_find_valid_state(struct cmd_find_state *);
 | 
			
		||||
void		 cmd_find_copy_state(struct cmd_find_state *,
 | 
			
		||||
@@ -1750,10 +1745,14 @@ void		 cmd_find_from_winlink(struct cmd_find_state *,
 | 
			
		||||
int		 cmd_find_from_session_window(struct cmd_find_state *,
 | 
			
		||||
		     struct session *, struct window *);
 | 
			
		||||
int		 cmd_find_from_window(struct cmd_find_state *, struct window *);
 | 
			
		||||
int		 cmd_find_from_pane(struct cmd_find_state *,
 | 
			
		||||
		     struct window_pane *);
 | 
			
		||||
void		 cmd_find_from_winlink_pane(struct cmd_find_state *,
 | 
			
		||||
		     struct winlink *, struct window_pane *);
 | 
			
		||||
int		 cmd_find_from_pane(struct cmd_find_state *,
 | 
			
		||||
		     struct window_pane *);
 | 
			
		||||
int		 cmd_find_from_client(struct cmd_find_state *, struct client *);
 | 
			
		||||
int		 cmd_find_from_mouse(struct cmd_find_state *,
 | 
			
		||||
		     struct mouse_event *);
 | 
			
		||||
int		 cmd_find_from_nothing(struct cmd_find_state *);
 | 
			
		||||
 | 
			
		||||
/* cmd.c */
 | 
			
		||||
int		 cmd_pack_argv(int, char **, char *, size_t);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user