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