options-table.c revision 1.48
1/* $OpenBSD: options-table.c,v 1.48 2014/04/17 07:55:43 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 loop up the real type when
32 * the 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}}#{?pane_dead,[dead],}"
532	},
533
534	{ .name = "c0-change-trigger",
535	  .type = OPTIONS_TABLE_NUMBER,
536	  .default_num = 250,
537	  .minimum = 0,
538	  .maximum = USHRT_MAX
539	},
540
541	{ .name = "c0-change-interval",
542	  .type = OPTIONS_TABLE_NUMBER,
543	  .default_num = 100,
544	  .minimum = 1,
545	  .maximum = USHRT_MAX
546	},
547
548	{ .name = "clock-mode-colour",
549	  .type = OPTIONS_TABLE_COLOUR,
550	  .default_num = 4
551	},
552
553	{ .name = "clock-mode-style",
554	  .type = OPTIONS_TABLE_CHOICE,
555	  .choices = options_table_clock_mode_style_list,
556	  .default_num = 1
557	},
558
559	{ .name = "force-height",
560	  .type = OPTIONS_TABLE_NUMBER,
561	  .minimum = 0,
562	  .maximum = INT_MAX,
563	  .default_num = 0
564	},
565
566	{ .name = "force-width",
567	  .type = OPTIONS_TABLE_NUMBER,
568	  .minimum = 0,
569	  .maximum = INT_MAX,
570	  .default_num = 0
571	},
572
573	{ .name = "main-pane-height",
574	  .type = OPTIONS_TABLE_NUMBER,
575	  .minimum = 1,
576	  .maximum = INT_MAX,
577	  .default_num = 24
578	},
579
580	{ .name = "main-pane-width",
581	  .type = OPTIONS_TABLE_NUMBER,
582	  .minimum = 1,
583	  .maximum = INT_MAX,
584	  .default_num = 80
585	},
586
587	{ .name = "mode-attr",
588	  .type = OPTIONS_TABLE_ATTRIBUTES,
589	  .default_num = 0,
590	  .style = "mode-style"
591	},
592
593	{ .name = "mode-bg",
594	  .type = OPTIONS_TABLE_COLOUR,
595	  .default_num = 3,
596	  .style = "mode-style"
597	},
598
599	{ .name = "mode-fg",
600	  .type = OPTIONS_TABLE_COLOUR,
601	  .default_num = 0,
602	  .style = "mode-style"
603	},
604
605	{ .name = "mode-keys",
606	  .type = OPTIONS_TABLE_CHOICE,
607	  .choices = options_table_mode_keys_list,
608	  .default_num = MODEKEY_EMACS
609	},
610
611	{ .name = "mode-mouse",
612	  .type = OPTIONS_TABLE_CHOICE,
613	  .choices = options_table_mode_mouse_list,
614	  .default_num = 0
615	},
616
617	{ .name = "mode-style",
618	  .type = OPTIONS_TABLE_STYLE,
619	  .default_str = "bg=yellow,fg=black"
620	},
621
622	{ .name = "monitor-activity",
623	  .type = OPTIONS_TABLE_FLAG,
624	  .default_num = 0
625	},
626
627	{ .name = "monitor-silence",
628	  .type = OPTIONS_TABLE_NUMBER,
629	  .minimum = 0,
630	  .maximum = INT_MAX,
631	  .default_num = 0
632	},
633
634	{ .name = "other-pane-height",
635	  .type = OPTIONS_TABLE_NUMBER,
636	  .minimum = 0,
637	  .maximum = INT_MAX,
638	  .default_num = 0
639	},
640
641	{ .name = "other-pane-width",
642	  .type = OPTIONS_TABLE_NUMBER,
643	  .minimum = 0,
644	  .maximum = INT_MAX,
645	  .default_num = 0
646	},
647
648	{ .name = "pane-base-index",
649	  .type = OPTIONS_TABLE_NUMBER,
650	  .minimum = 0,
651	  .maximum = USHRT_MAX,
652	  .default_num = 0
653	},
654
655	{ .name = "remain-on-exit",
656	  .type = OPTIONS_TABLE_FLAG,
657	  .default_num = 0
658	},
659
660	{ .name = "synchronize-panes",
661	  .type = OPTIONS_TABLE_FLAG,
662	  .default_num = 0
663	},
664
665	{ .name = "utf8",
666	  .type = OPTIONS_TABLE_FLAG,
667	  .default_num = 0 /* overridden in main() */
668	},
669
670	{ .name = "window-status-activity-attr",
671	  .type = OPTIONS_TABLE_ATTRIBUTES,
672	  .default_num = GRID_ATTR_REVERSE,
673	  .style = "window-status-activity-style"
674	},
675
676	{ .name = "window-status-activity-bg",
677	  .type = OPTIONS_TABLE_COLOUR,
678	  .default_num = 8,
679	  .style = "window-status-activity-style"
680	},
681
682	{ .name = "window-status-activity-fg",
683	  .type = OPTIONS_TABLE_COLOUR,
684	  .default_num = 8,
685	  .style = "window-status-activity-style"
686	},
687
688	{ .name = "window-status-activity-style",
689	  .type = OPTIONS_TABLE_STYLE,
690	  .default_str = "reverse"
691	},
692
693	{ .name = "window-status-attr",
694	  .type = OPTIONS_TABLE_ATTRIBUTES,
695	  .default_num = 0,
696	  .style = "window-status-style"
697	},
698
699	{ .name = "window-status-bell-attr",
700	  .type = OPTIONS_TABLE_ATTRIBUTES,
701	  .default_num = GRID_ATTR_REVERSE,
702	  .style = "window-status-bell-style"
703	},
704
705	{ .name = "window-status-bell-bg",
706	  .type = OPTIONS_TABLE_COLOUR,
707	  .default_num = 8,
708	  .style = "window-status-bell-style"
709	},
710
711	{ .name = "window-status-bell-fg",
712	  .type = OPTIONS_TABLE_COLOUR,
713	  .default_num = 8,
714	  .style = "window-status-bell-style"
715	},
716
717	{ .name = "window-status-bell-style",
718	  .type = OPTIONS_TABLE_STYLE,
719	  .default_str = "reverse"
720	},
721
722	{ .name = "window-status-bg",
723	  .type = OPTIONS_TABLE_COLOUR,
724	  .default_num = 8,
725	  .style = "window-status-style"
726	},
727
728	{ .name = "window-status-current-attr",
729	  .type = OPTIONS_TABLE_ATTRIBUTES,
730	  .default_num = 0,
731	  .style = "window-status-current-style"
732	},
733
734	{ .name = "window-status-current-bg",
735	  .type = OPTIONS_TABLE_COLOUR,
736	  .default_num = 8,
737	  .style = "window-status-current-style"
738	},
739
740	{ .name = "window-status-current-fg",
741	  .type = OPTIONS_TABLE_COLOUR,
742	  .default_num = 8,
743	  .style = "window-status-current-style"
744	},
745
746	{ .name = "window-status-current-format",
747	  .type = OPTIONS_TABLE_STRING,
748	  .default_str = "#I:#W#F"
749	},
750
751	{ .name = "window-status-current-style",
752	  .type = OPTIONS_TABLE_STYLE,
753	  .default_str = "default"
754	},
755
756	{ .name = "window-status-fg",
757	  .type = OPTIONS_TABLE_COLOUR,
758	  .default_num = 8,
759	  .style = "window-status-style"
760	},
761
762	{ .name = "window-status-format",
763	  .type = OPTIONS_TABLE_STRING,
764	  .default_str = "#I:#W#F"
765	},
766
767	{ .name = "window-status-last-attr",
768	  .type = OPTIONS_TABLE_ATTRIBUTES,
769	  .default_num = 0,
770	  .style = "window-status-last-style"
771	},
772
773	{ .name = "window-status-last-bg",
774	  .type = OPTIONS_TABLE_COLOUR,
775	  .default_num = 8,
776	  .style = "window-status-last-style"
777	},
778
779	{ .name = "window-status-last-fg",
780	  .type = OPTIONS_TABLE_COLOUR,
781	  .default_num = 8,
782	  .style = "window-status-last-style"
783	},
784
785	{ .name = "window-status-last-style",
786	  .type = OPTIONS_TABLE_STYLE,
787	  .default_str = "default"
788	},
789
790	{ .name = "window-status-separator",
791	  .type = OPTIONS_TABLE_STRING,
792	  .default_str = " "
793	},
794
795	{ .name = "window-status-style",
796	  .type = OPTIONS_TABLE_STYLE,
797	  .default_str = "default"
798	},
799
800	{ .name = "wrap-search",
801	  .type = OPTIONS_TABLE_FLAG,
802	  .default_num = 1
803	},
804
805	{ .name = "xterm-keys",
806	  .type = OPTIONS_TABLE_FLAG,
807	  .default_num = 0
808	},
809
810	{ .name = NULL }
811};
812
813/* Populate an options tree from a table. */
814void
815options_table_populate_tree(
816    const struct options_table_entry *table, struct options *oo)
817{
818	const struct options_table_entry	*oe;
819
820	for (oe = table; oe->name != NULL; oe++) {
821		switch (oe->type) {
822		case OPTIONS_TABLE_STRING:
823			options_set_string(oo, oe->name, "%s", oe->default_str);
824			break;
825		case OPTIONS_TABLE_STYLE:
826			options_set_style(oo, oe->name, oe->default_str, 0);
827			break;
828		default:
829			options_set_number(oo, oe->name, oe->default_num);
830			break;
831		}
832	}
833}
834
835/* Print an option using its type from the table. */
836const char *
837options_table_print_entry(const struct options_table_entry *oe,
838    struct options_entry *o, int no_quotes)
839{
840	static char	 out[BUFSIZ];
841	const char	*s;
842
843	*out = '\0';
844	switch (oe->type) {
845	case OPTIONS_TABLE_STRING:
846		if (no_quotes)
847			xsnprintf(out, sizeof out, "%s", o->str);
848		else
849			xsnprintf(out, sizeof out, "\"%s\"", o->str);
850		break;
851	case OPTIONS_TABLE_NUMBER:
852		xsnprintf(out, sizeof out, "%lld", o->num);
853		break;
854	case OPTIONS_TABLE_KEY:
855		xsnprintf(out, sizeof out, "%s",
856		    key_string_lookup_key(o->num));
857		break;
858	case OPTIONS_TABLE_COLOUR:
859		s = colour_tostring(o->num);
860		xsnprintf(out, sizeof out, "%s", s);
861		break;
862	case OPTIONS_TABLE_ATTRIBUTES:
863		s = attributes_tostring(o->num);
864		xsnprintf(out, sizeof out, "%s", s);
865		break;
866	case OPTIONS_TABLE_FLAG:
867		if (o->num)
868			strlcpy(out, "on", sizeof out);
869		else
870			strlcpy(out, "off", sizeof out);
871		break;
872	case OPTIONS_TABLE_CHOICE:
873		s = oe->choices[o->num];
874		xsnprintf(out, sizeof out, "%s", s);
875		break;
876	case OPTIONS_TABLE_STYLE:
877		s = style_tostring(&o->style);
878		xsnprintf(out, sizeof out, "%s", s);
879		break;
880	}
881	return (out);
882}
883
884/* Find an option. */
885int
886options_table_find(
887    const char *optstr, const struct options_table_entry **table,
888    const struct options_table_entry **oe)
889{
890	static const struct options_table_entry	*tables[] = {
891		server_options_table,
892		window_options_table,
893		session_options_table
894	};
895	const struct options_table_entry	*oe_loop;
896	u_int					 i;
897
898	for (i = 0; i < nitems(tables); i++) {
899		for (oe_loop = tables[i]; oe_loop->name != NULL; oe_loop++) {
900			if (strncmp(oe_loop->name, optstr, strlen(optstr)) != 0)
901				continue;
902
903			/* If already found, ambiguous. */
904			if (*oe != NULL)
905				return (-1);
906			*oe = oe_loop;
907			*table = tables[i];
908
909			/* Bail now if an exact match. */
910			if (strcmp((*oe)->name, optstr) == 0)
911				break;
912		}
913	}
914	return (0);
915}
916