Annotation of src/usr.bin/tmux/cmd-choose-window.c, Revision 1.19
1.19 ! nicm 1: /* $OpenBSD: cmd-choose-window.c,v 1.18 2011/01/04 00:42:46 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>
1.8 nicm 20:
21: #include <ctype.h>
1.1 nicm 22:
23: #include "tmux.h"
24:
25: /*
26: * Enter choice mode to choose a window.
27: */
28:
29: int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
30:
31: void cmd_choose_window_callback(void *, int);
1.7 nicm 32: void cmd_choose_window_free(void *);
1.1 nicm 33:
34: const struct cmd_entry cmd_choose_window_entry = {
35: "choose-window", NULL,
1.19 ! nicm 36: "F:t:", 0, 1,
! 37: CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
1.18 nicm 38: 0,
39: NULL,
40: NULL,
41: cmd_choose_window_exec
1.1 nicm 42: };
43:
44: struct cmd_choose_window_data {
1.9 nicm 45: struct client *client;
46: struct session *session;
1.7 nicm 47: char *template;
1.1 nicm 48: };
49:
50: int
51: cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
52: {
1.18 nicm 53: struct args *args = self->args;
1.1 nicm 54: struct cmd_choose_window_data *cdata;
55: struct session *s;
56: struct winlink *wl, *wm;
1.19 ! nicm 57: struct format_tree *ft;
! 58: const char *template;
! 59: char *line;
1.1 nicm 60: u_int idx, cur;
61:
62: if (ctx->curclient == NULL) {
63: ctx->error(ctx, "must be run interactively");
64: return (-1);
65: }
66: s = ctx->curclient->session;
67:
1.18 nicm 68: if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
1.1 nicm 69: return (-1);
70:
71: if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
72: return (0);
73:
1.19 ! nicm 74: if ((template = args_get(args, 'F')) == NULL)
! 75: template = DEFAULT_WINDOW_TEMPLATE;
! 76:
1.1 nicm 77: cur = idx = 0;
78: RB_FOREACH(wm, winlinks, &s->windows) {
79: if (wm == s->curw)
80: cur = idx;
81: idx++;
82:
1.19 ! nicm 83: ft = format_create();
! 84: format_add(ft, "line", "%u", idx);
! 85: format_session(ft, s);
! 86: format_winlink(ft, s, wm);
! 87:
! 88: line = format_expand(ft, template);
! 89: window_choose_add(wl->window->active, idx, "%s", line);
1.17 nicm 90:
1.19 ! nicm 91: xfree(line);
! 92: format_free(ft);
1.1 nicm 93: }
94:
95: cdata = xmalloc(sizeof *cdata);
1.18 nicm 96: if (args->argc != 0)
97: cdata->template = xstrdup(args->argv[0]);
1.7 nicm 98: else
99: cdata->template = xstrdup("select-window -t '%%'");
1.9 nicm 100: cdata->session = s;
101: cdata->session->references++;
102: cdata->client = ctx->curclient;
103: cdata->client->references++;
1.1 nicm 104:
1.12 nicm 105: window_choose_ready(wl->window->active,
1.7 nicm 106: cur, cmd_choose_window_callback, cmd_choose_window_free, cdata);
1.1 nicm 107:
1.12 nicm 108: return (0);
1.1 nicm 109: }
110:
111: void
112: cmd_choose_window_callback(void *data, int idx)
113: {
114: struct cmd_choose_window_data *cdata = data;
1.16 nicm 115: struct session *s = cdata->session;
1.7 nicm 116: struct cmd_list *cmdlist;
117: struct cmd_ctx ctx;
118: char *target, *template, *cause;
119:
120: if (idx == -1)
121: return;
1.16 nicm 122: if (!session_alive(s))
123: return;
1.9 nicm 124: if (cdata->client->flags & CLIENT_DEAD)
1.12 nicm 125: return;
1.7 nicm 126:
1.16 nicm 127: xasprintf(&target, "%s:%d", s->name, idx);
1.7 nicm 128: template = cmd_template_replace(cdata->template, target, 1);
129: xfree(target);
130:
131: if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
132: if (cause != NULL) {
133: *cause = toupper((u_char) *cause);
1.9 nicm 134: status_message_set(cdata->client, "%s", cause);
1.7 nicm 135: xfree(cause);
136: }
137: xfree(template);
138: return;
139: }
140: xfree(template);
141:
142: ctx.msgdata = NULL;
1.9 nicm 143: ctx.curclient = cdata->client;
1.7 nicm 144:
145: ctx.error = key_bindings_error;
146: ctx.print = key_bindings_print;
147: ctx.info = key_bindings_info;
148:
149: ctx.cmdclient = NULL;
150:
151: cmd_list_exec(cmdlist, &ctx);
152: cmd_list_free(cmdlist);
153: }
1.1 nicm 154:
1.7 nicm 155: void
156: cmd_choose_window_free(void *data)
157: {
158: struct cmd_choose_window_data *cdata = data;
159:
1.9 nicm 160: cdata->session->references--;
161: cdata->client->references--;
1.7 nicm 162: xfree(cdata->template);
163: xfree(cdata);
1.1 nicm 164: }