Add a -o option to set-option to prevent setting an option already set,

from Thiago Padilha.
pull/1/head
Nicholas Marriott 2013-03-24 09:55:02 +00:00
parent 20636d956d
commit a05b8c4143
2 changed files with 90 additions and 64 deletions

View File

@ -27,44 +27,44 @@
* Set an option. * Set an option.
*/ */
enum cmd_retval cmd_set_option_exec(struct cmd *, struct cmd_ctx *); enum cmd_retval cmd_set_option_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_set_option_user(struct cmd *, struct cmd_ctx *, enum cmd_retval cmd_set_option_user(struct cmd *, struct cmd_q *,
const char *, const char *); const char *, const char *);
int cmd_set_option_unset(struct cmd *, struct cmd_ctx *, int cmd_set_option_unset(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
int cmd_set_option_set(struct cmd *, struct cmd_ctx *, int cmd_set_option_set(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
struct options_entry *cmd_set_option_key(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_key(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
struct options_entry *cmd_set_option_attributes(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_attributes(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *, const struct options_table_entry *, struct options *,
const char *); const char *);
const struct cmd_entry cmd_set_option_entry = { const struct cmd_entry cmd_set_option_entry = {
"set-option", "set", "set-option", "set",
"agqst:uw", 1, 2, "agoqst:uw", 1, 2,
"[-agsquw] [-t target-session|target-window] option [value]", "[-agosquw] [-t target-session|target-window] option [value]",
0, 0,
NULL, NULL,
NULL, NULL,
@ -73,8 +73,8 @@ const struct cmd_entry cmd_set_option_entry = {
const struct cmd_entry cmd_set_window_option_entry = { const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw", "set-window-option", "setw",
"agqt:u", 1, 2, "agoqt:u", 1, 2,
"[-agqu] " CMD_TARGET_WINDOW_USAGE " option [value]", "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
0, 0,
NULL, NULL,
NULL, NULL,
@ -82,7 +82,7 @@ const struct cmd_entry cmd_set_window_option_entry = {
}; };
enum cmd_retval enum cmd_retval
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
{ {
struct args *args = self->args; struct args *args = self->args;
const struct options_table_entry *table, *oe; const struct options_table_entry *table, *oe;
@ -97,7 +97,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Get the option name and value. */ /* Get the option name and value. */
optstr = args->argv[0]; optstr = args->argv[0];
if (*optstr == '\0') { if (*optstr == '\0') {
ctx->error(ctx, "invalid option"); cmdq_error(cmdq, "invalid option");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (args->argc < 2) if (args->argc < 2)
@ -107,16 +107,16 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Is this a user option? */ /* Is this a user option? */
if (*optstr == '@') if (*optstr == '@')
return (cmd_set_option_user(self, ctx, optstr, valstr)); return (cmd_set_option_user(self, cmdq, optstr, valstr));
/* Find the option entry, try each table. */ /* Find the option entry, try each table. */
table = oe = NULL; table = oe = NULL;
if (options_table_find(optstr, &table, &oe) != 0) { if (options_table_find(optstr, &table, &oe) != 0) {
ctx->error(ctx, "ambiguous option: %s", optstr); cmdq_error(cmdq, "ambiguous option: %s", optstr);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (oe == NULL) { if (oe == NULL) {
ctx->error(ctx, "unknown option: %s", optstr); cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@ -127,7 +127,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
if (args_has(self->args, 'g')) if (args_has(self->args, 'g'))
oo = &global_w_options; oo = &global_w_options;
else { else {
wl = cmd_find_window(ctx, args_get(args, 't'), NULL); wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
if (wl == NULL) if (wl == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
oo = &wl->window->options; oo = &wl->window->options;
@ -136,22 +136,27 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
if (args_has(self->args, 'g')) if (args_has(self->args, 'g'))
oo = &global_s_options; oo = &global_s_options;
else { else {
s = cmd_find_session(ctx, args_get(args, 't'), 0); s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL) if (s == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
oo = &s->options; oo = &s->options;
} }
} else { } else {
ctx->error(ctx, "unknown table"); cmdq_error(cmdq, "unknown table");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
/* Unset or set the option. */ /* Unset or set the option. */
if (args_has(args, 'u')) { if (args_has(args, 'u')) {
if (cmd_set_option_unset(self, ctx, oe, oo, valstr) != 0) if (cmd_set_option_unset(self, cmdq, oe, oo, valstr) != 0)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} else { } else {
if (cmd_set_option_set(self, ctx, oe, oo, valstr) != 0) if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
if (!args_has(args, 'q'))
cmdq_print(cmdq, "already set: %s", optstr);
return (CMD_RETURN_NORMAL);
}
if (cmd_set_option_set(self, cmdq, oe, oo, valstr) != 0)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@ -180,7 +185,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Set user option. */ /* Set user option. */
enum cmd_retval enum cmd_retval
cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr, cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
const char *valstr) const char *valstr)
{ {
struct args *args = self->args; struct args *args = self->args;
@ -195,7 +200,7 @@ cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr,
if (args_has(self->args, 'g')) if (args_has(self->args, 'g'))
oo = &global_w_options; oo = &global_w_options;
else { else {
wl = cmd_find_window(ctx, args_get(args, 't'), NULL); wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
if (wl == NULL) if (wl == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
oo = &wl->window->options; oo = &wl->window->options;
@ -204,7 +209,7 @@ cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr,
if (args_has(self->args, 'g')) if (args_has(self->args, 'g'))
oo = &global_s_options; oo = &global_s_options;
else { else {
s = cmd_find_session(ctx, args_get(args, 't'), 0); s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL) if (s == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
oo = &s->options; oo = &s->options;
@ -213,23 +218,30 @@ cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr,
if (args_has(args, 'u')) { if (args_has(args, 'u')) {
if (options_find1(oo, optstr) == NULL) { if (options_find1(oo, optstr) == NULL) {
ctx->error(ctx, "unknown option: %s", optstr); cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (valstr != NULL) { if (valstr != NULL) {
ctx->error(ctx, "value passed to unset option: %s", cmdq_error(cmdq, "value passed to unset option: %s",
optstr); optstr);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
options_remove(oo, optstr); options_remove(oo, optstr);
} else { } else {
if (valstr == NULL) { if (valstr == NULL) {
ctx->error(ctx, "empty value"); cmdq_error(cmdq, "empty value");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
if (!args_has(args, 'q'))
cmdq_print(cmdq, "already set: %s", optstr);
return (CMD_RETURN_NORMAL);
}
options_set_string(oo, optstr, "%s", valstr); options_set_string(oo, optstr, "%s", valstr);
if (!args_has(args, 'q')) if (!args_has(args, 'q')) {
ctx->info(ctx, "set option: %s -> %s", optstr, valstr); cmdq_info(cmdq, "set option: %s -> %s", optstr,
valstr);
}
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
@ -237,29 +249,29 @@ cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, const char* optstr,
/* Unset an option. */ /* Unset an option. */
int int
cmd_set_option_unset(struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
struct args *args = self->args; struct args *args = self->args;
if (args_has(args, 'g')) { if (args_has(args, 'g')) {
ctx->error(ctx, "can't unset global option: %s", oe->name); cmdq_error(cmdq, "can't unset global option: %s", oe->name);
return (-1); return (-1);
} }
if (value != NULL) { if (value != NULL) {
ctx->error(ctx, "value passed to unset option: %s", oe->name); cmdq_error(cmdq, "value passed to unset option: %s", oe->name);
return (-1); return (-1);
} }
options_remove(oo, oe->name); options_remove(oo, oe->name);
if (!args_has(args, 'q')) if (!args_has(args, 'q'))
ctx->info(ctx, "unset option: %s", oe->name); cmdq_info(cmdq, "unset option: %s", oe->name);
return (0); return (0);
} }
/* Set an option. */ /* Set an option. */
int int
cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
struct args *args = self->args; struct args *args = self->args;
@ -267,32 +279,32 @@ cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx,
const char *s; const char *s;
if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) { if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
ctx->error(ctx, "empty value"); cmdq_error(cmdq, "empty value");
return (-1); return (-1);
} }
o = NULL; o = NULL;
switch (oe->type) { switch (oe->type) {
case OPTIONS_TABLE_STRING: case OPTIONS_TABLE_STRING:
o = cmd_set_option_string(self, ctx, oe, oo, value); o = cmd_set_option_string(self, cmdq, oe, oo, value);
break; break;
case OPTIONS_TABLE_NUMBER: case OPTIONS_TABLE_NUMBER:
o = cmd_set_option_number(self, ctx, oe, oo, value); o = cmd_set_option_number(self, cmdq, oe, oo, value);
break; break;
case OPTIONS_TABLE_KEY: case OPTIONS_TABLE_KEY:
o = cmd_set_option_key(self, ctx, oe, oo, value); o = cmd_set_option_key(self, cmdq, oe, oo, value);
break; break;
case OPTIONS_TABLE_COLOUR: case OPTIONS_TABLE_COLOUR:
o = cmd_set_option_colour(self, ctx, oe, oo, value); o = cmd_set_option_colour(self, cmdq, oe, oo, value);
break; break;
case OPTIONS_TABLE_ATTRIBUTES: case OPTIONS_TABLE_ATTRIBUTES:
o = cmd_set_option_attributes(self, ctx, oe, oo, value); o = cmd_set_option_attributes(self, cmdq, oe, oo, value);
break; break;
case OPTIONS_TABLE_FLAG: case OPTIONS_TABLE_FLAG:
o = cmd_set_option_flag(self, ctx, oe, oo, value); o = cmd_set_option_flag(self, cmdq, oe, oo, value);
break; break;
case OPTIONS_TABLE_CHOICE: case OPTIONS_TABLE_CHOICE:
o = cmd_set_option_choice(self, ctx, oe, oo, value); o = cmd_set_option_choice(self, cmdq, oe, oo, value);
break; break;
} }
if (o == NULL) if (o == NULL)
@ -300,13 +312,13 @@ cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx,
s = options_table_print_entry(oe, o, 0); s = options_table_print_entry(oe, o, 0);
if (!args_has(args, 'q')) if (!args_has(args, 'q'))
ctx->info(ctx, "set option: %s -> %s", oe->name, s); cmdq_info(cmdq, "set option: %s -> %s", oe->name, s);
return (0); return (0);
} }
/* Set a string option. */ /* Set a string option. */
struct options_entry * struct options_entry *
cmd_set_option_string(struct cmd *self, unused struct cmd_ctx *ctx, cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
struct args *args = self->args; struct args *args = self->args;
@ -327,7 +339,7 @@ cmd_set_option_string(struct cmd *self, unused struct cmd_ctx *ctx,
/* Set a number option. */ /* Set a number option. */
struct options_entry * struct options_entry *
cmd_set_option_number(unused struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
long long ll; long long ll;
@ -335,7 +347,7 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_ctx *ctx,
ll = strtonum(value, oe->minimum, oe->maximum, &errstr); ll = strtonum(value, oe->minimum, oe->maximum, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value); cmdq_error(cmdq, "value is %s: %s", errstr, value);
return (NULL); return (NULL);
} }
@ -344,13 +356,13 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_ctx *ctx,
/* Set a key option. */ /* Set a key option. */
struct options_entry * struct options_entry *
cmd_set_option_key(unused struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
int key; int key;
if ((key = key_string_lookup_string(value)) == KEYC_NONE) { if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
ctx->error(ctx, "bad key: %s", value); cmdq_error(cmdq, "bad key: %s", value);
return (NULL); return (NULL);
} }
@ -359,13 +371,13 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_ctx *ctx,
/* Set a colour option. */ /* Set a colour option. */
struct options_entry * struct options_entry *
cmd_set_option_colour(unused struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
int colour; int colour;
if ((colour = colour_fromstring(value)) == -1) { if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value); cmdq_error(cmdq, "bad colour: %s", value);
return (NULL); return (NULL);
} }
@ -374,13 +386,13 @@ cmd_set_option_colour(unused struct cmd *self, struct cmd_ctx *ctx,
/* Set an attributes option. */ /* Set an attributes option. */
struct options_entry * struct options_entry *
cmd_set_option_attributes(unused struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
int attr; int attr;
if ((attr = attributes_fromstring(value)) == -1) { if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value); cmdq_error(cmdq, "bad attributes: %s", value);
return (NULL); return (NULL);
} }
@ -389,7 +401,7 @@ cmd_set_option_attributes(unused struct cmd *self, struct cmd_ctx *ctx,
/* Set a flag option. */ /* Set a flag option. */
struct options_entry * struct options_entry *
cmd_set_option_flag(unused struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
int flag; int flag;
@ -406,7 +418,7 @@ cmd_set_option_flag(unused struct cmd *self, struct cmd_ctx *ctx,
strcasecmp(value, "no") == 0) strcasecmp(value, "no") == 0)
flag = 0; flag = 0;
else { else {
ctx->error(ctx, "bad value: %s", value); cmdq_error(cmdq, "bad value: %s", value);
return (NULL); return (NULL);
} }
} }
@ -416,8 +428,9 @@ cmd_set_option_flag(unused struct cmd *self, struct cmd_ctx *ctx,
/* Set a choice option. */ /* Set a choice option. */
struct options_entry * struct options_entry *
cmd_set_option_choice(unused struct cmd *self, struct cmd_ctx *ctx, cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value) const struct options_table_entry *oe, struct options *oo,
const char *value)
{ {
const char **choicep; const char **choicep;
int n, choice = -1; int n, choice = -1;
@ -429,13 +442,13 @@ cmd_set_option_choice(unused struct cmd *self, struct cmd_ctx *ctx,
continue; continue;
if (choice != -1) { if (choice != -1) {
ctx->error(ctx, "ambiguous value: %s", value); cmdq_error(cmdq, "ambiguous value: %s", value);
return (NULL); return (NULL);
} }
choice = n - 1; choice = n - 1;
} }
if (choice == -1) { if (choice == -1) {
ctx->error(ctx, "unknown value: %s", value); cmdq_error(cmdq, "unknown value: %s", value);
return (NULL); return (NULL);
} }

15
tmux.1
View File

@ -1992,7 +1992,7 @@ abc123
Commands which set options are as follows: Commands which set options are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo Ic set-option .It Xo Ic set-option
.Op Fl agqsuw .Op Fl agoqsuw
.Op Fl t Ar target-session | Ar target-window .Op Fl t Ar target-session | Ar target-window
.Ar option Ar value .Ar option Ar value
.Xc .Xc
@ -2021,6 +2021,10 @@ options.
It is not possible to unset a global option. It is not possible to unset a global option.
.Pp .Pp
The The
.Fl o
flag prevents setting an option that is already set.
.Pp
The
.Fl q .Fl q
flag suppresses the informational message (as if the flag suppresses the informational message (as if the
.Ic quiet .Ic quiet
@ -3466,6 +3470,7 @@ Miscellaneous commands are as follows:
Display a large clock. Display a large clock.
.It Xo Ic if-shell .It Xo Ic if-shell
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Op Fl b
.Ar shell-command command .Ar shell-command command
.Op Ar command .Op Ar command
.Xc .Xc
@ -3481,12 +3486,17 @@ Before being executed, shell-command is expanded using the rules specified in th
.Sx FORMATS .Sx FORMATS
section, including those relevant to section, including those relevant to
.Ar target-pane . .Ar target-pane .
With
.Fl b ,
.Ar shell-command
is run in the background.
.It Ic lock-server .It Ic lock-server
.D1 (alias: Ic lock ) .D1 (alias: Ic lock )
Lock each client individually by running the command specified by the Lock each client individually by running the command specified by the
.Ic lock-command .Ic lock-command
option. option.
.It Xo Ic run-shell .It Xo Ic run-shell
.Fl b
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Ar shell-command .Ar shell-command
.Xc .Xc
@ -3498,6 +3508,9 @@ Before being executed, shell-command is expanded using the rules specified in
the the
.Sx FORMATS .Sx FORMATS
section. section.
With
.Fl b ,
the command is run in the background.
After it finishes, any output to stdout is displayed in copy mode (in the pane After it finishes, any output to stdout is displayed in copy mode (in the pane
specified by specified by
.Fl t .Fl t