mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 18:38:48 +00:00
PatchSet 870
Date: 2011/03/27 21:27:26 Author: nicm Branch: HEAD Tag: (none) Log: Give each pane created in a tmux server a unique id (starting from 0), put it in the TMUX_PANE environment variable and accept it as a target. Suggested by and with testing and tweaks from Ben Boeckel.
This commit is contained in:
parent
95832241aa
commit
536fc24653
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd-list-panes.c,v 1.7 2011-01-07 14:45:34 tcunha Exp $ */
|
/* $Id: cmd-list-panes.c,v 1.8 2011-04-06 22:16:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -64,8 +64,8 @@ cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
}
|
}
|
||||||
size += gd->hsize * sizeof *gd->linedata;
|
size += gd->hsize * sizeof *gd->linedata;
|
||||||
|
|
||||||
ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes]%s%s",
|
ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes] %%%u%s%s",
|
||||||
n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size,
|
n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size, wp->id,
|
||||||
wp == wp->window->active ? " (active)" : "",
|
wp == wp->window->active ? " (active)" : "",
|
||||||
wp->fd == -1 ? " (dead)" : "");
|
wp->fd == -1 ? " (dead)" : "");
|
||||||
n++;
|
n++;
|
||||||
|
79
cmd.c
79
cmd.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd.c,v 1.149 2011-02-14 23:11:33 tcunha Exp $ */
|
/* $Id: cmd.c,v 1.150 2011-04-06 22:16:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -117,6 +117,9 @@ struct client *cmd_lookup_client(const char *);
|
|||||||
struct session *cmd_lookup_session(const char *, int *);
|
struct session *cmd_lookup_session(const char *, int *);
|
||||||
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
|
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
|
||||||
int cmd_lookup_index(struct session *, const char *, int *);
|
int cmd_lookup_index(struct session *, const char *, int *);
|
||||||
|
struct window_pane *cmd_lookup_paneid(const char *);
|
||||||
|
struct session *cmd_pane_session(struct cmd_ctx *,
|
||||||
|
struct window_pane *, struct winlink **);
|
||||||
struct winlink *cmd_find_window_offset(const char *, struct session *, int *);
|
struct winlink *cmd_find_window_offset(const char *, struct session *, int *);
|
||||||
int cmd_find_index_offset(const char *, struct session *, int *);
|
int cmd_find_index_offset(const char *, struct session *, int *);
|
||||||
struct window_pane *cmd_find_pane_offset(const char *, struct winlink *);
|
struct window_pane *cmd_find_pane_offset(const char *, struct winlink *);
|
||||||
@ -638,11 +641,64 @@ cmd_lookup_index(struct session *s, const char *name, int *ambiguous)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lookup pane id. An initial % means a pane id. sp must already point to the
|
||||||
|
* current session.
|
||||||
|
*/
|
||||||
|
struct window_pane *
|
||||||
|
cmd_lookup_paneid(const char *arg)
|
||||||
|
{
|
||||||
|
const char *errstr;
|
||||||
|
u_int paneid;
|
||||||
|
|
||||||
|
if (*arg != '%')
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
paneid = strtonum(arg + 1, 0, UINT_MAX, &errstr);
|
||||||
|
if (errstr != NULL)
|
||||||
|
return (NULL);
|
||||||
|
return (window_pane_find_by_id(paneid));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find session and winlink for pane. */
|
||||||
|
struct session *
|
||||||
|
cmd_pane_session(struct cmd_ctx *ctx, struct window_pane *wp,
|
||||||
|
struct winlink **wlp)
|
||||||
|
{
|
||||||
|
struct session *s;
|
||||||
|
struct sessionslist ss;
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
|
/* If this pane is in the current session, return that winlink. */
|
||||||
|
s = cmd_current_session(ctx);
|
||||||
|
if (s != NULL) {
|
||||||
|
wl = winlink_find_by_window(&s->windows, wp->window);
|
||||||
|
if (wl != NULL) {
|
||||||
|
if (wlp != NULL)
|
||||||
|
*wlp = wl;
|
||||||
|
return (s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise choose from all sessions with this pane. */
|
||||||
|
ARRAY_INIT(&ss);
|
||||||
|
RB_FOREACH(s, sessions, &sessions) {
|
||||||
|
if (winlink_find_by_window(&s->windows, wp->window) != NULL)
|
||||||
|
ARRAY_ADD(&ss, s);
|
||||||
|
}
|
||||||
|
s = cmd_choose_session_list(&ss);
|
||||||
|
ARRAY_FREE(&ss);
|
||||||
|
if (wlp != NULL)
|
||||||
|
*wlp = winlink_find_by_window(&s->windows, wp->window);
|
||||||
|
return (s);
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the target session or report an error and return NULL. */
|
/* Find the target session or report an error and return NULL. */
|
||||||
struct session *
|
struct session *
|
||||||
cmd_find_session(struct cmd_ctx *ctx, const char *arg)
|
cmd_find_session(struct cmd_ctx *ctx, const char *arg)
|
||||||
{
|
{
|
||||||
struct session *s;
|
struct session *s;
|
||||||
|
struct window_pane *wp;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
char *tmparg;
|
char *tmparg;
|
||||||
size_t arglen;
|
size_t arglen;
|
||||||
@ -653,6 +709,10 @@ cmd_find_session(struct cmd_ctx *ctx, const char *arg)
|
|||||||
return (cmd_current_session(ctx));
|
return (cmd_current_session(ctx));
|
||||||
tmparg = xstrdup(arg);
|
tmparg = xstrdup(arg);
|
||||||
|
|
||||||
|
/* Lookup as pane id. */
|
||||||
|
if ((wp = cmd_lookup_paneid(arg)) != NULL)
|
||||||
|
return (cmd_pane_session(ctx, wp, NULL));
|
||||||
|
|
||||||
/* Trim a single trailing colon if any. */
|
/* Trim a single trailing colon if any. */
|
||||||
arglen = strlen(tmparg);
|
arglen = strlen(tmparg);
|
||||||
if (arglen != 0 && tmparg[arglen - 1] == ':')
|
if (arglen != 0 && tmparg[arglen - 1] == ':')
|
||||||
@ -683,6 +743,7 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
|
|||||||
{
|
{
|
||||||
struct session *s;
|
struct session *s;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
|
struct window_pane *wp;
|
||||||
const char *winptr;
|
const char *winptr;
|
||||||
char *sessptr = NULL;
|
char *sessptr = NULL;
|
||||||
int ambiguous = 0;
|
int ambiguous = 0;
|
||||||
@ -703,6 +764,14 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
|
|||||||
return (s->curw);
|
return (s->curw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lookup as pane id. */
|
||||||
|
if ((wp = cmd_lookup_paneid(arg)) != NULL) {
|
||||||
|
s = cmd_pane_session(ctx, wp, &wl);
|
||||||
|
if (sp != NULL)
|
||||||
|
*sp = s;
|
||||||
|
return (wl);
|
||||||
|
}
|
||||||
|
|
||||||
/* Time to look at the argument. If it is empty, that is an error. */
|
/* Time to look at the argument. If it is empty, that is an error. */
|
||||||
if (*arg == '\0')
|
if (*arg == '\0')
|
||||||
goto not_found;
|
goto not_found;
|
||||||
@ -997,6 +1066,14 @@ cmd_find_pane(struct cmd_ctx *ctx,
|
|||||||
return (s->curw);
|
return (s->curw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lookup as pane id. */
|
||||||
|
if ((*wpp = cmd_lookup_paneid(arg)) != NULL) {
|
||||||
|
s = cmd_pane_session(ctx, *wpp, &wl);
|
||||||
|
if (sp != NULL)
|
||||||
|
*sp = s;
|
||||||
|
return (wl);
|
||||||
|
}
|
||||||
|
|
||||||
/* Look for a separating period. */
|
/* Look for a separating period. */
|
||||||
if ((period = strrchr(arg, '.')) == NULL)
|
if ((period = strrchr(arg, '.')) == NULL)
|
||||||
goto no_period;
|
goto no_period;
|
||||||
|
3
server.c
3
server.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: server.c,v 1.253 2011-02-15 15:12:28 tcunha Exp $ */
|
/* $Id: server.c,v 1.254 2011-04-06 22:16:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -142,6 +142,7 @@ server_start(void)
|
|||||||
log_debug("server started, pid %ld", (long) getpid());
|
log_debug("server started, pid %ld", (long) getpid());
|
||||||
|
|
||||||
ARRAY_INIT(&windows);
|
ARRAY_INIT(&windows);
|
||||||
|
RB_INIT(&all_window_panes);
|
||||||
ARRAY_INIT(&clients);
|
ARRAY_INIT(&clients);
|
||||||
ARRAY_INIT(&dead_clients);
|
ARRAY_INIT(&dead_clients);
|
||||||
RB_INIT(&sessions);
|
RB_INIT(&sessions);
|
||||||
|
13
tmux.1
13
tmux.1
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: tmux.1,v 1.296 2011-03-19 23:27:35 tcunha Exp $
|
.\" $Id: tmux.1,v 1.297 2011-04-06 22:16:33 nicm Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
.\"
|
.\"
|
||||||
@ -453,6 +453,17 @@ select-window -t:+2
|
|||||||
When dealing with a session that doesn't contain sequential window indexes,
|
When dealing with a session that doesn't contain sequential window indexes,
|
||||||
they will be correctly skipped.
|
they will be correctly skipped.
|
||||||
.Pp
|
.Pp
|
||||||
|
.Nm
|
||||||
|
also gives each pane created in a server an identifier consisting of a
|
||||||
|
.Ql %
|
||||||
|
and a number, starting from zero.
|
||||||
|
A pane's identifier is unique for the life of the
|
||||||
|
.Nm
|
||||||
|
server and is passed to the child process of the pane in the
|
||||||
|
.Ev TMUX_PANE
|
||||||
|
environment variable.
|
||||||
|
It may be used alone to target a pane or the window containing it.
|
||||||
|
.Pp
|
||||||
.Ar shell-command
|
.Ar shell-command
|
||||||
arguments are
|
arguments are
|
||||||
.Xr sh 1
|
.Xr sh 1
|
||||||
|
10
tmux.h
10
tmux.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tmux.h,v 1.612 2011-03-19 23:30:37 tcunha Exp $ */
|
/* $Id: tmux.h,v 1.613 2011-04-06 22:16:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -775,6 +775,8 @@ struct window_mode {
|
|||||||
|
|
||||||
/* Child window structure. */
|
/* Child window structure. */
|
||||||
struct window_pane {
|
struct window_pane {
|
||||||
|
u_int id;
|
||||||
|
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct layout_cell *layout_cell;
|
struct layout_cell *layout_cell;
|
||||||
|
|
||||||
@ -817,8 +819,10 @@ struct window_pane {
|
|||||||
void *modedata;
|
void *modedata;
|
||||||
|
|
||||||
TAILQ_ENTRY(window_pane) entry;
|
TAILQ_ENTRY(window_pane) entry;
|
||||||
|
RB_ENTRY(window_pane) tree_entry;
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(window_panes, window_pane);
|
TAILQ_HEAD(window_panes, window_pane);
|
||||||
|
RB_HEAD(window_pane_tree, window_pane);
|
||||||
|
|
||||||
/* Window structure. */
|
/* Window structure. */
|
||||||
struct window {
|
struct window {
|
||||||
@ -1821,8 +1825,11 @@ int screen_check_selection(struct screen *, u_int, u_int);
|
|||||||
|
|
||||||
/* window.c */
|
/* window.c */
|
||||||
extern struct windows windows;
|
extern struct windows windows;
|
||||||
|
extern struct window_pane_tree all_window_panes;
|
||||||
int winlink_cmp(struct winlink *, struct winlink *);
|
int winlink_cmp(struct winlink *, struct winlink *);
|
||||||
RB_PROTOTYPE(winlinks, winlink, entry, winlink_cmp);
|
RB_PROTOTYPE(winlinks, winlink, entry, winlink_cmp);
|
||||||
|
int window_pane_cmp(struct window_pane *, struct window_pane *);
|
||||||
|
RB_PROTOTYPE(window_pane_tree, window_pane, tree_entry, window_pane_cmp);
|
||||||
struct winlink *winlink_find_by_index(struct winlinks *, int);
|
struct winlink *winlink_find_by_index(struct winlinks *, int);
|
||||||
struct winlink *winlink_find_by_window(struct winlinks *, struct window *);
|
struct winlink *winlink_find_by_window(struct winlinks *, struct window *);
|
||||||
int winlink_next_index(struct winlinks *, int);
|
int winlink_next_index(struct winlinks *, int);
|
||||||
@ -1857,6 +1864,7 @@ struct window_pane *window_pane_previous_by_number(struct window *,
|
|||||||
u_int window_pane_index(struct window *, struct window_pane *);
|
u_int window_pane_index(struct window *, struct window_pane *);
|
||||||
u_int window_count_panes(struct window *);
|
u_int window_count_panes(struct window *);
|
||||||
void window_destroy_panes(struct window *);
|
void window_destroy_panes(struct window *);
|
||||||
|
struct window_pane *window_pane_find_by_id(u_int);
|
||||||
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
|
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
|
||||||
void window_pane_destroy(struct window_pane *);
|
void window_pane_destroy(struct window_pane *);
|
||||||
int window_pane_spawn(struct window_pane *, const char *,
|
int window_pane_spawn(struct window_pane *, const char *,
|
||||||
|
33
window.c
33
window.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window.c,v 1.145 2011-02-15 15:09:52 tcunha Exp $ */
|
/* $Id: window.c,v 1.146 2011-04-06 22:16:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -53,6 +53,10 @@
|
|||||||
/* Global window list. */
|
/* Global window list. */
|
||||||
struct windows windows;
|
struct windows windows;
|
||||||
|
|
||||||
|
/* Global panes tree. */
|
||||||
|
struct window_pane_tree all_window_panes;
|
||||||
|
u_int next_window_pane;
|
||||||
|
|
||||||
void window_pane_read_callback(struct bufferevent *, void *);
|
void window_pane_read_callback(struct bufferevent *, void *);
|
||||||
void window_pane_error_callback(struct bufferevent *, short, void *);
|
void window_pane_error_callback(struct bufferevent *, short, void *);
|
||||||
|
|
||||||
@ -64,6 +68,14 @@ winlink_cmp(struct winlink *wl1, struct winlink *wl2)
|
|||||||
return (wl1->idx - wl2->idx);
|
return (wl1->idx - wl2->idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RB_GENERATE(window_pane_tree, window_pane, tree_entry, window_pane_cmp);
|
||||||
|
|
||||||
|
int
|
||||||
|
window_pane_cmp(struct window_pane *wp1, struct window_pane *wp2)
|
||||||
|
{
|
||||||
|
return (wp1->id - wp2->id);
|
||||||
|
}
|
||||||
|
|
||||||
struct winlink *
|
struct winlink *
|
||||||
winlink_find_by_window(struct winlinks *wwl, struct window *w)
|
winlink_find_by_window(struct winlinks *wwl, struct window *w)
|
||||||
{
|
{
|
||||||
@ -492,6 +504,16 @@ window_printable_flags(struct session *s, struct winlink *wl)
|
|||||||
return (xstrdup(flags));
|
return (xstrdup(flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find pane in global tree by id. */
|
||||||
|
struct window_pane *
|
||||||
|
window_pane_find_by_id(u_int id)
|
||||||
|
{
|
||||||
|
struct window_pane wp;
|
||||||
|
|
||||||
|
wp.id = id;
|
||||||
|
return (RB_FIND(window_pane_tree, &all_window_panes, &wp));
|
||||||
|
}
|
||||||
|
|
||||||
struct window_pane *
|
struct window_pane *
|
||||||
window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
||||||
{
|
{
|
||||||
@ -500,6 +522,9 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
|||||||
wp = xcalloc(1, sizeof *wp);
|
wp = xcalloc(1, sizeof *wp);
|
||||||
wp->window = w;
|
wp->window = w;
|
||||||
|
|
||||||
|
wp->id = next_window_pane++;
|
||||||
|
RB_INSERT(window_pane_tree, &all_window_panes, wp);
|
||||||
|
|
||||||
wp->cmd = NULL;
|
wp->cmd = NULL;
|
||||||
wp->shell = NULL;
|
wp->shell = NULL;
|
||||||
wp->cwd = NULL;
|
wp->cwd = NULL;
|
||||||
@ -552,6 +577,8 @@ window_pane_destroy(struct window_pane *wp)
|
|||||||
bufferevent_free(wp->pipe_event);
|
bufferevent_free(wp->pipe_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RB_REMOVE(window_pane_tree, &all_window_panes, wp);
|
||||||
|
|
||||||
if (wp->cwd != NULL)
|
if (wp->cwd != NULL)
|
||||||
xfree(wp->cwd);
|
xfree(wp->cwd);
|
||||||
if (wp->shell != NULL)
|
if (wp->shell != NULL)
|
||||||
@ -566,7 +593,7 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
|
|||||||
const char *cwd, struct environ *env, struct termios *tio, char **cause)
|
const char *cwd, struct environ *env, struct termios *tio, char **cause)
|
||||||
{
|
{
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
char *argv0;
|
char *argv0, paneid[16];
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
struct termios tio2;
|
struct termios tio2;
|
||||||
|
|
||||||
@ -613,6 +640,8 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
|
|||||||
|
|
||||||
closefrom(STDERR_FILENO + 1);
|
closefrom(STDERR_FILENO + 1);
|
||||||
|
|
||||||
|
xsnprintf(paneid, sizeof paneid, "%%%u", wp->id);
|
||||||
|
environ_set(env, "TMUX_PANE", paneid);
|
||||||
environ_push(env);
|
environ_push(env);
|
||||||
|
|
||||||
clear_signals(1);
|
clear_signals(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user