Add detach-on-destroy previous and next, mostly from Alexis Hildebrandt.

This commit is contained in:
nicm 2023-09-01 13:48:54 +00:00
parent 71d453f169
commit c1e6e54e6e
4 changed files with 44 additions and 34 deletions

View File

@ -86,7 +86,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", "previous", "next", NULL
};
static const char *options_table_extended_keys_list[] = {
"off", "on", "always", NULL

View File

@ -29,8 +29,7 @@
#include "tmux.h"
static struct session *server_next_session(struct session *);
static void server_destroy_session_group(struct session *);
static void server_destroy_session_group(struct session *);
void
server_redraw_client(struct client *c)
@ -209,8 +208,8 @@ server_kill_window(struct window *w, int renumber)
if (session_detach(s, wl)) {
server_destroy_session_group(s);
break;
} else
server_redraw_session_group(s);
}
server_redraw_session_group(s);
}
if (renumber)
@ -384,9 +383,10 @@ server_destroy_session_group(struct session *s)
struct session_group *sg;
struct session *s1;
if ((sg = session_group_contains(s)) == NULL)
if ((sg = session_group_contains(s)) == NULL) {
server_destroy_session(s);
else {
session_destroy(s, 1, __func__);
} else {
TAILQ_FOREACH_SAFE(s, &sg->sessions, gentry, s1) {
server_destroy_session(s);
session_destroy(s, 1, __func__);
@ -395,52 +395,55 @@ server_destroy_session_group(struct session *s)
}
static struct session *
server_next_session(struct session *s)
server_find_session(struct session *s,
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 (s_loop != s && (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
server_newer_session(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
server_newer_detached_session(struct session *s_loop, struct session *s_out)
{
if (s_loop->attached)
return (0);
return (server_newer_session(s_loop, s_out));
}
void
server_destroy_session(struct session *s)
{
struct client *c;
struct session *s_new;
struct session *s_new = NULL;
int detach_on_destroy;
detach_on_destroy = options_get_number(s->options, "detach-on-destroy");
if (detach_on_destroy == 0)
s_new = server_next_session(s);
s_new = server_find_session(s, server_newer_session);
else if (detach_on_destroy == 2)
s_new = server_next_detached_session(s);
else
s_new = server_find_session(s, server_newer_detached_session);
else if (detach_on_destroy == 3)
s_new = session_previous_session(s);
else if (detach_on_destroy == 4)
s_new = session_next_session(s);
if (s_new == s)
s_new = NULL;
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
c->session = NULL;
c->last_session = NULL;
server_client_set_session(c, s_new);
if (s_new == NULL)
c->flags |= CLIENT_EXIT;

View File

@ -367,11 +367,9 @@ session_detach(struct session *s, struct winlink *wl)
session_group_synchronize_from(s);
if (RB_EMPTY(&s->windows)) {
session_destroy(s, 1, __func__);
if (RB_EMPTY(&s->windows))
return (1);
}
return (0);
return (0);
}
/* Return if session has window. */

15
tmux.1
View File

@ -4039,16 +4039,25 @@ 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 | previous | next
.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
If
.Ic off ,
the client is switched to the most recently active of the remaining
sessions.
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 previous
or
.Ic next ,
the client is switched to the previous or next session in alphabetical order.
.It Ic display-panes-active-colour Ar colour
Set the colour used by the
.Ic display-panes