Try this.

Use -t $TMUX_PANE.

Note that if tmux needs the session as well it'll follow the normal
process to get it ("current" session if it contains the pane, otherwise
best session from all of those with the pane).

For example, paste-buffer takes a pane target but it needs the session
to know where to paste from (probably -b should accept session:buffer
but that's a separate issue).


Index: cmd.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/cmd.c,v
retrieving revision 1.46
diff -u -p -r1.46 cmd.c
--- cmd.c       29 Oct 2010 20:11:57 -0000      1.46
+++ cmd.c       13 Nov 2010 18:02:40 -0000
@@ -118,9 +118,12 @@ struct client      *cmd_lookup_client(const c
 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)
@@ -629,21 +632,81 @@ cmd_lookup_index(struct session *s, cons
        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 sessions  ss;
+       struct winlink  *wl;
+       u_int            i;
+
+       /* 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);
+       for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
+               if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
+                       continue;
+               if (winlink_find_by_window(&s->windows, wp->window) != NULL)
+                       ARRAY_ADD(&ss, s);
+       }
+       s = cmd_choose_session(&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] == ':')
@@ -672,11 +735,12 @@ cmd_find_session(struct cmd_ctx *ctx, co
 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
@@ -694,6 +758,14 @@ cmd_find_window(struct cmd_ctx *ctx, con
                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;
@@ -986,6 +1058,12 @@ cmd_find_pane(struct cmd_ctx *ctx,
        if (arg == NULL) {
                *wpp = s->curw->window->active;
                return (s->curw);
+       }
+
+       /* Lookup as pane id. */
+       if ((*wpp = cmd_lookup_paneid(arg)) != NULL) {
+               *sp = cmd_pane_session(ctx, *wpp, &wl);
+               return (wl);
        }
 
        /* Look for a separating period. */
Index: server.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/server.c,v
retrieving revision 1.96
diff -u -p -r1.96 server.c
--- server.c    18 Oct 2010 20:00:02 -0000      1.96
+++ server.c    13 Nov 2010 18:02:40 -0000
@@ -145,6 +145,7 @@ server_start(void)
        log_debug("server started, pid %ld", (long) getpid());
 
        ARRAY_INIT(&windows);
+       RB_INIT(&all_window_panes);
        ARRAY_INIT(&clients);
        ARRAY_INIT(&dead_clients);
        ARRAY_INIT(&sessions);
Index: tmux.h
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.h,v
retrieving revision 1.246
diff -u -p -r1.246 tmux.h
--- tmux.h      11 Nov 2010 20:51:30 -0000      1.246
+++ tmux.h      13 Nov 2010 18:02:41 -0000
@@ -781,6 +781,8 @@ struct window_mode {
 
 /* Child window structure. */
 struct window_pane {
+       u_int            id;
+
        struct window   *window;
        struct layout_cell *layout_cell;
 
@@ -823,8 +825,10 @@ struct window_pane {
        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 {
@@ -1833,8 +1837,11 @@ int       screen_check_selection(struct scree
 
 /* 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);
@@ -1868,6 +1875,7 @@ struct window_pane *window_pane_previous
 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 *,
Index: window.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/window.c,v
retrieving revision 1.58
diff -u -p -r1.58 window.c
--- window.c    23 Oct 2010 13:04:34 -0000      1.58
+++ window.c    13 Nov 2010 18:02:42 -0000
@@ -56,6 +56,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 *);
 
@@ -67,6 +71,14 @@ winlink_cmp(struct winlink *wl1, struct 
        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)
 {
@@ -461,6 +475,16 @@ window_destroy_panes(struct window *w)
        }
 }
 
+/* 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)
 {
@@ -469,6 +493,9 @@ window_pane_create(struct window *w, u_i
        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;
@@ -521,6 +548,8 @@ window_pane_destroy(struct window_pane *
                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)
@@ -536,7 +565,7 @@ window_pane_spawn(struct window_pane *wp
 {
        struct winsize   ws;
        int              mode;
-       char            *argv0;
+       char            *argv0, paneid[16];
        const char      *ptr;
        struct termios   tio2;
 
@@ -583,6 +612,8 @@ window_pane_spawn(struct window_pane *wp
 
                closefrom(STDERR_FILENO + 1);
 
+               xsnprintf(paneid, sizeof paneid, "%%%u", wp->id);
+               environ_set(env, "TMUX_PANE", paneid);
                environ_push(env);
 
                clear_signals(1);



On Sat, Nov 13, 2010 at 04:53:56PM +0000, Nicholas Marriott wrote:
> Other problem is this could be reused... maybe an ever-increasing pane
> id is a better move.
> 
> 
> On Sat, Nov 13, 2010 at 04:51:23PM +0000, Nicholas Marriott wrote:
> > > > 
> > > > Also, since panes and such can move around, tracking a specific pane to
> > > > interact with via scripts and such can be hard. Would it be possible to
> > > > have tmux inject a TMUX_PANE_ID into a pane's environment that is static
> > > > and unique for the life of the pane so that panes can always be reached?
> > > > Maybe using '%' as an ID identifier in target commands would be
> > > > possible. Commands to query for the current pane with focus and get back
> > > > its address and ID would also make sense.
> > > 
> > > This is a nice idea, I'll add it to the todo list.
> > 
> > I was thinking about this and in fact every pane already has a unique
> > identifier - the name of the slave side of the pty. So if we just made
> > it so that you could pass that as a pane target and so the pty was in eg
> > list-panes, it'd work.
> > 
> > It isn't in the environment, but we could put it in as part of $TMUX or
> > in $TMUX_TTY or something (probably the latter, I regret making TMUX
> > compound rather than separate variables).
> > 
> > Only problem is confusion with client identifiers which use their pty.
> > 
> > > 
> > > > 
> > > > This problem arises in screen.vim[1] which cannot reliably track a tmux
> > > > pane to interact with a specific one.
> > > > 
> > > > --Ben
> > > > 
> > > > [1]https://github.com/ervandew/screen
> > > 
> > > 
> > > 
> > > > ------------------------------------------------------------------------------
> > > > Centralized Desktop Delivery: Dell and VMware Reference Architecture
> > > > Simplifying enterprise desktop deployment and management using
> > > > Dell EqualLogic storage and VMware View: A highly scalable, end-to-end
> > > > client virtualization framework. Read more!
> > > > http://p.sf.net/sfu/dell-eql-dev2dev
> > > 
> > > > _______________________________________________
> > > > tmux-users mailing list
> > > > tmux-users@lists.sourceforge.net
> > > > https://lists.sourceforge.net/lists/listinfo/tmux-users
> > > 
> > 
> > ------------------------------------------------------------------------------
> > Centralized Desktop Delivery: Dell and VMware Reference Architecture
> > Simplifying enterprise desktop deployment and management using
> > Dell EqualLogic storage and VMware View: A highly scalable, end-to-end
> > client virtualization framework. Read more!
> > http://p.sf.net/sfu/dell-eql-dev2dev
> > _______________________________________________
> > tmux-users mailing list
> > tmux-users@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/tmux-users

------------------------------------------------------------------------------
Centralized Desktop Delivery: Dell and VMware Reference Architecture
Simplifying enterprise desktop deployment and management using
Dell EqualLogic storage and VMware View: A highly scalable, end-to-end
client virtualization framework. Read more!
http://p.sf.net/sfu/dell-eql-dev2dev
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to