Annotation of src/usr.bin/tmux/window-choose.c, Revision 1.26
1.26 ! nicm 1: /* $OpenBSD: window-choose.c,v 1.25 2012/08/27 21:29:23 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
1.19 nicm 21: #include <ctype.h>
1.21 nicm 22: #include <stdlib.h>
1.1 nicm 23: #include <string.h>
24:
25: #include "tmux.h"
26:
27: struct screen *window_choose_init(struct window_pane *);
28: void window_choose_free(struct window_pane *);
29: void window_choose_resize(struct window_pane *, u_int, u_int);
1.16 nicm 30: void window_choose_key(struct window_pane *, struct session *, int);
1.1 nicm 31: void window_choose_mouse(
1.16 nicm 32: struct window_pane *, struct session *, struct mouse_event *);
1.1 nicm 33:
1.19 nicm 34: void window_choose_fire_callback(
35: struct window_pane *, struct window_choose_data *);
1.1 nicm 36: void window_choose_redraw_screen(struct window_pane *);
37: void window_choose_write_line(
1.13 nicm 38: struct window_pane *, struct screen_write_ctx *, u_int);
1.1 nicm 39:
40: void window_choose_scroll_up(struct window_pane *);
41: void window_choose_scroll_down(struct window_pane *);
42:
1.22 nicm 43: enum window_choose_input_type {
44: WINDOW_CHOOSE_NORMAL = -1,
45: WINDOW_CHOOSE_GOTO_ITEM,
46: };
47:
1.1 nicm 48: const struct window_mode window_choose_mode = {
49: window_choose_init,
50: window_choose_free,
51: window_choose_resize,
52: window_choose_key,
53: window_choose_mouse,
54: NULL,
55: };
56:
57: struct window_choose_mode_data {
58: struct screen screen;
59:
60: struct mode_key_data mdata;
61:
62: ARRAY_DECL(, struct window_choose_mode_item) list;
1.22 nicm 63: int width;
1.1 nicm 64: u_int top;
65: u_int selected;
1.22 nicm 66: enum window_choose_input_type input_type;
67: const char *input_prompt;
68: char *input_str;
1.1 nicm 69:
1.19 nicm 70: void (*callbackfn)(struct window_choose_data *);
71: void (*freefn)(struct window_choose_data *);
1.1 nicm 72: };
73:
1.25 nicm 74: int window_choose_key_index(struct window_choose_mode_data *, u_int);
75: int window_choose_index_key(struct window_choose_mode_data *, int);
1.22 nicm 76: void window_choose_prompt_input(enum window_choose_input_type,
77: const char *, struct window_pane *, int);
1.11 nicm 78:
1.1 nicm 79: void
1.19 nicm 80: window_choose_add(struct window_pane *wp, struct window_choose_data *wcd)
1.1 nicm 81: {
82: struct window_choose_mode_data *data = wp->modedata;
83: struct window_choose_mode_item *item;
1.22 nicm 84: char tmp[10];
1.1 nicm 85:
86: ARRAY_EXPAND(&data->list, 1);
87: item = &ARRAY_LAST(&data->list);
88:
1.19 nicm 89: item->name = format_expand(wcd->ft, wcd->ft_template);
90: item->wcd = wcd;
1.22 nicm 91: item->pos = ARRAY_LENGTH(&data->list) - 1;
92:
1.25 nicm 93: data->width = xsnprintf (tmp, sizeof tmp , "%u", item->pos);
1.1 nicm 94: }
95:
96: void
1.3 nicm 97: window_choose_ready(struct window_pane *wp, u_int cur,
1.19 nicm 98: void (*callbackfn)(struct window_choose_data *),
99: void (*freefn)(struct window_choose_data *))
1.1 nicm 100: {
101: struct window_choose_mode_data *data = wp->modedata;
102: struct screen *s = &data->screen;
103:
104: data->selected = cur;
105: if (data->selected > screen_size_y(s) - 1)
106: data->top = ARRAY_LENGTH(&data->list) - screen_size_y(s);
107:
1.3 nicm 108: data->callbackfn = callbackfn;
109: data->freefn = freefn;
1.1 nicm 110:
111: window_choose_redraw_screen(wp);
112: }
113:
114: struct screen *
115: window_choose_init(struct window_pane *wp)
116: {
117: struct window_choose_mode_data *data;
118: struct screen *s;
1.5 nicm 119: int keys;
1.1 nicm 120:
121: wp->modedata = data = xmalloc(sizeof *data);
1.3 nicm 122:
123: data->callbackfn = NULL;
124: data->freefn = NULL;
1.22 nicm 125: data->input_type = WINDOW_CHOOSE_NORMAL;
126: data->input_str = xstrdup("");
127: data->input_prompt = NULL;
1.3 nicm 128:
1.1 nicm 129: ARRAY_INIT(&data->list);
130: data->top = 0;
131:
132: s = &data->screen;
133: screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
134: s->mode &= ~MODE_CURSOR;
1.7 nicm 135: if (options_get_number(&wp->window->options, "mode-mouse"))
1.17 nicm 136: s->mode |= MODE_MOUSE_STANDARD;
1.1 nicm 137:
1.5 nicm 138: keys = options_get_number(&wp->window->options, "mode-keys");
139: if (keys == MODEKEY_EMACS)
1.6 nicm 140: mode_key_init(&data->mdata, &mode_key_tree_emacs_choice);
1.5 nicm 141: else
1.6 nicm 142: mode_key_init(&data->mdata, &mode_key_tree_vi_choice);
1.1 nicm 143:
144: return (s);
145: }
146:
1.19 nicm 147: struct window_choose_data *
148: window_choose_data_create(struct cmd_ctx *ctx)
149: {
150: struct window_choose_data *wcd;
151:
152: wcd = xmalloc(sizeof *wcd);
153: wcd->ft = format_create();
154: wcd->ft_template = NULL;
1.20 nicm 155: wcd->command = NULL;
1.24 nicm 156: wcd->wl = NULL;
1.19 nicm 157: wcd->client = ctx->curclient;
158: wcd->session = ctx->curclient->session;
159: wcd->idx = -1;
160:
161: return (wcd);
162: }
163:
1.1 nicm 164: void
165: window_choose_free(struct window_pane *wp)
166: {
167: struct window_choose_mode_data *data = wp->modedata;
1.19 nicm 168: struct window_choose_mode_item *item;
1.1 nicm 169: u_int i;
170:
1.19 nicm 171: for (i = 0; i < ARRAY_LENGTH(&data->list); i++) {
172: item = &ARRAY_ITEM(&data->list, i);
173: if (data->freefn != NULL && item->wcd != NULL)
174: data->freefn(item->wcd);
1.21 nicm 175: free(item->name);
1.19 nicm 176: }
1.1 nicm 177: ARRAY_FREE(&data->list);
1.22 nicm 178: free(data->input_str);
1.1 nicm 179:
180: screen_free(&data->screen);
1.21 nicm 181: free(data);
1.1 nicm 182: }
183:
184: void
185: window_choose_resize(struct window_pane *wp, u_int sx, u_int sy)
186: {
187: struct window_choose_mode_data *data = wp->modedata;
188: struct screen *s = &data->screen;
189:
190: data->top = 0;
191: if (data->selected > sy - 1)
192: data->top = data->selected - (sy - 1);
193:
194: screen_resize(s, sx, sy);
195: window_choose_redraw_screen(wp);
196: }
197:
1.18 nicm 198: void
1.19 nicm 199: window_choose_fire_callback(
200: struct window_pane *wp, struct window_choose_data *wcd)
1.18 nicm 201: {
202: struct window_choose_mode_data *data = wp->modedata;
203: const struct window_mode *oldmode;
204:
205: oldmode = wp->mode;
206: wp->mode = NULL;
207:
1.19 nicm 208: data->callbackfn(wcd);
1.18 nicm 209:
210: wp->mode = oldmode;
211: }
212:
1.22 nicm 213: void
214: window_choose_prompt_input(enum window_choose_input_type input_type,
215: const char *prompt, struct window_pane *wp, int key)
216: {
217: struct window_choose_mode_data *data = wp->modedata;
218: size_t input_len;
219:
220: data->input_type = input_type;
221: data->input_prompt = prompt;
222: input_len = strlen(data->input_str) + 2;
223:
224: data->input_str = xrealloc(data->input_str, 1, input_len);
225: data->input_str[input_len - 2] = key;
226: data->input_str[input_len - 1] = '\0';
227:
228: window_choose_redraw_screen(wp);
229: }
230:
1.12 nicm 231: /* ARGSUSED */
1.1 nicm 232: void
1.16 nicm 233: window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
1.1 nicm 234: {
235: struct window_choose_mode_data *data = wp->modedata;
236: struct screen *s = &data->screen;
237: struct screen_write_ctx ctx;
238: struct window_choose_mode_item *item;
1.22 nicm 239: size_t input_len;
240: u_int items, n;
1.11 nicm 241: int idx;
1.1 nicm 242:
243: items = ARRAY_LENGTH(&data->list);
244:
1.25 nicm 245: if (data->input_type == WINDOW_CHOOSE_GOTO_ITEM) {
246: switch (mode_key_lookup(&data->mdata, key)) {
247: case MODEKEYCHOICE_CANCEL:
248: data->input_type = WINDOW_CHOOSE_NORMAL;
249: window_choose_redraw_screen(wp);
1.22 nicm 250: break;
1.25 nicm 251: case MODEKEYCHOICE_CHOOSE:
1.22 nicm 252: n = strtonum(data->input_str, 0, INT_MAX, NULL);
1.25 nicm 253: if (n > items - 1) {
254: data->input_type = WINDOW_CHOOSE_NORMAL;
255: window_choose_redraw_screen(wp);
1.22 nicm 256: break;
1.25 nicm 257: }
1.22 nicm 258: item = &ARRAY_ITEM(&data->list, n);
259: window_choose_fire_callback(wp, item->wcd);
260: window_pane_reset_mode(wp);
261: break;
1.25 nicm 262: case MODEKEYCHOICE_BACKSPACE:
263: input_len = strlen(data->input_str);
264: if (input_len > 0)
265: data->input_str[input_len - 1] = '\0';
266: window_choose_redraw_screen(wp);
267: break;
268: default:
269: if (key < '0' || key > '9')
270: break;
271: window_choose_prompt_input(WINDOW_CHOOSE_GOTO_ITEM,
272: "Goto Item", wp, key);
273: break;
1.22 nicm 274: }
1.25 nicm 275: return;
276: }
277:
278: switch (mode_key_lookup(&data->mdata, key)) {
279: case MODEKEYCHOICE_CANCEL:
280: window_choose_fire_callback(wp, NULL);
281: window_pane_reset_mode(wp);
282: break;
283: case MODEKEYCHOICE_CHOOSE:
284: item = &ARRAY_ITEM(&data->list, data->selected);
285: window_choose_fire_callback(wp, item->wcd);
286: window_pane_reset_mode(wp);
1.1 nicm 287: break;
1.5 nicm 288: case MODEKEYCHOICE_UP:
1.1 nicm 289: if (items == 0)
290: break;
291: if (data->selected == 0) {
292: data->selected = items - 1;
293: if (data->selected > screen_size_y(s) - 1)
294: data->top = items - screen_size_y(s);
295: window_choose_redraw_screen(wp);
296: break;
297: }
298: data->selected--;
299: if (data->selected < data->top)
300: window_choose_scroll_up(wp);
301: else {
302: screen_write_start(&ctx, wp, NULL);
303: window_choose_write_line(
304: wp, &ctx, data->selected - data->top);
305: window_choose_write_line(
306: wp, &ctx, data->selected + 1 - data->top);
307: screen_write_stop(&ctx);
308: }
309: break;
1.5 nicm 310: case MODEKEYCHOICE_DOWN:
1.1 nicm 311: if (items == 0)
312: break;
313: if (data->selected == items - 1) {
314: data->selected = 0;
315: data->top = 0;
316: window_choose_redraw_screen(wp);
317: break;
318: }
319: data->selected++;
1.5 nicm 320:
1.15 nicm 321: if (data->selected < data->top + screen_size_y(s)) {
1.1 nicm 322: screen_write_start(&ctx, wp, NULL);
323: window_choose_write_line(
324: wp, &ctx, data->selected - data->top);
325: window_choose_write_line(
326: wp, &ctx, data->selected - 1 - data->top);
327: screen_write_stop(&ctx);
1.15 nicm 328: } else
329: window_choose_scroll_down(wp);
330: break;
331: case MODEKEYCHOICE_SCROLLUP:
332: if (items == 0 || data->top == 0)
333: break;
334: if (data->selected == data->top + screen_size_y(s) - 1) {
335: data->selected--;
336: window_choose_scroll_up(wp);
337: screen_write_start(&ctx, wp, NULL);
338: window_choose_write_line(
339: wp, &ctx, screen_size_y(s) - 1);
340: screen_write_stop(&ctx);
341: } else
342: window_choose_scroll_up(wp);
343: break;
344: case MODEKEYCHOICE_SCROLLDOWN:
345: if (items == 0 ||
346: data->top + screen_size_y(&data->screen) >= items)
347: break;
348: if (data->selected == data->top) {
349: data->selected++;
350: window_choose_scroll_down(wp);
351: screen_write_start(&ctx, wp, NULL);
352: window_choose_write_line(wp, &ctx, 0);
353: screen_write_stop(&ctx);
354: } else
355: window_choose_scroll_down(wp);
1.1 nicm 356: break;
1.5 nicm 357: case MODEKEYCHOICE_PAGEUP:
1.1 nicm 358: if (data->selected < screen_size_y(s)) {
359: data->selected = 0;
360: data->top = 0;
361: } else {
362: data->selected -= screen_size_y(s);
363: if (data->top < screen_size_y(s))
364: data->top = 0;
365: else
366: data->top -= screen_size_y(s);
367: }
1.13 nicm 368: window_choose_redraw_screen(wp);
1.1 nicm 369: break;
1.5 nicm 370: case MODEKEYCHOICE_PAGEDOWN:
1.1 nicm 371: data->selected += screen_size_y(s);
372: if (data->selected > items - 1)
373: data->selected = items - 1;
374: data->top += screen_size_y(s);
375: if (screen_size_y(s) < items) {
376: if (data->top + screen_size_y(s) > items)
377: data->top = items - screen_size_y(s);
378: } else
379: data->top = 0;
380: if (data->selected < data->top)
381: data->top = data->selected;
382: window_choose_redraw_screen(wp);
383: break;
1.22 nicm 384: case MODEKEYCHOICE_BACKSPACE:
385: input_len = strlen(data->input_str);
386: if (input_len > 0)
387: data->input_str[input_len - 1] = '\0';
388: window_choose_redraw_screen(wp);
389: break;
390: case MODEKEYCHOICE_STARTNUMBERPREFIX:
1.25 nicm 391: key &= KEYC_MASK_KEY;
392: if (key < '0' || key > '9')
1.11 nicm 393: break;
1.25 nicm 394: window_choose_prompt_input(WINDOW_CHOOSE_GOTO_ITEM,
395: "Goto Item", wp, key);
1.22 nicm 396: break;
397: default:
1.25 nicm 398: idx = window_choose_index_key(data, key);
399: if (idx < 0 || (u_int) idx >= ARRAY_LENGTH(&data->list))
400: break;
401: data->selected = idx;
402:
403: item = &ARRAY_ITEM(&data->list, data->selected);
404: window_choose_fire_callback(wp, item->wcd);
405: window_pane_reset_mode(wp);
1.1 nicm 406: break;
407: }
408: }
409:
1.12 nicm 410: /* ARGSUSED */
1.1 nicm 411: void
1.10 nicm 412: window_choose_mouse(
1.16 nicm 413: struct window_pane *wp, unused struct session *sess, struct mouse_event *m)
1.1 nicm 414: {
415: struct window_choose_mode_data *data = wp->modedata;
416: struct screen *s = &data->screen;
417: struct window_choose_mode_item *item;
418: u_int idx;
419:
1.10 nicm 420: if ((m->b & 3) == 3)
1.1 nicm 421: return;
1.10 nicm 422: if (m->x >= screen_size_x(s))
1.1 nicm 423: return;
1.10 nicm 424: if (m->y >= screen_size_y(s))
1.1 nicm 425: return;
426:
1.10 nicm 427: idx = data->top + m->y;
1.1 nicm 428: if (idx >= ARRAY_LENGTH(&data->list))
429: return;
430: data->selected = idx;
431:
432: item = &ARRAY_ITEM(&data->list, data->selected);
1.19 nicm 433: window_choose_fire_callback(wp, item->wcd);
1.1 nicm 434: window_pane_reset_mode(wp);
435: }
436:
437: void
438: window_choose_write_line(
439: struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
440: {
441: struct window_choose_mode_data *data = wp->modedata;
442: struct window_choose_mode_item *item;
1.9 nicm 443: struct options *oo = &wp->window->options;
1.1 nicm 444: struct screen *s = &data->screen;
445: struct grid_cell gc;
1.22 nicm 446: size_t last, xoff = 0;
1.25 nicm 447: char hdr[32], label[32];
448: int utf8flag, key;
1.1 nicm 449:
1.3 nicm 450: if (data->callbackfn == NULL)
1.1 nicm 451: fatalx("called before callback assigned");
452:
1.22 nicm 453: last = screen_size_y(s) - 1;
1.2 nicm 454: utf8flag = options_get_number(&wp->window->options, "utf8");
1.1 nicm 455: memcpy(&gc, &grid_default_cell, sizeof gc);
1.22 nicm 456: if (data->selected == data->top + py)
457: window_mode_attrs(&gc, oo);
1.1 nicm 458:
459: screen_write_cursormove(ctx, 0, py);
460: if (data->top + py < ARRAY_LENGTH(&data->list)) {
461: item = &ARRAY_ITEM(&data->list, data->top + py);
1.24 nicm 462: if (item->wcd->wl != NULL &&
463: item->wcd->wl->flags & WINLINK_ALERTFLAGS)
464: gc.attr |= GRID_ATTR_BRIGHT;
1.11 nicm 465:
1.25 nicm 466: key = window_choose_key_index(data, data->top + py);
467: if (key != -1)
468: xsnprintf (label, sizeof label, "(%c)", key);
469: else
470: xsnprintf (label, sizeof label, "(%d)", item->pos);
471: screen_write_nputs(ctx, screen_size_x(s) - 1, &gc, utf8flag,
472: "%*s %s", data->width + 2, label, item->name);
1.1 nicm 473: }
474: while (s->cx < screen_size_x(s))
475: screen_write_putc(ctx, &gc, ' ');
1.11 nicm 476:
1.22 nicm 477: if (data->input_type != WINDOW_CHOOSE_NORMAL) {
478: window_mode_attrs(&gc, oo);
1.11 nicm 479:
1.22 nicm 480: xoff = xsnprintf(hdr, sizeof hdr,
481: "%s: %s", data->input_prompt, data->input_str);
482: screen_write_cursormove(ctx, 0, last);
483: screen_write_puts(ctx, &gc, "%s", hdr);
484: screen_write_cursormove(ctx, xoff, py);
485: memcpy(&gc, &grid_default_cell, sizeof gc);
1.11 nicm 486: }
1.22 nicm 487:
1.11 nicm 488: }
489:
490: int
1.25 nicm 491: window_choose_key_index(struct window_choose_mode_data *data, u_int idx)
492: {
493: static const char keys[] = "0123456789"
494: "abcdefghijklmnopqrstuvwxyz"
495: "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
496: const char *ptr;
497: int mkey;
498:
499: for (ptr = keys; *ptr != '\0'; ptr++) {
500: mkey = mode_key_lookup(&data->mdata, *ptr);
501: if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
502: continue;
503: if (idx-- == 0)
504: return (*ptr);
505: }
506: return (-1);
507: }
508:
509: int
510: window_choose_index_key(struct window_choose_mode_data *data, int key)
1.11 nicm 511: {
1.25 nicm 512: static const char keys[] = "0123456789"
513: "abcdefghijklmnopqrstuvwxyz"
514: "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1.11 nicm 515: const char *ptr;
1.25 nicm 516: int mkey;
1.11 nicm 517: u_int idx = 0;
518:
519: for (ptr = keys; *ptr != '\0'; ptr++) {
1.25 nicm 520: mkey = mode_key_lookup(&data->mdata, *ptr);
521: if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
522: continue;
1.11 nicm 523: if (key == *ptr)
524: return (idx);
525: idx++;
526: }
527: return (-1);
1.1 nicm 528: }
529:
530: void
531: window_choose_redraw_screen(struct window_pane *wp)
532: {
533: struct window_choose_mode_data *data = wp->modedata;
534: struct screen *s = &data->screen;
535: struct screen_write_ctx ctx;
536: u_int i;
537:
538: screen_write_start(&ctx, wp, NULL);
539: for (i = 0; i < screen_size_y(s); i++)
540: window_choose_write_line(wp, &ctx, i);
541: screen_write_stop(&ctx);
542: }
543:
544: void
545: window_choose_scroll_up(struct window_pane *wp)
546: {
547: struct window_choose_mode_data *data = wp->modedata;
548: struct screen_write_ctx ctx;
549:
550: if (data->top == 0)
551: return;
552: data->top--;
553:
554: screen_write_start(&ctx, wp, NULL);
555: screen_write_cursormove(&ctx, 0, 0);
556: screen_write_insertline(&ctx, 1);
557: window_choose_write_line(wp, &ctx, 0);
558: if (screen_size_y(&data->screen) > 1)
559: window_choose_write_line(wp, &ctx, 1);
560: screen_write_stop(&ctx);
561: }
562:
563: void
564: window_choose_scroll_down(struct window_pane *wp)
565: {
566: struct window_choose_mode_data *data = wp->modedata;
567: struct screen *s = &data->screen;
568: struct screen_write_ctx ctx;
569:
570: if (data->top >= ARRAY_LENGTH(&data->list))
571: return;
572: data->top++;
573:
574: screen_write_start(&ctx, wp, NULL);
575: screen_write_cursormove(&ctx, 0, 0);
576: screen_write_deleteline(&ctx, 1);
577: window_choose_write_line(wp, &ctx, screen_size_y(s) - 1);
578: if (screen_size_y(&data->screen) > 1)
579: window_choose_write_line(wp, &ctx, screen_size_y(s) - 2);
580: screen_write_stop(&ctx);
1.19 nicm 581: }
582:
583: void
584: window_choose_ctx(struct window_choose_data *cdata)
585: {
586: struct cmd_ctx ctx;
587: struct cmd_list *cmdlist;
1.20 nicm 588: char *cause;
1.19 nicm 589:
1.20 nicm 590: /* The command template will have already been replaced. But if it's
591: * NULL, bail here.
592: */
593: if (cdata->command == NULL)
594: return;
1.19 nicm 595:
1.20 nicm 596: if (cmd_string_parse(cdata->command, &cmdlist, &cause) != 0) {
1.19 nicm 597: if (cause != NULL) {
598: *cause = toupper((u_char) *cause);
599: status_message_set(cdata->client, "%s", cause);
1.21 nicm 600: free(cause);
1.19 nicm 601: }
602: return;
603: }
604:
605: ctx.msgdata = NULL;
606: ctx.curclient = cdata->client;
607:
608: ctx.error = key_bindings_error;
609: ctx.print = key_bindings_print;
610: ctx.info = key_bindings_info;
611:
612: ctx.cmdclient = NULL;
613:
614: cmd_list_exec(cmdlist, &ctx);
615: cmd_list_free(cmdlist);
1.20 nicm 616: }
617:
618: struct window_choose_data *
619: window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx,
1.22 nicm 620: struct session *s, const char *template, char *action, u_int idx)
1.20 nicm 621: {
622: struct window_choose_data *wcd;
623:
624: wcd = window_choose_data_create(ctx);
625: wcd->idx = s->idx;
626: wcd->command = cmd_template_replace(action, s->name, 1);
627: wcd->ft_template = xstrdup(template);
628: format_add(wcd->ft, "line", "%u", idx);
629: format_session(wcd->ft, s);
630:
631: wcd->client->references++;
632: wcd->session->references++;
633:
634: window_choose_add(wp, wcd);
635:
636: return (wcd);
1.26 ! nicm 637: }
! 638:
! 639: struct window_choose_data *
! 640: window_choose_add_item(struct window_pane *wp, struct cmd_ctx *ctx,
! 641: struct winlink *wl, const char *template, char *action, u_int idx)
! 642: {
! 643: struct window_choose_data *wcd;
! 644: char *action_data;
! 645:
! 646: wcd = window_choose_data_create(ctx);
! 647: wcd->idx = wl->idx;
! 648: wcd->ft_template = xstrdup(template);
! 649: format_add(wcd->ft, "line", "%u", idx);
! 650: format_session(wcd->ft, wcd->session);
! 651: format_winlink(wcd->ft, wcd->session, wl);
! 652: format_window_pane(wcd->ft, wl->window->active);
! 653:
! 654: wcd->client->references++;
! 655: wcd->session->references++;
! 656:
! 657: window_choose_add(wp, wcd);
! 658:
! 659: /*
! 660: * Interpolate action_data here, since the data we pass back is the
! 661: * expanded template itself.
! 662: */
! 663: xasprintf(&action_data, "%s", format_expand(wcd->ft, wcd->ft_template));
! 664: wcd->command = cmd_template_replace(action, action_data, 1);
! 665: free(action_data);
! 666:
! 667: return (wcd);
! 668:
1.20 nicm 669: }
670:
671: struct window_choose_data *
672: window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx,
1.22 nicm 673: struct session *s, struct winlink *wl, const char *template,
674: char *action, u_int idx)
1.20 nicm 675: {
676: struct window_choose_data *wcd;
677: char *action_data;
678:
679: wcd = window_choose_data_create(ctx);
680:
681: xasprintf(&action_data, "%s:%d", s->name, wl->idx);
682: wcd->command = cmd_template_replace(action, action_data, 1);
1.21 nicm 683: free(action_data);
1.20 nicm 684:
685: wcd->idx = wl->idx;
1.24 nicm 686: wcd->wl = wl;
1.20 nicm 687: wcd->ft_template = xstrdup(template);
688: format_add(wcd->ft, "line", "%u", idx);
689: format_session(wcd->ft, s);
690: format_winlink(wcd->ft, s, wl);
691: format_window_pane(wcd->ft, wl->window->active);
692:
693: wcd->client->references++;
694: wcd->session->references++;
695:
696: window_choose_add(wp, wcd);
697:
698: return (wcd);
1.1 nicm 699: }