Add new preceding and following detach-on-destroy option

switching to the session that alphabetically precedes or follows
the current one.
pull/3665/head
Alexis Hildebrandt 2023-08-17 08:31:08 +02:00
parent 12ae2716b3
commit 9a41118a2b
3 changed files with 38 additions and 19 deletions

View File

@ -85,7 +85,7 @@ static const char *options_table_remain_on_exit_list[] = {
"off", "on", "failed", NULL
};
static const char *options_table_detach_on_destroy_list[] = {
"off", "on", "no-detached", NULL
"off", "on", "no-detached", "preceding", "following", NULL
};
static const char *options_table_extended_keys_list[] = {
"off", "on", "always", NULL

View File

@ -395,33 +395,38 @@ server_destroy_session_group(struct session *s)
}
static struct session *
server_recent_session(struct session *s)
server_filtered_session(struct session *s, int attached,
int (*f)(struct session *, struct session *))
{
struct session *s_loop, *s_out = NULL;
RB_FOREACH(s_loop, sessions, &sessions) {
if (s_loop == s)
continue;
if (s_out == NULL ||
timercmp(&s_loop->activity_time, &s_out->activity_time, <))
if (attached && s_loop->attached)
continue;
if (s_out == NULL || f(s_loop, s_out))
s_out = s_loop;
}
return (s_out);
}
static struct session *
server_next_detached_session(struct session *s)
static int
timercmp_filter(struct session *s_loop, struct session *s_out)
{
struct session *s_loop, *s_out = NULL;
return timercmp(&s_loop->activity_time, &s_out->activity_time, <);
}
RB_FOREACH(s_loop, sessions, &sessions) {
if (s_loop == s || s_loop->attached)
continue;
if (s_out == NULL ||
timercmp(&s_loop->activity_time, &s_out->activity_time, <))
s_out = s_loop;
}
return (s_out);
static int
preceding_filter(struct session *s_loop, struct session *s_out)
{
return strncmp(s_loop->name, s_out->name, strlen(s_loop->name)) < 0;
}
static int
following_filter(struct session *s_loop, struct session *s_out)
{
return strncmp(s_loop->name, s_out->name, strlen(s_loop->name)) > 0;
}
void
@ -433,9 +438,13 @@ server_destroy_session(struct session *s)
detach_on_destroy = options_get_number(s->options, "detach-on-destroy");
if (detach_on_destroy == 0)
s_new = server_recent_session(s);
s_new = server_filtered_session(s, 0, timercmp_filter);
else if (detach_on_destroy == 2)
s_new = server_next_detached_session(s);
s_new = server_filtered_session(s, 1, timercmp_filter);
else if (detach_on_destroy == 3)
s_new = server_filtered_session(s, 0, preceding_filter);
else if (detach_on_destroy == 4)
s_new = server_filtered_session(s, 0, following_filter);
else
s_new = NULL;
TAILQ_FOREACH(c, &clients, entry) {

14
tmux.1
View File

@ -4042,9 +4042,11 @@ The default is 80x24.
If enabled and the session is no longer attached to any clients, it is
destroyed.
.It Xo Ic detach-on-destroy
.Op Ic off | on | no-detached
.Op Ic off | on | no-detached | preceding | following
.Xc
If on (the default), the client is detached when the session it is attached to
If
.Ic on
(the default), the client is detached when the session it is attached to
is destroyed.
If off, the client is switched to the most recently active of the remaining
sessions.
@ -4052,6 +4054,14 @@ If
.Ic no-detached ,
the client is detached only if there are no detached sessions; if detached
sessions exist, the client is switched to the most recently active.
If
.Ic preceding ,
the client is switched to the session preceding the current one in alphabetical
order.
If
.Ic following ,
the client is switched to the session following the current one in alphabetical
order.
.It Ic display-panes-active-colour Ar colour
Set the colour used by the
.Ic display-panes