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:
Tiago Cunha
2010-12-22 15:36:44 +00:00
parent 9f3399da00
commit a373235106
12 changed files with 155 additions and 195 deletions

59
cmd.c
View File

@ -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) {