Annotation of src/usr.bin/tmux/cmd-command-prompt.c, Revision 1.11
1.11 ! nicm 1: /* $OpenBSD: cmd-command-prompt.c,v 1.10 2009/08/25 12:18:51 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:
1.8 nicm 30: void cmd_command_prompt_init(struct cmd *, int);
31: int cmd_command_prompt_parse(struct cmd *, int, char **, char **);
32: int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
33: void cmd_command_prompt_free(struct cmd *);
34: size_t cmd_command_prompt_print(struct cmd *, char *, size_t);
35:
36: int cmd_command_prompt_callback(void *, const char *);
37: void cmd_command_prompt_cfree(void *);
1.1 nicm 38:
39: const struct cmd_entry cmd_command_prompt_entry = {
40: "command-prompt", NULL,
1.8 nicm 41: CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]",
42: 0, 0,
1.1 nicm 43: cmd_command_prompt_init,
1.8 nicm 44: cmd_command_prompt_parse,
1.1 nicm 45: cmd_command_prompt_exec,
1.8 nicm 46: cmd_command_prompt_free,
47: cmd_command_prompt_print
1.1 nicm 48: };
49:
50: struct cmd_command_prompt_data {
1.8 nicm 51: char *prompts;
52: char *target;
53: char *template;
54: };
55:
56: struct cmd_command_prompt_cdata {
1.1 nicm 57: struct client *c;
1.8 nicm 58: char *next_prompt;
59: char *prompts;
1.1 nicm 60: char *template;
1.8 nicm 61: int idx;
1.1 nicm 62: };
63:
64: void
65: cmd_command_prompt_init(struct cmd *self, int key)
66: {
1.8 nicm 67: struct cmd_command_prompt_data *data;
1.1 nicm 68:
1.8 nicm 69: self->data = data = xmalloc(sizeof *data);
70: data->prompts = NULL;
71: data->target = NULL;
72: data->template = NULL;
1.1 nicm 73:
74: switch (key) {
75: case ',':
1.8 nicm 76: data->template = xstrdup("rename-window '%%'");
1.1 nicm 77: break;
78: case '.':
1.8 nicm 79: data->template = xstrdup("move-window -t '%%'");
1.1 nicm 80: break;
81: case 'f':
1.8 nicm 82: data->template = xstrdup("find-window '%%'");
1.1 nicm 83: break;
84: }
85: }
86:
87: int
1.8 nicm 88: cmd_command_prompt_parse(struct cmd *self, int argc, char **argv, char **cause)
89: {
90: struct cmd_command_prompt_data *data;
91: int opt;
92:
1.11 ! nicm 93: self->entry->init(self, KEYC_NONE);
1.8 nicm 94: data = self->data;
95:
96: while ((opt = getopt(argc, argv, "p:t:")) != -1) {
97: switch (opt) {
98: case 'p':
99: if (data->prompts == NULL)
100: data->prompts = xstrdup(optarg);
101: break;
102: case 't':
103: if (data->target == NULL)
104: data->target = xstrdup(optarg);
105: break;
106: default:
107: goto usage;
108: }
109: }
110: argc -= optind;
111: argv += optind;
112: if (argc != 0 && argc != 1)
113: goto usage;
114:
115: if (argc == 1)
116: data->template = xstrdup(argv[0]);
117:
118: return (0);
119:
120: usage:
121: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
122:
123: self->entry->free(self);
124: return (-1);
125: }
126:
127: int
1.1 nicm 128: cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
129: {
1.8 nicm 130: struct cmd_command_prompt_data *data = self->data;
131: struct cmd_command_prompt_cdata *cdata;
1.1 nicm 132: struct client *c;
1.8 nicm 133: char *prompt, *ptr;
134: size_t n;
1.1 nicm 135:
136: if ((c = cmd_find_client(ctx, data->target)) == NULL)
137: return (-1);
138:
139: if (c->prompt_string != NULL)
140: return (0);
141:
142: cdata = xmalloc(sizeof *cdata);
143: cdata->c = c;
1.8 nicm 144: cdata->idx = 1;
145: cdata->next_prompt = NULL;
146: cdata->prompts = NULL;
147: cdata->template = NULL;
148:
149: if (data->template != NULL)
150: cdata->template = xstrdup(data->template);
151: else
152: cdata->template = xstrdup("%1");
153: if (data->prompts != NULL)
154: cdata->prompts = xstrdup(data->prompts);
155: else if (data->template != NULL) {
156: n = strcspn(data->template, " ,");
157: xasprintf(&cdata->prompts, "(%.*s) ", (int) n, data->template);
158: } else
159: cdata->prompts = xstrdup(":");
160:
161: cdata->next_prompt = cdata->prompts;
162: ptr = strsep(&cdata->next_prompt, ",");
163: if (data->prompts == NULL)
164: prompt = xstrdup(ptr);
165: else
166: xasprintf(&prompt, "%s ", ptr);
167: status_prompt_set(c, prompt, cmd_command_prompt_callback,
168: cmd_command_prompt_cfree, cdata, 0);
169: xfree(prompt);
1.1 nicm 170:
171: return (0);
172: }
173:
1.8 nicm 174: void
175: cmd_command_prompt_free(struct cmd *self)
176: {
177: struct cmd_command_prompt_data *data = self->data;
178:
179: if (data->prompts != NULL)
180: xfree(data->prompts);
181: if (data->target != NULL)
182: xfree(data->target);
183: if (data->template != NULL)
184: xfree(data->template);
185: xfree(data);
186: }
187:
188: size_t
189: cmd_command_prompt_print(struct cmd *self, char *buf, size_t len)
190: {
191: struct cmd_command_prompt_data *data = self->data;
192: size_t off = 0;
193:
194: off += xsnprintf(buf, len, "%s", self->entry->name);
195: if (data == NULL)
196: return (off);
197: if (off < len && data->prompts != NULL)
198: off += cmd_prarg(buf + off, len - off, " -p ", data->prompts);
199: if (off < len && data->target != NULL)
200: off += cmd_prarg(buf + off, len - off, " -t ", data->target);
201: if (off < len && data->template != NULL)
202: off += cmd_prarg(buf + off, len - off, " ", data->template);
203: return (off);
204: }
205:
1.1 nicm 206: int
207: cmd_command_prompt_callback(void *data, const char *s)
208: {
1.8 nicm 209: struct cmd_command_prompt_cdata *cdata = data;
1.1 nicm 210: struct client *c = cdata->c;
211: struct cmd_list *cmdlist;
1.8 nicm 212: struct cmd_ctx ctx;
213: char *cause, *newtempl, *prompt, *ptr;
1.1 nicm 214:
1.8 nicm 215: if (s == NULL)
1.1 nicm 216: return (0);
217:
1.10 nicm 218: newtempl = cmd_template_replace(cdata->template, s, cdata->idx);
1.8 nicm 219: xfree(cdata->template);
220: cdata->template = newtempl;
221:
222: if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
223: xasprintf(&prompt, "%s ", ptr);
224: status_prompt_update(c, prompt);
225: xfree(prompt);
226: cdata->idx++;
227: return (1);
228: }
1.1 nicm 229:
1.8 nicm 230: if (cmd_string_parse(newtempl, &cmdlist, &cause) != 0) {
231: if (cause != NULL) {
232: *cause = toupper((u_char) *cause);
233: status_message_set(c, "%s", cause);
234: xfree(cause);
1.1 nicm 235: }
1.8 nicm 236: return (0);
1.1 nicm 237: }
238:
239: ctx.msgdata = NULL;
240: ctx.curclient = c;
241:
242: ctx.error = key_bindings_error;
243: ctx.print = key_bindings_print;
244: ctx.info = key_bindings_info;
245:
246: ctx.cmdclient = NULL;
247:
248: cmd_list_exec(cmdlist, &ctx);
249: cmd_list_free(cmdlist);
250:
1.4 nicm 251: if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
1.1 nicm 252: return (1);
253: return (0);
1.4 nicm 254: }
255:
256: void
1.8 nicm 257: cmd_command_prompt_cfree(void *data)
1.4 nicm 258: {
1.8 nicm 259: struct cmd_command_prompt_cdata *cdata = data;
1.4 nicm 260:
1.8 nicm 261: if (cdata->prompts != NULL)
262: xfree(cdata->prompts);
1.4 nicm 263: if (cdata->template != NULL)
264: xfree(cdata->template);
265: xfree(cdata);
1.1 nicm 266: }