Annotation of src/usr.bin/tmux/cmd-choose-client.c, Revision 1.7
1.7 ! nicm 1: /* $OpenBSD: cmd-choose-client.c,v 1.6 2011/08/16 10:00:52 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.2 nicm 20:
21: #include <ctype.h>
1.1 nicm 22:
23: #include "tmux.h"
24:
25: /*
26: * Enter choice mode to choose a client.
27: */
28:
29: int cmd_choose_client_exec(struct cmd *, struct cmd_ctx *);
30:
31: void cmd_choose_client_callback(void *, int);
32: void cmd_choose_client_free(void *);
33:
34: const struct cmd_entry cmd_choose_client_entry = {
35: "choose-client", NULL,
1.7 ! nicm 36: "F:t:", 0, 1,
! 37: CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
1.5 nicm 38: 0,
39: NULL,
40: NULL,
41: cmd_choose_client_exec
1.1 nicm 42: };
43:
44: struct cmd_choose_client_data {
1.3 nicm 45: struct client *client;
1.1 nicm 46: char *template;
47: };
48:
49: int
50: cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
51: {
1.5 nicm 52: struct args *args = self->args;
1.1 nicm 53: struct cmd_choose_client_data *cdata;
1.7 ! nicm 54: struct format_tree *ft;
1.1 nicm 55: struct winlink *wl;
56: struct client *c;
1.7 ! nicm 57: char *line;
! 58: const char *template;
1.1 nicm 59: u_int i, idx, cur;
60:
61: if (ctx->curclient == NULL) {
62: ctx->error(ctx, "must be run interactively");
63: return (-1);
64: }
65:
1.5 nicm 66: if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
1.1 nicm 67: return (-1);
68:
69: if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
70: return (0);
71:
1.7 ! nicm 72: if ((template = args_get(args, 'F')) == NULL)
! 73: template = DEFAULT_CLIENT_TEMPLATE;
! 74:
1.1 nicm 75: cur = idx = 0;
76: for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
77: c = ARRAY_ITEM(&clients, i);
78: if (c == NULL || c->session == NULL)
79: continue;
80: if (c == ctx->curclient)
81: cur = idx;
82: idx++;
83:
1.7 ! nicm 84: ft = format_create();
! 85: format_add(ft, "line", "%u", i);
! 86: format_session(ft, c->session);
! 87: format_client(ft, c);
! 88:
! 89: line = format_expand(ft, template);
! 90: window_choose_add(wl->window->active, i, "%s", line);
! 91: xfree(line);
! 92:
! 93: format_free(ft);
1.1 nicm 94: }
95:
96: cdata = xmalloc(sizeof *cdata);
1.5 nicm 97: if (args->argc != 0)
98: cdata->template = xstrdup(args->argv[0]);
1.1 nicm 99: else
100: cdata->template = xstrdup("detach-client -t '%%'");
1.3 nicm 101: cdata->client = ctx->curclient;
102: cdata->client->references++;
1.1 nicm 103:
104: window_choose_ready(wl->window->active,
105: cur, cmd_choose_client_callback, cmd_choose_client_free, cdata);
106:
107: return (0);
108: }
109:
110: void
111: cmd_choose_client_callback(void *data, int idx)
112: {
113: struct cmd_choose_client_data *cdata = data;
1.3 nicm 114: struct client *c;
1.1 nicm 115: struct cmd_list *cmdlist;
116: struct cmd_ctx ctx;
117: char *template, *cause;
118:
119: if (idx == -1)
120: return;
1.3 nicm 121: if (cdata->client->flags & CLIENT_DEAD)
1.1 nicm 122: return;
123:
124: if ((u_int) idx > ARRAY_LENGTH(&clients) - 1)
125: return;
1.3 nicm 126: c = ARRAY_ITEM(&clients, idx);
127: if (c == NULL || c->session == NULL)
1.1 nicm 128: return;
1.3 nicm 129: template = cmd_template_replace(cdata->template, c->tty.path, 1);
1.1 nicm 130:
131: if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
132: if (cause != NULL) {
133: *cause = toupper((u_char) *cause);
134: status_message_set(c, "%s", cause);
135: xfree(cause);
136: }
137: xfree(template);
138: return;
139: }
140: xfree(template);
141:
142: ctx.msgdata = NULL;
1.3 nicm 143: ctx.curclient = cdata->client;
1.1 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: }
154:
155: void
156: cmd_choose_client_free(void *data)
157: {
158: struct cmd_choose_client_data *cdata = data;
159:
1.3 nicm 160: cdata->client->references--;
1.1 nicm 161: xfree(cdata->template);
162: xfree(cdata);
163: }