cmd-command-prompt.c revision 1.1 1 1.1 jmmv /* $Id: cmd-command-prompt.c,v 1.1 2011/03/10 09:15:36 jmmv Exp $ */
2 1.1 jmmv
3 1.1 jmmv /*
4 1.1 jmmv * Copyright (c) 2008 Nicholas Marriott <nicm (at) users.sourceforge.net>
5 1.1 jmmv *
6 1.1 jmmv * Permission to use, copy, modify, and distribute this software for any
7 1.1 jmmv * purpose with or without fee is hereby granted, provided that the above
8 1.1 jmmv * copyright notice and this permission notice appear in all copies.
9 1.1 jmmv *
10 1.1 jmmv * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 1.1 jmmv * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 1.1 jmmv * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 1.1 jmmv * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 1.1 jmmv * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 1.1 jmmv * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 1.1 jmmv * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 1.1 jmmv */
18 1.1 jmmv
19 1.1 jmmv #include <sys/types.h>
20 1.1 jmmv
21 1.1 jmmv #include <ctype.h>
22 1.1 jmmv #include <string.h>
23 1.1 jmmv
24 1.1 jmmv #include "tmux.h"
25 1.1 jmmv
26 1.1 jmmv /*
27 1.1 jmmv * Prompt for command in client.
28 1.1 jmmv */
29 1.1 jmmv
30 1.1 jmmv void cmd_command_prompt_init(struct cmd *, int);
31 1.1 jmmv int cmd_command_prompt_parse(struct cmd *, int, char **, char **);
32 1.1 jmmv int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
33 1.1 jmmv void cmd_command_prompt_free(struct cmd *);
34 1.1 jmmv size_t cmd_command_prompt_print(struct cmd *, char *, size_t);
35 1.1 jmmv
36 1.1 jmmv int cmd_command_prompt_callback(void *, const char *);
37 1.1 jmmv void cmd_command_prompt_cfree(void *);
38 1.1 jmmv
39 1.1 jmmv const struct cmd_entry cmd_command_prompt_entry = {
40 1.1 jmmv "command-prompt", NULL,
41 1.1 jmmv CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]",
42 1.1 jmmv 0, "",
43 1.1 jmmv cmd_command_prompt_init,
44 1.1 jmmv cmd_command_prompt_parse,
45 1.1 jmmv cmd_command_prompt_exec,
46 1.1 jmmv cmd_command_prompt_free,
47 1.1 jmmv cmd_command_prompt_print
48 1.1 jmmv };
49 1.1 jmmv
50 1.1 jmmv struct cmd_command_prompt_data {
51 1.1 jmmv char *prompts;
52 1.1 jmmv char *target;
53 1.1 jmmv char *template;
54 1.1 jmmv };
55 1.1 jmmv
56 1.1 jmmv struct cmd_command_prompt_cdata {
57 1.1 jmmv struct client *c;
58 1.1 jmmv char *next_prompt;
59 1.1 jmmv char *prompts;
60 1.1 jmmv char *template;
61 1.1 jmmv int idx;
62 1.1 jmmv };
63 1.1 jmmv
64 1.1 jmmv void
65 1.1 jmmv cmd_command_prompt_init(struct cmd *self, int key)
66 1.1 jmmv {
67 1.1 jmmv struct cmd_command_prompt_data *data;
68 1.1 jmmv
69 1.1 jmmv self->data = data = xmalloc(sizeof *data);
70 1.1 jmmv data->prompts = NULL;
71 1.1 jmmv data->target = NULL;
72 1.1 jmmv data->template = NULL;
73 1.1 jmmv
74 1.1 jmmv switch (key) {
75 1.1 jmmv case ',':
76 1.1 jmmv data->template = xstrdup("rename-window '%%'");
77 1.1 jmmv break;
78 1.1 jmmv case '.':
79 1.1 jmmv data->template = xstrdup("move-window -t '%%'");
80 1.1 jmmv break;
81 1.1 jmmv case 'f':
82 1.1 jmmv data->template = xstrdup("find-window '%%'");
83 1.1 jmmv break;
84 1.1 jmmv case '\'':
85 1.1 jmmv data->template = xstrdup("select-window -t ':%%'");
86 1.1 jmmv data->prompts = xstrdup("index");
87 1.1 jmmv break;
88 1.1 jmmv }
89 1.1 jmmv }
90 1.1 jmmv
91 1.1 jmmv int
92 1.1 jmmv cmd_command_prompt_parse(struct cmd *self, int argc, char **argv, char **cause)
93 1.1 jmmv {
94 1.1 jmmv struct cmd_command_prompt_data *data;
95 1.1 jmmv int opt;
96 1.1 jmmv
97 1.1 jmmv self->entry->init(self, KEYC_NONE);
98 1.1 jmmv data = self->data;
99 1.1 jmmv
100 1.1 jmmv while ((opt = getopt(argc, argv, "p:t:")) != -1) {
101 1.1 jmmv switch (opt) {
102 1.1 jmmv case 'p':
103 1.1 jmmv if (data->prompts == NULL)
104 1.1 jmmv data->prompts = xstrdup(optarg);
105 1.1 jmmv break;
106 1.1 jmmv case 't':
107 1.1 jmmv if (data->target == NULL)
108 1.1 jmmv data->target = xstrdup(optarg);
109 1.1 jmmv break;
110 1.1 jmmv default:
111 1.1 jmmv goto usage;
112 1.1 jmmv }
113 1.1 jmmv }
114 1.1 jmmv argc -= optind;
115 1.1 jmmv argv += optind;
116 1.1 jmmv if (argc != 0 && argc != 1)
117 1.1 jmmv goto usage;
118 1.1 jmmv
119 1.1 jmmv if (argc == 1)
120 1.1 jmmv data->template = xstrdup(argv[0]);
121 1.1 jmmv
122 1.1 jmmv return (0);
123 1.1 jmmv
124 1.1 jmmv usage:
125 1.1 jmmv xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
126 1.1 jmmv
127 1.1 jmmv self->entry->free(self);
128 1.1 jmmv return (-1);
129 1.1 jmmv }
130 1.1 jmmv
131 1.1 jmmv int
132 1.1 jmmv cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
133 1.1 jmmv {
134 1.1 jmmv struct cmd_command_prompt_data *data = self->data;
135 1.1 jmmv struct cmd_command_prompt_cdata *cdata;
136 1.1 jmmv struct client *c;
137 1.1 jmmv char *prompt, *ptr;
138 1.1 jmmv size_t n;
139 1.1 jmmv
140 1.1 jmmv if ((c = cmd_find_client(ctx, data->target)) == NULL)
141 1.1 jmmv return (-1);
142 1.1 jmmv
143 1.1 jmmv if (c->prompt_string != NULL)
144 1.1 jmmv return (0);
145 1.1 jmmv
146 1.1 jmmv cdata = xmalloc(sizeof *cdata);
147 1.1 jmmv cdata->c = c;
148 1.1 jmmv cdata->idx = 1;
149 1.1 jmmv cdata->next_prompt = NULL;
150 1.1 jmmv cdata->prompts = NULL;
151 1.1 jmmv cdata->template = NULL;
152 1.1 jmmv
153 1.1 jmmv if (data->template != NULL)
154 1.1 jmmv cdata->template = xstrdup(data->template);
155 1.1 jmmv else
156 1.1 jmmv cdata->template = xstrdup("%1");
157 1.1 jmmv if (data->prompts != NULL)
158 1.1 jmmv cdata->prompts = xstrdup(data->prompts);
159 1.1 jmmv else if (data->template != NULL) {
160 1.1 jmmv n = strcspn(data->template, " ,");
161 1.1 jmmv xasprintf(&cdata->prompts, "(%.*s) ", (int) n, data->template);
162 1.1 jmmv } else
163 1.1 jmmv cdata->prompts = xstrdup(":");
164 1.1 jmmv
165 1.1 jmmv cdata->next_prompt = cdata->prompts;
166 1.1 jmmv ptr = strsep(&cdata->next_prompt, ",");
167 1.1 jmmv if (data->prompts == NULL)
168 1.1 jmmv prompt = xstrdup(ptr);
169 1.1 jmmv else
170 1.1 jmmv xasprintf(&prompt, "%s ", ptr);
171 1.1 jmmv status_prompt_set(c, prompt, cmd_command_prompt_callback,
172 1.1 jmmv cmd_command_prompt_cfree, cdata, 0);
173 1.1 jmmv xfree(prompt);
174 1.1 jmmv
175 1.1 jmmv return (0);
176 1.1 jmmv }
177 1.1 jmmv
178 1.1 jmmv void
179 1.1 jmmv cmd_command_prompt_free(struct cmd *self)
180 1.1 jmmv {
181 1.1 jmmv struct cmd_command_prompt_data *data = self->data;
182 1.1 jmmv
183 1.1 jmmv if (data->prompts != NULL)
184 1.1 jmmv xfree(data->prompts);
185 1.1 jmmv if (data->target != NULL)
186 1.1 jmmv xfree(data->target);
187 1.1 jmmv if (data->template != NULL)
188 1.1 jmmv xfree(data->template);
189 1.1 jmmv xfree(data);
190 1.1 jmmv }
191 1.1 jmmv
192 1.1 jmmv size_t
193 1.1 jmmv cmd_command_prompt_print(struct cmd *self, char *buf, size_t len)
194 1.1 jmmv {
195 1.1 jmmv struct cmd_command_prompt_data *data = self->data;
196 1.1 jmmv size_t off = 0;
197 1.1 jmmv
198 1.1 jmmv off += xsnprintf(buf, len, "%s", self->entry->name);
199 1.1 jmmv if (data == NULL)
200 1.1 jmmv return (off);
201 1.1 jmmv if (off < len && data->prompts != NULL)
202 1.1 jmmv off += cmd_prarg(buf + off, len - off, " -p ", data->prompts);
203 1.1 jmmv if (off < len && data->target != NULL)
204 1.1 jmmv off += cmd_prarg(buf + off, len - off, " -t ", data->target);
205 1.1 jmmv if (off < len && data->template != NULL)
206 1.1 jmmv off += cmd_prarg(buf + off, len - off, " ", data->template);
207 1.1 jmmv return (off);
208 1.1 jmmv }
209 1.1 jmmv
210 1.1 jmmv int
211 1.1 jmmv cmd_command_prompt_callback(void *data, const char *s)
212 1.1 jmmv {
213 1.1 jmmv struct cmd_command_prompt_cdata *cdata = data;
214 1.1 jmmv struct client *c = cdata->c;
215 1.1 jmmv struct cmd_list *cmdlist;
216 1.1 jmmv struct cmd_ctx ctx;
217 1.1 jmmv char *cause, *newtempl, *prompt, *ptr;
218 1.1 jmmv
219 1.1 jmmv if (s == NULL)
220 1.1 jmmv return (0);
221 1.1 jmmv
222 1.1 jmmv newtempl = cmd_template_replace(cdata->template, s, cdata->idx);
223 1.1 jmmv xfree(cdata->template);
224 1.1 jmmv cdata->template = newtempl;
225 1.1 jmmv
226 1.1 jmmv if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
227 1.1 jmmv xasprintf(&prompt, "%s ", ptr);
228 1.1 jmmv status_prompt_update(c, prompt);
229 1.1 jmmv xfree(prompt);
230 1.1 jmmv cdata->idx++;
231 1.1 jmmv return (1);
232 1.1 jmmv }
233 1.1 jmmv
234 1.1 jmmv if (cmd_string_parse(newtempl, &cmdlist, &cause) != 0) {
235 1.1 jmmv if (cause != NULL) {
236 1.1 jmmv *cause = toupper((u_char) *cause);
237 1.1 jmmv status_message_set(c, "%s", cause);
238 1.1 jmmv xfree(cause);
239 1.1 jmmv }
240 1.1 jmmv return (0);
241 1.1 jmmv }
242 1.1 jmmv
243 1.1 jmmv ctx.msgdata = NULL;
244 1.1 jmmv ctx.curclient = c;
245 1.1 jmmv
246 1.1 jmmv ctx.error = key_bindings_error;
247 1.1 jmmv ctx.print = key_bindings_print;
248 1.1 jmmv ctx.info = key_bindings_info;
249 1.1 jmmv
250 1.1 jmmv ctx.cmdclient = NULL;
251 1.1 jmmv
252 1.1 jmmv cmd_list_exec(cmdlist, &ctx);
253 1.1 jmmv cmd_list_free(cmdlist);
254 1.1 jmmv
255 1.1 jmmv if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
256 1.1 jmmv return (1);
257 1.1 jmmv return (0);
258 1.1 jmmv }
259 1.1 jmmv
260 1.1 jmmv void
261 1.1 jmmv cmd_command_prompt_cfree(void *data)
262 1.1 jmmv {
263 1.1 jmmv struct cmd_command_prompt_cdata *cdata = data;
264 1.1 jmmv
265 1.1 jmmv if (cdata->prompts != NULL)
266 1.1 jmmv xfree(cdata->prompts);
267 1.1 jmmv if (cdata->template != NULL)
268 1.1 jmmv xfree(cdata->template);
269 1.1 jmmv xfree(cdata);
270 1.1 jmmv }
271