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