Sync OpenBSD patchset 927:

Allow the initial context on prompts to be set with the new -I option to
command-prompt. From Tiago Cunha.
This commit is contained in:
Tiago Cunha 2011-07-03 21:52:50 +00:00
parent ff7343c203
commit e097f0b4ee
5 changed files with 77 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $Id: cmd-command-prompt.c,v 1.31 2011-05-22 16:26:38 tcunha Exp $ */ /* $Id$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -20,6 +20,7 @@
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <time.h>
#include "tmux.h" #include "tmux.h"
@ -36,8 +37,8 @@ void cmd_command_prompt_free(void *);
const struct cmd_entry cmd_command_prompt_entry = { const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL, "command-prompt", NULL,
"p:t:", 0, 1, "I:p:t:", 0, 1,
CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]", "[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
0, 0,
cmd_command_prompt_key_binding, cmd_command_prompt_key_binding,
NULL, NULL,
@ -46,6 +47,8 @@ const struct cmd_entry cmd_command_prompt_entry = {
struct cmd_command_prompt_cdata { struct cmd_command_prompt_cdata {
struct client *c; struct client *c;
char *inputs;
char *next_input;
char *next_prompt; char *next_prompt;
char *prompts; char *prompts;
char *template; char *template;
@ -79,9 +82,10 @@ int
cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
const char *prompts; const char *inputs, *prompts;
struct cmd_command_prompt_cdata *cdata; struct cmd_command_prompt_cdata *cdata;
struct client *c; struct client *c;
char *input = NULL;
char *prompt, *prompt_replaced, *ptr; char *prompt, *prompt_replaced, *ptr;
size_t n; size_t n;
@ -94,6 +98,8 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->c = c; cdata->c = c;
cdata->idx = 1; cdata->idx = 1;
cdata->inputs = NULL;
cdata->next_input = NULL;
cdata->next_prompt = NULL; cdata->next_prompt = NULL;
cdata->prompts = NULL; cdata->prompts = NULL;
cdata->template = NULL; cdata->template = NULL;
@ -103,8 +109,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
else else
cdata->template = xstrdup("%1"); cdata->template = xstrdup("%1");
prompts = args_get(args, 'p'); if ((prompts = args_get(args, 'p')) != NULL)
if (prompts != NULL)
cdata->prompts = xstrdup(prompts); cdata->prompts = xstrdup(prompts);
else if (args->argc != 0) { else if (args->argc != 0) {
n = strcspn(cdata->template, " ,"); n = strcspn(cdata->template, " ,");
@ -112,6 +117,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
} else } else
cdata->prompts = xstrdup(":"); cdata->prompts = xstrdup(":");
/* Get first prompt. */
cdata->next_prompt = cdata->prompts; cdata->next_prompt = cdata->prompts;
ptr = strsep(&cdata->next_prompt, ","); ptr = strsep(&cdata->next_prompt, ",");
if (prompts == NULL) if (prompts == NULL)
@ -122,8 +128,22 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
xasprintf(&prompt, "%s ", prompt_replaced); xasprintf(&prompt, "%s ", prompt_replaced);
xfree(prompt_replaced); xfree(prompt_replaced);
} }
status_prompt_set(c, prompt, cmd_command_prompt_callback,
/* Get initial prompt input. */
if ((inputs = args_get(args, 'I')) != NULL) {
cdata->inputs = xstrdup(inputs);
cdata->next_input = cdata->inputs;
ptr = strsep(&cdata->next_input, ",");
input = status_replace(c, NULL, NULL, NULL, ptr, time(NULL),
0);
}
status_prompt_set(c, prompt, input, cmd_command_prompt_callback,
cmd_command_prompt_free, cdata, 0); cmd_command_prompt_free, cdata, 0);
if (input != NULL)
xfree(input);
xfree(prompt); xfree(prompt);
return (0); return (0);
@ -136,29 +156,43 @@ cmd_command_prompt_callback(void *data, const char *s)
struct client *c = cdata->c; struct client *c = cdata->c;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd_ctx ctx; struct cmd_ctx ctx;
char *cause, *newtempl, *prompt, *ptr; char *cause, *new_template, *prompt;
char *prompt_replaced; char *prompt_replaced, *ptr, *input = NULL;
if (s == NULL) if (s == NULL)
return (0); return (0);
newtempl = cmd_template_replace(cdata->template, s, cdata->idx); new_template = cmd_template_replace(cdata->template, s, cdata->idx);
xfree(cdata->template); xfree(cdata->template);
cdata->template = newtempl; cdata->template = new_template;
/*
* Check if there are more prompts; if so, get its respective input
* and update the prompt data.
*/
if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) { if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
prompt_replaced = status_replace(c, NULL, NULL, NULL, ptr, prompt_replaced = status_replace(c, NULL, NULL, NULL, ptr,
time(NULL), 0); time(NULL), 0);
xasprintf(&prompt, "%s ", prompt_replaced); xasprintf(&prompt, "%s ", prompt_replaced);
status_prompt_update(c, prompt);
/* Find next input and expand special sequences. */
if ((ptr = strsep(&cdata->next_input, ",")) != NULL) {
input = status_replace(c, NULL, NULL, NULL, ptr,
time(NULL), 0);
}
status_prompt_update(c, prompt, input);
if (input != NULL)
xfree(input);
xfree(prompt_replaced); xfree(prompt_replaced);
xfree(prompt); xfree(prompt);
cdata->idx++; cdata->idx++;
return (1); return (1);
} }
if (cmd_string_parse(newtempl, &cmdlist, &cause) != 0) { if (cmd_string_parse(new_template, &cmdlist, &cause) != 0) {
if (cause != NULL) { if (cause != NULL) {
*cause = toupper((u_char) *cause); *cause = toupper((u_char) *cause);
status_message_set(c, "%s", cause); status_message_set(c, "%s", cause);
@ -189,6 +223,8 @@ cmd_command_prompt_free(void *data)
{ {
struct cmd_command_prompt_cdata *cdata = data; struct cmd_command_prompt_cdata *cdata = data;
if (cdata->inputs != NULL)
xfree(cdata->inputs);
if (cdata->prompts != NULL) if (cdata->prompts != NULL)
xfree(cdata->prompts); xfree(cdata->prompts);
if (cdata->template != NULL) if (cdata->template != NULL)

View File

@ -1,4 +1,4 @@
/* $Id: cmd-confirm-before.c,v 1.13 2011-01-07 14:45:34 tcunha Exp $ */ /* $Id$ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@ -87,9 +87,8 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(args->argv[0]); cdata->cmd = xstrdup(args->argv[0]);
cdata->c = c; cdata->c = c;
status_prompt_set(cdata->c, buf, status_prompt_set(cdata->c, buf, NULL, cmd_confirm_before_callback,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata, cmd_confirm_before_free, cdata, PROMPT_SINGLE);
PROMPT_SINGLE);
xfree(buf); xfree(buf);
return (1); return (1);

View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.160 2011-05-05 10:02:36 tcunha Exp $ */ /* $Id$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -815,7 +815,7 @@ status_message_redraw(struct client *c)
/* Enable status line prompt. */ /* Enable status line prompt. */
void void
status_prompt_set(struct client *c, const char *msg, status_prompt_set(struct client *c, const char *msg, const char *input,
int (*callbackfn)(void *, const char *), void (*freefn)(void *), int (*callbackfn)(void *, const char *), void (*freefn)(void *),
void *data, int flags) void *data, int flags)
{ {
@ -826,8 +826,11 @@ status_prompt_set(struct client *c, const char *msg,
c->prompt_string = xstrdup(msg); c->prompt_string = xstrdup(msg);
c->prompt_buffer = xstrdup(""); if (input != NULL)
c->prompt_index = 0; c->prompt_buffer = xstrdup(input);
else
c->prompt_buffer = xstrdup("");
c->prompt_index = strlen(c->prompt_buffer);
c->prompt_callbackfn = callbackfn; c->prompt_callbackfn = callbackfn;
c->prompt_freefn = freefn; c->prompt_freefn = freefn;
@ -871,13 +874,17 @@ status_prompt_clear(struct client *c)
/* Update status line prompt with a new prompt string. */ /* Update status line prompt with a new prompt string. */
void void
status_prompt_update(struct client *c, const char *msg) status_prompt_update(struct client *c, const char *msg, const char *input)
{ {
xfree(c->prompt_string); xfree(c->prompt_string);
c->prompt_string = xstrdup(msg); c->prompt_string = xstrdup(msg);
*c->prompt_buffer = '\0'; xfree(c->prompt_buffer);
c->prompt_index = 0; if (input != NULL)
c->prompt_buffer = xstrdup(input);
else
c->prompt_buffer = xstrdup("");
c->prompt_index = strlen(c->prompt_buffer);
c->prompt_hindex = 0; c->prompt_hindex = 0;

11
tmux.1
View File

@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: June 5 2011 $ .Dd $Mdocdate: July 2 2011 $
.Dt TMUX 1 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@ -2635,6 +2635,7 @@ session option.
Commands related to the status line are as follows: Commands related to the status line are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo Ic command-prompt .It Xo Ic command-prompt
.Op Fl I Ar inputs
.Op Fl p Ar prompts .Op Fl p Ar prompts
.Op Fl t Ar target-client .Op Fl t Ar target-client
.Op Ar template .Op Ar template
@ -2647,6 +2648,9 @@ to execute commands interactively.
If If
.Ar template .Ar template
is specified, it is used as the command. is specified, it is used as the command.
If present,
.Fl I
is a comma-separated list of the initial text for each prompt.
If If
.Fl p .Fl p
is given, is given,
@ -2657,7 +2661,10 @@ a single prompt is displayed, constructed from
if it is present, or if it is present, or
.Ql \&: .Ql \&:
if not. if not.
The .Pp
Both
.Ar inputs
and
.Ar prompts .Ar prompts
may contain the special character sequences supported by the may contain the special character sequences supported by the
.Ic status-left .Ic status-left

4
tmux.h
View File

@ -1700,12 +1700,12 @@ char *status_replace(struct client *, struct session *,
void printflike2 status_message_set(struct client *, const char *, ...); void printflike2 status_message_set(struct client *, const char *, ...);
void status_message_clear(struct client *); void status_message_clear(struct client *);
int status_message_redraw(struct client *); int status_message_redraw(struct client *);
void status_prompt_set(struct client *, const char *, void status_prompt_set(struct client *, const char *, const char *,
int (*)(void *, const char *), void (*)(void *), void *, int); int (*)(void *, const char *), void (*)(void *), void *, int);
void status_prompt_clear(struct client *); void status_prompt_clear(struct client *);
int status_prompt_redraw(struct client *); int status_prompt_redraw(struct client *);
void status_prompt_key(struct client *, int); void status_prompt_key(struct client *, int);
void status_prompt_update(struct client *, const char *); void status_prompt_update(struct client *, const char *, const char *);
/* resize.c */ /* resize.c */
void recalculate_sizes(void); void recalculate_sizes(void);