Add support for non-array command options

A followup commit will add a new default-client-command option.

Addresses #4416
This commit is contained in:
David Mandelberg
2025-03-21 15:48:03 -04:00
parent dbdc07e5ec
commit 557c2d7b25
2 changed files with 62 additions and 0 deletions

View File

@@ -260,6 +260,7 @@ options_default(struct options *oo, const struct options_table_entry *oe)
struct options_entry *o; struct options_entry *o;
union options_value *ov; union options_value *ov;
u_int i; u_int i;
struct cmd_parse_result *pr;
o = options_empty(oo, oe); o = options_empty(oo, oe);
ov = &o->value; ov = &o->value;
@@ -278,6 +279,17 @@ options_default(struct options *oo, const struct options_table_entry *oe)
case OPTIONS_TABLE_STRING: case OPTIONS_TABLE_STRING:
ov->string = xstrdup(oe->default_str); ov->string = xstrdup(oe->default_str);
break; break;
case OPTIONS_TABLE_COMMAND:
pr = cmd_parse_from_string(oe->default_str, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
free(pr->error);
break;
case CMD_PARSE_SUCCESS:
ov->cmdlist = pr->cmdlist;
break;
}
break;
default: default:
ov->number = oe->default_num; ov->number = oe->default_num;
break; break;
@@ -737,6 +749,19 @@ options_get_number(struct options *oo, const char *name)
return (o->value.number); return (o->value.number);
} }
const struct cmd_list *
options_get_command(struct options *oo, const char *name)
{
struct options_entry *o;
o = options_get(oo, name);
if (o == NULL)
fatalx("missing option %s", name);
if (!OPTIONS_IS_COMMAND(o))
fatalx("option %s is not a command", name);
return (o->value.cmdlist);
}
struct options_entry * struct options_entry *
options_set_string(struct options *oo, const char *name, int append, options_set_string(struct options *oo, const char *name, int append,
const char *fmt, ...) const char *fmt, ...)
@@ -798,6 +823,30 @@ options_set_number(struct options *oo, const char *name, long long value)
return (o); return (o);
} }
struct options_entry *
options_set_command(struct options *oo, const char *name,
struct cmd_list *value)
{
struct options_entry *o;
if (*name == '@')
fatalx("user option %s must be a string", name);
o = options_get_only(oo, name);
if (o == NULL) {
o = options_default(oo, options_parent_table_entry(oo, name));
if (o == NULL)
return (NULL);
}
if (!OPTIONS_IS_COMMAND(o))
fatalx("option %s is not a command", name);
if (o->value.cmdlist != NULL)
cmd_list_free(o->value.cmdlist);
o->value.cmdlist = value;
return (o);
}
int int
options_scope_from_name(struct args *args, int window, options_scope_from_name(struct args *args, int window,
const char *name, struct cmd_find_state *fs, struct options **oo, const char *name, struct cmd_find_state *fs, struct options **oo,
@@ -1054,6 +1103,7 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
const char *errstr, *new; const char *errstr, *new;
char *old; char *old;
key_code key; key_code key;
struct cmd_parse_result *pr;
if (oe != NULL) { if (oe != NULL) {
if (value == NULL && if (value == NULL &&
@@ -1112,6 +1162,15 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
case OPTIONS_TABLE_CHOICE: case OPTIONS_TABLE_CHOICE:
return (options_from_string_choice(oe, oo, name, value, cause)); return (options_from_string_choice(oe, oo, name, value, cause));
case OPTIONS_TABLE_COMMAND: case OPTIONS_TABLE_COMMAND:
pr = cmd_parse_from_string(value, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
*cause = pr->error;
return (-1);
case CMD_PARSE_SUCCESS:
options_set_command(oo, name, pr->cmdlist);
return (0);
}
break; break;
} }
return (-1); return (-1);

3
tmux.h
View File

@@ -2393,10 +2393,13 @@ struct options_entry *options_match_get(struct options *, const char *, int *,
int, int *); int, int *);
const char *options_get_string(struct options *, const char *); const char *options_get_string(struct options *, const char *);
long long options_get_number(struct options *, const char *); long long options_get_number(struct options *, const char *);
const struct cmd_list *options_get_command(struct options *, const char *);
struct options_entry * printflike(4, 5) options_set_string(struct options *, struct options_entry * printflike(4, 5) options_set_string(struct options *,
const char *, int, const char *, ...); const char *, int, const char *, ...);
struct options_entry *options_set_number(struct options *, const char *, struct options_entry *options_set_number(struct options *, const char *,
long long); long long);
struct options_entry *options_set_command(struct options *, const char *,
struct cmd_list *);
int options_scope_from_name(struct args *, int, int options_scope_from_name(struct args *, int,
const char *, struct cmd_find_state *, struct options **, const char *, struct cmd_find_state *, struct options **,
char **); char **);