diff --git a/cmd-set-option.c b/cmd-set-option.c index b35d60d8..ad058b8e 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -42,8 +42,8 @@ const struct cmd_entry cmd_set_option_entry = { .name = "set-option", .alias = "set", - .args = { "agoqst:uw", 1, 2 }, - .usage = "[-agosquw] [-t target-window] option [value]", + .args = { "aFgoqst:uw", 1, 2 }, + .usage = "[-aFgosquw] [-t target-window] option [value]", .target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL }, @@ -55,8 +55,8 @@ const struct cmd_entry cmd_set_window_option_entry = { .name = "set-window-option", .alias = "setw", - .args = { "agoqt:u", 1, 2 }, - .usage = "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]", + .args = { "aFgoqt:u", 1, 2 }, + .usage = "[-aFgoqu] " CMD_TARGET_WINDOW_USAGE " option [value]", .target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL }, @@ -70,33 +70,38 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) struct args *args = self->args; int append = args_has(args, 'a'); struct cmd_find_state *fs = &item->target; + struct client *c, *loop; struct session *s = fs->s; struct winlink *wl = fs->wl; struct window *w; - struct client *c; enum options_table_scope scope; struct options *oo; struct options_entry *parent, *o; - char *name; - const char *value, *target; + char *name, *argument, *value = NULL, *cause; + const char *target; int window, idx, already, error, ambiguous; - char *cause; + + /* Expand argument. */ + c = cmd_find_client(item, NULL, 1); + argument = format_single(item, args->argv[0], c, s, wl, NULL); /* Parse option name and index. */ - name = options_match(args->argv[0], &idx, &ambiguous); + name = options_match(argument, &idx, &ambiguous); if (name == NULL) { if (args_has(args, 'q')) - return (CMD_RETURN_NORMAL); + goto out; if (ambiguous) - cmdq_error(item, "ambiguous option: %s", args->argv[0]); + cmdq_error(item, "ambiguous option: %s", argument); else - cmdq_error(item, "invalid option: %s", args->argv[0]); - return (CMD_RETURN_ERROR); + cmdq_error(item, "invalid option: %s", argument); + goto fail; } if (args->argc < 2) value = NULL; + else if (args_has(args, 'F')) + value = format_single(item, args->argv[1], c, s, wl, NULL); else - value = args->argv[1]; + value = xstrdup(args->argv[1]); /* * Figure out the scope: for user options it comes from the arguments, @@ -114,12 +119,12 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) scope = OPTIONS_TABLE_WINDOW; else { scope = OPTIONS_TABLE_NONE; - xasprintf(&cause, "unknown option: %s", args->argv[0]); + xasprintf(&cause, "unknown option: %s", argument); } } if (scope == OPTIONS_TABLE_NONE) { if (args_has(args, 'q')) - return (CMD_RETURN_NORMAL); + goto out; cmdq_error(item, "%s", cause); free(cause); goto fail; @@ -159,7 +164,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) /* Check that array options and indexes match up. */ if (idx != -1) { if (*name == '@' || options_array_size(parent, NULL) == -1) { - cmdq_error(item, "not an array: %s", args->argv[0]); + cmdq_error(item, "not an array: %s", argument); goto fail; } } @@ -176,8 +181,8 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) } if (already) { if (args_has(args, 'q')) - return (CMD_RETURN_NORMAL); - cmdq_error(item, "already set: %s", args->argv[0]); + goto out; + cmdq_error(item, "already set: %s", argument); goto fail; } } @@ -217,7 +222,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) options_array_clear(o); options_array_assign(o, value); } else if (options_array_set(o, idx, value, append) != 0) { - cmdq_error(item, "invalid index: %s", args->argv[0]); + cmdq_error(item, "invalid index: %s", argument); goto fail; } } @@ -232,8 +237,8 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) } } if (strcmp(name, "key-table") == 0) { - TAILQ_FOREACH(c, &clients, entry) - server_client_set_key_table(c, NULL); + TAILQ_FOREACH(loop, &clients, entry) + server_client_set_key_table(loop, NULL); } if (strcmp(name, "status") == 0 || strcmp(name, "status-interval") == 0) @@ -257,15 +262,20 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) * anyway. */ recalculate_sizes(); - TAILQ_FOREACH(c, &clients, entry) { - if (c->session != NULL) - server_redraw_client(c); + TAILQ_FOREACH(loop, &clients, entry) { + if (loop->session != NULL) + server_redraw_client(loop); } +out: + free(argument); + free(value); free(name); return (CMD_RETURN_NORMAL); fail: + free(argument); + free(value); free(name); return (CMD_RETURN_ERROR); } diff --git a/cmd-show-options.c b/cmd-show-options.c index a0889c3a..f043beca 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -128,25 +128,36 @@ cmd_show_options_one(struct cmd *self, struct cmdq_item *item, struct options *oo) { struct args *args = self->args; + struct client *c = cmd_find_client(item, NULL, 1); + struct session *s = item->target.s; + struct winlink *wl = item->target.wl; struct options_entry *o; int idx, ambiguous; - const char *name = args->argv[0]; + char *name; + name = format_single(item, args->argv[0], c, s, wl, NULL); o = options_match_get(oo, name, &idx, 1, &ambiguous); if (o == NULL) { - if (args_has(args, 'q')) + if (args_has(args, 'q')) { + free(name); return (CMD_RETURN_NORMAL); + } if (ambiguous) { cmdq_error(item, "ambiguous option: %s", name); + free(name); return (CMD_RETURN_ERROR); } if (*name != '@' && - options_match_get(oo, name, &idx, 0, &ambiguous) != NULL) + options_match_get(oo, name, &idx, 0, &ambiguous) != NULL) { + free(name); return (CMD_RETURN_NORMAL); + } cmdq_error(item, "unknown option: %s", name); + free(name); return (CMD_RETURN_ERROR); } cmd_show_options_print(self, item, o, idx); + free(name); return (CMD_RETURN_NORMAL); } diff --git a/tmux.1 b/tmux.1 index 96320f56..e38cb185 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2331,7 +2331,7 @@ abc123 Commands which set options are as follows: .Bl -tag -width Ds .It Xo Ic set-option -.Op Fl agoqsuw +.Op Fl aFgoqsuw .Op Fl t Ar target-session | Ar target-window .Ar option Ar value .Xc @@ -2347,6 +2347,8 @@ otherwise a session option. If .Fl g is given, the global session or window option is set. +.Fl F +expands formats in the option value. The .Fl u flag unsets an option, so a session inherits the option from the global @@ -2897,7 +2899,7 @@ The default is .Ql \ -_@ . .El .It Xo Ic set-window-option -.Op Fl agoqu +.Op Fl aFgoqu .Op Fl t Ar target-window .Ar option Ar value .Xc @@ -2905,6 +2907,7 @@ The default is Set a window option. The .Fl a , +.Fl F , .Fl g , .Fl o , .Fl q