options-table.c revision 1.53
1/* $OpenBSD: options-table.c,v 1.53 2015/02/06 15:09:34 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 = "prefix",
279	  .type = OPTIONS_TABLE_KEY,
280	  .default_num = '\002',
281	},
282
283	{ .name = "prefix2",
284	  .type = OPTIONS_TABLE_KEY,
285	  .default_num = KEYC_NONE,
286	},
287
288	{ .name = "renumber-windows",
289	  .type = OPTIONS_TABLE_FLAG,
290	  .default_num = 0
291	},
292
293	{ .name = "repeat-time",
294	  .type = OPTIONS_TABLE_NUMBER,
295	  .minimum = 0,
296	  .maximum = SHRT_MAX,
297	  .default_num = 500
298	},
299
300	{ .name = "set-remain-on-exit",
301	  .type = OPTIONS_TABLE_FLAG,
302	  .default_num = 0
303	},
304
305	{ .name = "set-titles",
306	  .type = OPTIONS_TABLE_FLAG,
307	  .default_num = 0
308	},
309
310	{ .name = "set-titles-string",
311	  .type = OPTIONS_TABLE_STRING,
312	  .default_str = "#S:#I:#W - \"#T\""
313	},
314
315	{ .name = "status",
316	  .type = OPTIONS_TABLE_FLAG,
317	  .default_num = 1
318	},
319
320	{ .name = "status-attr",
321	  .type = OPTIONS_TABLE_ATTRIBUTES,
322	  .default_num = 0,
323	  .style = "status-style"
324	},
325
326	{ .name = "status-bg",
327	  .type = OPTIONS_TABLE_COLOUR,
328	  .default_num = 2,
329	  .style = "status-style"
330	},
331
332	{ .name = "status-fg",
333	  .type = OPTIONS_TABLE_COLOUR,
334	  .default_num = 0,
335	  .style = "status-style"
336	},
337
338	{ .name = "status-interval",
339	  .type = OPTIONS_TABLE_NUMBER,
340	  .minimum = 0,
341	  .maximum = INT_MAX,
342	  .default_num = 15
343	},
344
345	{ .name = "status-justify",
346	  .type = OPTIONS_TABLE_CHOICE,
347	  .choices = options_table_status_justify_list,
348	  .default_num = 0
349	},
350
351	{ .name = "status-keys",
352	  .type = OPTIONS_TABLE_CHOICE,
353	  .choices = options_table_status_keys_list,
354	  .default_num = MODEKEY_EMACS
355	},
356
357	{ .name = "status-left",
358	  .type = OPTIONS_TABLE_STRING,
359	  .default_str = "[#S] "
360	},
361
362	{ .name = "status-left-attr",
363	  .type = OPTIONS_TABLE_ATTRIBUTES,
364	  .default_num = 0,
365	  .style = "status-left-style"
366	},
367
368	{ .name = "status-left-bg",
369	  .type = OPTIONS_TABLE_COLOUR,
370	  .default_num = 8,
371	  .style = "status-left-style"
372	},
373
374	{ .name = "status-left-fg",
375	  .type = OPTIONS_TABLE_COLOUR,
376	  .default_num = 8,
377	  .style = "status-left-style"
378	},
379
380	{ .name = "status-left-length",
381	  .type = OPTIONS_TABLE_NUMBER,
382	  .minimum = 0,
383	  .maximum = SHRT_MAX,
384	  .default_num = 10
385	},
386
387	{ .name = "status-left-style",
388	  .type = OPTIONS_TABLE_STYLE,
389	  .default_str = "default"
390	},
391
392	{ .name = "status-position",
393	  .type = OPTIONS_TABLE_CHOICE,
394	  .choices = options_table_status_position_list,
395	  .default_num = 1
396	},
397
398	{ .name = "status-right",
399	  .type = OPTIONS_TABLE_STRING,
400	  .default_str = " \"#{=21:pane_title}\" %H:%M %d-%b-%y"
401	},
402
403	{ .name = "status-right-attr",
404	  .type = OPTIONS_TABLE_ATTRIBUTES,
405	  .default_num = 0,
406	  .style = "status-right-style"
407	},
408
409	{ .name = "status-right-bg",
410	  .type = OPTIONS_TABLE_COLOUR,
411	  .default_num = 8,
412	  .style = "status-right-style"
413	},
414
415	{ .name = "status-right-fg",
416	  .type = OPTIONS_TABLE_COLOUR,
417	  .default_num = 8,
418	  .style = "status-right-style"
419	},
420
421	{ .name = "status-right-length",
422	  .type = OPTIONS_TABLE_NUMBER,
423	  .minimum = 0,
424	  .maximum = SHRT_MAX,
425	  .default_num = 40
426	},
427
428	{ .name = "status-right-style",
429	  .type = OPTIONS_TABLE_STYLE,
430	  .default_str = "default"
431	},
432
433	{ .name = "status-style",
434	  .type = OPTIONS_TABLE_STYLE,
435	  .default_str = "bg=green,fg=black"
436	},
437
438	{ .name = "status-utf8",
439	  .type = OPTIONS_TABLE_FLAG,
440	  .default_num = 0 /* overridden in main() */
441	},
442
443	{ .name = "update-environment",
444	  .type = OPTIONS_TABLE_STRING,
445	  .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
446	                 "SSH_CONNECTION WINDOWID XAUTHORITY"
447
448	},
449
450	{ .name = "visual-activity",
451	  .type = OPTIONS_TABLE_FLAG,
452	  .default_num = 0
453	},
454
455	{ .name = "visual-bell",
456	  .type = OPTIONS_TABLE_FLAG,
457	  .default_num = 0
458	},
459
460	{ .name = "visual-silence",
461	  .type = OPTIONS_TABLE_FLAG,
462	  .default_num = 0
463	},
464
465	{ .name = "word-separators",
466	  .type = OPTIONS_TABLE_STRING,
467	  .default_str = " -_@"
468	},
469
470	{ .name = NULL }
471};
472
473/* Window options. */
474const struct options_table_entry window_options_table[] = {
475	{ .name = "aggressive-resize",
476	  .type = OPTIONS_TABLE_FLAG,
477	  .default_num = 0
478	},
479
480	{ .name = "allow-rename",
481	  .type = OPTIONS_TABLE_FLAG,
482	  .default_num = 1
483	},
484
485	{ .name = "alternate-screen",
486	  .type = OPTIONS_TABLE_FLAG,
487	  .default_num = 1
488	},
489
490	{ .name = "automatic-rename",
491	  .type = OPTIONS_TABLE_FLAG,
492	  .default_num = 1
493	},
494
495	{ .name = "automatic-rename-format",
496	  .type = OPTIONS_TABLE_STRING,
497	  .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}"
498	                 "#{?pane_dead,[dead],}"
499	},
500
501	{ .name = "c0-change-trigger",
502	  .type = OPTIONS_TABLE_NUMBER,
503	  .default_num = 250,
504	  .minimum = 0,
505	  .maximum = USHRT_MAX
506	},
507
508	{ .name = "c0-change-interval",
509	  .type = OPTIONS_TABLE_NUMBER,
510	  .default_num = 100,
511	  .minimum = 1,
512	  .maximum = USHRT_MAX
513	},
514
515	{ .name = "clock-mode-colour",
516	  .type = OPTIONS_TABLE_COLOUR,
517	  .default_num = 4
518	},
519
520	{ .name = "clock-mode-style",
521	  .type = OPTIONS_TABLE_CHOICE,
522	  .choices = options_table_clock_mode_style_list,
523	  .default_num = 1
524	},
525
526	{ .name = "force-height",
527	  .type = OPTIONS_TABLE_NUMBER,
528	  .minimum = 0,
529	  .maximum = INT_MAX,
530	  .default_num = 0
531	},
532
533	{ .name = "force-width",
534	  .type = OPTIONS_TABLE_NUMBER,
535	  .minimum = 0,
536	  .maximum = INT_MAX,
537	  .default_num = 0
538	},
539
540	{ .name = "main-pane-height",
541	  .type = OPTIONS_TABLE_NUMBER,
542	  .minimum = 1,
543	  .maximum = INT_MAX,
544	  .default_num = 24
545	},
546
547	{ .name = "main-pane-width",
548	  .type = OPTIONS_TABLE_NUMBER,
549	  .minimum = 1,
550	  .maximum = INT_MAX,
551	  .default_num = 80
552	},
553
554	{ .name = "mode-attr",
555	  .type = OPTIONS_TABLE_ATTRIBUTES,
556	  .default_num = 0,
557	  .style = "mode-style"
558	},
559
560	{ .name = "mode-bg",
561	  .type = OPTIONS_TABLE_COLOUR,
562	  .default_num = 3,
563	  .style = "mode-style"
564	},
565
566	{ .name = "mode-fg",
567	  .type = OPTIONS_TABLE_COLOUR,
568	  .default_num = 0,
569	  .style = "mode-style"
570	},
571
572	{ .name = "mode-keys",
573	  .type = OPTIONS_TABLE_CHOICE,
574	  .choices = options_table_mode_keys_list,
575	  .default_num = MODEKEY_EMACS
576	},
577
578	{ .name = "mode-mouse",
579	  .type = OPTIONS_TABLE_CHOICE,
580	  .choices = options_table_mode_mouse_list,
581	  .default_num = 0
582	},
583
584	{ .name = "mode-style",
585	  .type = OPTIONS_TABLE_STYLE,
586	  .default_str = "bg=yellow,fg=black"
587	},
588
589	{ .name = "monitor-activity",
590	  .type = OPTIONS_TABLE_FLAG,
591	  .default_num = 0
592	},
593
594	{ .name = "monitor-silence",
595	  .type = OPTIONS_TABLE_NUMBER,
596	  .minimum = 0,
597	  .maximum = INT_MAX,
598	  .default_num = 0
599	},
600
601	{ .name = "other-pane-height",
602	  .type = OPTIONS_TABLE_NUMBER,
603	  .minimum = 0,
604	  .maximum = INT_MAX,
605	  .default_num = 0
606	},
607
608	{ .name = "other-pane-width",
609	  .type = OPTIONS_TABLE_NUMBER,
610	  .minimum = 0,
611	  .maximum = INT_MAX,
612	  .default_num = 0
613	},
614
615	{ .name = "pane-active-border-bg",
616	  .type = OPTIONS_TABLE_COLOUR,
617	  .default_num = 8,
618	  .style = "pane-active-border-style"
619	},
620
621	{ .name = "pane-active-border-fg",
622	  .type = OPTIONS_TABLE_COLOUR,
623	  .default_num = 2,
624	  .style = "pane-active-border-style"
625	},
626
627	{ .name = "pane-active-border-style",
628	  .type = OPTIONS_TABLE_STYLE,
629	  .default_str = "fg=green"
630	},
631
632	{ .name = "pane-base-index",
633	  .type = OPTIONS_TABLE_NUMBER,
634	  .minimum = 0,
635	  .maximum = USHRT_MAX,
636	  .default_num = 0
637	},
638
639	{ .name = "pane-border-bg",
640	  .type = OPTIONS_TABLE_COLOUR,
641	  .default_num = 8,
642	  .style = "pane-border-style"
643	},
644
645	{ .name = "pane-border-fg",
646	  .type = OPTIONS_TABLE_COLOUR,
647	  .default_num = 8,
648	  .style = "pane-border-style"
649	},
650
651	{ .name = "pane-border-style",
652	  .type = OPTIONS_TABLE_STYLE,
653	  .default_str = "default"
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