options-table.c revision 1.50
1/* $OpenBSD: options-table.c,v 1.50 2014/04/17 12:57:28 nicm Exp $ */
2
3/*
4 * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
5 *
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.
9 *
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.
17 */
18
19#include <sys/types.h>
20
21#include <string.h>
22#include <paths.h>
23
24#include "tmux.h"
25
26/*
27 * This file has a tables with all the server, session and window
28 * options. These tables are the master copy of the options with their real
29 * (user-visible) types, range limits and default values. At start these are
30 * copied into the runtime global options trees (which only has number and
31 * string types). These tables are then used to look up the real type when the
32 * user sets an option or its value needs to be shown.
33 */
34
35/* Choice option type lists. */
36const char *options_table_mode_keys_list[] = {
37	"emacs", "vi", NULL
38};
39const char *options_table_mode_mouse_list[] = {
40	"off", "on", "copy-mode", NULL
41};
42const char *options_table_clock_mode_style_list[] = {
43	"12", "24", NULL
44};
45const char *options_table_status_keys_list[] = {
46	"emacs", "vi", NULL
47};
48const char *options_table_status_justify_list[] = {
49	"left", "centre", "right", NULL
50};
51const char *options_table_status_position_list[] = {
52	"top", "bottom", NULL
53};
54const char *options_table_bell_action_list[] = {
55	"none", "any", "current", NULL
56};
57
58/* Server options. */
59const struct options_table_entry server_options_table[] = {
60	{ .name = "buffer-limit",
61	  .type = OPTIONS_TABLE_NUMBER,
62	  .minimum = 1,
63	  .maximum = INT_MAX,
64	  .default_num = 20
65	},
66
67	{ .name = "escape-time",
68	  .type = OPTIONS_TABLE_NUMBER,
69	  .minimum = 0,
70	  .maximum = INT_MAX,
71	  .default_num = 500
72	},
73
74	{ .name = "exit-unattached",
75	  .type = OPTIONS_TABLE_FLAG,
76	  .default_num = 0
77	},
78
79	{ .name = "focus-events",
80	  .type = OPTIONS_TABLE_FLAG,
81	  .default_num = 0
82	},
83
84	{ .name = "message-limit",
85	  .type = OPTIONS_TABLE_NUMBER,
86	  .minimum = 0,
87	  .maximum = INT_MAX,
88	  .default_num = 100
89	},
90
91	{ .name = "quiet",
92	  .type = OPTIONS_TABLE_FLAG,
93	  .default_num = 0
94	},
95
96	{ .name = "set-clipboard",
97	  .type = OPTIONS_TABLE_FLAG,
98	  .default_num = 1
99	},
100
101	{ .name = "terminal-overrides",
102	  .type = OPTIONS_TABLE_STRING,
103	  .default_str = "*256col*:colors=256"
104	                 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
105	                 ":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
106			 ":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT"
107	},
108
109	{ .name = NULL }
110};
111
112/* Session options. */
113const struct options_table_entry session_options_table[] = {
114	{ .name = "assume-paste-time",
115	  .type = OPTIONS_TABLE_NUMBER,
116	  .minimum = 0,
117	  .maximum = INT_MAX,
118	  .default_num = 1,
119	},
120
121	{ .name = "base-index",
122	  .type = OPTIONS_TABLE_NUMBER,
123	  .minimum = 0,
124	  .maximum = INT_MAX,
125	  .default_num = 0
126	},
127
128	{ .name = "bell-action",
129	  .type = OPTIONS_TABLE_CHOICE,
130	  .choices = options_table_bell_action_list,
131	  .default_num = BELL_ANY
132	},
133
134	{ .name = "bell-on-alert",
135	  .type = OPTIONS_TABLE_FLAG,
136	  .default_num = 0
137	},
138
139	{ .name = "default-command",
140	  .type = OPTIONS_TABLE_STRING,
141	  .default_str = ""
142	},
143
144	{ .name = "default-shell",
145	  .type = OPTIONS_TABLE_STRING,
146	  .default_str = _PATH_BSHELL
147	},
148
149	{ .name = "default-terminal",
150	  .type = OPTIONS_TABLE_STRING,
151	  .default_str = "screen"
152	},
153
154	{ .name = "destroy-unattached",
155	  .type = OPTIONS_TABLE_FLAG,
156	  .default_num = 0
157	},
158
159	{ .name = "detach-on-destroy",
160	  .type = OPTIONS_TABLE_FLAG,
161	  .default_num = 1
162	},
163
164	{ .name = "display-panes-active-colour",
165	  .type = OPTIONS_TABLE_COLOUR,
166	  .default_num = 1
167	},
168
169	{ .name = "display-panes-colour",
170	  .type = OPTIONS_TABLE_COLOUR,
171	  .default_num = 4
172	},
173
174	{ .name = "display-panes-time",
175	  .type = OPTIONS_TABLE_NUMBER,
176	  .minimum = 1,
177	  .maximum = INT_MAX,
178	  .default_num = 1000
179	},
180
181	{ .name = "display-time",
182	  .type = OPTIONS_TABLE_NUMBER,
183	  .minimum = 1,
184	  .maximum = INT_MAX,
185	  .default_num = 750
186	},
187
188	{ .name = "history-limit",
189	  .type = OPTIONS_TABLE_NUMBER,
190	  .minimum = 0,
191	  .maximum = INT_MAX,
192	  .default_num = 2000
193	},
194
195	{ .name = "lock-after-time",
196	  .type = OPTIONS_TABLE_NUMBER,
197	  .minimum = 0,
198	  .maximum = INT_MAX,
199	  .default_num = 0
200	},
201
202	{ .name = "lock-command",
203	  .type = OPTIONS_TABLE_STRING,
204	  .default_str = "lock -np"
205	},
206
207	{ .name = "lock-server",
208	  .type = OPTIONS_TABLE_FLAG,
209	  .default_num = 1
210	},
211
212	{ .name = "message-attr",
213	  .type = OPTIONS_TABLE_ATTRIBUTES,
214	  .default_num = 0,
215	  .style = "message-style"
216	},
217
218	{ .name = "message-bg",
219	  .type = OPTIONS_TABLE_COLOUR,
220	  .default_num = 3,
221	  .style = "message-style"
222	},
223
224	{ .name = "message-command-attr",
225	  .type = OPTIONS_TABLE_ATTRIBUTES,
226	  .default_num = 0,
227	  .style = "message-command-style"
228	},
229
230	{ .name = "message-command-bg",
231	  .type = OPTIONS_TABLE_COLOUR,
232	  .default_num = 0,
233	  .style = "message-command-style"
234	},
235
236	{ .name = "message-command-fg",
237	  .type = OPTIONS_TABLE_COLOUR,
238	  .default_num = 3,
239	  .style = "message-command-style"
240	},
241
242	{ .name = "message-command-style",
243	  .type = OPTIONS_TABLE_STYLE,
244	  .default_str = "bg=black,fg=yellow"
245	},
246
247	{ .name = "message-fg",
248	  .type = OPTIONS_TABLE_COLOUR,
249	  .default_num = 0,
250	  .style = "message-style"
251	},
252
253	{ .name = "message-style",
254	  .type = OPTIONS_TABLE_STYLE,
255	  .default_str = "bg=yellow,fg=black"
256	},
257
258	{ .name = "mouse-resize-pane",
259	  .type = OPTIONS_TABLE_FLAG,
260	  .default_num = 0
261	},
262
263	{ .name = "mouse-select-pane",
264	  .type = OPTIONS_TABLE_FLAG,
265	  .default_num = 0
266	},
267
268	{ .name = "mouse-select-window",
269	  .type = OPTIONS_TABLE_FLAG,
270	  .default_num = 0
271	},
272
273	{ .name = "mouse-utf8",
274	  .type = OPTIONS_TABLE_FLAG,
275	  .default_num = 0
276	},
277
278	{ .name = "pane-active-border-bg",
279	  .type = OPTIONS_TABLE_COLOUR,
280	  .default_num = 8,
281	  .style = "pane-active-border-style"
282	},
283
284	{ .name = "pane-active-border-fg",
285	  .type = OPTIONS_TABLE_COLOUR,
286	  .default_num = 2,
287	  .style = "pane-active-border-style"
288	},
289
290	{ .name = "pane-active-border-style",
291	  .type = OPTIONS_TABLE_STYLE,
292	  .default_str = "fg=green"
293	},
294
295	{ .name = "pane-border-bg",
296	  .type = OPTIONS_TABLE_COLOUR,
297	  .default_num = 8,
298	  .style = "pane-border-style"
299	},
300
301	{ .name = "pane-border-fg",
302	  .type = OPTIONS_TABLE_COLOUR,
303	  .default_num = 8,
304	  .style = "pane-border-style"
305	},
306
307	{ .name = "pane-border-style",
308	  .type = OPTIONS_TABLE_STYLE,
309	  .default_str = "default"
310	},
311
312	{ .name = "prefix",
313	  .type = OPTIONS_TABLE_KEY,
314	  .default_num = '\002',
315	},
316
317	{ .name = "prefix2",
318	  .type = OPTIONS_TABLE_KEY,
319	  .default_num = KEYC_NONE,
320	},
321
322	{ .name = "renumber-windows",
323	  .type = OPTIONS_TABLE_FLAG,
324	  .default_num = 0
325	},
326
327	{ .name = "repeat-time",
328	  .type = OPTIONS_TABLE_NUMBER,
329	  .minimum = 0,
330	  .maximum = SHRT_MAX,
331	  .default_num = 500
332	},
333
334	{ .name = "set-remain-on-exit",
335	  .type = OPTIONS_TABLE_FLAG,
336	  .default_num = 0
337	},
338
339	{ .name = "set-titles",
340	  .type = OPTIONS_TABLE_FLAG,
341	  .default_num = 0
342	},
343
344	{ .name = "set-titles-string",
345	  .type = OPTIONS_TABLE_STRING,
346	  .default_str = "#S:#I:#W - \"#T\""
347	},
348
349	{ .name = "status",
350	  .type = OPTIONS_TABLE_FLAG,
351	  .default_num = 1
352	},
353
354	{ .name = "status-attr",
355	  .type = OPTIONS_TABLE_ATTRIBUTES,
356	  .default_num = 0,
357	  .style = "status-style"
358	},
359
360	{ .name = "status-bg",
361	  .type = OPTIONS_TABLE_COLOUR,
362	  .default_num = 2,
363	  .style = "status-style"
364	},
365
366	{ .name = "status-fg",
367	  .type = OPTIONS_TABLE_COLOUR,
368	  .default_num = 0,
369	  .style = "status-style"
370	},
371
372	{ .name = "status-interval",
373	  .type = OPTIONS_TABLE_NUMBER,
374	  .minimum = 0,
375	  .maximum = INT_MAX,
376	  .default_num = 15
377	},
378
379	{ .name = "status-justify",
380	  .type = OPTIONS_TABLE_CHOICE,
381	  .choices = options_table_status_justify_list,
382	  .default_num = 0
383	},
384
385	{ .name = "status-keys",
386	  .type = OPTIONS_TABLE_CHOICE,
387	  .choices = options_table_status_keys_list,
388	  .default_num = MODEKEY_EMACS
389	},
390
391	{ .name = "status-left",
392	  .type = OPTIONS_TABLE_STRING,
393	  .default_str = "[#S]"
394	},
395
396	{ .name = "status-left-attr",
397	  .type = OPTIONS_TABLE_ATTRIBUTES,
398	  .default_num = 0,
399	  .style = "status-left-style"
400	},
401
402	{ .name = "status-left-bg",
403	  .type = OPTIONS_TABLE_COLOUR,
404	  .default_num = 8,
405	  .style = "status-left-style"
406	},
407
408	{ .name = "status-left-fg",
409	  .type = OPTIONS_TABLE_COLOUR,
410	  .default_num = 8,
411	  .style = "status-left-style"
412	},
413
414	{ .name = "status-left-length",
415	  .type = OPTIONS_TABLE_NUMBER,
416	  .minimum = 0,
417	  .maximum = SHRT_MAX,
418	  .default_num = 10
419	},
420
421	{ .name = "status-left-style",
422	  .type = OPTIONS_TABLE_STYLE,
423	  .default_str = "default"
424	},
425
426	{ .name = "status-position",
427	  .type = OPTIONS_TABLE_CHOICE,
428	  .choices = options_table_status_position_list,
429	  .default_num = 1
430	},
431
432	{ .name = "status-right",
433	  .type = OPTIONS_TABLE_STRING,
434	  .default_str = "\"#{=22:pane_title}\" %H:%M %d-%b-%y"
435	},
436
437	{ .name = "status-right-attr",
438	  .type = OPTIONS_TABLE_ATTRIBUTES,
439	  .default_num = 0,
440	  .style = "status-right-style"
441	},
442
443	{ .name = "status-right-bg",
444	  .type = OPTIONS_TABLE_COLOUR,
445	  .default_num = 8,
446	  .style = "status-right-style"
447	},
448
449	{ .name = "status-right-fg",
450	  .type = OPTIONS_TABLE_COLOUR,
451	  .default_num = 8,
452	  .style = "status-right-style"
453	},
454
455	{ .name = "status-right-length",
456	  .type = OPTIONS_TABLE_NUMBER,
457	  .minimum = 0,
458	  .maximum = SHRT_MAX,
459	  .default_num = 40
460	},
461
462	{ .name = "status-right-style",
463	  .type = OPTIONS_TABLE_STYLE,
464	  .default_str = "default"
465	},
466
467	{ .name = "status-style",
468	  .type = OPTIONS_TABLE_STYLE,
469	  .default_str = "bg=green,fg=black"
470	},
471
472	{ .name = "status-utf8",
473	  .type = OPTIONS_TABLE_FLAG,
474	  .default_num = 0 /* overridden in main() */
475	},
476
477	{ .name = "update-environment",
478	  .type = OPTIONS_TABLE_STRING,
479	  .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
480	                 "SSH_CONNECTION WINDOWID XAUTHORITY"
481
482	},
483
484	{ .name = "visual-activity",
485	  .type = OPTIONS_TABLE_FLAG,
486	  .default_num = 0
487	},
488
489	{ .name = "visual-bell",
490	  .type = OPTIONS_TABLE_FLAG,
491	  .default_num = 0
492	},
493
494	{ .name = "visual-silence",
495	  .type = OPTIONS_TABLE_FLAG,
496	  .default_num = 0
497	},
498
499	{ .name = "word-separators",
500	  .type = OPTIONS_TABLE_STRING,
501	  .default_str = " -_@"
502	},
503
504	{ .name = NULL }
505};
506
507/* Window options. */
508const struct options_table_entry window_options_table[] = {
509	{ .name = "aggressive-resize",
510	  .type = OPTIONS_TABLE_FLAG,
511	  .default_num = 0
512	},
513
514	{ .name = "allow-rename",
515	  .type = OPTIONS_TABLE_FLAG,
516	  .default_num = 1
517	},
518
519	{ .name = "alternate-screen",
520	  .type = OPTIONS_TABLE_FLAG,
521	  .default_num = 1
522	},
523
524	{ .name = "automatic-rename",
525	  .type = OPTIONS_TABLE_FLAG,
526	  .default_num = 1
527	},
528
529	{ .name = "automatic-rename-format",
530	  .type = OPTIONS_TABLE_STRING,
531	  .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}"
532	                 "#{?pane_dead,[dead],}"
533	},
534
535	{ .name = "c0-change-trigger",
536	  .type = OPTIONS_TABLE_NUMBER,
537	  .default_num = 250,
538	  .minimum = 0,
539	  .maximum = USHRT_MAX
540	},
541
542	{ .name = "c0-change-interval",
543	  .type = OPTIONS_TABLE_NUMBER,
544	  .default_num = 100,
545	  .minimum = 1,
546	  .maximum = USHRT_MAX
547	},
548
549	{ .name = "clock-mode-colour",
550	  .type = OPTIONS_TABLE_COLOUR,
551	  .default_num = 4
552	},
553
554	{ .name = "clock-mode-style",
555	  .type = OPTIONS_TABLE_CHOICE,
556	  .choices = options_table_clock_mode_style_list,
557	  .default_num = 1
558	},
559
560	{ .name = "force-height",
561	  .type = OPTIONS_TABLE_NUMBER,
562	  .minimum = 0,
563	  .maximum = INT_MAX,
564	  .default_num = 0
565	},
566
567	{ .name = "force-width",
568	  .type = OPTIONS_TABLE_NUMBER,
569	  .minimum = 0,
570	  .maximum = INT_MAX,
571	  .default_num = 0
572	},
573
574	{ .name = "main-pane-height",
575	  .type = OPTIONS_TABLE_NUMBER,
576	  .minimum = 1,
577	  .maximum = INT_MAX,
578	  .default_num = 24
579	},
580
581	{ .name = "main-pane-width",
582	  .type = OPTIONS_TABLE_NUMBER,
583	  .minimum = 1,
584	  .maximum = INT_MAX,
585	  .default_num = 80
586	},
587
588	{ .name = "mode-attr",
589	  .type = OPTIONS_TABLE_ATTRIBUTES,
590	  .default_num = 0,
591	  .style = "mode-style"
592	},
593
594	{ .name = "mode-bg",
595	  .type = OPTIONS_TABLE_COLOUR,
596	  .default_num = 3,
597	  .style = "mode-style"
598	},
599
600	{ .name = "mode-fg",
601	  .type = OPTIONS_TABLE_COLOUR,
602	  .default_num = 0,
603	  .style = "mode-style"
604	},
605
606	{ .name = "mode-keys",
607	  .type = OPTIONS_TABLE_CHOICE,
608	  .choices = options_table_mode_keys_list,
609	  .default_num = MODEKEY_EMACS
610	},
611
612	{ .name = "mode-mouse",
613	  .type = OPTIONS_TABLE_CHOICE,
614	  .choices = options_table_mode_mouse_list,
615	  .default_num = 0
616	},
617
618	{ .name = "mode-style",
619	  .type = OPTIONS_TABLE_STYLE,
620	  .default_str = "bg=yellow,fg=black"
621	},
622
623	{ .name = "monitor-activity",
624	  .type = OPTIONS_TABLE_FLAG,
625	  .default_num = 0
626	},
627
628	{ .name = "monitor-silence",
629	  .type = OPTIONS_TABLE_NUMBER,
630	  .minimum = 0,
631	  .maximum = INT_MAX,
632	  .default_num = 0
633	},
634
635	{ .name = "other-pane-height",
636	  .type = OPTIONS_TABLE_NUMBER,
637	  .minimum = 0,
638	  .maximum = INT_MAX,
639	  .default_num = 0
640	},
641
642	{ .name = "other-pane-width",
643	  .type = OPTIONS_TABLE_NUMBER,
644	  .minimum = 0,
645	  .maximum = INT_MAX,
646	  .default_num = 0
647	},
648
649	{ .name = "pane-base-index",
650	  .type = OPTIONS_TABLE_NUMBER,
651	  .minimum = 0,
652	  .maximum = USHRT_MAX,
653	  .default_num = 0
654	},
655
656	{ .name = "remain-on-exit",
657	  .type = OPTIONS_TABLE_FLAG,
658	  .default_num = 0
659	},
660
661	{ .name = "synchronize-panes",
662	  .type = OPTIONS_TABLE_FLAG,
663	  .default_num = 0
664	},
665
666	{ .name = "utf8",
667	  .type = OPTIONS_TABLE_FLAG,
668	  .default_num = 0 /* overridden in main() */
669	},
670
671	{ .name = "window-status-activity-attr",
672	  .type = OPTIONS_TABLE_ATTRIBUTES,
673	  .default_num = GRID_ATTR_REVERSE,
674	  .style = "window-status-activity-style"
675	},
676
677	{ .name = "window-status-activity-bg",
678	  .type = OPTIONS_TABLE_COLOUR,
679	  .default_num = 8,
680	  .style = "window-status-activity-style"
681	},
682
683	{ .name = "window-status-activity-fg",
684	  .type = OPTIONS_TABLE_COLOUR,
685	  .default_num = 8,
686	  .style = "window-status-activity-style"
687	},
688
689	{ .name = "window-status-activity-style",
690	  .type = OPTIONS_TABLE_STYLE,
691	  .default_str = "reverse"
692	},
693
694	{ .name = "window-status-attr",
695	  .type = OPTIONS_TABLE_ATTRIBUTES,
696	  .default_num = 0,
697	  .style = "window-status-style"
698	},
699
700	{ .name = "window-status-bell-attr",
701	  .type = OPTIONS_TABLE_ATTRIBUTES,
702	  .default_num = GRID_ATTR_REVERSE,
703	  .style = "window-status-bell-style"
704	},
705
706	{ .name = "window-status-bell-bg",
707	  .type = OPTIONS_TABLE_COLOUR,
708	  .default_num = 8,
709	  .style = "window-status-bell-style"
710	},
711
712	{ .name = "window-status-bell-fg",
713	  .type = OPTIONS_TABLE_COLOUR,
714	  .default_num = 8,
715	  .style = "window-status-bell-style"
716	},
717
718	{ .name = "window-status-bell-style",
719	  .type = OPTIONS_TABLE_STYLE,
720	  .default_str = "reverse"
721	},
722
723	{ .name = "window-status-bg",
724	  .type = OPTIONS_TABLE_COLOUR,
725	  .default_num = 8,
726	  .style = "window-status-style"
727	},
728
729	{ .name = "window-status-current-attr",
730	  .type = OPTIONS_TABLE_ATTRIBUTES,
731	  .default_num = 0,
732	  .style = "window-status-current-style"
733	},
734
735	{ .name = "window-status-current-bg",
736	  .type = OPTIONS_TABLE_COLOUR,
737	  .default_num = 8,
738	  .style = "window-status-current-style"
739	},
740
741	{ .name = "window-status-current-fg",
742	  .type = OPTIONS_TABLE_COLOUR,
743	  .default_num = 8,
744	  .style = "window-status-current-style"
745	},
746
747	{ .name = "window-status-current-format",
748	  .type = OPTIONS_TABLE_STRING,
749	  .default_str = "#I:#W#F"
750	},
751
752	{ .name = "window-status-current-style",
753	  .type = OPTIONS_TABLE_STYLE,
754	  .default_str = "default"
755	},
756
757	{ .name = "window-status-fg",
758	  .type = OPTIONS_TABLE_COLOUR,
759	  .default_num = 8,
760	  .style = "window-status-style"
761	},
762
763	{ .name = "window-status-format",
764	  .type = OPTIONS_TABLE_STRING,
765	  .default_str = "#I:#W#F"
766	},
767
768	{ .name = "window-status-last-attr",
769	  .type = OPTIONS_TABLE_ATTRIBUTES,
770	  .default_num = 0,
771	  .style = "window-status-last-style"
772	},
773
774	{ .name = "window-status-last-bg",
775	  .type = OPTIONS_TABLE_COLOUR,
776	  .default_num = 8,
777	  .style = "window-status-last-style"
778	},
779
780	{ .name = "window-status-last-fg",
781	  .type = OPTIONS_TABLE_COLOUR,
782	  .default_num = 8,
783	  .style = "window-status-last-style"
784	},
785
786	{ .name = "window-status-last-style",
787	  .type = OPTIONS_TABLE_STYLE,
788	  .default_str = "default"
789	},
790
791	{ .name = "window-status-separator",
792	  .type = OPTIONS_TABLE_STRING,
793	  .default_str = " "
794	},
795
796	{ .name = "window-status-style",
797	  .type = OPTIONS_TABLE_STYLE,
798	  .default_str = "default"
799	},
800
801	{ .name = "wrap-search",
802	  .type = OPTIONS_TABLE_FLAG,
803	  .default_num = 1
804	},
805
806	{ .name = "xterm-keys",
807	  .type = OPTIONS_TABLE_FLAG,
808	  .default_num = 0
809	},
810
811	{ .name = NULL }
812};
813
814/* Populate an options tree from a table. */
815void
816options_table_populate_tree(
817    const struct options_table_entry *table, struct options *oo)
818{
819	const struct options_table_entry	*oe;
820
821	for (oe = table; oe->name != NULL; oe++) {
822		switch (oe->type) {
823		case OPTIONS_TABLE_STRING:
824			options_set_string(oo, oe->name, "%s", oe->default_str);
825			break;
826		case OPTIONS_TABLE_STYLE:
827			options_set_style(oo, oe->name, oe->default_str, 0);
828			break;
829		default:
830			options_set_number(oo, oe->name, oe->default_num);
831			break;
832		}
833	}
834}
835
836/* Print an option using its type from the table. */
837const char *
838options_table_print_entry(const struct options_table_entry *oe,
839    struct options_entry *o, int no_quotes)
840{
841	static char	 out[BUFSIZ];
842	const char	*s;
843
844	*out = '\0';
845	switch (oe->type) {
846	case OPTIONS_TABLE_STRING:
847		if (no_quotes)
848			xsnprintf(out, sizeof out, "%s", o->str);
849		else
850			xsnprintf(out, sizeof out, "\"%s\"", o->str);
851		break;
852	case OPTIONS_TABLE_NUMBER:
853		xsnprintf(out, sizeof out, "%lld", o->num);
854		break;
855	case OPTIONS_TABLE_KEY:
856		xsnprintf(out, sizeof out, "%s",
857		    key_string_lookup_key(o->num));
858		break;
859	case OPTIONS_TABLE_COLOUR:
860		s = colour_tostring(o->num);
861		xsnprintf(out, sizeof out, "%s", s);
862		break;
863	case OPTIONS_TABLE_ATTRIBUTES:
864		s = attributes_tostring(o->num);
865		xsnprintf(out, sizeof out, "%s", s);
866		break;
867	case OPTIONS_TABLE_FLAG:
868		if (o->num)
869			strlcpy(out, "on", sizeof out);
870		else
871			strlcpy(out, "off", sizeof out);
872		break;
873	case OPTIONS_TABLE_CHOICE:
874		s = oe->choices[o->num];
875		xsnprintf(out, sizeof out, "%s", s);
876		break;
877	case OPTIONS_TABLE_STYLE:
878		s = style_tostring(&o->style);
879		xsnprintf(out, sizeof out, "%s", s);
880		break;
881	}
882	return (out);
883}
884
885/* Find an option. */
886int
887options_table_find(
888    const char *optstr, const struct options_table_entry **table,
889    const struct options_table_entry **oe)
890{
891	static const struct options_table_entry	*tables[] = {
892		server_options_table,
893		window_options_table,
894		session_options_table
895	};
896	const struct options_table_entry	*oe_loop;
897	u_int					 i;
898
899	for (i = 0; i < nitems(tables); i++) {
900		for (oe_loop = tables[i]; oe_loop->name != NULL; oe_loop++) {
901			if (strncmp(oe_loop->name, optstr, strlen(optstr)) != 0)
902				continue;
903
904			/* If already found, ambiguous. */
905			if (*oe != NULL)
906				return (-1);
907			*oe = oe_loop;
908			*table = tables[i];
909
910			/* Bail now if an exact match. */
911			if (strcmp((*oe)->name, optstr) == 0)
912				break;
913		}
914	}
915	return (0);
916}
917