I'm not sure about the type_flags stuff in here.

I'd probably have some smaller functions like window_choose_add_window
and window_choose_add_session which add 1 line with the window or
session.

Then for choose-window you do:

for each window in session:
    if (window_choose_add_window(s, w, 0))
        cur = idx;
    idx++

And for choose-session you do:

for each session:
    if (window_choose_add_session(s, 0))
        cur = idx
    idx++

An for your new one:

for each session:
    is_cur = window_choose_add_session(w, 0)
    for each window in session:
        if (window_choose_add_window(s, w, 1) && is_cur)
           cur = idx
        idx++

Where eg 0 or 1 is the level of the element in the tree (indented or
bold or something).

The best thing rather than messing around with a union or long might be
to make the closure for the choose callback a struct which has the stuff
to identify session and window and client, then each command just uses
whichever of those it likes.


On Mon, Dec 27, 2010 at 07:34:15PM +0000, Thomas Adam wrote:
> Factor out the code which puts the choice of choosing windows and/or
> sessions into a common place.
> ---
>  cmd-choose-session.c |   28 +------------
>  cmd-choose-window.c  |   35 ++--------------
>  window-choose.c      |  107 
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 113 insertions(+), 57 deletions(-)
> 
> diff --git a/cmd-choose-session.c b/cmd-choose-session.c
> index 7d9cdd4..603fe43 100644
> --- a/cmd-choose-session.c
> +++ b/cmd-choose-session.c
> @@ -53,10 +53,7 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx 
> *ctx)
>       struct cmd_target_data          *data = self->data;
>       struct cmd_choose_session_data  *cdata;
>       struct winlink                  *wl;
> -     struct session                  *s;
> -     struct session_group            *sg;
> -     u_int                            i, idx, cur;
> -     char                             tmp[64];
> +     u_int                            cur;
>  
>       if (ctx->curclient == NULL) {
>               ctx->error(ctx, "must be run interactively");
> @@ -69,28 +66,7 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx 
> *ctx)
>       if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
>               return (0);
>  
> -     cur = idx = 0;
> -     for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
> -             s = ARRAY_ITEM(&sessions, i);
> -             if (s == NULL)
> -                     continue;
> -             if (s == ctx->curclient->session)
> -                     cur = idx;
> -             idx++;
> -
> -             sg = session_group_find(s);
> -             if (sg == NULL)
> -                     *tmp = '\0';
> -             else {
> -                     idx = session_group_index(sg);
> -                     xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
> -             }
> -
> -             window_choose_add(wl->window->active, i,
> -                 "%s: %u windows [%ux%u]%s%s", s->name,
> -                 winlink_count(&s->windows), s->sx, s->sy,
> -                 tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
> -     }
> +     cur = window_choose_item_data(ctx, wl, WIN_CHOOSE_SESSIONS);
>  
>       cdata = xmalloc(sizeof *cdata);
>       if (data->arg != NULL)
> diff --git a/cmd-choose-window.c b/cmd-choose-window.c
> index c39c0ed..f7fa66e 100644
> --- a/cmd-choose-window.c
> +++ b/cmd-choose-window.c
> @@ -53,17 +53,15 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx 
> *ctx)
>  {
>       struct cmd_target_data          *data = self->data;
>       struct cmd_choose_window_data   *cdata;
> +     struct winlink                  *wl;
>       struct session                  *s;
> -     struct winlink                  *wl, *wm;
> -     struct window                   *w;
> -     u_int                            idx, cur;
> -     char                            *flags, *title;
> -     const char                      *left, *right;
> +     u_int                            cur;
>  
>       if (ctx->curclient == NULL) {
>               ctx->error(ctx, "must be run interactively");
>               return (-1);
>       }
> +
>       s = ctx->curclient->session;
>  
>       if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
> @@ -72,32 +70,7 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx 
> *ctx)
>       if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
>               return (0);
>  
> -     cur = idx = 0;
> -     RB_FOREACH(wm, winlinks, &s->windows) {
> -             w = wm->window;
> -
> -             if (wm == s->curw)
> -                     cur = idx;
> -             idx++;
> -
> -             flags = window_printable_flags(s, wm);
> -             title = w->active->screen->title;
> -             if (wm == wl)
> -                     title = w->active->base.title;
> -             left = " \"";
> -             right = "\"";
> -             if (*title == '\0')
> -                     left = right = "";
> -
> -             window_choose_add(wl->window->active,
> -                 wm->idx, "%3d: %s%s [%ux%u] (%u panes%s)%s%s%s",
> -                 wm->idx, w->name, flags, w->sx, w->sy, 
> window_count_panes(w),
> -                 w->active->fd == -1 ? ", dead" : "",
> -                 left, title, right);
> -     }
> -
> -     if (flags != NULL)
> -             xfree(flags);
> +     cur = window_choose_item_data(ctx, wl, WIN_CHOOSE_WINDOWS);
>  
>       cdata = xmalloc(sizeof *cdata);
>       if (data->arg != NULL)
> diff --git a/window-choose.c b/window-choose.c
> index bce3ecb..4b1980d 100644
> --- a/window-choose.c
> +++ b/window-choose.c
> @@ -35,6 +35,7 @@ void        window_choose_write_line(
>  
>  void window_choose_scroll_up(struct window_pane *);
>  void window_choose_scroll_down(struct window_pane *);
> +int  window_choose_item_window(struct session *, struct winlink *);
>  
>  const struct window_mode window_choose_mode = {
>       window_choose_init,
> @@ -455,3 +456,109 @@ window_choose_scroll_down(struct window_pane *wp)
>               window_choose_write_line(wp, &ctx, screen_size_y(s) - 2);
>       screen_write_stop(&ctx);
>  }
> +
> +int window_choose_item_window(struct session *s, struct winlink *wl)
> +{
> +     struct winlink          *wm;
> +     struct window           *w;
> +     const char              *left, *right;
> +     char                    *flags, *title;
> +     u_int                    cur, idx;
> +
> +     idx = cur = 0;
> +     RB_FOREACH(wm, winlinks, &s->windows) {
> +             w = wm->window;
> +
> +             if (wm == s->curw)
> +                     cur = idx;
> +             idx++;
> +
> +             flags = window_printable_flags(s, wm);
> +             title = w->active->screen->title;
> +             if (wm == wl)
> +                     title = w->active->base.title;
> +             left = " \"";
> +             right = "\"";
> +             if (*title == '\0')
> +                     left = right = "";
> +
> +             window_choose_add(wl->window->active,
> +                 wm->idx, "%3d: %s%s [%ux%u] (%u panes%s)%s%s%s",
> +                 wm->idx, w->name, flags, w->sx, w->sy, 
> window_count_panes(w),
> +                 w->active->fd == -1 ? ", dead" : "",
> +                 left, title, right);
> +
> +             if (flags != NULL)
> +                     xfree(flags);
> +     }
> +
> +     return cur;
> +}
> +
> +int
> +window_choose_item_data(struct cmd_ctx *ctx, struct winlink *wl, int 
> type_flags)
> +{
> +     struct session          *s;
> +     struct session_group    *sg;
> +     u_int                    ses_count;
> +        u_int                         selected, cur_win, cur_ses;
> +     u_int                    idx, cur_ses_win, total_items;
> +     char                     tmp[64];
> +     u_int                    window_total;
> +
> +     /* XXX: Ugly. */
> +     selected = cur_win = idx = total_items = 0;
> +
> +     if (type_flags == WIN_CHOOSE_WINDOWS) {
> +             s = ctx->curclient->session;
> +             return (window_choose_item_window(s, wl));
> +     }
> +
> +     for (ses_count = 0; ses_count < ARRAY_LENGTH(&sessions); ses_count++) {
> +             window_total = 0;
> +
> +             s = ARRAY_ITEM(&sessions, ses_count);
> +             if (s == NULL)
> +                     continue;
> +             if (s == ctx->curclient->session)
> +                     selected = idx;
> +             idx++;
> +
> +             sg = session_group_find(s);
> +             if (sg == NULL)
> +                     *tmp = '\0';
> +             else {
> +                     idx = session_group_index(sg);
> +                     xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
> +             }
> +
> +             window_choose_add(wl->window->active, ses_count,
> +                 "%s: %u windows [%ux%u]%s%s", s->name,
> +                 winlink_count(&s->windows), s->sx, s->sy,
> +                 tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
> +
> +             if (type_flags == WIN_CHOOSE_SESSIONS)
> +                     continue;
> +
> +             if (type_flags == WIN_CHOOSE_WINDOWS_SESSIONS) {
> +                     cur_win = window_choose_item_window(s, wl);
> +                     window_total = winlink_count(&s->windows);
> +                     total_items += window_total;
> +
> +                     if (!(s->flags & SESSION_UNATTACHED))
> +                     {
> +                             /* Then the session is attached.  This is the
> +                              * one we're interested in jumping to in the
> +                              * list -- but as a consequence we jump
> +                              * straight to the window which we work out
> +                              * based on the session it's in.
> +                              */
> +                             cur_ses = (total_items - window_total);
> +                             cur_ses_win = (cur_ses + cur_win + selected) + 
> 1;
> +                     }
> +             }
> +     }
> +
> +     return (type_flags == WIN_CHOOSE_WINDOWS_SESSIONS ?
> +             cur_ses_win : selected);
> +}
> -- 
> 1.7.2.3
> 
> ------------------------------------------------------------------------------
> Learn how Oracle Real Application Clusters (RAC) One Node allows customers
> to consolidate database storage, standardize their database environment, and, 
> should the need arise, upgrade to a full multi-node Oracle RAC database 
> without downtime or disruption
> http://p.sf.net/sfu/oracle-sfdevnl
> _______________________________________________
> tmux-users mailing list
> tmux-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tmux-users

------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and, 
should the need arise, upgrade to a full multi-node Oracle RAC database 
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to