version 1.26, 2012/09/03 09:57:57 |
version 1.27, 2012/10/02 08:16:28 |
|
|
void window_choose_scroll_up(struct window_pane *); |
void window_choose_scroll_up(struct window_pane *); |
void window_choose_scroll_down(struct window_pane *); |
void window_choose_scroll_down(struct window_pane *); |
|
|
|
void window_choose_collapse(struct window_pane *, struct session *); |
|
void window_choose_expand(struct window_pane *, struct session *, u_int); |
|
void window_choose_collapse_all(struct window_pane *); |
|
void window_choose_expand_all(struct window_pane *); |
|
|
enum window_choose_input_type { |
enum window_choose_input_type { |
WINDOW_CHOOSE_NORMAL = -1, |
WINDOW_CHOOSE_NORMAL = -1, |
WINDOW_CHOOSE_GOTO_ITEM, |
WINDOW_CHOOSE_GOTO_ITEM, |
|
|
struct mode_key_data mdata; |
struct mode_key_data mdata; |
|
|
ARRAY_DECL(, struct window_choose_mode_item) list; |
ARRAY_DECL(, struct window_choose_mode_item) list; |
|
ARRAY_DECL(, struct window_choose_mode_item) old_list; |
int width; |
int width; |
u_int top; |
u_int top; |
u_int selected; |
u_int selected; |
|
|
item->name = format_expand(wcd->ft, wcd->ft_template); |
item->name = format_expand(wcd->ft, wcd->ft_template); |
item->wcd = wcd; |
item->wcd = wcd; |
item->pos = ARRAY_LENGTH(&data->list) - 1; |
item->pos = ARRAY_LENGTH(&data->list) - 1; |
|
item->state = 0; |
|
|
data->width = xsnprintf (tmp, sizeof tmp , "%u", item->pos); |
data->width = xsnprintf (tmp, sizeof tmp , "%u", item->pos); |
} |
} |
|
|
data->callbackfn = callbackfn; |
data->callbackfn = callbackfn; |
data->freefn = freefn; |
data->freefn = freefn; |
|
|
|
ARRAY_CONCAT(&data->old_list, &data->list); |
|
|
|
window_choose_collapse_all(wp); |
window_choose_redraw_screen(wp); |
window_choose_redraw_screen(wp); |
} |
} |
|
|
|
|
data->input_prompt = NULL; |
data->input_prompt = NULL; |
|
|
ARRAY_INIT(&data->list); |
ARRAY_INIT(&data->list); |
|
ARRAY_INIT(&data->old_list); |
data->top = 0; |
data->top = 0; |
|
|
s = &data->screen; |
s = &data->screen; |
|
|
wcd->ft_template = NULL; |
wcd->ft_template = NULL; |
wcd->command = NULL; |
wcd->command = NULL; |
wcd->wl = NULL; |
wcd->wl = NULL; |
|
wcd->tree_session = NULL; |
wcd->client = ctx->curclient; |
wcd->client = ctx->curclient; |
wcd->session = ctx->curclient->session; |
wcd->session = ctx->curclient->session; |
wcd->idx = -1; |
wcd->idx = -1; |
|
wcd->type = 0; |
|
|
return (wcd); |
return (wcd); |
} |
} |
|
|
free(item->name); |
free(item->name); |
} |
} |
ARRAY_FREE(&data->list); |
ARRAY_FREE(&data->list); |
|
ARRAY_FREE(&data->old_list); |
free(data->input_str); |
free(data->input_str); |
|
|
screen_free(&data->screen); |
screen_free(&data->screen); |
|
|
window_choose_redraw_screen(wp); |
window_choose_redraw_screen(wp); |
} |
} |
|
|
|
void |
|
window_choose_collapse(struct window_pane *wp, struct session *s) |
|
{ |
|
struct window_choose_mode_data *data = wp->modedata; |
|
struct window_choose_mode_item *item, *chosen; |
|
struct window_choose_data *wcd; |
|
u_int i, pos; |
|
|
|
ARRAY_DECL(, struct window_choose_mode_item) list_copy; |
|
ARRAY_INIT(&list_copy); |
|
|
|
pos = data->selected; |
|
|
|
chosen = &ARRAY_ITEM(&data->list, pos); |
|
chosen->state &= ~TREE_EXPANDED; |
|
|
|
/* |
|
* Trying to mangle the &data->list in-place has lots of problems, so |
|
* assign the actual result we want to render and copy the new one over |
|
* the top of it. |
|
*/ |
|
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) |
|
{ |
|
item = &ARRAY_ITEM(&data->list, i); |
|
wcd = item->wcd; |
|
|
|
if (s == wcd->tree_session) { |
|
/* We only show the session when collapsed. */ |
|
if (wcd->type & TREE_SESSION) { |
|
item->state &= ~TREE_EXPANDED; |
|
|
|
ARRAY_ADD(&list_copy, |
|
ARRAY_ITEM(&data->list, i)); |
|
/* |
|
* Update the selection to this session item so |
|
* we don't end up highlighting a non-existent |
|
* item. |
|
*/ |
|
data->selected = i; |
|
} |
|
} else |
|
ARRAY_ADD(&list_copy, ARRAY_ITEM(&data->list, i)); |
|
} |
|
|
|
if (!ARRAY_EMPTY(&list_copy)) { |
|
ARRAY_FREE(&data->list); |
|
ARRAY_CONCAT(&data->list, &list_copy); |
|
} |
|
} |
|
|
|
void |
|
window_choose_collapse_all(struct window_pane *wp) |
|
{ |
|
struct window_choose_mode_data *data = wp->modedata; |
|
struct window_choose_mode_item *item, *chosen; |
|
struct session *s; |
|
u_int i; |
|
|
|
chosen = &ARRAY_ITEM(&data->list, data->selected); |
|
|
|
RB_FOREACH(s, sessions, &sessions) |
|
window_choose_collapse(wp, s); |
|
|
|
/* Reset the selection back to the starting session. */ |
|
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) { |
|
item = &ARRAY_ITEM(&data->list, i); |
|
|
|
if (chosen->wcd->session != item->wcd->tree_session) |
|
continue; |
|
|
|
if (item->wcd->type & TREE_SESSION) |
|
data->selected = i; |
|
} |
|
window_choose_redraw_screen(wp); |
|
} |
|
|
|
void |
|
window_choose_expand_all(struct window_pane *wp) |
|
{ |
|
struct window_choose_mode_data *data = wp->modedata; |
|
struct window_choose_mode_item *item; |
|
struct session *s; |
|
u_int i; |
|
|
|
RB_FOREACH(s, sessions, &sessions) { |
|
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) { |
|
item = &ARRAY_ITEM(&data->list, i); |
|
|
|
if (s != item->wcd->tree_session) |
|
continue; |
|
|
|
if (item->wcd->type & TREE_SESSION) |
|
window_choose_expand(wp, s, i); |
|
} |
|
} |
|
|
|
window_choose_redraw_screen(wp); |
|
} |
|
|
|
void |
|
window_choose_expand(struct window_pane *wp, struct session *s, u_int pos) |
|
{ |
|
struct window_choose_mode_data *data = wp->modedata; |
|
struct window_choose_mode_item *item, *chosen; |
|
struct window_choose_data *wcd; |
|
u_int i, items; |
|
|
|
chosen = &ARRAY_ITEM(&data->list, pos); |
|
items = ARRAY_LENGTH(&data->old_list) - 1; |
|
|
|
/* It's not possible to expand anything other than sessions. */ |
|
if (!(chosen->wcd->type & TREE_SESSION)) |
|
return; |
|
|
|
/* Don't re-expand a session which is already expanded. */ |
|
if (chosen->state & TREE_EXPANDED) |
|
return; |
|
|
|
/* Mark the session entry as expanded. */ |
|
chosen->state |= TREE_EXPANDED; |
|
|
|
/* |
|
* Go back through the original list of all sessions and windows, and |
|
* pull out the windows where the session matches the selection chosen |
|
* to expand. |
|
*/ |
|
for (i = items; i > 0; i--) { |
|
item = &ARRAY_ITEM(&data->old_list, i); |
|
item->state |= TREE_EXPANDED; |
|
wcd = item->wcd; |
|
|
|
if (s == wcd->tree_session) { |
|
/* |
|
* Since the session is already displayed, we only care |
|
* to add back in window for it. |
|
*/ |
|
if (wcd->type & TREE_WINDOW) { |
|
/* |
|
* If the insertion point for adding the |
|
* windows to the session falls inside the |
|
* range of the list, then we insert these |
|
* entries in order *AFTER* the selected |
|
* session. |
|
*/ |
|
if (pos < i ) { |
|
ARRAY_INSERT(&data->list, |
|
pos + 1, |
|
ARRAY_ITEM(&data->old_list, |
|
i)); |
|
} else { |
|
/* Ran out of room, add to the end. */ |
|
ARRAY_ADD(&data->list, |
|
ARRAY_ITEM(&data->old_list, |
|
i)); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
void |
void |
window_choose_key(struct window_pane *wp, unused struct session *sess, int key) |
window_choose_key(struct window_pane *wp, unused struct session *sess, int key) |
|
|
struct screen_write_ctx ctx; |
struct screen_write_ctx ctx; |
struct window_choose_mode_item *item; |
struct window_choose_mode_item *item; |
size_t input_len; |
size_t input_len; |
u_int items, n; |
u_int items, n; |
int idx; |
int idx; |
|
|
items = ARRAY_LENGTH(&data->list); |
items = ARRAY_LENGTH(&data->list); |
|
|
window_choose_fire_callback(wp, item->wcd); |
window_choose_fire_callback(wp, item->wcd); |
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
break; |
break; |
|
case MODEKEYCHOICE_TREE_TOGGLE: |
|
item = &ARRAY_ITEM(&data->list, data->selected); |
|
if (item->state & TREE_EXPANDED) |
|
window_choose_collapse(wp, item->wcd->tree_session); |
|
else { |
|
window_choose_expand(wp, item->wcd->tree_session, |
|
data->selected); |
|
} |
|
window_choose_redraw_screen(wp); |
|
break; |
|
case MODEKEYCHOICE_TREE_COLLAPSE: |
|
item = &ARRAY_ITEM(&data->list, data->selected); |
|
if (item->state & TREE_EXPANDED) { |
|
window_choose_collapse(wp, item->wcd->tree_session); |
|
window_choose_redraw_screen(wp); |
|
} |
|
break; |
|
case MODEKEYCHOICE_TREE_COLLAPSE_ALL: |
|
window_choose_collapse_all(wp); |
|
break; |
|
case MODEKEYCHOICE_TREE_EXPAND: |
|
item = &ARRAY_ITEM(&data->list, data->selected); |
|
if (!(item->state & TREE_EXPANDED)) { |
|
window_choose_expand(wp, item->wcd->tree_session, |
|
data->selected); |
|
window_choose_redraw_screen(wp); |
|
} |
|
break; |
|
case MODEKEYCHOICE_TREE_EXPAND_ALL: |
|
window_choose_expand_all(wp); |
|
break; |
case MODEKEYCHOICE_UP: |
case MODEKEYCHOICE_UP: |
if (items == 0) |
if (items == 0) |
break; |
break; |
|
|
else |
else |
xsnprintf (label, sizeof label, "(%d)", item->pos); |
xsnprintf (label, sizeof label, "(%d)", item->pos); |
screen_write_nputs(ctx, screen_size_x(s) - 1, &gc, utf8flag, |
screen_write_nputs(ctx, screen_size_x(s) - 1, &gc, utf8flag, |
"%*s %s", data->width + 2, label, item->name); |
"%*s %s %s", data->width + 2, label, |
|
/* |
|
* Add indication to tree if necessary about whether it's |
|
* expanded or not. |
|
*/ |
|
(item->wcd->type & TREE_SESSION) ? |
|
(item->state & TREE_EXPANDED ? "-" : "+") : "", item->name); |
} |
} |
while (s->cx < screen_size_x(s)) |
while (s->cx < screen_size_x(s)) |
screen_write_putc(ctx, &gc, ' '); |
screen_write_putc(ctx, &gc, ' '); |
|
|
|
|
wcd = window_choose_data_create(ctx); |
wcd = window_choose_data_create(ctx); |
wcd->idx = s->idx; |
wcd->idx = s->idx; |
|
wcd->tree_session = s; |
|
wcd->type = TREE_SESSION; |
wcd->command = cmd_template_replace(action, s->name, 1); |
wcd->command = cmd_template_replace(action, s->name, 1); |
wcd->ft_template = xstrdup(template); |
wcd->ft_template = xstrdup(template); |
format_add(wcd->ft, "line", "%u", idx); |
format_add(wcd->ft, "line", "%u", idx); |
|
|
|
|
wcd->idx = wl->idx; |
wcd->idx = wl->idx; |
wcd->wl = wl; |
wcd->wl = wl; |
|
wcd->tree_session = s; |
|
wcd->type = TREE_WINDOW; |
wcd->ft_template = xstrdup(template); |
wcd->ft_template = xstrdup(template); |
format_add(wcd->ft, "line", "%u", idx); |
format_add(wcd->ft, "line", "%u", idx); |
format_session(wcd->ft, s); |
format_session(wcd->ft, s); |