Annotation of src/usr.bin/tmux/cmd-command-prompt.c, Revision 1.18
1.18 ! nicm 1: /* $OpenBSD: cmd-command-prompt.c,v 1.17 2011/07/02 21:05:44 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>
1.17 nicm 23: #include <time.h>
1.1 nicm 24:
25: #include "tmux.h"
26:
27: /*
28: * Prompt for command in client.
29: */
30:
1.14 nicm 31: void cmd_command_prompt_key_binding(struct cmd *, int);
32: int cmd_command_prompt_check(struct args *);
33: int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
1.8 nicm 34:
1.14 nicm 35: int cmd_command_prompt_callback(void *, const char *);
36: void cmd_command_prompt_free(void *);
1.1 nicm 37:
38: const struct cmd_entry cmd_command_prompt_entry = {
39: "command-prompt", NULL,
1.17 nicm 40: "I:p:t:", 0, 1,
41: "[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
1.14 nicm 42: 0,
43: cmd_command_prompt_key_binding,
44: NULL,
45: cmd_command_prompt_exec
1.8 nicm 46: };
47:
48: struct cmd_command_prompt_cdata {
1.1 nicm 49: struct client *c;
1.17 nicm 50: char *inputs;
51: char *next_input;
1.8 nicm 52: char *next_prompt;
53: char *prompts;
1.1 nicm 54: char *template;
1.8 nicm 55: int idx;
1.1 nicm 56: };
57:
58: void
1.14 nicm 59: cmd_command_prompt_key_binding(struct cmd *self, int key)
1.1 nicm 60: {
61: switch (key) {
1.18 ! nicm 62: case '$':
! 63: self->args = args_create(1, "rename-session '%%'");
! 64: args_set(self->args, 'I', "#S");
! 65: break;
1.1 nicm 66: case ',':
1.14 nicm 67: self->args = args_create(1, "rename-window '%%'");
1.18 ! nicm 68: args_set(self->args, 'I', "#W");
1.1 nicm 69: break;
70: case '.':
1.14 nicm 71: self->args = args_create(1, "move-window -t '%%'");
1.1 nicm 72: break;
73: case 'f':
1.14 nicm 74: self->args = args_create(1, "find-window '%%'");
1.13 nicm 75: break;
76: case '\'':
1.14 nicm 77: self->args = args_create(1, "select-window -t ':%%'");
78: args_set(self->args, 'p', "index");
79: break;
80: default:
81: self->args = args_create(0);
1.1 nicm 82: break;
83: }
84: }
85:
86: int
87: cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
88: {
1.14 nicm 89: struct args *args = self->args;
1.17 nicm 90: const char *inputs, *prompts;
1.8 nicm 91: struct cmd_command_prompt_cdata *cdata;
1.1 nicm 92: struct client *c;
1.17 nicm 93: char *input = NULL;
1.16 nicm 94: char *prompt, *prompt_replaced, *ptr;
1.8 nicm 95: size_t n;
1.1 nicm 96:
1.14 nicm 97: if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
1.1 nicm 98: return (-1);
99:
100: if (c->prompt_string != NULL)
101: return (0);
102:
103: cdata = xmalloc(sizeof *cdata);
104: cdata->c = c;
1.8 nicm 105: cdata->idx = 1;
1.17 nicm 106: cdata->inputs = NULL;
107: cdata->next_input = NULL;
1.8 nicm 108: cdata->next_prompt = NULL;
109: cdata->prompts = NULL;
110: cdata->template = NULL;
111:
1.14 nicm 112: if (args->argc != 0)
113: cdata->template = xstrdup(args->argv[0]);
1.8 nicm 114: else
115: cdata->template = xstrdup("%1");
1.14 nicm 116:
1.17 nicm 117: if ((prompts = args_get(args, 'p')) != NULL)
1.14 nicm 118: cdata->prompts = xstrdup(prompts);
119: else if (args->argc != 0) {
120: n = strcspn(cdata->template, " ,");
121: xasprintf(&cdata->prompts, "(%.*s) ", (int) n, cdata->template);
1.8 nicm 122: } else
123: cdata->prompts = xstrdup(":");
124:
1.17 nicm 125: /* Get first prompt. */
1.8 nicm 126: cdata->next_prompt = cdata->prompts;
127: ptr = strsep(&cdata->next_prompt, ",");
1.14 nicm 128: if (prompts == NULL)
1.8 nicm 129: prompt = xstrdup(ptr);
1.16 nicm 130: else {
131: prompt_replaced = status_replace(c, NULL, NULL, NULL, ptr,
132: time(NULL), 0);
133: xasprintf(&prompt, "%s ", prompt_replaced);
134: xfree(prompt_replaced);
135: }
1.17 nicm 136:
137: /* Get initial prompt input. */
138: if ((inputs = args_get(args, 'I')) != NULL) {
139: cdata->inputs = xstrdup(inputs);
140: cdata->next_input = cdata->inputs;
141: ptr = strsep(&cdata->next_input, ",");
142:
143: input = status_replace(c, NULL, NULL, NULL, ptr, time(NULL),
144: 0);
145: }
146:
147: status_prompt_set(c, prompt, input, cmd_command_prompt_callback,
1.14 nicm 148: cmd_command_prompt_free, cdata, 0);
1.17 nicm 149:
150: if (input != NULL)
151: xfree(input);
1.8 nicm 152: xfree(prompt);
1.1 nicm 153:
154: return (0);
155: }
156:
157: int
158: cmd_command_prompt_callback(void *data, const char *s)
159: {
1.8 nicm 160: struct cmd_command_prompt_cdata *cdata = data;
1.1 nicm 161: struct client *c = cdata->c;
162: struct cmd_list *cmdlist;
1.8 nicm 163: struct cmd_ctx ctx;
1.17 nicm 164: char *cause, *new_template, *prompt;
165: char *prompt_replaced, *ptr, *input = NULL;
1.1 nicm 166:
1.8 nicm 167: if (s == NULL)
1.1 nicm 168: return (0);
169:
1.17 nicm 170: new_template = cmd_template_replace(cdata->template, s, cdata->idx);
1.8 nicm 171: xfree(cdata->template);
1.17 nicm 172: cdata->template = new_template;
1.8 nicm 173:
1.17 nicm 174: /*
175: * Check if there are more prompts; if so, get its respective input
176: * and update the prompt data.
177: */
1.8 nicm 178: if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
1.16 nicm 179: prompt_replaced = status_replace(c, NULL, NULL, NULL, ptr,
180: time(NULL), 0);
181: xasprintf(&prompt, "%s ", prompt_replaced);
182:
1.17 nicm 183: /* Find next input and expand special sequences. */
184: if ((ptr = strsep(&cdata->next_input, ",")) != NULL) {
185: input = status_replace(c, NULL, NULL, NULL, ptr,
186: time(NULL), 0);
187: }
188:
189: status_prompt_update(c, prompt, input);
190:
191: if (input != NULL)
192: xfree(input);
1.16 nicm 193: xfree(prompt_replaced);
1.8 nicm 194: xfree(prompt);
1.17 nicm 195:
1.8 nicm 196: cdata->idx++;
197: return (1);
198: }
1.1 nicm 199:
1.17 nicm 200: if (cmd_string_parse(new_template, &cmdlist, &cause) != 0) {
1.8 nicm 201: if (cause != NULL) {
202: *cause = toupper((u_char) *cause);
203: status_message_set(c, "%s", cause);
204: xfree(cause);
1.1 nicm 205: }
1.8 nicm 206: return (0);
1.1 nicm 207: }
208:
209: ctx.msgdata = NULL;
210: ctx.curclient = c;
211:
212: ctx.error = key_bindings_error;
213: ctx.print = key_bindings_print;
214: ctx.info = key_bindings_info;
215:
216: ctx.cmdclient = NULL;
217:
218: cmd_list_exec(cmdlist, &ctx);
219: cmd_list_free(cmdlist);
220:
1.4 nicm 221: if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
1.1 nicm 222: return (1);
223: return (0);
1.4 nicm 224: }
225:
226: void
1.14 nicm 227: cmd_command_prompt_free(void *data)
1.4 nicm 228: {
1.8 nicm 229: struct cmd_command_prompt_cdata *cdata = data;
1.4 nicm 230:
1.17 nicm 231: if (cdata->inputs != NULL)
232: xfree(cdata->inputs);
1.8 nicm 233: if (cdata->prompts != NULL)
234: xfree(cdata->prompts);
1.4 nicm 235: if (cdata->template != NULL)
236: xfree(cdata->template);
237: xfree(cdata);
1.1 nicm 238: }