Add detach-on-destroy previous and next, mostly from Alexis Hildebrandt.
authornicm <nicm@openbsd.org>
Fri, 1 Sep 2023 13:48:54 +0000 (13:48 +0000)
committernicm <nicm@openbsd.org>
Fri, 1 Sep 2023 13:48:54 +0000 (13:48 +0000)
usr.bin/tmux/options-table.c
usr.bin/tmux/server-fn.c
usr.bin/tmux/session.c
usr.bin/tmux/tmux.1

index 9b46389..7f51a0a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.167 2023/08/15 07:01:47 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.168 2023/09/01 13:48:54 nicm Exp $ */
 
 /*
  * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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
index 36c7231..75acd18 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-fn.c,v 1.133 2022/03/08 18:31:46 nicm Exp $ */
+/* $OpenBSD: server-fn.c,v 1.134 2023/09/01 13:48:54 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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;
index 84bcbf4..6884939 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.94 2023/07/19 13:03:36 nicm Exp $ */
+/* $OpenBSD: session.c,v 1.95 2023/09/01 13:48:54 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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. */
index e3a6d84..1072bf7 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.929 2023/08/23 08:40:25 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.930 2023/09/01 13:48:54 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
 .\"
@@ -14,7 +14,7 @@
 .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: August 23 2023 $
+.Dd $Mdocdate: September 1 2023 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -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