[BACK]Return to window-choose.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/window-choose.c, Revision 1.20

1.20    ! nicm        1: /* $OpenBSD: window-choose.c,v 1.19 2012/06/25 14:08:55 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.1       nicm       22: #include <string.h>
                     23:
                     24: #include "tmux.h"
                     25:
                     26: struct screen *window_choose_init(struct window_pane *);
                     27: void   window_choose_free(struct window_pane *);
                     28: void   window_choose_resize(struct window_pane *, u_int, u_int);
1.16      nicm       29: void   window_choose_key(struct window_pane *, struct session *, int);
1.1       nicm       30: void   window_choose_mouse(
1.16      nicm       31:            struct window_pane *, struct session *, struct mouse_event *);
1.1       nicm       32:
1.19      nicm       33: void   window_choose_fire_callback(
                     34:            struct window_pane *, struct window_choose_data *);
1.1       nicm       35: void   window_choose_redraw_screen(struct window_pane *);
                     36: void   window_choose_write_line(
1.13      nicm       37:            struct window_pane *, struct screen_write_ctx *, u_int);
1.1       nicm       38:
                     39: void   window_choose_scroll_up(struct window_pane *);
                     40: void   window_choose_scroll_down(struct window_pane *);
                     41:
                     42: const struct window_mode window_choose_mode = {
                     43:        window_choose_init,
                     44:        window_choose_free,
                     45:        window_choose_resize,
                     46:        window_choose_key,
                     47:        window_choose_mouse,
                     48:        NULL,
                     49: };
                     50:
                     51: struct window_choose_mode_data {
                     52:        struct screen           screen;
                     53:
                     54:        struct mode_key_data    mdata;
                     55:
                     56:        ARRAY_DECL(, struct window_choose_mode_item) list;
                     57:        u_int                   top;
                     58:        u_int                   selected;
                     59:
1.19      nicm       60:        void                    (*callbackfn)(struct window_choose_data *);
                     61:        void                    (*freefn)(struct window_choose_data *);
1.1       nicm       62: };
                     63:
1.11      nicm       64: int    window_choose_key_index(struct window_choose_mode_data *, u_int);
                     65: int    window_choose_index_key(struct window_choose_mode_data *, int);
                     66:
1.1       nicm       67: void
1.19      nicm       68: window_choose_add(struct window_pane *wp, struct window_choose_data *wcd)
1.1       nicm       69: {
                     70:        struct window_choose_mode_data  *data = wp->modedata;
                     71:        struct window_choose_mode_item  *item;
                     72:
                     73:        ARRAY_EXPAND(&data->list, 1);
                     74:        item = &ARRAY_LAST(&data->list);
                     75:
1.19      nicm       76:        item->name = format_expand(wcd->ft, wcd->ft_template);
                     77:        item->wcd = wcd;
1.1       nicm       78: }
                     79:
                     80: void
1.3       nicm       81: window_choose_ready(struct window_pane *wp, u_int cur,
1.19      nicm       82:     void (*callbackfn)(struct window_choose_data *),
                     83:     void (*freefn)(struct window_choose_data *))
1.1       nicm       84: {
                     85:        struct window_choose_mode_data  *data = wp->modedata;
                     86:        struct screen                   *s = &data->screen;
                     87:
                     88:        data->selected = cur;
                     89:        if (data->selected > screen_size_y(s) - 1)
                     90:                data->top = ARRAY_LENGTH(&data->list) - screen_size_y(s);
                     91:
1.3       nicm       92:        data->callbackfn = callbackfn;
                     93:        data->freefn = freefn;
1.1       nicm       94:
                     95:        window_choose_redraw_screen(wp);
                     96: }
                     97:
                     98: struct screen *
                     99: window_choose_init(struct window_pane *wp)
                    100: {
                    101:        struct window_choose_mode_data  *data;
                    102:        struct screen                   *s;
1.5       nicm      103:        int                              keys;
1.1       nicm      104:
                    105:        wp->modedata = data = xmalloc(sizeof *data);
1.3       nicm      106:
                    107:        data->callbackfn = NULL;
                    108:        data->freefn = NULL;
                    109:
1.1       nicm      110:        ARRAY_INIT(&data->list);
                    111:        data->top = 0;
                    112:
                    113:        s = &data->screen;
                    114:        screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
                    115:        s->mode &= ~MODE_CURSOR;
1.7       nicm      116:        if (options_get_number(&wp->window->options, "mode-mouse"))
1.17      nicm      117:                s->mode |= MODE_MOUSE_STANDARD;
1.1       nicm      118:
1.5       nicm      119:        keys = options_get_number(&wp->window->options, "mode-keys");
                    120:        if (keys == MODEKEY_EMACS)
1.6       nicm      121:                mode_key_init(&data->mdata, &mode_key_tree_emacs_choice);
1.5       nicm      122:        else
1.6       nicm      123:                mode_key_init(&data->mdata, &mode_key_tree_vi_choice);
1.1       nicm      124:
                    125:        return (s);
                    126: }
                    127:
1.19      nicm      128: struct window_choose_data *
                    129: window_choose_data_create(struct cmd_ctx *ctx)
                    130: {
                    131:        struct window_choose_data       *wcd;
                    132:
                    133:        wcd = xmalloc(sizeof *wcd);
                    134:        wcd->ft = format_create();
                    135:        wcd->ft_template = NULL;
1.20    ! nicm      136:        wcd->command = NULL;
1.19      nicm      137:        wcd->client = ctx->curclient;
                    138:        wcd->session = ctx->curclient->session;
                    139:        wcd->idx = -1;
                    140:
                    141:        return (wcd);
                    142: }
                    143:
1.1       nicm      144: void
                    145: window_choose_free(struct window_pane *wp)
                    146: {
                    147:        struct window_choose_mode_data  *data = wp->modedata;
1.19      nicm      148:        struct window_choose_mode_item  *item;
1.1       nicm      149:        u_int                            i;
                    150:
1.19      nicm      151:        for (i = 0; i < ARRAY_LENGTH(&data->list); i++) {
                    152:                item = &ARRAY_ITEM(&data->list, i);
                    153:                if (data->freefn != NULL && item->wcd != NULL)
                    154:                        data->freefn(item->wcd);
                    155:                xfree(item->name);
                    156:        }
1.1       nicm      157:        ARRAY_FREE(&data->list);
                    158:
                    159:        screen_free(&data->screen);
                    160:        xfree(data);
                    161: }
                    162:
                    163: void
                    164: window_choose_resize(struct window_pane *wp, u_int sx, u_int sy)
                    165: {
                    166:        struct window_choose_mode_data  *data = wp->modedata;
                    167:        struct screen                   *s = &data->screen;
                    168:
                    169:        data->top = 0;
                    170:        if (data->selected > sy - 1)
                    171:                data->top = data->selected - (sy - 1);
                    172:
                    173:        screen_resize(s, sx, sy);
                    174:        window_choose_redraw_screen(wp);
                    175: }
                    176:
1.18      nicm      177: void
1.19      nicm      178: window_choose_fire_callback(
                    179:        struct window_pane *wp, struct window_choose_data *wcd)
1.18      nicm      180: {
                    181:        struct window_choose_mode_data  *data = wp->modedata;
                    182:        const struct window_mode        *oldmode;
                    183:
                    184:        oldmode = wp->mode;
                    185:        wp->mode = NULL;
                    186:
1.19      nicm      187:        data->callbackfn(wcd);
1.18      nicm      188:
                    189:        wp->mode = oldmode;
                    190: }
                    191:
1.12      nicm      192: /* ARGSUSED */
1.1       nicm      193: void
1.16      nicm      194: window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
1.1       nicm      195: {
                    196:        struct window_choose_mode_data  *data = wp->modedata;
                    197:        struct screen                   *s = &data->screen;
                    198:        struct screen_write_ctx          ctx;
                    199:        struct window_choose_mode_item  *item;
1.11      nicm      200:        u_int                            items;
                    201:        int                              idx;
1.1       nicm      202:
                    203:        items = ARRAY_LENGTH(&data->list);
                    204:
                    205:        switch (mode_key_lookup(&data->mdata, key)) {
1.5       nicm      206:        case MODEKEYCHOICE_CANCEL:
1.19      nicm      207:                window_choose_fire_callback(wp, NULL);
1.1       nicm      208:                window_pane_reset_mode(wp);
                    209:                break;
1.5       nicm      210:        case MODEKEYCHOICE_CHOOSE:
1.1       nicm      211:                item = &ARRAY_ITEM(&data->list, data->selected);
1.19      nicm      212:                window_choose_fire_callback(wp, item->wcd);
1.1       nicm      213:                window_pane_reset_mode(wp);
                    214:                break;
1.5       nicm      215:        case MODEKEYCHOICE_UP:
1.1       nicm      216:                if (items == 0)
                    217:                        break;
                    218:                if (data->selected == 0) {
                    219:                        data->selected = items - 1;
                    220:                        if (data->selected > screen_size_y(s) - 1)
                    221:                                data->top = items - screen_size_y(s);
                    222:                        window_choose_redraw_screen(wp);
                    223:                        break;
                    224:                }
                    225:                data->selected--;
                    226:                if (data->selected < data->top)
                    227:                        window_choose_scroll_up(wp);
                    228:                else {
                    229:                        screen_write_start(&ctx, wp, NULL);
                    230:                        window_choose_write_line(
                    231:                            wp, &ctx, data->selected - data->top);
                    232:                        window_choose_write_line(
                    233:                            wp, &ctx, data->selected + 1 - data->top);
                    234:                        screen_write_stop(&ctx);
                    235:                }
                    236:                break;
1.5       nicm      237:        case MODEKEYCHOICE_DOWN:
1.1       nicm      238:                if (items == 0)
                    239:                        break;
                    240:                if (data->selected == items - 1) {
                    241:                        data->selected = 0;
                    242:                        data->top = 0;
                    243:                        window_choose_redraw_screen(wp);
                    244:                        break;
                    245:                }
                    246:                data->selected++;
1.5       nicm      247:
1.15      nicm      248:                if (data->selected < data->top + screen_size_y(s)) {
1.1       nicm      249:                        screen_write_start(&ctx, wp, NULL);
                    250:                        window_choose_write_line(
                    251:                            wp, &ctx, data->selected - data->top);
                    252:                        window_choose_write_line(
                    253:                            wp, &ctx, data->selected - 1 - data->top);
                    254:                        screen_write_stop(&ctx);
1.15      nicm      255:                } else
                    256:                        window_choose_scroll_down(wp);
                    257:                break;
                    258:        case MODEKEYCHOICE_SCROLLUP:
                    259:                if (items == 0 || data->top == 0)
                    260:                        break;
                    261:                if (data->selected == data->top + screen_size_y(s) - 1) {
                    262:                        data->selected--;
                    263:                        window_choose_scroll_up(wp);
                    264:                        screen_write_start(&ctx, wp, NULL);
                    265:                        window_choose_write_line(
                    266:                            wp, &ctx, screen_size_y(s) - 1);
                    267:                        screen_write_stop(&ctx);
                    268:                } else
                    269:                        window_choose_scroll_up(wp);
                    270:                break;
                    271:        case MODEKEYCHOICE_SCROLLDOWN:
                    272:                if (items == 0 ||
                    273:                    data->top + screen_size_y(&data->screen) >= items)
                    274:                        break;
                    275:                if (data->selected == data->top) {
                    276:                        data->selected++;
                    277:                        window_choose_scroll_down(wp);
                    278:                        screen_write_start(&ctx, wp, NULL);
                    279:                        window_choose_write_line(wp, &ctx, 0);
                    280:                        screen_write_stop(&ctx);
                    281:                } else
                    282:                        window_choose_scroll_down(wp);
1.1       nicm      283:                break;
1.5       nicm      284:        case MODEKEYCHOICE_PAGEUP:
1.1       nicm      285:                if (data->selected < screen_size_y(s)) {
                    286:                        data->selected = 0;
                    287:                        data->top = 0;
                    288:                } else {
                    289:                        data->selected -= screen_size_y(s);
                    290:                        if (data->top < screen_size_y(s))
                    291:                                data->top = 0;
                    292:                        else
                    293:                                data->top -= screen_size_y(s);
                    294:                }
1.13      nicm      295:                window_choose_redraw_screen(wp);
1.1       nicm      296:                break;
1.5       nicm      297:        case MODEKEYCHOICE_PAGEDOWN:
1.1       nicm      298:                data->selected += screen_size_y(s);
                    299:                if (data->selected > items - 1)
                    300:                        data->selected = items - 1;
                    301:                data->top += screen_size_y(s);
                    302:                if (screen_size_y(s) < items) {
                    303:                        if (data->top + screen_size_y(s) > items)
                    304:                                data->top = items - screen_size_y(s);
                    305:                } else
                    306:                        data->top = 0;
                    307:                if (data->selected < data->top)
                    308:                        data->top = data->selected;
                    309:                window_choose_redraw_screen(wp);
                    310:                break;
                    311:        default:
1.11      nicm      312:                idx = window_choose_index_key(data, key);
                    313:                if (idx < 0 || (u_int) idx >= ARRAY_LENGTH(&data->list))
                    314:                        break;
                    315:                data->selected = idx;
1.13      nicm      316:
1.11      nicm      317:                item = &ARRAY_ITEM(&data->list, data->selected);
1.19      nicm      318:                window_choose_fire_callback(wp, item->wcd);
1.11      nicm      319:                window_pane_reset_mode(wp);
1.1       nicm      320:                break;
                    321:        }
                    322: }
                    323:
1.12      nicm      324: /* ARGSUSED */
1.1       nicm      325: void
1.10      nicm      326: window_choose_mouse(
1.16      nicm      327:     struct window_pane *wp, unused struct session *sess, struct mouse_event *m)
1.1       nicm      328: {
                    329:        struct window_choose_mode_data  *data = wp->modedata;
                    330:        struct screen                   *s = &data->screen;
                    331:        struct window_choose_mode_item  *item;
                    332:        u_int                            idx;
                    333:
1.10      nicm      334:        if ((m->b & 3) == 3)
1.1       nicm      335:                return;
1.10      nicm      336:        if (m->x >= screen_size_x(s))
1.1       nicm      337:                return;
1.10      nicm      338:        if (m->y >= screen_size_y(s))
1.1       nicm      339:                return;
                    340:
1.10      nicm      341:        idx = data->top + m->y;
1.1       nicm      342:        if (idx >= ARRAY_LENGTH(&data->list))
                    343:                return;
                    344:        data->selected = idx;
                    345:
                    346:        item = &ARRAY_ITEM(&data->list, data->selected);
1.19      nicm      347:        window_choose_fire_callback(wp, item->wcd);
1.1       nicm      348:        window_pane_reset_mode(wp);
                    349: }
                    350:
                    351: void
                    352: window_choose_write_line(
                    353:     struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
                    354: {
                    355:        struct window_choose_mode_data  *data = wp->modedata;
                    356:        struct window_choose_mode_item  *item;
1.9       nicm      357:        struct options                  *oo = &wp->window->options;
1.1       nicm      358:        struct screen                   *s = &data->screen;
                    359:        struct grid_cell                 gc;
1.14      nicm      360:        int                              utf8flag, key;
1.1       nicm      361:
1.3       nicm      362:        if (data->callbackfn == NULL)
1.1       nicm      363:                fatalx("called before callback assigned");
                    364:
1.2       nicm      365:        utf8flag = options_get_number(&wp->window->options, "utf8");
1.1       nicm      366:        memcpy(&gc, &grid_default_cell, sizeof gc);
                    367:        if (data->selected == data->top + py) {
1.9       nicm      368:                colour_set_fg(&gc, options_get_number(oo, "mode-fg"));
                    369:                colour_set_bg(&gc, options_get_number(oo, "mode-bg"));
                    370:                gc.attr |= options_get_number(oo, "mode-attr");
1.1       nicm      371:        }
                    372:
                    373:        screen_write_cursormove(ctx, 0, py);
                    374:        if (data->top + py  < ARRAY_LENGTH(&data->list)) {
                    375:                item = &ARRAY_ITEM(&data->list, data->top + py);
1.11      nicm      376:                key = window_choose_key_index(data, data->top + py);
                    377:                if (key != -1) {
                    378:                        screen_write_nputs(ctx, screen_size_x(s) - 1,
                    379:                            &gc, utf8flag, "(%c) %s", key, item->name);
                    380:                } else {
                    381:                        screen_write_nputs(ctx, screen_size_x(s) - 1,
                    382:                            &gc, utf8flag, "    %s", item->name);
                    383:                }
                    384:
1.1       nicm      385:        }
                    386:        while (s->cx < screen_size_x(s))
                    387:                screen_write_putc(ctx, &gc, ' ');
1.11      nicm      388: }
                    389:
                    390: int
                    391: window_choose_key_index(struct window_choose_mode_data *data, u_int idx)
                    392: {
                    393:        static const char       keys[] = "0123456789abcdefghijklmnopqrstuvwxyz";
                    394:        const char             *ptr;
                    395:        int                     mkey;
                    396:
                    397:        for (ptr = keys; *ptr != '\0'; ptr++) {
                    398:                mkey = mode_key_lookup(&data->mdata, *ptr);
                    399:                if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
                    400:                        continue;
                    401:                if (idx-- == 0)
                    402:                        return (*ptr);
                    403:        }
                    404:        return (-1);
                    405: }
                    406:
                    407: int
                    408: window_choose_index_key(struct window_choose_mode_data *data, int key)
                    409: {
                    410:        static const char       keys[] = "0123456789abcdefghijklmnopqrstuvwxyz";
                    411:        const char             *ptr;
                    412:        int                     mkey;
                    413:        u_int                   idx = 0;
                    414:
                    415:        for (ptr = keys; *ptr != '\0'; ptr++) {
                    416:                mkey = mode_key_lookup(&data->mdata, *ptr);
                    417:                if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER)
                    418:                        continue;
                    419:                if (key == *ptr)
                    420:                        return (idx);
                    421:                idx++;
                    422:        }
                    423:        return (-1);
1.1       nicm      424: }
                    425:
                    426: void
                    427: window_choose_redraw_screen(struct window_pane *wp)
                    428: {
                    429:        struct window_choose_mode_data  *data = wp->modedata;
                    430:        struct screen                   *s = &data->screen;
                    431:        struct screen_write_ctx          ctx;
                    432:        u_int                            i;
                    433:
                    434:        screen_write_start(&ctx, wp, NULL);
                    435:        for (i = 0; i < screen_size_y(s); i++)
                    436:                window_choose_write_line(wp, &ctx, i);
                    437:        screen_write_stop(&ctx);
                    438: }
                    439:
                    440: void
                    441: window_choose_scroll_up(struct window_pane *wp)
                    442: {
                    443:        struct window_choose_mode_data  *data = wp->modedata;
                    444:        struct screen_write_ctx          ctx;
                    445:
                    446:        if (data->top == 0)
                    447:                return;
                    448:        data->top--;
                    449:
                    450:        screen_write_start(&ctx, wp, NULL);
                    451:        screen_write_cursormove(&ctx, 0, 0);
                    452:        screen_write_insertline(&ctx, 1);
                    453:        window_choose_write_line(wp, &ctx, 0);
                    454:        if (screen_size_y(&data->screen) > 1)
                    455:                window_choose_write_line(wp, &ctx, 1);
                    456:        screen_write_stop(&ctx);
                    457: }
                    458:
                    459: void
                    460: window_choose_scroll_down(struct window_pane *wp)
                    461: {
                    462:        struct window_choose_mode_data  *data = wp->modedata;
                    463:        struct screen                   *s = &data->screen;
                    464:        struct screen_write_ctx          ctx;
                    465:
                    466:        if (data->top >= ARRAY_LENGTH(&data->list))
                    467:                return;
                    468:        data->top++;
                    469:
                    470:        screen_write_start(&ctx, wp, NULL);
                    471:        screen_write_cursormove(&ctx, 0, 0);
                    472:        screen_write_deleteline(&ctx, 1);
                    473:        window_choose_write_line(wp, &ctx, screen_size_y(s) - 1);
                    474:        if (screen_size_y(&data->screen) > 1)
                    475:                window_choose_write_line(wp, &ctx, screen_size_y(s) - 2);
                    476:        screen_write_stop(&ctx);
1.19      nicm      477: }
                    478:
                    479: void
                    480: window_choose_ctx(struct window_choose_data *cdata)
                    481: {
                    482:        struct cmd_ctx           ctx;
                    483:        struct cmd_list         *cmdlist;
1.20    ! nicm      484:        char                    *cause;
1.19      nicm      485:
1.20    ! nicm      486:        /* The command template will have already been replaced.  But if it's
        !           487:         * NULL, bail here.
        !           488:         */
        !           489:        if (cdata->command == NULL)
        !           490:                return;
1.19      nicm      491:
1.20    ! nicm      492:        if (cmd_string_parse(cdata->command, &cmdlist, &cause) != 0) {
1.19      nicm      493:                if (cause != NULL) {
                    494:                        *cause = toupper((u_char) *cause);
                    495:                        status_message_set(cdata->client, "%s", cause);
                    496:                        xfree(cause);
                    497:                }
                    498:                return;
                    499:        }
                    500:
                    501:        ctx.msgdata = NULL;
                    502:        ctx.curclient = cdata->client;
                    503:
                    504:        ctx.error = key_bindings_error;
                    505:        ctx.print = key_bindings_print;
                    506:        ctx.info = key_bindings_info;
                    507:
                    508:        ctx.cmdclient = NULL;
                    509:
                    510:        cmd_list_exec(cmdlist, &ctx);
                    511:        cmd_list_free(cmdlist);
1.20    ! nicm      512: }
        !           513:
        !           514: struct window_choose_data *
        !           515: window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx,
        !           516:        struct session *s, const char *template, char *action, u_int idx)
        !           517: {
        !           518:        struct window_choose_data       *wcd;
        !           519:
        !           520:        wcd = window_choose_data_create(ctx);
        !           521:        wcd->idx = s->idx;
        !           522:        wcd->command = cmd_template_replace(action, s->name, 1);
        !           523:        wcd->ft_template = xstrdup(template);
        !           524:        format_add(wcd->ft, "line", "%u", idx);
        !           525:        format_session(wcd->ft, s);
        !           526:
        !           527:        wcd->client->references++;
        !           528:        wcd->session->references++;
        !           529:
        !           530:        window_choose_add(wp, wcd);
        !           531:
        !           532:        return (wcd);
        !           533: }
        !           534:
        !           535: struct window_choose_data *
        !           536: window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx,
        !           537:        struct session *s, struct winlink *wl, const char *template,
        !           538:        char *action, u_int idx)
        !           539: {
        !           540:        struct window_choose_data       *wcd;
        !           541:        char                            *action_data;
        !           542:
        !           543:        wcd = window_choose_data_create(ctx);
        !           544:
        !           545:        xasprintf(&action_data, "%s:%d", s->name, wl->idx);
        !           546:        wcd->command = cmd_template_replace(action, action_data, 1);
        !           547:        xfree(action_data);
        !           548:
        !           549:        wcd->idx = wl->idx;
        !           550:        wcd->ft_template = xstrdup(template);
        !           551:        format_add(wcd->ft, "line", "%u", idx);
        !           552:        format_session(wcd->ft, s);
        !           553:        format_winlink(wcd->ft, s, wl);
        !           554:        format_window_pane(wcd->ft, wl->window->active);
        !           555:
        !           556:        wcd->client->references++;
        !           557:        wcd->session->references++;
        !           558:
        !           559:        window_choose_add(wp, wcd);
        !           560:
        !           561:        return (wcd);
1.1       nicm      562: }