mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Sync OpenBSD patchset 806:
Store sessions in an RB tree by name rather than a list, this is tidier and allows them to easily be shown sorted in various lists (list-sessions/choose-sessions). Keep a session index which is used in a couple of places internally but make it an ever-increasing number rather than filling in gaps with new sessions.
This commit is contained in:
		
							
								
								
									
										59
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								cmd.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd.c,v 1.145 2010-12-06 21:48:56 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd.c,v 1.146 2010-12-22 15:36:44 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -111,7 +111,8 @@ const struct cmd_entry *cmd_table[] = {
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct session	*cmd_choose_session(struct sessions *);
 | 
			
		||||
struct session	*cmd_choose_session_list(struct sessionslist *);
 | 
			
		||||
struct session	*cmd_choose_session(void);
 | 
			
		||||
struct client	*cmd_choose_client(struct clients *);
 | 
			
		||||
struct client	*cmd_lookup_client(const char *);
 | 
			
		||||
struct session	*cmd_lookup_session(const char *, int *);
 | 
			
		||||
@@ -315,10 +316,9 @@ cmd_current_session(struct cmd_ctx *ctx)
 | 
			
		||||
	struct msg_command_data	*data = ctx->msgdata;
 | 
			
		||||
	struct client		*c = ctx->cmdclient;
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
	struct sessions		 ss;
 | 
			
		||||
	struct sessionslist	 ss;
 | 
			
		||||
	struct winlink		*wl;
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
	int			 found;
 | 
			
		||||
 | 
			
		||||
	if (ctx->curclient != NULL && ctx->curclient->session != NULL)
 | 
			
		||||
@@ -331,9 +331,7 @@ cmd_current_session(struct cmd_ctx *ctx)
 | 
			
		||||
	 */
 | 
			
		||||
	if (c != NULL && c->tty.path != NULL) {
 | 
			
		||||
		ARRAY_INIT(&ss);
 | 
			
		||||
		for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
			
		||||
			if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
 | 
			
		||||
				continue;
 | 
			
		||||
		RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
			found = 0;
 | 
			
		||||
			RB_FOREACH(wl, winlinks, &s->windows) {
 | 
			
		||||
				TAILQ_FOREACH(wp, &wl->window->panes, entry) {
 | 
			
		||||
@@ -349,25 +347,43 @@ cmd_current_session(struct cmd_ctx *ctx)
 | 
			
		||||
				ARRAY_ADD(&ss, s);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s = cmd_choose_session(&ss);
 | 
			
		||||
		s = cmd_choose_session_list(&ss);
 | 
			
		||||
		ARRAY_FREE(&ss);
 | 
			
		||||
		if (s != NULL)
 | 
			
		||||
			return (s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Use the session from the TMUX environment variable. */
 | 
			
		||||
	if (data != NULL &&
 | 
			
		||||
	    data->pid == getpid() &&
 | 
			
		||||
	    data->idx <= ARRAY_LENGTH(&sessions) &&
 | 
			
		||||
	    (s = ARRAY_ITEM(&sessions, data->idx)) != NULL)
 | 
			
		||||
		return (s);
 | 
			
		||||
	if (data != NULL && data->pid == getpid()) {
 | 
			
		||||
		s = session_find_by_index(data->idx);
 | 
			
		||||
		if (s != NULL)
 | 
			
		||||
			return (s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (cmd_choose_session(&sessions));
 | 
			
		||||
	return (cmd_choose_session());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find the most recently used session. */
 | 
			
		||||
struct session *
 | 
			
		||||
cmd_choose_session(void)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s, *sbest;
 | 
			
		||||
	struct timeval	*tv = NULL;
 | 
			
		||||
 | 
			
		||||
	sbest = NULL;
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
		if (tv == NULL || timercmp(&s->activity_time, tv, >)) {
 | 
			
		||||
			sbest = s;
 | 
			
		||||
			tv = &s->activity_time;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (sbest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find the most recently used session from a list. */
 | 
			
		||||
struct session *
 | 
			
		||||
cmd_choose_session(struct sessions *ss)
 | 
			
		||||
cmd_choose_session_list(struct sessionslist *ss)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s, *sbest;
 | 
			
		||||
	struct timeval	*tv = NULL;
 | 
			
		||||
@@ -515,7 +531,6 @@ struct session *
 | 
			
		||||
cmd_lookup_session(const char *name, int *ambiguous)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s, *sfound;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	*ambiguous = 0;
 | 
			
		||||
 | 
			
		||||
@@ -524,21 +539,15 @@ cmd_lookup_session(const char *name, int *ambiguous)
 | 
			
		||||
	 * be unique so an exact match can't be ambigious and can just be
 | 
			
		||||
	 * returned.
 | 
			
		||||
	 */
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
			
		||||
		if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (strcmp(name, s->name) == 0)
 | 
			
		||||
			return (s);
 | 
			
		||||
	}
 | 
			
		||||
	if ((s = session_find(name)) != NULL)
 | 
			
		||||
		return (s);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Otherwise look for partial matches, returning early if it is found to
 | 
			
		||||
	 * be ambiguous.
 | 
			
		||||
	 */
 | 
			
		||||
	sfound = NULL;
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
			
		||||
		if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
		if (strncmp(name, s->name, strlen(name)) == 0 ||
 | 
			
		||||
		    fnmatch(name, s->name, 0) == 0) {
 | 
			
		||||
			if (sfound != NULL) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user