4 * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
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.
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.
19 #include <sys/types.h>
30 * Option handling; each option has a name, type and value and is stored in
34 struct options_array_item
{
36 union options_value value
;
37 RB_ENTRY(options_array_item
) entry
;
40 options_array_cmp(struct options_array_item
*a1
, struct options_array_item
*a2
)
42 if (a1
->index
< a2
->index
)
44 if (a1
->index
> a2
->index
)
48 RB_GENERATE_STATIC(options_array
, options_array_item
, entry
, options_array_cmp
);
50 struct options_entry
{
51 struct options
*owner
;
54 const struct options_table_entry
*tableentry
;
55 union options_value value
;
60 RB_ENTRY(options_entry
) entry
;
64 RB_HEAD(options_tree
, options_entry
) tree
;
65 struct options
*parent
;
68 static struct options_entry
*options_add(struct options
*, const char *);
69 static void options_remove(struct options_entry
*);
71 #define OPTIONS_IS_STRING(o) \
72 ((o)->tableentry == NULL || \
73 (o)->tableentry->type == OPTIONS_TABLE_STRING)
74 #define OPTIONS_IS_NUMBER(o) \
75 ((o)->tableentry != NULL && \
76 ((o)->tableentry->type == OPTIONS_TABLE_NUMBER || \
77 (o)->tableentry->type == OPTIONS_TABLE_KEY || \
78 (o)->tableentry->type == OPTIONS_TABLE_COLOUR || \
79 (o)->tableentry->type == OPTIONS_TABLE_FLAG || \
80 (o)->tableentry->type == OPTIONS_TABLE_CHOICE))
81 #define OPTIONS_IS_COMMAND(o) \
82 ((o)->tableentry != NULL && \
83 (o)->tableentry->type == OPTIONS_TABLE_COMMAND)
85 #define OPTIONS_IS_ARRAY(o) \
86 ((o)->tableentry != NULL && \
87 ((o)->tableentry->flags & OPTIONS_TABLE_IS_ARRAY))
89 static int options_cmp(struct options_entry
*, struct options_entry
*);
90 RB_GENERATE_STATIC(options_tree
, options_entry
, entry
, options_cmp
);
93 options_cmp(struct options_entry
*lhs
, struct options_entry
*rhs
)
95 return (strcmp(lhs
->name
, rhs
->name
));
99 options_map_name(const char *name
)
101 const struct options_name_map
*map
;
103 for (map
= options_other_names
; map
->from
!= NULL
; map
++) {
104 if (strcmp(map
->from
, name
) == 0)
110 static const struct options_table_entry
*
111 options_parent_table_entry(struct options
*oo
, const char *s
)
113 struct options_entry
*o
;
115 if (oo
->parent
== NULL
)
116 fatalx("no parent options for %s", s
);
117 o
= options_get(oo
->parent
, s
);
119 fatalx("%s not in parent options", s
);
120 return (o
->tableentry
);
124 options_value_free(struct options_entry
*o
, union options_value
*ov
)
126 if (OPTIONS_IS_STRING(o
))
128 if (OPTIONS_IS_COMMAND(o
) && ov
->cmdlist
!= NULL
)
129 cmd_list_free(ov
->cmdlist
);
133 options_value_to_string(struct options_entry
*o
, union options_value
*ov
,
138 if (OPTIONS_IS_COMMAND(o
))
139 return (cmd_list_print(ov
->cmdlist
, 0));
140 if (OPTIONS_IS_NUMBER(o
)) {
141 switch (o
->tableentry
->type
) {
142 case OPTIONS_TABLE_NUMBER
:
143 xasprintf(&s
, "%lld", ov
->number
);
145 case OPTIONS_TABLE_KEY
:
146 s
= xstrdup(key_string_lookup_key(ov
->number
, 0));
148 case OPTIONS_TABLE_COLOUR
:
149 s
= xstrdup(colour_tostring(ov
->number
));
151 case OPTIONS_TABLE_FLAG
:
153 xasprintf(&s
, "%lld", ov
->number
);
155 s
= xstrdup(ov
->number
? "on" : "off");
157 case OPTIONS_TABLE_CHOICE
:
158 s
= xstrdup(o
->tableentry
->choices
[ov
->number
]);
161 fatalx("not a number option type");
165 if (OPTIONS_IS_STRING(o
))
166 return (xstrdup(ov
->string
));
167 return (xstrdup(""));
171 options_create(struct options
*parent
)
175 oo
= xcalloc(1, sizeof *oo
);
182 options_free(struct options
*oo
)
184 struct options_entry
*o
, *tmp
;
186 RB_FOREACH_SAFE(o
, options_tree
, &oo
->tree
, tmp
)
192 options_get_parent(struct options
*oo
)
198 options_set_parent(struct options
*oo
, struct options
*parent
)
203 struct options_entry
*
204 options_first(struct options
*oo
)
206 return (RB_MIN(options_tree
, &oo
->tree
));
209 struct options_entry
*
210 options_next(struct options_entry
*o
)
212 return (RB_NEXT(options_tree
, &oo
->tree
, o
));
215 struct options_entry
*
216 options_get_only(struct options
*oo
, const char *name
)
218 struct options_entry o
= { .name
= name
}, *found
;
220 found
= RB_FIND(options_tree
, &oo
->tree
, &o
);
222 o
.name
= options_map_name(name
);
223 return (RB_FIND(options_tree
, &oo
->tree
, &o
));
228 struct options_entry
*
229 options_get(struct options
*oo
, const char *name
)
231 struct options_entry
*o
;
233 o
= options_get_only(oo
, name
);
238 o
= options_get_only(oo
, name
);
243 struct options_entry
*
244 options_empty(struct options
*oo
, const struct options_table_entry
*oe
)
246 struct options_entry
*o
;
248 o
= options_add(oo
, oe
->name
);
251 if (oe
->flags
& OPTIONS_TABLE_IS_ARRAY
)
252 RB_INIT(&o
->value
.array
);
257 struct options_entry
*
258 options_default(struct options
*oo
, const struct options_table_entry
*oe
)
260 struct options_entry
*o
;
261 union options_value
*ov
;
264 o
= options_empty(oo
, oe
);
267 if (oe
->flags
& OPTIONS_TABLE_IS_ARRAY
) {
268 if (oe
->default_arr
== NULL
) {
269 options_array_assign(o
, oe
->default_str
, NULL
);
272 for (i
= 0; oe
->default_arr
[i
] != NULL
; i
++)
273 options_array_set(o
, i
, oe
->default_arr
[i
], 0, NULL
);
278 case OPTIONS_TABLE_STRING
:
279 ov
->string
= xstrdup(oe
->default_str
);
282 ov
->number
= oe
->default_num
;
289 options_default_to_string(const struct options_table_entry
*oe
)
294 case OPTIONS_TABLE_STRING
:
295 case OPTIONS_TABLE_COMMAND
:
296 s
= xstrdup(oe
->default_str
);
298 case OPTIONS_TABLE_NUMBER
:
299 xasprintf(&s
, "%lld", oe
->default_num
);
301 case OPTIONS_TABLE_KEY
:
302 s
= xstrdup(key_string_lookup_key(oe
->default_num
, 0));
304 case OPTIONS_TABLE_COLOUR
:
305 s
= xstrdup(colour_tostring(oe
->default_num
));
307 case OPTIONS_TABLE_FLAG
:
308 s
= xstrdup(oe
->default_num
? "on" : "off");
310 case OPTIONS_TABLE_CHOICE
:
311 s
= xstrdup(oe
->choices
[oe
->default_num
]);
314 fatalx("unknown option type");
319 static struct options_entry
*
320 options_add(struct options
*oo
, const char *name
)
322 struct options_entry
*o
;
324 o
= options_get_only(oo
, name
);
328 o
= xcalloc(1, sizeof *o
);
330 o
->name
= xstrdup(name
);
332 RB_INSERT(options_tree
, &oo
->tree
, o
);
337 options_remove(struct options_entry
*o
)
339 struct options
*oo
= o
->owner
;
341 if (OPTIONS_IS_ARRAY(o
))
342 options_array_clear(o
);
344 options_value_free(o
, &o
->value
);
345 RB_REMOVE(options_tree
, &oo
->tree
, o
);
346 free((void *)o
->name
);
351 options_name(struct options_entry
*o
)
357 options_owner(struct options_entry
*o
)
362 const struct options_table_entry
*
363 options_table_entry(struct options_entry
*o
)
365 return (o
->tableentry
);
368 static struct options_array_item
*
369 options_array_item(struct options_entry
*o
, u_int idx
)
371 struct options_array_item a
;
374 return (RB_FIND(options_array
, &o
->value
.array
, &a
));
377 static struct options_array_item
*
378 options_array_new(struct options_entry
*o
, u_int idx
)
380 struct options_array_item
*a
;
382 a
= xcalloc(1, sizeof *a
);
384 RB_INSERT(options_array
, &o
->value
.array
, a
);
389 options_array_free(struct options_entry
*o
, struct options_array_item
*a
)
391 options_value_free(o
, &a
->value
);
392 RB_REMOVE(options_array
, &o
->value
.array
, a
);
397 options_array_clear(struct options_entry
*o
)
399 struct options_array_item
*a
, *a1
;
401 if (!OPTIONS_IS_ARRAY(o
))
404 RB_FOREACH_SAFE(a
, options_array
, &o
->value
.array
, a1
)
405 options_array_free(o
, a
);
408 union options_value
*
409 options_array_get(struct options_entry
*o
, u_int idx
)
411 struct options_array_item
*a
;
413 if (!OPTIONS_IS_ARRAY(o
))
415 a
= options_array_item(o
, idx
);
422 options_array_set(struct options_entry
*o
, u_int idx
, const char *value
,
423 int append
, char **cause
)
425 struct options_array_item
*a
;
427 struct cmd_parse_result
*pr
;
430 if (!OPTIONS_IS_ARRAY(o
)) {
432 *cause
= xstrdup("not an array");
437 a
= options_array_item(o
, idx
);
439 options_array_free(o
, a
);
443 if (OPTIONS_IS_COMMAND(o
)) {
444 pr
= cmd_parse_from_string(value
, NULL
);
445 switch (pr
->status
) {
446 case CMD_PARSE_ERROR
:
452 case CMD_PARSE_SUCCESS
:
456 a
= options_array_item(o
, idx
);
458 a
= options_array_new(o
, idx
);
460 options_value_free(o
, &a
->value
);
461 a
->value
.cmdlist
= pr
->cmdlist
;
465 if (OPTIONS_IS_STRING(o
)) {
466 a
= options_array_item(o
, idx
);
467 if (a
!= NULL
&& append
)
468 xasprintf(&new, "%s%s", a
->value
.string
, value
);
470 new = xstrdup(value
);
472 a
= options_array_new(o
, idx
);
474 options_value_free(o
, &a
->value
);
475 a
->value
.string
= new;
479 if (o
->tableentry
->type
== OPTIONS_TABLE_COLOUR
) {
480 if ((number
= colour_fromstring(value
)) == -1) {
481 xasprintf(cause
, "bad colour: %s", value
);
484 a
= options_array_item(o
, idx
);
486 a
= options_array_new(o
, idx
);
488 options_value_free(o
, &a
->value
);
489 a
->value
.number
= number
;
494 *cause
= xstrdup("wrong array type");
499 options_array_assign(struct options_entry
*o
, const char *s
, char **cause
)
501 const char *separator
;
502 char *copy
, *next
, *string
;
505 separator
= o
->tableentry
->separator
;
506 if (separator
== NULL
)
508 if (*separator
== '\0') {
511 for (i
= 0; i
< UINT_MAX
; i
++) {
512 if (options_array_item(o
, i
) == NULL
)
515 return (options_array_set(o
, i
, s
, 0, cause
));
520 copy
= string
= xstrdup(s
);
521 while ((next
= strsep(&string
, separator
)) != NULL
) {
524 for (i
= 0; i
< UINT_MAX
; i
++) {
525 if (options_array_item(o
, i
) == NULL
)
530 if (options_array_set(o
, i
, next
, 0, cause
) != 0) {
539 struct options_array_item
*
540 options_array_first(struct options_entry
*o
)
542 if (!OPTIONS_IS_ARRAY(o
))
544 return (RB_MIN(options_array
, &o
->value
.array
));
547 struct options_array_item
*
548 options_array_next(struct options_array_item
*a
)
550 return (RB_NEXT(options_array
, &o
->value
.array
, a
));
554 options_array_item_index(struct options_array_item
*a
)
559 union options_value
*
560 options_array_item_value(struct options_array_item
*a
)
566 options_is_array(struct options_entry
*o
)
568 return (OPTIONS_IS_ARRAY(o
));
572 options_is_string(struct options_entry
*o
)
574 return (OPTIONS_IS_STRING(o
));
578 options_to_string(struct options_entry
*o
, int idx
, int numeric
)
580 struct options_array_item
*a
;
582 if (OPTIONS_IS_ARRAY(o
)) {
584 return (xstrdup(""));
585 a
= options_array_item(o
, idx
);
587 return (xstrdup(""));
588 return (options_value_to_string(o
, &a
->value
, numeric
));
590 return (options_value_to_string(o
, &o
->value
, numeric
));
594 options_parse(const char *name
, int *idx
)
596 char *copy
, *cp
, *end
;
600 copy
= xstrdup(name
);
601 if ((cp
= strchr(copy
, '[')) == NULL
) {
605 end
= strchr(cp
+ 1, ']');
606 if (end
== NULL
|| end
[1] != '\0' || !isdigit((u_char
)end
[-1])) {
610 if (sscanf(cp
, "[%d]", idx
) != 1 || *idx
< 0) {
618 struct options_entry
*
619 options_parse_get(struct options
*oo
, const char *s
, int *idx
, int only
)
621 struct options_entry
*o
;
624 name
= options_parse(s
, idx
);
628 o
= options_get_only(oo
, name
);
630 o
= options_get(oo
, name
);
636 options_match(const char *s
, int *idx
, int *ambiguous
)
638 const struct options_table_entry
*oe
, *found
;
643 parsed
= options_parse(s
, idx
);
646 if (*parsed
== '@') {
651 name
= options_map_name(parsed
);
652 namelen
= strlen(name
);
655 for (oe
= options_table
; oe
->name
!= NULL
; oe
++) {
656 if (strcmp(oe
->name
, name
) == 0) {
660 if (strncmp(oe
->name
, name
, namelen
) == 0) {
674 return (xstrdup(found
->name
));
677 struct options_entry
*
678 options_match_get(struct options
*oo
, const char *s
, int *idx
, int only
,
682 struct options_entry
*o
;
684 name
= options_match(s
, idx
, ambiguous
);
689 o
= options_get_only(oo
, name
);
691 o
= options_get(oo
, name
);
697 options_get_string(struct options
*oo
, const char *name
)
699 struct options_entry
*o
;
701 o
= options_get(oo
, name
);
703 fatalx("missing option %s", name
);
704 if (!OPTIONS_IS_STRING(o
))
705 fatalx("option %s is not a string", name
);
706 return (o
->value
.string
);
710 options_get_number(struct options
*oo
, const char *name
)
712 struct options_entry
*o
;
714 o
= options_get(oo
, name
);
716 fatalx("missing option %s", name
);
717 if (!OPTIONS_IS_NUMBER(o
))
718 fatalx("option %s is not a number", name
);
719 return (o
->value
.number
);
722 struct options_entry
*
723 options_set_string(struct options
*oo
, const char *name
, int append
,
724 const char *fmt
, ...)
726 struct options_entry
*o
;
728 const char *separator
= "";
732 xvasprintf(&s
, fmt
, ap
);
735 o
= options_get_only(oo
, name
);
736 if (o
!= NULL
&& append
&& OPTIONS_IS_STRING(o
)) {
738 separator
= o
->tableentry
->separator
;
739 if (separator
== NULL
)
742 xasprintf(&value
, "%s%s%s", o
->value
.string
, separator
, s
);
746 if (o
== NULL
&& *name
== '@')
747 o
= options_add(oo
, name
);
748 else if (o
== NULL
) {
749 o
= options_default(oo
, options_parent_table_entry(oo
, name
));
754 if (!OPTIONS_IS_STRING(o
))
755 fatalx("option %s is not a string", name
);
756 free(o
->value
.string
);
757 o
->value
.string
= value
;
762 struct options_entry
*
763 options_set_number(struct options
*oo
, const char *name
, long long value
)
765 struct options_entry
*o
;
768 fatalx("user option %s must be a string", name
);
770 o
= options_get_only(oo
, name
);
772 o
= options_default(oo
, options_parent_table_entry(oo
, name
));
777 if (!OPTIONS_IS_NUMBER(o
))
778 fatalx("option %s is not a number", name
);
779 o
->value
.number
= value
;
784 options_scope_from_name(struct args
*args
, int window
,
785 const char *name
, struct cmd_find_state
*fs
, struct options
**oo
,
788 struct session
*s
= fs
->s
;
789 struct winlink
*wl
= fs
->wl
;
790 struct window_pane
*wp
= fs
->wp
;
791 const char *target
= args_get(args
, 't');
792 const struct options_table_entry
*oe
;
793 int scope
= OPTIONS_TABLE_NONE
;
796 return (options_scope_from_flags(args
, window
, fs
, oo
, cause
));
798 for (oe
= options_table
; oe
->name
!= NULL
; oe
++) {
799 if (strcmp(oe
->name
, name
) == 0)
802 if (oe
->name
== NULL
) {
803 xasprintf(cause
, "unknown option: %s", name
);
804 return (OPTIONS_TABLE_NONE
);
807 case OPTIONS_TABLE_SERVER
:
808 *oo
= global_options
;
809 scope
= OPTIONS_TABLE_SERVER
;
811 case OPTIONS_TABLE_SESSION
:
812 if (args_has(args
, 'g')) {
813 *oo
= global_s_options
;
814 scope
= OPTIONS_TABLE_SESSION
;
815 } else if (s
== NULL
&& target
!= NULL
)
816 xasprintf(cause
, "no such session: %s", target
);
818 xasprintf(cause
, "no current session");
821 scope
= OPTIONS_TABLE_SESSION
;
824 case OPTIONS_TABLE_WINDOW
|OPTIONS_TABLE_PANE
:
825 if (args_has(args
, 'p')) {
826 if (wp
== NULL
&& target
!= NULL
)
827 xasprintf(cause
, "no such pane: %s", target
);
829 xasprintf(cause
, "no current pane");
832 scope
= OPTIONS_TABLE_PANE
;
837 case OPTIONS_TABLE_WINDOW
:
838 if (args_has(args
, 'g')) {
839 *oo
= global_w_options
;
840 scope
= OPTIONS_TABLE_WINDOW
;
841 } else if (wl
== NULL
&& target
!= NULL
)
842 xasprintf(cause
, "no such window: %s", target
);
844 xasprintf(cause
, "no current window");
846 *oo
= wl
->window
->options
;
847 scope
= OPTIONS_TABLE_WINDOW
;
855 options_scope_from_flags(struct args
*args
, int window
,
856 struct cmd_find_state
*fs
, struct options
**oo
, char **cause
)
858 struct session
*s
= fs
->s
;
859 struct winlink
*wl
= fs
->wl
;
860 struct window_pane
*wp
= fs
->wp
;
861 const char *target
= args_get(args
, 't');
863 if (args_has(args
, 's')) {
864 *oo
= global_options
;
865 return (OPTIONS_TABLE_SERVER
);
868 if (args_has(args
, 'p')) {
871 xasprintf(cause
, "no such pane: %s", target
);
873 xasprintf(cause
, "no current pane");
874 return (OPTIONS_TABLE_NONE
);
877 return (OPTIONS_TABLE_PANE
);
878 } else if (window
|| args_has(args
, 'w')) {
879 if (args_has(args
, 'g')) {
880 *oo
= global_w_options
;
881 return (OPTIONS_TABLE_WINDOW
);
885 xasprintf(cause
, "no such window: %s", target
);
887 xasprintf(cause
, "no current window");
888 return (OPTIONS_TABLE_NONE
);
890 *oo
= wl
->window
->options
;
891 return (OPTIONS_TABLE_WINDOW
);
893 if (args_has(args
, 'g')) {
894 *oo
= global_s_options
;
895 return (OPTIONS_TABLE_SESSION
);
899 xasprintf(cause
, "no such session: %s", target
);
901 xasprintf(cause
, "no current session");
902 return (OPTIONS_TABLE_NONE
);
905 return (OPTIONS_TABLE_SESSION
);
910 options_string_to_style(struct options
*oo
, const char *name
,
911 struct format_tree
*ft
)
913 struct options_entry
*o
;
917 o
= options_get(oo
, name
);
918 if (o
== NULL
|| !OPTIONS_IS_STRING(o
))
924 log_debug("%s: %s is '%s'", __func__
, name
, s
);
926 style_set(&o
->style
, &grid_default_cell
);
927 o
->cached
= (strstr(s
, "#{") == NULL
);
929 if (ft
!= NULL
&& !o
->cached
) {
930 expanded
= format_expand(ft
, s
);
931 if (style_parse(&o
->style
, &grid_default_cell
, expanded
) != 0) {
937 if (style_parse(&o
->style
, &grid_default_cell
, s
) != 0)
944 options_from_string_check(const struct options_table_entry
*oe
,
945 const char *value
, char **cause
)
951 if (strcmp(oe
->name
, "default-shell") == 0 && !checkshell(value
)) {
952 xasprintf(cause
, "not a suitable shell: %s", value
);
955 if (oe
->pattern
!= NULL
&& fnmatch(oe
->pattern
, value
, 0) != 0) {
956 xasprintf(cause
, "value is invalid: %s", value
);
959 if ((oe
->flags
& OPTIONS_TABLE_IS_STYLE
) &&
960 strstr(value
, "#{") == NULL
&&
961 style_parse(&sy
, &grid_default_cell
, value
) != 0) {
962 xasprintf(cause
, "invalid style: %s", value
);
969 options_from_string_flag(struct options
*oo
, const char *name
,
970 const char *value
, char **cause
)
974 if (value
== NULL
|| *value
== '\0')
975 flag
= !options_get_number(oo
, name
);
976 else if (strcmp(value
, "1") == 0 ||
977 strcasecmp(value
, "on") == 0 ||
978 strcasecmp(value
, "yes") == 0)
980 else if (strcmp(value
, "0") == 0 ||
981 strcasecmp(value
, "off") == 0 ||
982 strcasecmp(value
, "no") == 0)
985 xasprintf(cause
, "bad value: %s", value
);
988 options_set_number(oo
, name
, flag
);
993 options_find_choice(const struct options_table_entry
*oe
, const char *value
,
997 int n
= 0, choice
= -1;
999 for (cp
= oe
->choices
; *cp
!= NULL
; cp
++) {
1000 if (strcmp(*cp
, value
) == 0)
1005 xasprintf(cause
, "unknown value: %s", value
);
1012 options_from_string_choice(const struct options_table_entry
*oe
,
1013 struct options
*oo
, const char *name
, const char *value
, char **cause
)
1017 if (value
== NULL
) {
1018 choice
= options_get_number(oo
, name
);
1022 choice
= options_find_choice(oe
, value
, cause
);
1026 options_set_number(oo
, name
, choice
);
1031 options_from_string(struct options
*oo
, const struct options_table_entry
*oe
,
1032 const char *name
, const char *value
, int append
, char **cause
)
1034 enum options_table_type type
;
1036 const char *errstr
, *new;
1041 if (value
== NULL
&&
1042 oe
->type
!= OPTIONS_TABLE_FLAG
&&
1043 oe
->type
!= OPTIONS_TABLE_CHOICE
) {
1044 xasprintf(cause
, "empty value");
1050 xasprintf(cause
, "bad option name");
1053 type
= OPTIONS_TABLE_STRING
;
1057 case OPTIONS_TABLE_STRING
:
1058 old
= xstrdup(options_get_string(oo
, name
));
1059 options_set_string(oo
, name
, append
, "%s", value
);
1061 new = options_get_string(oo
, name
);
1062 if (options_from_string_check(oe
, new, cause
) != 0) {
1063 options_set_string(oo
, name
, 0, "%s", old
);
1069 case OPTIONS_TABLE_NUMBER
:
1070 number
= strtonum(value
, oe
->minimum
, oe
->maximum
, &errstr
);
1071 if (errstr
!= NULL
) {
1072 xasprintf(cause
, "value is %s: %s", errstr
, value
);
1075 options_set_number(oo
, name
, number
);
1077 case OPTIONS_TABLE_KEY
:
1078 key
= key_string_lookup_string(value
);
1079 if (key
== KEYC_UNKNOWN
) {
1080 xasprintf(cause
, "bad key: %s", value
);
1083 options_set_number(oo
, name
, key
);
1085 case OPTIONS_TABLE_COLOUR
:
1086 if ((number
= colour_fromstring(value
)) == -1) {
1087 xasprintf(cause
, "bad colour: %s", value
);
1090 options_set_number(oo
, name
, number
);
1092 case OPTIONS_TABLE_FLAG
:
1093 return (options_from_string_flag(oo
, name
, value
, cause
));
1094 case OPTIONS_TABLE_CHOICE
:
1095 return (options_from_string_choice(oe
, oo
, name
, value
, cause
));
1096 case OPTIONS_TABLE_COMMAND
:
1103 options_push_changes(const char *name
)
1105 struct client
*loop
;
1108 struct window_pane
*wp
;
1111 if (strcmp(name
, "automatic-rename") == 0) {
1112 RB_FOREACH(w
, windows
, &windows
) {
1113 if (w
->active
== NULL
)
1115 if (options_get_number(w
->options
, name
))
1116 w
->active
->flags
|= PANE_CHANGED
;
1119 if (strcmp(name
, "cursor-colour") == 0) {
1120 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
) {
1121 c
= options_get_number(wp
->options
, name
);
1122 wp
->screen
->default_ccolour
= c
;
1125 if (strcmp(name
, "cursor-style") == 0) {
1126 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
) {
1127 wp
->screen
->default_mode
= 0;
1128 screen_set_cursor_style(options_get_number(wp
->options
,
1129 name
), &wp
->screen
->default_cstyle
,
1130 &wp
->screen
->default_mode
);
1133 if (strcmp(name
, "key-table") == 0) {
1134 TAILQ_FOREACH(loop
, &clients
, entry
)
1135 server_client_set_key_table(loop
, NULL
);
1137 if (strcmp(name
, "user-keys") == 0) {
1138 TAILQ_FOREACH(loop
, &clients
, entry
) {
1139 if (loop
->tty
.flags
& TTY_OPENED
)
1140 tty_keys_build(&loop
->tty
);
1143 if (strcmp(name
, "status") == 0 ||
1144 strcmp(name
, "status-interval") == 0)
1145 status_timer_start_all();
1146 if (strcmp(name
, "monitor-silence") == 0)
1148 if (strcmp(name
, "window-style") == 0 ||
1149 strcmp(name
, "window-active-style") == 0) {
1150 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
)
1151 wp
->flags
|= PANE_STYLECHANGED
;
1153 if (strcmp(name
, "pane-colours") == 0) {
1154 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
)
1155 colour_palette_from_option(&wp
->palette
, wp
->options
);
1157 if (strcmp(name
, "pane-border-status") == 0) {
1158 RB_FOREACH(w
, windows
, &windows
)
1159 layout_fix_panes(w
, NULL
);
1161 RB_FOREACH(s
, sessions
, &sessions
)
1162 status_update_cache(s
);
1164 recalculate_sizes();
1165 TAILQ_FOREACH(loop
, &clients
, entry
) {
1166 if (loop
->session
!= NULL
)
1167 server_redraw_client(loop
);
1172 options_remove_or_default(struct options_entry
*o
, int idx
, char **cause
)
1174 struct options
*oo
= o
->owner
;
1177 if (o
->tableentry
!= NULL
&&
1178 (oo
== global_options
||
1179 oo
== global_s_options
||
1180 oo
== global_w_options
))
1181 options_default(oo
, o
->tableentry
);
1184 } else if (options_array_set(o
, idx
, NULL
, 0, cause
) != 0)