Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam 2015-06-04 12:59:41 +01:00
commit 02e348c069
11 changed files with 296 additions and 40 deletions

View File

@ -28,6 +28,7 @@
#define CMD_FIND_PREFER_UNATTACHED 0x1 #define CMD_FIND_PREFER_UNATTACHED 0x1
#define CMD_FIND_QUIET 0x2 #define CMD_FIND_QUIET 0x2
#define CMD_FIND_WINDOW_INDEX 0x4 #define CMD_FIND_WINDOW_INDEX 0x4
#define CMD_FIND_DEFAULT_MARKED 0x8
enum cmd_find_type { enum cmd_find_type {
CMD_FIND_PANE, CMD_FIND_PANE,
@ -758,7 +759,14 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
/* Find current state. */ /* Find current state. */
cmd_find_clear_state(&current, cmdq, flags); 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) if (~flags & CMD_FIND_QUIET)
cmdq_error(cmdq, "no current session"); cmdq_error(cmdq, "no current session");
goto error; goto error;
@ -797,9 +805,24 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
} }
return (&fs); 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. */ /* Find separators if they exist. */
copy = xstrdup(target);
colon = strchr(copy, ':'); colon = strchr(copy, ':');
if (colon != NULL) if (colon != NULL)
*colon++ = '\0'; *colon++ = '\0';
@ -1052,6 +1075,24 @@ cmd_find_window(struct cmd_q *cmdq, const char *target, struct session **sp)
return (fs->wl); 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. */ /* Find the target pane and report an error and return NULL. */
struct winlink * struct winlink *
cmd_find_pane(struct cmd_q *cmdq, const char *target, struct session **sp, cmd_find_pane(struct cmd_q *cmdq, const char *target, struct session **sp,
@ -1071,6 +1112,26 @@ cmd_find_pane(struct cmd_q *cmdq, const char *target, struct session **sp,
return (fs->wl); 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. */ /* Find the target client or report an error and return NULL. */
struct client * struct client *
cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet) cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet)

View File

@ -74,7 +74,7 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
dst_idx = dst_wl->idx; dst_idx = dst_wl->idx;
server_unzoom_window(dst_w); 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) if (src_wl == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
src_w = src_wl->window; src_w = src_wl->window;

View File

@ -28,8 +28,8 @@ enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_select_pane_entry = { const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp", "select-pane", "selectp",
"DdegLlP:Rt:U", 0, 0, "DdegLlMmP:Rt:U", 0, 0,
"[-DdegLlRU] [-P style] " CMD_TARGET_PANE_USAGE, "[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE,
0, 0,
cmd_select_pane_exec 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 args *args = self->args;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp; struct session *s;
struct window_pane *wp, *lastwp, *markedwp;
const char *style; const char *style;
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) { 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); 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); 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(self->args, 'P') || args_has(self->args, 'g')) {
if (args_has(args, 'P')) { if (args_has(args, 'P')) {
style = args_get(args, 'P'); style = args_get(args, 'P');

View File

@ -58,18 +58,22 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
src_wp = TAILQ_NEXT(dst_wp, entry); src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL) if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes); src_wp = TAILQ_FIRST(&dst_w->panes);
src_wl = dst_wl;
} else if (args_has(self->args, 'U')) { } else if (args_has(self->args, 'U')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry); src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL) if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes); src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
src_wl = dst_wl;
} else { } 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) if (src_wl == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
src_w = src_wl->window; src_w = src_wl->window;
} }
} else { } 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) if (src_wl == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
src_w = src_wl->window; src_w = src_wl->window;

View File

@ -47,7 +47,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window *w; struct window *w;
target_src = args_get(args, 's'); 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); return (CMD_RETURN_ERROR);
target_dst = args_get(args, 't'); target_dst = args_get(args, 't');
if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL) if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL)

View File

@ -177,6 +177,7 @@ key_bindings_init(void)
"bind ? list-keys", "bind ? list-keys",
"bind D choose-client", "bind D choose-client",
"bind L switch-client -l", "bind L switch-client -l",
"bind M select-pane -M",
"bind [ copy-mode", "bind [ copy-mode",
"bind ] paste-buffer", "bind ] paste-buffer",
"bind c new-window", "bind c new-window",
@ -184,6 +185,7 @@ key_bindings_init(void)
"bind f command-prompt \"find-window '%%'\"", "bind f command-prompt \"find-window '%%'\"",
"bind i display-message", "bind i display-message",
"bind l last-window", "bind l last-window",
"bind m select-pane -m",
"bind n next-window", "bind n next-window",
"bind o select-pane -t:.+", "bind o select-pane -t:.+",
"bind p previous-window", "bind p previous-window",
@ -222,6 +224,7 @@ key_bindings_init(void)
"bind -n MouseDrag1Border resize-pane -M", "bind -n MouseDrag1Border resize-pane -M",
"bind -n MouseDown1Status select-window -t=", "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 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; u_int i;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;

View File

@ -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_cell_border(struct client *, u_int, u_int);
int screen_redraw_check_cell(struct client *, u_int, u_int, int screen_redraw_check_cell(struct client *, u_int, u_int,
struct window_pane **); struct window_pane **);
int screen_redraw_check_active(u_int, u_int, int, struct window *, int screen_redraw_check_is(u_int, u_int, int, struct window *,
struct window_pane *); struct window_pane *, struct window_pane *);
void screen_redraw_draw_borders(struct client *, int, u_int); void screen_redraw_draw_borders(struct client *, int, u_int);
void screen_redraw_draw_panes(struct client *, 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); return (CELL_OUTSIDE);
} }
/* Check active pane indicator. */ /* Check if the border of a particular pane. */
int int
screen_redraw_check_active(u_int px, u_int py, int type, struct window *w, screen_redraw_check_is(u_int px, u_int py, int type, struct window *w,
struct window_pane *wp) struct window_pane *wantwp, struct window_pane *wp)
{ {
/* Is this off the active pane border? */ /* 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); return (0);
/* If there are more than two panes, that's enough. */ /* 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) { if (wp->xoff == 0 && wp->sx == w->sx) {
/* This can either be the top pane or the bottom pane. */ /* This can either be the top pane or the bottom pane. */
if (wp->yoff == 0) { /* top pane */ if (wp->yoff == 0) { /* top pane */
if (wp == w->active) if (wp == wantwp)
return (px <= wp->sx / 2); return (px <= wp->sx / 2);
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) { if (wp->yoff == 0 && wp->sy == w->sy) {
/* This can either be the left pane or the right pane. */ /* This can either be the left pane or the right pane. */
if (wp->xoff == 0) { /* left pane */ if (wp->xoff == 0) { /* left pane */
if (wp == w->active) if (wp == wantwp)
return (py <= wp->sy / 2); return (py <= wp->sy / 2);
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 void
screen_redraw_draw_borders(struct client *c, int status, u_int top) 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 options *oo = &w->options;
struct tty *tty = &c->tty; struct tty *tty = &c->tty;
struct window_pane *wp; 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; u_int i, j, type, msgx = 0, msgy = 0;
int small, flags; int active, small, flags;
char msg[256]; char msg[256];
const char *tmp; const char *tmp;
size_t msglen = 0; 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"); style_apply(&active_gc, oo, "pane-active-border-style");
active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET; 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 (j = 0; j < tty->sy - status; j++) {
for (i = 0; i < tty->sx; i++) { for (i = 0; i < tty->sx; i++) {
type = screen_redraw_check_cell(c, i, j, &wp); type = screen_redraw_check_cell(c, i, j, &wp);
if (type == CELL_INSIDE) if (type == CELL_INSIDE)
continue; continue;
if (type == CELL_OUTSIDE && if (type == CELL_OUTSIDE && small &&
small && i > msgx && j == msgy) i > msgx && j == msgy)
continue; 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); tty_attributes(tty, &active_gc, NULL);
else else
tty_attributes(tty, &other_gc, NULL); tty_attributes(tty, &other_gc, NULL);

View File

@ -49,6 +49,12 @@ int server_shutdown;
struct event server_ev_accept; struct event server_ev_accept;
struct event server_ev_second; struct event server_ev_second;
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); int server_create_socket(void);
void server_loop(void); void server_loop(void);
int server_should_shutdown(void); int server_should_shutdown(void);
@ -63,6 +69,66 @@ void server_second_callback(int, short, void *);
void server_lock_server(void); void server_lock_server(void);
void server_lock_sessions(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. */ /* Create server socket. */
int int
server_create_socket(void) server_create_socket(void)

71
tmux.1
View File

@ -302,6 +302,12 @@ Change to the previous window.
Briefly display pane indexes. Briefly display pane indexes.
.It r .It r
Force redraw of the attached client. 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 .It s
Select a new session for the attached client interactively. Select a new session for the attached client interactively.
.It t .It t
@ -355,6 +361,8 @@ This section contains a list of the commands supported by
.Nm . .Nm .
Most commands accept the optional Most commands accept the optional
.Fl t .Fl t
(and sometimes
.Fl s )
argument with one of argument with one of
.Ar target-client , .Ar target-client ,
.Ar target-session .Ar target-session
@ -455,7 +463,6 @@ Each has a single-character alternative form.
.It Li "{last}" Ta "!" Ta "The last (previously current) window" .It Li "{last}" Ta "!" Ta "The last (previously current) window"
.It Li "{next}" Ta "+" Ta "The next window by number" .It Li "{next}" Ta "+" Ta "The next window by number"
.It Li "{previous}" Ta "-" Ta "The previous 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 .El
.Pp .Pp
.Ar target-pane .Ar target-pane
@ -485,7 +492,6 @@ The following special tokens are available for the pane index:
.It Li "{down}" Ta "" Ta "The pane below the active pane" .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 "{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 "{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 .El
.Pp .Pp
The tokens The tokens
@ -497,6 +503,27 @@ may be followed by an offset, for example:
select-window -t:+2 select-window -t:+2
.Ed .Ed
.Pp .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 Sessions, window and panes are each numbered with a unique ID; session IDs are
prefixed with a prefixed with a
.Ql $ , .Ql $ ,
@ -1444,6 +1471,13 @@ option causes
.Ar src-pane .Ar src-pane
to be joined to left of or above to be joined to left of or above
.Ar dst-pane . .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 .It Xo Ic kill-pane
.Op Fl a .Op Fl a
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
@ -1799,7 +1833,7 @@ commands.
.Fl o .Fl o
applies the last set layout if possible (undoes the most recent layout change). applies the last set layout if possible (undoes the most recent layout change).
.It Xo Ic select-pane .It Xo Ic select-pane
.Op Fl DdegLlRU .Op Fl DdegLlMmRU
.Op Fl P Ar style .Op Fl P Ar style
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Xc .Xc
@ -1827,6 +1861,20 @@ enables or
.Fl d .Fl d
disables input to the pane. disables input to the pane.
.Pp .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 Each pane has a style: by default the
.Ic window-style .Ic window-style
and and
@ -1915,6 +1963,13 @@ swaps with the next pane (after it numerically).
instructs instructs
.Nm .Nm
not to change the active pane. 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 .It Xo Ic swap-window
.Op Fl d .Op Fl d
.Op Fl s Ar src-window .Op Fl s Ar src-window
@ -1926,6 +1981,15 @@ This is similar to
except the source and destination windows are swapped. except the source and destination windows are swapped.
It is an error if no window exists at It is an error if no window exists at
.Ar src-window . .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 .It Xo Ic unlink-window
.Op Fl k .Op Fl k
.Op Fl t Ar target-window .Op Fl t Ar target-window
@ -3493,6 +3557,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 "Window is monitored and activity has been detected."
.It Li "!" Ta "A bell has occurred in the window." .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 "~" 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." .It Li "Z" Ta "The window's active pane is zoomed."
.El .El
.Pp .Pp

13
tmux.h
View File

@ -1692,8 +1692,12 @@ struct session *cmd_find_current(struct cmd_q *);
struct session *cmd_find_session(struct cmd_q *, const char *, int); struct session *cmd_find_session(struct cmd_q *, const char *, int);
struct winlink *cmd_find_window(struct cmd_q *, const char *, struct winlink *cmd_find_window(struct cmd_q *, const char *,
struct session **); 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 winlink *cmd_find_pane(struct cmd_q *, const char *, struct session **,
struct window_pane **); 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); struct client *cmd_find_client(struct cmd_q *, const char *, int);
int cmd_find_index(struct cmd_q *, const char *, int cmd_find_index(struct cmd_q *, const char *,
struct session **); struct session **);
@ -1854,6 +1858,15 @@ const char *key_string_lookup_key(int);
/* server.c */ /* server.c */
extern struct clients clients; extern struct clients clients;
extern struct clients dead_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 *); int server_start(int, char *);
void server_update_socket(void); void server_update_socket(void);
void server_add_accept(int); void server_add_accept(int);

View File

@ -542,6 +542,9 @@ window_add_pane(struct window *w, u_int hlimit)
void void
window_lost_pane(struct window *w, struct window_pane *wp) window_lost_pane(struct window *w, struct window_pane *wp)
{ {
if (wp == marked_window_pane)
server_clear_marked();
if (wp == w->active) { if (wp == w->active) {
w->active = w->last; w->active = w->last;
w->last = NULL; w->last = NULL;
@ -660,6 +663,8 @@ window_printable_flags(struct session *s, struct winlink *wl)
flags[pos++] = '*'; flags[pos++] = '*';
if (wl == TAILQ_FIRST(&s->lastw)) if (wl == TAILQ_FIRST(&s->lastw))
flags[pos++] = '-'; flags[pos++] = '-';
if (server_check_marked() && wl == marked_winlink)
flags[pos++] = 'M';
if (wl->window->flags & WINDOW_ZOOMED) if (wl->window->flags & WINDOW_ZOOMED)
flags[pos++] = 'Z'; flags[pos++] = 'Z';
flags[pos] = '\0'; flags[pos] = '\0';