Annotation of src/usr.bin/tmux/cmd-choose-window.c, Revision 1.7
1.7 ! nicm 1: /* $OpenBSD: cmd-choose-window.c,v 1.6 2009/08/04 14:28: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:
21: #include "tmux.h"
22:
23: /*
24: * Enter choice mode to choose a window.
25: */
26:
27: int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
28:
29: void cmd_choose_window_callback(void *, int);
1.7 ! nicm 30: void cmd_choose_window_free(void *);
1.1 nicm 31:
32: const struct cmd_entry cmd_choose_window_entry = {
33: "choose-window", NULL,
1.7 ! nicm 34: CMD_TARGET_WINDOW_USAGE " [template]",
! 35: CMD_ARG01, 0,
1.1 nicm 36: cmd_target_init,
37: cmd_target_parse,
38: cmd_choose_window_exec,
39: cmd_target_free,
40: cmd_target_print
41: };
42:
43: struct cmd_choose_window_data {
1.7 ! nicm 44: u_int client;
! 45: u_int session;
! 46: char *template;
1.1 nicm 47: };
48:
49: int
50: cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
51: {
52: struct cmd_target_data *data = self->data;
53: struct cmd_choose_window_data *cdata;
54: struct session *s;
55: struct winlink *wl, *wm;
56: struct window *w;
57: u_int idx, cur;
1.6 nicm 58: char flag, *title;
59: const char *left, *right;
1.1 nicm 60:
61: if (ctx->curclient == NULL) {
62: ctx->error(ctx, "must be run interactively");
63: return (-1);
64: }
65: s = ctx->curclient->session;
66:
67: if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
68: return (-1);
69:
70: if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
71: return (0);
72:
73: cur = idx = 0;
74: RB_FOREACH(wm, winlinks, &s->windows) {
75: w = wm->window;
76:
77: if (wm == s->curw)
78: cur = idx;
79: idx++;
80:
1.6 nicm 81: flag = ' ';
82: if (session_alert_has(s, wm, WINDOW_ACTIVITY))
83: flag = '#';
84: else if (session_alert_has(s, wm, WINDOW_BELL))
85: flag = '!';
86: else if (session_alert_has(s, wm, WINDOW_CONTENT))
87: flag = '+';
88: else if (wm == s->curw)
89: flag = '*';
90: else if (wm == SLIST_FIRST(&s->lastw))
91: flag = '-';
92:
93: title = w->active->screen->title;
94: if (wm == wl)
95: title = w->active->base.title;
96: left = " \"";
97: right = "\"";
98: if (*title == '\0')
99: left = right = "";
100:
1.1 nicm 101: window_choose_add(wl->window->active,
1.6 nicm 102: wm->idx, "%3d: %s%c [%ux%u] (%u panes)%s%s%s",
103: wm->idx, w->name, flag, w->sx, w->sy, window_count_panes(w),
104: left, title, right);
1.1 nicm 105: }
106:
107: cdata = xmalloc(sizeof *cdata);
108: if (session_index(s, &cdata->session) != 0)
109: fatalx("session not found");
1.7 ! nicm 110: if (data->arg != NULL)
! 111: cdata->template = xstrdup(data->arg);
! 112: else
! 113: cdata->template = xstrdup("select-window -t '%%'");
! 114: cdata->client = server_client_index(ctx->curclient);
1.1 nicm 115:
1.7 ! nicm 116: window_choose_ready(wl->window->active,
! 117: cur, cmd_choose_window_callback, cmd_choose_window_free, cdata);
1.1 nicm 118:
119: return (0);
120: }
121:
122: void
123: cmd_choose_window_callback(void *data, int idx)
124: {
125: struct cmd_choose_window_data *cdata = data;
1.7 ! nicm 126: struct client *c;
1.1 nicm 127: struct session *s;
1.7 ! nicm 128: struct cmd_list *cmdlist;
! 129: struct cmd_ctx ctx;
! 130: char *target, *template, *cause;
! 131:
! 132: if (idx == -1)
! 133: return;
! 134: if (cdata->client > ARRAY_LENGTH(&clients) - 1)
! 135: return;
! 136: c = ARRAY_ITEM(&clients, cdata->client);
! 137: if (cdata->session > ARRAY_LENGTH(&sessions) - 1)
! 138: return;
! 139: s = ARRAY_ITEM(&sessions, cdata->session);
! 140: if (c->session != s)
! 141: return;
! 142:
! 143: xasprintf(&target, "%s:%d", s->name, idx);
! 144: template = cmd_template_replace(cdata->template, target, 1);
! 145: xfree(target);
! 146:
! 147: if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
! 148: if (cause != NULL) {
! 149: *cause = toupper((u_char) *cause);
! 150: status_message_set(c, "%s", cause);
! 151: xfree(cause);
! 152: }
! 153: xfree(template);
! 154: return;
! 155: }
! 156: xfree(template);
! 157:
! 158: ctx.msgdata = NULL;
! 159: ctx.curclient = c;
! 160:
! 161: ctx.error = key_bindings_error;
! 162: ctx.print = key_bindings_print;
! 163: ctx.info = key_bindings_info;
! 164:
! 165: ctx.cmdclient = NULL;
! 166:
! 167: cmd_list_exec(cmdlist, &ctx);
! 168: cmd_list_free(cmdlist);
! 169: }
1.1 nicm 170:
1.7 ! nicm 171: void
! 172: cmd_choose_window_free(void *data)
! 173: {
! 174: struct cmd_choose_window_data *cdata = data;
! 175:
! 176: xfree(cdata->template);
! 177: xfree(cdata);
1.1 nicm 178: }