Annotation of src/usr.bin/tmux/cmd-command-prompt.c, Revision 1.2
1.2 ! nicm 1: /* $OpenBSD: cmd-command-prompt.c,v 1.1 2009/06/01 22:58:49 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2008 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 <ctype.h>
22: #include <string.h>
23:
24: #include "tmux.h"
25:
26: /*
27: * Prompt for command in client.
28: */
29:
30: void cmd_command_prompt_init(struct cmd *, int);
31: int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
32:
33: int cmd_command_prompt_callback(void *, const char *);
34:
35: const struct cmd_entry cmd_command_prompt_entry = {
36: "command-prompt", NULL,
37: CMD_TARGET_CLIENT_USAGE " [template]",
1.2 ! nicm 38: CMD_ARG01, 0,
1.1 nicm 39: cmd_command_prompt_init,
40: cmd_target_parse,
41: cmd_command_prompt_exec,
42: cmd_target_send,
43: cmd_target_recv,
44: cmd_target_free,
45: cmd_target_print
46: };
47:
48: struct cmd_command_prompt_data {
49: struct client *c;
50: char *template;
51: };
52:
53: void
54: cmd_command_prompt_init(struct cmd *self, int key)
55: {
56: struct cmd_target_data *data;
57:
58: cmd_target_init(self, key);
59: data = self->data;
60:
61: switch (key) {
62: case ',':
63: data->arg = xstrdup("rename-window '%%'");
64: break;
65: case '.':
66: data->arg = xstrdup("move-window -t '%%'");
67: break;
68: case 'f':
69: data->arg = xstrdup("find-window '%%'");
70: break;
71: }
72: }
73:
74: int
75: cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
76: {
77: struct cmd_target_data *data = self->data;
78: struct cmd_command_prompt_data *cdata;
79: struct client *c;
80: char *hdr, *ptr;
81:
82: if ((c = cmd_find_client(ctx, data->target)) == NULL)
83: return (-1);
84:
85: if (c->prompt_string != NULL)
86: return (0);
87:
88: cdata = xmalloc(sizeof *cdata);
89: cdata->c = c;
90: if (data->arg != NULL) {
91: cdata->template = xstrdup(data->arg);
92: if ((ptr = strchr(data->arg, ' ')) == NULL)
93: ptr = strchr(data->arg, '\0');
94: xasprintf(&hdr, "(%.*s) ", (int) (ptr - data->arg), data->arg);
95: } else {
96: cdata->template = NULL;
97: hdr = xstrdup(":");
98: }
99: status_prompt_set(c, hdr, cmd_command_prompt_callback, cdata, 0);
100: xfree(hdr);
101:
102: return (0);
103: }
104:
105: int
106: cmd_command_prompt_callback(void *data, const char *s)
107: {
108: struct cmd_command_prompt_data *cdata = data;
109: struct client *c = cdata->c;
110: struct cmd_list *cmdlist;
111: struct cmd_ctx ctx;
112: char *cause, *ptr, *buf, ch;
113: size_t len, slen;
114:
115: if (s == NULL) {
116: xfree(cdata);
117: return (0);
118: }
119: slen = strlen(s);
120:
121: len = 0;
122: buf = NULL;
123: if (cdata->template != NULL) {
124: ptr = cdata->template;
125: while (*ptr != '\0') {
126: switch (ch = *ptr++) {
127: case '%':
128: if (*ptr != '%')
129: break;
130: ptr++;
131:
132: buf = xrealloc(buf, 1, len + slen + 1);
133: memcpy(buf + len, s, slen);
134: len += slen;
135: break;
136: default:
137: buf = xrealloc(buf, 1, len + 2);
138: buf[len++] = ch;
139: break;
140: }
141: }
142: xfree(cdata->template);
143:
144: buf[len] = '\0';
145: s = buf;
146: }
147: xfree(cdata);
148:
149: if (cmd_string_parse(s, &cmdlist, &cause) != 0) {
150: if (cause == NULL)
151: return (0);
152: *cause = toupper((u_char) *cause);
153: status_message_set(c, cause);
154: xfree(cause);
155: cmdlist = NULL;
156: }
157: if (buf != NULL)
158: xfree(buf);
159: if (cmdlist == NULL)
160: return (0);
161:
162: ctx.msgdata = NULL;
163: ctx.cursession = c->session;
164: ctx.curclient = c;
165:
166: ctx.error = key_bindings_error;
167: ctx.print = key_bindings_print;
168: ctx.info = key_bindings_info;
169:
170: ctx.cmdclient = NULL;
171:
172: cmd_list_exec(cmdlist, &ctx);
173: cmd_list_free(cmdlist);
174:
175: if (c->prompt_callback != (void *) &cmd_command_prompt_callback)
176: return (1);
177: return (0);
178: }