No?

On Sat, Nov 13, 2010 at 06:14:25PM +0000, Nicholas Marriott wrote:
> 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

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to