tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cmd-command-prompt.c
Go to the documentation of this file.
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
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 <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25 
26 #include "tmux.h"
27 
28 /*
29  * Prompt for command in client.
30  */
31 
32 static enum cmd_retval cmd_command_prompt_exec(struct cmd *,
33  struct cmdq_item *);
34 
35 static int cmd_command_prompt_callback(struct client *, void *,
36  const char *, int);
37 static void cmd_command_prompt_free(void *);
38 
39 const struct cmd_entry cmd_command_prompt_entry = {
40  .name = "command-prompt",
41  .alias = NULL,
42 
43  .args = { "1kiI:Np:Tt:W", 0, 1 },
44  .usage = "[-1kiNTW] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
45  "[template]",
46 
47  .flags = CMD_CLIENT_TFLAG,
49 };
50 
52  int flags;
53 
54  char *inputs;
55  char *next_input;
56 
57  char *prompts;
58  char *next_prompt;
59 
60  char *template;
61  int idx;
62 };
63 
64 static enum cmd_retval
65 cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
66 {
67  struct args *args = cmd_get_args(self);
68  struct client *tc = cmdq_get_target_client(item);
69  struct cmd_find_state *target = cmdq_get_target(item);
70  const char *inputs, *prompts;
71  struct cmd_command_prompt_cdata *cdata;
72  char *prompt, *ptr, *input = NULL;
73  size_t n;
74 
75  if (tc->prompt_string != NULL)
76  return (CMD_RETURN_NORMAL);
77 
78  cdata = xcalloc(1, sizeof *cdata);
79 
80  cdata->inputs = NULL;
81  cdata->next_input = NULL;
82 
83  cdata->prompts = NULL;
84  cdata->next_prompt = NULL;
85 
86  cdata->template = NULL;
87  cdata->idx = 1;
88 
89  if (args->argc != 0)
90  cdata->template = xstrdup(args->argv[0]);
91  else
92  cdata->template = xstrdup("%1");
93 
94  if ((prompts = args_get(args, 'p')) != NULL)
95  cdata->prompts = xstrdup(prompts);
96  else if (args->argc != 0) {
97  n = strcspn(cdata->template, " ,");
98  xasprintf(&cdata->prompts, "(%.*s) ", (int) n, cdata->template);
99  } else
100  cdata->prompts = xstrdup(":");
101 
102  /* Get first prompt. */
103  cdata->next_prompt = cdata->prompts;
104  ptr = strsep(&cdata->next_prompt, ",");
105  if (prompts == NULL)
106  prompt = xstrdup(ptr);
107  else
108  xasprintf(&prompt, "%s ", ptr);
109 
110  /* Get initial prompt input. */
111  if ((inputs = args_get(args, 'I')) != NULL) {
112  cdata->inputs = xstrdup(inputs);
113  cdata->next_input = cdata->inputs;
114  input = strsep(&cdata->next_input, ",");
115  }
116 
117  if (args_has(args, '1'))
118  cdata->flags |= PROMPT_SINGLE;
119  else if (args_has(args, 'N'))
120  cdata->flags |= PROMPT_NUMERIC;
121  else if (args_has(args, 'i'))
122  cdata->flags |= PROMPT_INCREMENTAL;
123  else if (args_has(args, 'k'))
124  cdata->flags |= PROMPT_KEY;
125  else if (args_has(args, 'W'))
126  cdata->flags |= PROMPT_WINDOW;
127  else if (args_has(args, 'T'))
128  cdata->flags |= PROMPT_TARGET;
129  status_prompt_set(tc, target, prompt, input,
131  cdata->flags);
132  free(prompt);
133 
134  return (CMD_RETURN_NORMAL);
135 }
136 
137 static int
138 cmd_command_prompt_callback(struct client *c, void *data, const char *s,
139  int done)
140 {
141  struct cmd_command_prompt_cdata *cdata = data;
142  char *new_template, *prompt, *ptr, *error;
143  char *input = NULL;
144  enum cmd_parse_status status;
145 
146  if (s == NULL)
147  return (0);
148  if (done && (cdata->flags & PROMPT_INCREMENTAL))
149  return (0);
150 
151  new_template = cmd_template_replace(cdata->template, s, cdata->idx);
152  if (done) {
153  free(cdata->template);
154  cdata->template = new_template;
155  }
156 
157  /*
158  * Check if there are more prompts; if so, get its respective input
159  * and update the prompt data.
160  */
161  if (done && (ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
162  xasprintf(&prompt, "%s ", ptr);
163  input = strsep(&cdata->next_input, ",");
164  status_prompt_update(c, prompt, input);
165 
166  free(prompt);
167  cdata->idx++;
168  return (1);
169  }
170 
171  status = cmd_parse_and_append(new_template, NULL, c, NULL, &error);
172  if (status == CMD_PARSE_ERROR) {
173  cmdq_append(c, cmdq_get_error(error));
174  free(error);
175  }
176 
177  if (!done)
178  free(new_template);
180  return (1);
181  return (0);
182 }
183 
184 static void
186 {
187  struct cmd_command_prompt_cdata *cdata = data;
188 
189  free(cdata->inputs);
190  free(cdata->prompts);
191  free(cdata->template);
192  free(cdata);
193 }
int args_has(struct args *args, u_char flag)
Definition: arguments.c:259
const char * args_get(struct args *args, u_char flag)
Definition: arguments.c:295
static int cmd_command_prompt_callback(struct client *, void *, const char *, int)
static void cmd_command_prompt_free(void *)
static enum cmd_retval cmd_command_prompt_exec(struct cmd *, struct cmdq_item *)
const struct cmd_entry cmd_command_prompt_entry
enum cmd_parse_status cmd_parse_and_append(const char *s, struct cmd_parse_input *pi, struct client *c, struct cmdq_state *state, char **error)
Definition: cmd-parse.c:641
struct client * cmdq_get_target_client(struct cmdq_item *item)
Definition: cmd-queue.c:157
struct cmdq_item * cmdq_get_error(const char *error)
Definition: cmd-queue.c:671
struct cmd_find_state * cmdq_get_target(struct cmdq_item *item)
Definition: cmd-queue.c:171
struct cmdq_item * cmdq_append(struct client *c, struct cmdq_item *item)
Definition: cmd-queue.c:288
struct args * cmd_get_args(struct cmd *cmd)
Definition: cmd.c:393
char * cmd_template_replace(const char *template, const char *s, int idx)
Definition: cmd.c:778
char * strsep(char **, const char *)
void status_prompt_update(struct client *c, const char *msg, const char *input)
Definition: status.c:630
void status_prompt_set(struct client *c, struct cmd_find_state *fs, const char *msg, const char *input, prompt_input_cb inputcb, prompt_free_cb freecb, void *data, int flags)
Definition: status.c:546
Definition: tmux.h:1435
int argc
Definition: tmux.h:1437
char ** argv
Definition: tmux.h:1438
Definition: tmux.h:1608
char * prompt_string
Definition: tmux.h:1723
prompt_input_cb prompt_inputcb
Definition: tmux.h:1727
Definition: tmux.h:1525
const char * name
Definition: tmux.h:1526
Definition: cmd.c:212
cmd_retval
Definition: tmux.h:1475
@ CMD_RETURN_NORMAL
Definition: tmux.h:1477
#define PROMPT_SINGLE
Definition: tmux.h:1734
#define CMD_TARGET_CLIENT_USAGE
Definition: tmux.h:1861
#define PROMPT_WINDOW
Definition: tmux.h:1739
#define PROMPT_INCREMENTAL
Definition: tmux.h:1736
#define PROMPT_NUMERIC
Definition: tmux.h:1735
cmd_parse_status
Definition: tmux.h:1483
@ CMD_PARSE_ERROR
Definition: tmux.h:1485
#define CMD_CLIENT_TFLAG
Definition: tmux.h:1543
#define PROMPT_TARGET
Definition: tmux.h:1740
#define PROMPT_KEY
Definition: tmux.h:1738
int xasprintf(char **ret, const char *fmt,...)
Definition: xmalloc.c:109
void * xcalloc(size_t nmemb, size_t size)
Definition: xmalloc.c:41
char * xstrdup(const char *str)
Definition: xmalloc.c:89