Add support for a single "marked pane". There is one marked pane in the
authornicm <nicm@openbsd.org>
Thu, 4 Jun 2015 11:43:51 +0000 (11:43 +0000)
committernicm <nicm@openbsd.org>
Thu, 4 Jun 2015 11:43:51 +0000 (11:43 +0000)
server at a time; it may be toggled or cleared with select-pane -m and
-M (the border is highlighted). A new target '~' or '{marked}' specifies
the marked pane to commands and it is the default target for the
swap-pane and join-pane -s flag (this makes them much simpler to use -
mark the source pane and then change to the target pane to run swapp or
joinp).

usr.bin/tmux/cmd-find.c
usr.bin/tmux/cmd-join-pane.c
usr.bin/tmux/cmd-select-pane.c
usr.bin/tmux/cmd-swap-pane.c
usr.bin/tmux/cmd-swap-window.c
usr.bin/tmux/key-bindings.c
usr.bin/tmux/screen-redraw.c
usr.bin/tmux/server.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h
usr.bin/tmux/window.c

index 28c9758..dcfda1c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-find.c,v 1.7 2015/05/07 11:42:56 nicm Exp $ */
+/* $OpenBSD: cmd-find.c,v 1.8 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,6 +29,7 @@
 #define CMD_FIND_PREFER_UNATTACHED 0x1
 #define CMD_FIND_QUIET 0x2
 #define CMD_FIND_WINDOW_INDEX 0x4
+#define CMD_FIND_DEFAULT_MARKED 0x8
 
 enum cmd_find_type {
        CMD_FIND_PANE,
@@ -759,7 +760,14 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
 
        /* Find current state. */
        cmd_find_clear_state(&current, cmdq, flags);
-       if (cmd_find_current_session(&current) != 0) {
+       if (server_check_marked() && (flags & CMD_FIND_DEFAULT_MARKED)) {
+               current.s = marked_session;
+               current.wl = marked_winlink;
+               current.idx = current.wl->idx;
+               current.w = current.wl->window;
+               current.wp = marked_window_pane;
+       }
+       if (current.s == NULL && cmd_find_current_session(&current) != 0) {
                if (~flags & CMD_FIND_QUIET)
                        cmdq_error(cmdq, "no current session");
                goto error;
@@ -798,9 +806,24 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
                }
                return (&fs);
        }
-       copy = xstrdup(target);
+
+       /* Marked target is a plain ~ or {marked}. */
+       if (strcmp(target, "~") == 0 || strcmp(target, "{marked}") == 0) {
+               if (!server_check_marked()) {
+                       if (~flags & CMD_FIND_QUIET)
+                               cmdq_error(cmdq, "no marked target");
+                       goto error;
+               }
+               fs.s = marked_session;
+               fs.wl = marked_winlink;
+               fs.idx = fs.wl->idx;
+               fs.w = fs.wl->window;
+               fs.wp = marked_window_pane;
+               return (&fs);
+       }
 
        /* Find separators if they exist. */
+       copy = xstrdup(target);
        colon = strchr(copy, ':');
        if (colon != NULL)
                *colon++ = '\0';
@@ -1053,6 +1076,24 @@ cmd_find_window(struct cmd_q *cmdq, const char *target, struct session **sp)
        return (fs->wl);
 }
 
+/* Find the target window, defaulting to marked rather than current. */
+struct winlink *
+cmd_find_window_marked(struct cmd_q *cmdq, const char *target,
+    struct session **sp)
+{
+       struct cmd_find_state   *fs;
+       int                      flags = CMD_FIND_DEFAULT_MARKED;
+
+       fs = cmd_find_target(cmdq, target, CMD_FIND_WINDOW, flags);
+       cmd_find_log_state(__func__, target, fs);
+       if (fs == NULL)
+               return (NULL);
+
+       if (sp != NULL)
+               *sp = fs->s;
+       return (fs->wl);
+}
+
 /* Find the target pane and report an error and return NULL. */
 struct winlink *
 cmd_find_pane(struct cmd_q *cmdq, const char *target, struct session **sp,
@@ -1072,6 +1113,26 @@ cmd_find_pane(struct cmd_q *cmdq, const char *target, struct session **sp,
        return (fs->wl);
 }
 
+/* Find the target pane, defaulting to marked rather than current. */
+struct winlink *
+cmd_find_pane_marked(struct cmd_q *cmdq, const char *target,
+    struct session **sp, struct window_pane **wpp)
+{
+       struct cmd_find_state   *fs;
+       int                      flags = CMD_FIND_DEFAULT_MARKED;
+
+       fs = cmd_find_target(cmdq, target, CMD_FIND_PANE, flags);
+       cmd_find_log_state(__func__, target, fs);
+       if (fs == NULL)
+               return (NULL);
+
+       if (sp != NULL)
+               *sp = fs->s;
+       if (wpp != NULL)
+               *wpp = fs->wp;
+       return (fs->wl);
+}
+
 /* Find the target client or report an error and return NULL. */
 struct client *
 cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet)
index f8fa8a6..d9971e3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-join-pane.c,v 1.17 2014/10/20 22:29:25 nicm Exp $ */
+/* $OpenBSD: cmd-join-pane.c,v 1.18 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2011 George Nachman <tmux@georgester.com>
@@ -75,7 +75,7 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
        dst_idx = dst_wl->idx;
        server_unzoom_window(dst_w);
 
-       src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
+       src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL, &src_wp);
        if (src_wl == NULL)
                return (CMD_RETURN_ERROR);
        src_w = src_wl->window;
index 85cfc40..248e5ac 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-select-pane.c,v 1.23 2015/04/29 16:26:17 nicm Exp $ */
+/* $OpenBSD: cmd-select-pane.c,v 1.24 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,8 +28,8 @@ enum cmd_retval        cmd_select_pane_exec(struct cmd *, struct cmd_q *);
 
 const struct cmd_entry cmd_select_pane_entry = {
        "select-pane", "selectp",
-       "DdegLlP:Rt:U", 0, 0,
-       "[-DdegLlRU] [-P style] " CMD_TARGET_PANE_USAGE,
+       "DdegLlMmP:Rt:U", 0, 0,
+       "[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE,
        0,
        cmd_select_pane_exec
 };
@@ -47,7 +47,8 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
 {
        struct args             *args = self->args;
        struct winlink          *wl;
-       struct window_pane      *wp;
+       struct session          *s;
+       struct window_pane      *wp, *lastwp, *markedwp;
        const char              *style;
 
        if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
@@ -74,9 +75,31 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
                return (CMD_RETURN_NORMAL);
        }
 
-       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
+       if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
                return (CMD_RETURN_ERROR);
 
+       if (args_has(args, 'm') || args_has(args, 'M')) {
+               if (args_has(args, 'm') && !window_pane_visible(wp))
+                       return (CMD_RETURN_NORMAL);
+               lastwp = marked_window_pane;
+
+               if (args_has(args, 'M') || server_is_marked(s, wl, wp))
+                       server_clear_marked();
+               else
+                       server_set_marked(s, wl, wp);
+               markedwp = marked_window_pane;
+
+               if (lastwp != NULL) {
+                       server_redraw_window_borders(lastwp->window);
+                       server_status_window(lastwp->window);
+               }
+               if (markedwp != NULL) {
+                       server_redraw_window_borders(markedwp->window);
+                       server_status_window(markedwp->window);
+               }
+               return (CMD_RETURN_NORMAL);
+       }
+
        if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
                if (args_has(args, 'P')) {
                        style = args_get(args, 'P');
index 59554c1..100d18c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-swap-pane.c,v 1.19 2014/10/20 22:29:25 nicm Exp $ */
+/* $OpenBSD: cmd-swap-pane.c,v 1.20 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -58,18 +58,22 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
                        src_wp = TAILQ_NEXT(dst_wp, entry);
                        if (src_wp == NULL)
                                src_wp = TAILQ_FIRST(&dst_w->panes);
+                       src_wl = dst_wl;
                } else if (args_has(self->args, 'U')) {
                        src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
                        if (src_wp == NULL)
                                src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
+                       src_wl = dst_wl;
                } else {
-                       src_wl = cmd_find_pane(cmdq, NULL, NULL, &src_wp);
+                       src_wl = cmd_find_pane_marked(cmdq, NULL, NULL,
+                           &src_wp);
                        if (src_wl == NULL)
                                return (CMD_RETURN_ERROR);
                        src_w = src_wl->window;
                }
        } else {
-               src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
+               src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL,
+                   &src_wp);
                if (src_wl == NULL)
                        return (CMD_RETURN_ERROR);
                src_w = src_wl->window;
index a8cd845..bae3ec5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-swap-window.c,v 1.11 2014/10/20 22:29:25 nicm Exp $ */
+/* $OpenBSD: cmd-swap-window.c,v 1.12 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,7 +47,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
        struct window           *w;
 
        target_src = args_get(args, 's');
-       if ((wl_src = cmd_find_window(cmdq, target_src, &src)) == NULL)
+       if ((wl_src = cmd_find_window_marked(cmdq, target_src, &src)) == NULL)
                return (CMD_RETURN_ERROR);
        target_dst = args_get(args, 't');
        if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL)
index af436d3..bcee036 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: key-bindings.c,v 1.48 2015/05/07 11:42:56 nicm Exp $ */
+/* $OpenBSD: key-bindings.c,v 1.49 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -177,6 +177,7 @@ key_bindings_init(void)
                "bind ? list-keys",
                "bind D choose-client",
                "bind L switch-client -l",
+               "bind M select-pane -M",
                "bind [ copy-mode",
                "bind ] paste-buffer",
                "bind c new-window",
@@ -184,6 +185,7 @@ key_bindings_init(void)
                "bind f command-prompt \"find-window '%%'\"",
                "bind i display-message",
                "bind l last-window",
+               "bind m select-pane -m",
                "bind n next-window",
                "bind o select-pane -t:.+",
                "bind p previous-window",
@@ -222,6 +224,7 @@ key_bindings_init(void)
                "bind -n MouseDrag1Border resize-pane -M",
                "bind -n MouseDown1Status select-window -t=",
                "bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'",
+               "bind -n MouseDown3Pane select-pane -mt=",
        };
        u_int            i;
        struct cmd_list *cmdlist;
index 396500c..1f86a2d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen-redraw.c,v 1.31 2015/05/07 07:16:14 nicm Exp $ */
+/* $OpenBSD: screen-redraw.c,v 1.32 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,8 +26,8 @@ int   screen_redraw_cell_border1(struct window_pane *, u_int, u_int);
 int    screen_redraw_cell_border(struct client *, u_int, u_int);
 int    screen_redraw_check_cell(struct client *, u_int, u_int,
            struct window_pane **);
-int    screen_redraw_check_active(u_int, u_int, int, struct window *,
-           struct window_pane *);
+int    screen_redraw_check_is(u_int, u_int, int, struct window *,
+           struct window_pane *, struct window_pane *);
 
 void   screen_redraw_draw_borders(struct client *, int, u_int);
 void   screen_redraw_draw_panes(struct client *, u_int);
@@ -175,13 +175,13 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py,
        return (CELL_OUTSIDE);
 }
 
-/* Check active pane indicator. */
+/* Check if the border of a particular pane. */
 int
-screen_redraw_check_active(u_int px, u_int py, int type, struct window *w,
-    struct window_pane *wp)
+screen_redraw_check_is(u_int px, u_int py, int type, struct window *w,
+    struct window_pane *wantwp, struct window_pane *wp)
 {
        /* Is this off the active pane border? */
-       if (screen_redraw_cell_border1(w->active, px, py) != 1)
+       if (screen_redraw_cell_border1(wantwp, px, py) != 1)
                return (0);
 
        /* If there are more than two panes, that's enough. */
@@ -196,7 +196,7 @@ screen_redraw_check_active(u_int px, u_int py, int type, struct window *w,
        if (wp->xoff == 0 && wp->sx == w->sx) {
                /* This can either be the top pane or the bottom pane. */
                if (wp->yoff == 0) { /* top pane */
-                       if (wp == w->active)
+                       if (wp == wantwp)
                                return (px <= wp->sx / 2);
                        return (px > wp->sx / 2);
                }
@@ -207,7 +207,7 @@ screen_redraw_check_active(u_int px, u_int py, int type, struct window *w,
        if (wp->yoff == 0 && wp->sy == w->sy) {
                /* This can either be the left pane or the right pane. */
                if (wp->xoff == 0) { /* left pane */
-                       if (wp == w->active)
+                       if (wp == wantwp)
                                return (py <= wp->sy / 2);
                        return (py > wp->sy / 2);
                }
@@ -274,13 +274,15 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
 void
 screen_redraw_draw_borders(struct client *c, int status, u_int top)
 {
-       struct window           *w = c->session->curw->window;
+       struct session          *s = c->session;
+       struct window           *w = s->curw->window;
        struct options          *oo = &w->options;
        struct tty              *tty = &c->tty;
        struct window_pane      *wp;
-       struct grid_cell         active_gc, other_gc, msg_gc;
+       struct grid_cell         m_active_gc, active_gc, m_other_gc, other_gc;
+       struct grid_cell         msg_gc;
        u_int                    i, j, type, msgx = 0, msgy = 0;
-       int                      small, flags;
+       int                      active, small, flags;
        char                     msg[256];
        const char              *tmp;
        size_t                   msglen = 0;
@@ -314,15 +316,29 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
        style_apply(&active_gc, oo, "pane-active-border-style");
        active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET;
 
+       memcpy(&m_other_gc, &other_gc, sizeof m_other_gc);
+       m_other_gc.attr ^= GRID_ATTR_REVERSE;
+       memcpy(&m_active_gc, &active_gc, sizeof m_active_gc);
+       m_active_gc.attr ^= GRID_ATTR_REVERSE;
+
        for (j = 0; j < tty->sy - status; j++) {
                for (i = 0; i < tty->sx; i++) {
                        type = screen_redraw_check_cell(c, i, j, &wp);
                        if (type == CELL_INSIDE)
                                continue;
-                       if (type == CELL_OUTSIDE &&
-                           small && i > msgx && j == msgy)
+                       if (type == CELL_OUTSIDE && small &&
+                           i > msgx && j == msgy)
                                continue;
-                       if (screen_redraw_check_active(i, j, type, w, wp))
+                       active = screen_redraw_check_is(i, j, type, w,
+                           w->active, wp);
+                       if (server_is_marked(s, s->curw, marked_window_pane) &&
+                           screen_redraw_check_is(i, j, type, w,
+                           marked_window_pane, wp)) {
+                               if (active)
+                                       tty_attributes(tty, &m_active_gc, NULL);
+                               else
+                                       tty_attributes(tty, &m_other_gc, NULL);
+                       } else if (active)
                                tty_attributes(tty, &active_gc, NULL);
                        else
                                tty_attributes(tty, &other_gc, NULL);
index 53d65d5..98cecda 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.125 2015/06/01 09:20:19 nicm Exp $ */
+/* $OpenBSD: server.c,v 1.126 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -50,19 +50,85 @@ int          server_shutdown;
 struct event    server_ev_accept;
 struct event    server_ev_second;
 
-int             server_create_socket(void);
-void            server_loop(void);
-int             server_should_shutdown(void);
-void            server_send_shutdown(void);
-void            server_clean_dead(void);
-void            server_accept_callback(int, short, void *);
-void            server_signal_callback(int, short, void *);
-void            server_child_signal(void);
-void            server_child_exited(pid_t, int);
-void            server_child_stopped(pid_t, int);
-void            server_second_callback(int, short, void *);
-void            server_lock_server(void);
-void            server_lock_sessions(void);
+struct session         *marked_session;
+struct winlink         *marked_winlink;
+struct window          *marked_window;
+struct window_pane     *marked_window_pane;
+struct layout_cell     *marked_layout_cell;
+
+int    server_create_socket(void);
+void   server_loop(void);
+int    server_should_shutdown(void);
+void   server_send_shutdown(void);
+void   server_clean_dead(void);
+void   server_accept_callback(int, short, void *);
+void   server_signal_callback(int, short, void *);
+void   server_child_signal(void);
+void   server_child_exited(pid_t, int);
+void   server_child_stopped(pid_t, int);
+void   server_second_callback(int, short, void *);
+void   server_lock_server(void);
+void   server_lock_sessions(void);
+
+/* Set marked pane. */
+void
+server_set_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
+{
+       marked_session = s;
+       marked_winlink = wl;
+       marked_window = wl->window;
+       marked_window_pane = wp;
+       marked_layout_cell = wp->layout_cell;
+}
+
+/* Clear marked pane. */
+void
+server_clear_marked(void)
+{
+       marked_session = NULL;
+       marked_winlink = NULL;
+       marked_window = NULL;
+       marked_window_pane = NULL;
+       marked_layout_cell = NULL;
+}
+
+/* Is this the marked pane? */
+int
+server_is_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
+{
+       if (s == NULL || wl == NULL || wp == NULL)
+               return (0);
+       if (marked_session != s || marked_winlink != wl)
+               return (0);
+       if (marked_window_pane != wp)
+               return (0);
+       return (server_check_marked());
+}
+
+/* Check if the marked pane is still valid. */
+int
+server_check_marked(void)
+{
+       struct winlink  *wl;
+
+       if (marked_window_pane == NULL)
+               return (0);
+       if (marked_layout_cell != marked_window_pane->layout_cell)
+               return (0);
+
+       if (!session_alive(marked_session))
+               return (0);
+       RB_FOREACH(wl, winlinks, &marked_session->windows) {
+               if (wl->window == marked_window && wl == marked_winlink)
+                       break;
+       }
+       if (wl == NULL)
+               return (0);
+
+       if (!window_has_pane(marked_window, marked_window_pane))
+               return (0);
+       return (window_pane_visible(marked_window_pane));
+}
 
 /* Create server socket. */
 int
index 6d0fd14..bd5a4c1 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.431 2015/05/27 13:28:04 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.432 2015/06/04 11:43:51 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 .\"
@@ -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: May 27 2015 $
+.Dd $Mdocdate: June 4 2015 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -298,6 +298,12 @@ Change to the previous window.
 Briefly display pane indexes.
 .It r
 Force redraw of the attached client.
+.It m
+Mark the current pane (see
+.Ic select-pane
+.Fl m ) .
+.It M
+Clear the marked pane.
 .It s
 Select a new session for the attached client interactively.
 .It t
@@ -351,6 +357,8 @@ This section contains a list of the commands supported by
 .Nm .
 Most commands accept the optional
 .Fl t
+(and sometimes
+.Fl s )
 argument with one of
 .Ar target-client ,
 .Ar target-session
@@ -451,7 +459,6 @@ Each has a single-character alternative form.
 .It Li "{last}" Ta "!" Ta "The last (previously current) window"
 .It Li "{next}" Ta "+" Ta "The next window by number"
 .It Li "{previous}" Ta "-" Ta "The previous window by number"
-.It Li "{mouse}" Ta "=" Ta "The window where the mouse event happened"
 .El
 .Pp
 .Ar target-pane
@@ -481,7 +488,6 @@ The following special tokens are available for the pane index:
 .It Li "{down}" Ta "" Ta "The pane below the active pane"
 .It Li "{left}" Ta "" Ta "The pane to the left of the active pane"
 .It Li "{right}" Ta "" Ta "The pane to the right of the active pane"
-.It Li "{mouse}" Ta "=" Ta "The pane where the mouse event happened"
 .El
 .Pp
 The tokens
@@ -493,6 +499,27 @@ may be followed by an offset, for example:
 select-window -t:+2
 .Ed
 .Pp
+In addition,
+.Em target-session ,
+.Em target-window
+or
+.Em target-pane
+may consist entirely of the token
+.Ql {mouse}
+(alternative form
+.Ql = )
+to specify the most recent mouse event
+(see the
+.Sx MOUSE SUPPORT
+section)
+or
+.Ql {marked}
+(alternative form
+.Ql ~ )
+to specify the marked pane (see
+.Ic select-pane
+.Fl m ) .
+.Pp
 Sessions, window and panes are each numbered with a unique ID; session IDs are
 prefixed with a
 .Ql $ ,
@@ -1440,6 +1467,13 @@ option causes
 .Ar src-pane
 to be joined to left of or above
 .Ar dst-pane .
+.Pp
+If
+.Fl s
+is omitted and a marked pane is present (see
+.Ic select-pane
+.Fl m ) ,
+the marked pane is used rather than the current pane.
 .It Xo Ic kill-pane
 .Op Fl a
 .Op Fl t Ar target-pane
@@ -1795,7 +1829,7 @@ commands.
 .Fl o
 applies the last set layout if possible (undoes the most recent layout change).
 .It Xo Ic select-pane
-.Op Fl DdegLlRU
+.Op Fl DdegLlMmRU
 .Op Fl P Ar style
 .Op Fl t Ar target-pane
 .Xc
@@ -1823,6 +1857,20 @@ enables or
 .Fl d
 disables input to the pane.
 .Pp
+.Fl m
+and
+.Fl M
+are used to set and clear the
+.Em marked pane .
+There is one marked pane at a time, setting a new marked pane clears the last.
+The marked pane is the default target for
+.Fl s
+to
+.Ic join-pane ,
+.Ic swap-pane
+and
+.Ic swap-window .
+.Pp
 Each pane has a style: by default the
 .Ic window-style
 and
@@ -1911,6 +1959,13 @@ swaps with the next pane (after it numerically).
 instructs
 .Nm
 not to change the active pane.
+.Pp
+If
+.Fl s
+is omitted and a marked pane is present (see
+.Ic select-pane
+.Fl m ) ,
+the marked pane is used rather than the current pane.
 .It Xo Ic swap-window
 .Op Fl d
 .Op Fl s Ar src-window
@@ -1922,6 +1977,15 @@ This is similar to
 except the source and destination windows are swapped.
 It is an error if no window exists at
 .Ar src-window .
+.Pp
+Like
+.Ic swap-pane ,
+if
+.Fl s
+is omitted and a marked pane is present (see
+.Ic select-pane
+.Fl m ) ,
+the window containing the marked pane is used rather than the current window.
 .It Xo Ic unlink-window
 .Op Fl k
 .Op Fl t Ar target-window
@@ -3488,6 +3552,7 @@ The flag is one of the following symbols appended to the window name:
 .It Li "#" Ta "Window is monitored and activity has been detected."
 .It Li "!" Ta "A bell has occurred in the window."
 .It Li "~" Ta "The window has been silent for the monitor-silence interval."
+.It Li "M" Ta "The window contains the marked pane."
 .It Li "Z" Ta "The window's active pane is zoomed."
 .El
 .Pp
index a79ac4a..d3e835a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.515 2015/05/27 13:28:04 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.516 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1688,8 +1688,12 @@ struct session   *cmd_find_current(struct cmd_q *);
 struct session *cmd_find_session(struct cmd_q *, const char *, int);
 struct winlink *cmd_find_window(struct cmd_q *, const char *,
                     struct session **);
+struct winlink *cmd_find_window_marked(struct cmd_q *, const char *,
+                    struct session **);
 struct winlink *cmd_find_pane(struct cmd_q *, const char *, struct session **,
                     struct window_pane **);
+struct winlink *cmd_find_pane_marked(struct cmd_q *, const char *,
+                    struct session **, struct window_pane **);
 struct client  *cmd_find_client(struct cmd_q *, const char *, int);
 int             cmd_find_index(struct cmd_q *, const char *,
                     struct session **);
@@ -1850,6 +1854,15 @@ const char *key_string_lookup_key(int);
 /* server.c */
 extern struct clients clients;
 extern struct clients dead_clients;
+extern struct session *marked_session;
+extern struct winlink *marked_winlink;
+extern struct window_pane *marked_window_pane;
+void    server_set_marked(struct session *, struct winlink *,
+            struct window_pane *);
+void    server_clear_marked(void);
+int     server_is_marked(struct session *, struct winlink *,
+            struct window_pane *);
+int     server_check_marked(void);
 int     server_start(int, char *);
 void    server_update_socket(void);
 void    server_add_accept(int);
index e7e49ee..94489e1 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window.c,v 1.131 2015/05/12 22:40:38 nicm Exp $ */
+/* $OpenBSD: window.c,v 1.132 2015/06/04 11:43:51 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -543,6 +543,9 @@ window_add_pane(struct window *w, u_int hlimit)
 void
 window_lost_pane(struct window *w, struct window_pane *wp)
 {
+       if (wp == marked_window_pane)
+               server_clear_marked();
+
        if (wp == w->active) {
                w->active = w->last;
                w->last = NULL;
@@ -661,6 +664,8 @@ window_printable_flags(struct session *s, struct winlink *wl)
                flags[pos++] = '*';
        if (wl == TAILQ_FIRST(&s->lastw))
                flags[pos++] = '-';
+       if (server_check_marked() && wl == marked_winlink)
+               flags[pos++] = 'M';
        if (wl->window->flags & WINDOW_ZOOMED)
                flags[pos++] = 'Z';
        flags[pos] = '\0';