1*0a6a1f1dSLionel Sambuc /* Id */
2eda6f593SDavid van Moolenbroek
3eda6f593SDavid van Moolenbroek /*
4eda6f593SDavid van Moolenbroek * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
5eda6f593SDavid van Moolenbroek *
6eda6f593SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
7eda6f593SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
8eda6f593SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
9eda6f593SDavid van Moolenbroek *
10eda6f593SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11eda6f593SDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12eda6f593SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13eda6f593SDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14eda6f593SDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15eda6f593SDavid van Moolenbroek * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16eda6f593SDavid van Moolenbroek * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17eda6f593SDavid van Moolenbroek */
18eda6f593SDavid van Moolenbroek
19eda6f593SDavid van Moolenbroek #include <ctype.h>
20*0a6a1f1dSLionel Sambuc #include <stdlib.h>
21eda6f593SDavid van Moolenbroek #include <string.h>
22eda6f593SDavid van Moolenbroek
23eda6f593SDavid van Moolenbroek #include "tmux.h"
24eda6f593SDavid van Moolenbroek
25eda6f593SDavid van Moolenbroek /*
26eda6f593SDavid van Moolenbroek * Asks for confirmation before executing a command.
27eda6f593SDavid van Moolenbroek */
28eda6f593SDavid van Moolenbroek
29eda6f593SDavid van Moolenbroek void cmd_confirm_before_key_binding(struct cmd *, int);
30*0a6a1f1dSLionel Sambuc enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmd_q *);
31eda6f593SDavid van Moolenbroek
32eda6f593SDavid van Moolenbroek int cmd_confirm_before_callback(void *, const char *);
33eda6f593SDavid van Moolenbroek void cmd_confirm_before_free(void *);
34eda6f593SDavid van Moolenbroek
35eda6f593SDavid van Moolenbroek const struct cmd_entry cmd_confirm_before_entry = {
36eda6f593SDavid van Moolenbroek "confirm-before", "confirm",
37eda6f593SDavid van Moolenbroek "p:t:", 1, 1,
38eda6f593SDavid van Moolenbroek "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
39eda6f593SDavid van Moolenbroek 0,
40eda6f593SDavid van Moolenbroek cmd_confirm_before_key_binding,
41eda6f593SDavid van Moolenbroek cmd_confirm_before_exec
42eda6f593SDavid van Moolenbroek };
43eda6f593SDavid van Moolenbroek
44eda6f593SDavid van Moolenbroek struct cmd_confirm_before_data {
45eda6f593SDavid van Moolenbroek char *cmd;
46*0a6a1f1dSLionel Sambuc struct client *client;
47eda6f593SDavid van Moolenbroek };
48eda6f593SDavid van Moolenbroek
49eda6f593SDavid van Moolenbroek void
cmd_confirm_before_key_binding(struct cmd * self,int key)50eda6f593SDavid van Moolenbroek cmd_confirm_before_key_binding(struct cmd *self, int key)
51eda6f593SDavid van Moolenbroek {
52eda6f593SDavid van Moolenbroek switch (key) {
53eda6f593SDavid van Moolenbroek case '&':
54eda6f593SDavid van Moolenbroek self->args = args_create(1, "kill-window");
55eda6f593SDavid van Moolenbroek args_set(self->args, 'p', "kill-window #W? (y/n)");
56eda6f593SDavid van Moolenbroek break;
57eda6f593SDavid van Moolenbroek case 'x':
58eda6f593SDavid van Moolenbroek self->args = args_create(1, "kill-pane");
59eda6f593SDavid van Moolenbroek args_set(self->args, 'p', "kill-pane #P? (y/n)");
60eda6f593SDavid van Moolenbroek break;
61eda6f593SDavid van Moolenbroek default:
62eda6f593SDavid van Moolenbroek self->args = args_create(0);
63eda6f593SDavid van Moolenbroek break;
64eda6f593SDavid van Moolenbroek }
65eda6f593SDavid van Moolenbroek }
66eda6f593SDavid van Moolenbroek
67*0a6a1f1dSLionel Sambuc enum cmd_retval
cmd_confirm_before_exec(struct cmd * self,struct cmd_q * cmdq)68*0a6a1f1dSLionel Sambuc cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq)
69eda6f593SDavid van Moolenbroek {
70eda6f593SDavid van Moolenbroek struct args *args = self->args;
71eda6f593SDavid van Moolenbroek struct cmd_confirm_before_data *cdata;
72eda6f593SDavid van Moolenbroek struct client *c;
73eda6f593SDavid van Moolenbroek char *cmd, *copy, *new_prompt, *ptr;
74eda6f593SDavid van Moolenbroek const char *prompt;
75eda6f593SDavid van Moolenbroek
76*0a6a1f1dSLionel Sambuc if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
77*0a6a1f1dSLionel Sambuc return (CMD_RETURN_ERROR);
78eda6f593SDavid van Moolenbroek
79eda6f593SDavid van Moolenbroek if ((prompt = args_get(args, 'p')) != NULL)
80eda6f593SDavid van Moolenbroek xasprintf(&new_prompt, "%s ", prompt);
81eda6f593SDavid van Moolenbroek else {
82eda6f593SDavid van Moolenbroek ptr = copy = xstrdup(args->argv[0]);
83eda6f593SDavid van Moolenbroek cmd = strsep(&ptr, " \t");
84eda6f593SDavid van Moolenbroek xasprintf(&new_prompt, "Confirm '%s'? (y/n) ", cmd);
85*0a6a1f1dSLionel Sambuc free(copy);
86eda6f593SDavid van Moolenbroek }
87eda6f593SDavid van Moolenbroek
88eda6f593SDavid van Moolenbroek cdata = xmalloc(sizeof *cdata);
89eda6f593SDavid van Moolenbroek cdata->cmd = xstrdup(args->argv[0]);
90*0a6a1f1dSLionel Sambuc
91*0a6a1f1dSLionel Sambuc cdata->client = c;
92*0a6a1f1dSLionel Sambuc cdata->client->references++;
93*0a6a1f1dSLionel Sambuc
94*0a6a1f1dSLionel Sambuc status_prompt_set(c, new_prompt, NULL,
95eda6f593SDavid van Moolenbroek cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
96eda6f593SDavid van Moolenbroek PROMPT_SINGLE);
97eda6f593SDavid van Moolenbroek
98*0a6a1f1dSLionel Sambuc free(new_prompt);
99*0a6a1f1dSLionel Sambuc return (CMD_RETURN_NORMAL);
100eda6f593SDavid van Moolenbroek }
101eda6f593SDavid van Moolenbroek
102eda6f593SDavid van Moolenbroek int
cmd_confirm_before_callback(void * data,const char * s)103eda6f593SDavid van Moolenbroek cmd_confirm_before_callback(void *data, const char *s)
104eda6f593SDavid van Moolenbroek {
105eda6f593SDavid van Moolenbroek struct cmd_confirm_before_data *cdata = data;
106*0a6a1f1dSLionel Sambuc struct client *c = cdata->client;
107eda6f593SDavid van Moolenbroek struct cmd_list *cmdlist;
108eda6f593SDavid van Moolenbroek char *cause;
109eda6f593SDavid van Moolenbroek
110*0a6a1f1dSLionel Sambuc if (c->flags & CLIENT_DEAD)
111*0a6a1f1dSLionel Sambuc return (0);
112*0a6a1f1dSLionel Sambuc
113eda6f593SDavid van Moolenbroek if (s == NULL || *s == '\0')
114eda6f593SDavid van Moolenbroek return (0);
115eda6f593SDavid van Moolenbroek if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
116eda6f593SDavid van Moolenbroek return (0);
117eda6f593SDavid van Moolenbroek
118*0a6a1f1dSLionel Sambuc if (cmd_string_parse(cdata->cmd, &cmdlist, NULL, 0, &cause) != 0) {
119eda6f593SDavid van Moolenbroek if (cause != NULL) {
120*0a6a1f1dSLionel Sambuc cmdq_error(c->cmdq, "%s", cause);
121*0a6a1f1dSLionel Sambuc free(cause);
122eda6f593SDavid van Moolenbroek }
123eda6f593SDavid van Moolenbroek return (0);
124eda6f593SDavid van Moolenbroek }
125eda6f593SDavid van Moolenbroek
126*0a6a1f1dSLionel Sambuc cmdq_run(c->cmdq, cmdlist);
127eda6f593SDavid van Moolenbroek cmd_list_free(cmdlist);
128eda6f593SDavid van Moolenbroek
129eda6f593SDavid van Moolenbroek return (0);
130eda6f593SDavid van Moolenbroek }
131eda6f593SDavid van Moolenbroek
132eda6f593SDavid van Moolenbroek void
cmd_confirm_before_free(void * data)133eda6f593SDavid van Moolenbroek cmd_confirm_before_free(void *data)
134eda6f593SDavid van Moolenbroek {
135eda6f593SDavid van Moolenbroek struct cmd_confirm_before_data *cdata = data;
136*0a6a1f1dSLionel Sambuc struct client *c = cdata->client;
137eda6f593SDavid van Moolenbroek
138*0a6a1f1dSLionel Sambuc c->references--;
139*0a6a1f1dSLionel Sambuc
140*0a6a1f1dSLionel Sambuc free(cdata->cmd);
141*0a6a1f1dSLionel Sambuc free(cdata);
142eda6f593SDavid van Moolenbroek }
143