For initial session, use size of command client even if detached.
[tmux-openbsd.git] / cmd-choose-window.c
bloba1280927220b0d41a957935560331b14571e8730
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
21 #include <ctype.h>
23 #include "tmux.h"
26 * Enter choice mode to choose a window.
29 int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
31 void cmd_choose_window_callback(void *, int);
32 void cmd_choose_window_free(void *);
34 const struct cmd_entry cmd_choose_window_entry = {
35 "choose-window", NULL,
36 "t:", 0, 1,
37 CMD_TARGET_WINDOW_USAGE " [template]",
39 NULL,
40 NULL,
41 cmd_choose_window_exec
44 struct cmd_choose_window_data {
45 struct client *client;
46 struct session *session;
47 char *template;
50 int
51 cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
53 struct args *args = self->args;
54 struct cmd_choose_window_data *cdata;
55 struct session *s;
56 struct winlink *wl, *wm;
57 struct window *w;
58 u_int idx, cur;
59 char *flags, *title;
60 const char *left, *right;
62 if (ctx->curclient == NULL) {
63 ctx->error(ctx, "must be run interactively");
64 return (-1);
66 s = ctx->curclient->session;
68 if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
69 return (-1);
71 if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
72 return (0);
74 cur = idx = 0;
75 RB_FOREACH(wm, winlinks, &s->windows) {
76 w = wm->window;
78 if (wm == s->curw)
79 cur = idx;
80 idx++;
82 flags = window_printable_flags(s, wm);
83 title = w->active->screen->title;
84 if (wm == wl)
85 title = w->active->base.title;
86 left = " \"";
87 right = "\"";
88 if (*title == '\0')
89 left = right = "";
91 window_choose_add(wl->window->active,
92 wm->idx, "%3d: %s%s [%ux%u] (%u panes%s)%s%s%s",
93 wm->idx, w->name, flags, w->sx, w->sy, window_count_panes(w),
94 w->active->fd == -1 ? ", dead" : "",
95 left, title, right);
97 xfree(flags);
100 cdata = xmalloc(sizeof *cdata);
101 if (args->argc != 0)
102 cdata->template = xstrdup(args->argv[0]);
103 else
104 cdata->template = xstrdup("select-window -t '%%'");
105 cdata->session = s;
106 cdata->session->references++;
107 cdata->client = ctx->curclient;
108 cdata->client->references++;
110 window_choose_ready(wl->window->active,
111 cur, cmd_choose_window_callback, cmd_choose_window_free, cdata);
113 return (0);
116 void
117 cmd_choose_window_callback(void *data, int idx)
119 struct cmd_choose_window_data *cdata = data;
120 struct session *s = cdata->session;
121 struct cmd_list *cmdlist;
122 struct cmd_ctx ctx;
123 char *target, *template, *cause;
125 if (idx == -1)
126 return;
127 if (!session_alive(s))
128 return;
129 if (cdata->client->flags & CLIENT_DEAD)
130 return;
132 xasprintf(&target, "%s:%d", s->name, idx);
133 template = cmd_template_replace(cdata->template, target, 1);
134 xfree(target);
136 if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
137 if (cause != NULL) {
138 *cause = toupper((u_char) *cause);
139 status_message_set(cdata->client, "%s", cause);
140 xfree(cause);
142 xfree(template);
143 return;
145 xfree(template);
147 ctx.msgdata = NULL;
148 ctx.curclient = cdata->client;
150 ctx.error = key_bindings_error;
151 ctx.print = key_bindings_print;
152 ctx.info = key_bindings_info;
154 ctx.cmdclient = NULL;
156 cmd_list_exec(cmdlist, &ctx);
157 cmd_list_free(cmdlist);
160 void
161 cmd_choose_window_free(void *data)
163 struct cmd_choose_window_data *cdata = data;
165 cdata->session->references--;
166 cdata->client->references--;
167 xfree(cdata->template);
168 xfree(cdata);