Update of /cvsroot/tmux/tmux
In directory vz-cvs-2.sog:/tmp/cvs-serv18053

Modified Files:
        cmd-list-panes.c cmd.c server.c tmux.1 tmux.h window.c 
Log Message:
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.



Index: cmd.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd.c,v
retrieving revision 1.149
retrieving revision 1.150
diff -u -d -r1.149 -r1.150
--- cmd.c       14 Feb 2011 23:11:33 -0000      1.149
+++ cmd.c       6 Apr 2011 22:16:33 -0000       1.150
@@ -117,9 +117,12 @@
 struct session *cmd_lookup_session(const char *, int *);
 struct winlink *cmd_lookup_window(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 *);
 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 *);
 
 int
 cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
@@ -638,21 +641,78 @@
        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. */
 struct session *
 cmd_find_session(struct cmd_ctx *ctx, const char *arg)
 {
-       struct session  *s;
-       struct client   *c;
-       char            *tmparg;
-       size_t           arglen;
-       int              ambiguous;
+       struct session          *s;
+       struct window_pane      *wp;
+       struct client           *c;
+       char                    *tmparg;
+       size_t                   arglen;
+       int                      ambiguous;
 
        /* A NULL argument means the current session. */
        if (arg == NULL)
                return (cmd_current_session(ctx));
        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. */
        arglen = strlen(tmparg);
        if (arglen != 0 && tmparg[arglen - 1] == ':')
@@ -681,11 +741,12 @@
 struct winlink *
 cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
 {
-       struct session  *s;
-       struct winlink  *wl;
-       const char      *winptr;
-       char            *sessptr = NULL;
-       int              ambiguous = 0;
+       struct session          *s;
+       struct winlink          *wl;
+       struct window_pane      *wp;
+       const char              *winptr;
+       char                    *sessptr = NULL;
+       int                      ambiguous = 0;
 
        /*
         * Find the current session. There must always be a current session, if
@@ -703,6 +764,14 @@
                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. */
        if (*arg == '\0')
                goto not_found;
@@ -997,6 +1066,14 @@
                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. */
        if ((period = strrchr(arg, '.')) == NULL)
                goto no_period;

Index: tmux.1
===================================================================
RCS file: /cvsroot/tmux/tmux/tmux.1,v
retrieving revision 1.296
retrieving revision 1.297
diff -u -d -r1.296 -r1.297
--- tmux.1      19 Mar 2011 23:27:35 -0000      1.296
+++ tmux.1      6 Apr 2011 22:16:33 -0000       1.297
@@ -453,6 +453,17 @@
 When dealing with a session that doesn't contain sequential window indexes,
 they will be correctly skipped.
 .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
 arguments are
 .Xr sh 1

Index: cmd-list-panes.c
===================================================================
RCS file: /cvsroot/tmux/tmux/cmd-list-panes.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- cmd-list-panes.c    7 Jan 2011 14:45:34 -0000       1.7
+++ cmd-list-panes.c    6 Apr 2011 22:16:33 -0000       1.8
@@ -64,8 +64,8 @@
                }
                size += gd->hsize * sizeof *gd->linedata;
 
-               ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes]%s%s",
-                   n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size,
+               ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes] 
%%%u%s%s",
+                   n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size, wp->id,
                    wp == wp->window->active ? " (active)" : "",
                    wp->fd == -1 ? " (dead)" : "");
                n++;

Index: server.c
===================================================================
RCS file: /cvsroot/tmux/tmux/server.c,v
retrieving revision 1.253
retrieving revision 1.254
diff -u -d -r1.253 -r1.254
--- server.c    15 Feb 2011 15:12:28 -0000      1.253
+++ server.c    6 Apr 2011 22:16:33 -0000       1.254
@@ -142,6 +142,7 @@
        log_debug("server started, pid %ld", (long) getpid());
 
        ARRAY_INIT(&windows);
+       RB_INIT(&all_window_panes);
        ARRAY_INIT(&clients);
        ARRAY_INIT(&dead_clients);
        RB_INIT(&sessions);

Index: window.c
===================================================================
RCS file: /cvsroot/tmux/tmux/window.c,v
retrieving revision 1.145
retrieving revision 1.146
diff -u -d -r1.145 -r1.146
--- window.c    15 Feb 2011 15:09:52 -0000      1.145
+++ window.c    6 Apr 2011 22:16:33 -0000       1.146
@@ -53,6 +53,10 @@
 /* Global window list. */
 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_error_callback(struct bufferevent *, short, void *);
 
@@ -64,6 +68,14 @@
        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 *
 winlink_find_by_window(struct winlinks *wwl, struct window *w)
 {
@@ -492,6 +504,16 @@
        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 *
 window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
 {
@@ -500,6 +522,9 @@
        wp = xcalloc(1, sizeof *wp);
        wp->window = w;
 
+       wp->id = next_window_pane++;
+       RB_INSERT(window_pane_tree, &all_window_panes, wp);
+
        wp->cmd = NULL;
        wp->shell = NULL;
        wp->cwd = NULL;
@@ -552,6 +577,8 @@
                bufferevent_free(wp->pipe_event);
        }
 
+       RB_REMOVE(window_pane_tree, &all_window_panes, wp);
+
        if (wp->cwd != NULL)
                xfree(wp->cwd);
        if (wp->shell != NULL)
@@ -566,7 +593,7 @@
     const char *cwd, struct environ *env, struct termios *tio, char **cause)
 {
        struct winsize   ws;
-       char            *argv0;
+       char            *argv0, paneid[16];
        const char      *ptr;
        struct termios   tio2;
 
@@ -613,6 +640,8 @@
 
                closefrom(STDERR_FILENO + 1);
 
+               xsnprintf(paneid, sizeof paneid, "%%%u", wp->id);
+               environ_set(env, "TMUX_PANE", paneid);
                environ_push(env);
 
                clear_signals(1);

Index: tmux.h
===================================================================
RCS file: /cvsroot/tmux/tmux/tmux.h,v
retrieving revision 1.612
retrieving revision 1.613
diff -u -d -r1.612 -r1.613
--- tmux.h      19 Mar 2011 23:30:37 -0000      1.612
+++ tmux.h      6 Apr 2011 22:16:33 -0000       1.613
@@ -775,6 +775,8 @@
 
 /* Child window structure. */
 struct window_pane {
+       u_int            id;
+
        struct window   *window;
        struct layout_cell *layout_cell;
 
@@ -817,8 +819,10 @@
        void            *modedata;
 
        TAILQ_ENTRY(window_pane) entry;
+       RB_ENTRY(window_pane) tree_entry;
 };
 TAILQ_HEAD(window_panes, window_pane);
+RB_HEAD(window_pane_tree, window_pane);
 
 /* Window structure. */
 struct window {
@@ -1821,8 +1825,11 @@
 
 /* window.c */
 extern struct windows windows;
+extern struct window_pane_tree all_window_panes;
 int             winlink_cmp(struct winlink *, struct winlink *);
 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_window(struct winlinks *, struct window *);
 int             winlink_next_index(struct winlinks *, int);
@@ -1857,6 +1864,7 @@
 u_int           window_pane_index(struct window *, struct window_pane *);
 u_int           window_count_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);
 void            window_pane_destroy(struct window_pane *);
 int             window_pane_spawn(struct window_pane *, const char *,


------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to