options-table.c revision 1.20
1/* $OpenBSD: options-table.c,v 1.20 2012/01/29 09:37:02 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 = "quiet",
80	  .type = OPTIONS_TABLE_FLAG,
81	  .default_num = 0 /* overridden in main() */
82	},
83
84	{ .name = "set-clipboard",
85	  .type = OPTIONS_TABLE_FLAG,
86	  .default_num = 1
87	},
88
89	{ .name = NULL }
90};
91
92/* Session options. */
93const struct options_table_entry session_options_table[] = {
94	{ .name = "base-index",
95	  .type = OPTIONS_TABLE_NUMBER,
96	  .minimum = 0,
97	  .maximum = INT_MAX,
98	  .default_num = 0
99	},
100
101	{ .name = "bell-action",
102	  .type = OPTIONS_TABLE_CHOICE,
103	  .choices = options_table_bell_action_list,
104	  .default_num = BELL_ANY
105	},
106
107	{ .name = "bell-on-alert",
108	  .type = OPTIONS_TABLE_FLAG,
109	  .default_num = 0
110	},
111
112	{ .name = "default-command",
113	  .type = OPTIONS_TABLE_STRING,
114	  .default_str = ""
115	},
116
117	{ .name = "default-path",
118	  .type = OPTIONS_TABLE_STRING,
119	  .default_str = ""
120	},
121
122	{ .name = "default-shell",
123	  .type = OPTIONS_TABLE_STRING,
124	  .default_str = _PATH_BSHELL
125	},
126
127	{ .name = "default-terminal",
128	  .type = OPTIONS_TABLE_STRING,
129	  .default_str = "screen"
130	},
131
132	{ .name = "destroy-unattached",
133	  .type = OPTIONS_TABLE_FLAG,
134	  .default_num = 0
135	},
136
137	{ .name = "detach-on-destroy",
138	  .type = OPTIONS_TABLE_FLAG,
139	  .default_num = 1
140	},
141
142	{ .name = "display-panes-active-colour",
143	  .type = OPTIONS_TABLE_COLOUR,
144	  .default_num = 1
145	},
146
147	{ .name = "display-panes-colour",
148	  .type = OPTIONS_TABLE_COLOUR,
149	  .default_num = 4
150	},
151
152	{ .name = "display-panes-time",
153	  .type = OPTIONS_TABLE_NUMBER,
154	  .minimum = 1,
155	  .maximum = INT_MAX,
156	  .default_num = 1000
157	},
158
159	{ .name = "display-time",
160	  .type = OPTIONS_TABLE_NUMBER,
161	  .minimum = 1,
162	  .maximum = INT_MAX,
163	  .default_num = 750
164	},
165
166	{ .name = "history-limit",
167	  .type = OPTIONS_TABLE_NUMBER,
168	  .minimum = 0,
169	  .maximum = INT_MAX,
170	  .default_num = 2000
171	},
172
173	{ .name = "lock-after-time",
174	  .type = OPTIONS_TABLE_NUMBER,
175	  .minimum = 0,
176	  .maximum = INT_MAX,
177	  .default_num = 0
178	},
179
180	{ .name = "lock-command",
181	  .type = OPTIONS_TABLE_STRING,
182	  .default_str = "lock -np"
183	},
184
185	{ .name = "lock-server",
186	  .type = OPTIONS_TABLE_FLAG,
187	  .default_num = 1
188	},
189
190	{ .name = "message-attr",
191	  .type = OPTIONS_TABLE_ATTRIBUTES,
192	  .default_num = 0
193	},
194
195	{ .name = "message-bg",
196	  .type = OPTIONS_TABLE_COLOUR,
197	  .default_num = 3
198	},
199
200	{ .name = "message-command-attr",
201	  .type = OPTIONS_TABLE_ATTRIBUTES,
202	  .default_num = 0
203	},
204
205	{ .name = "message-command-bg",
206	  .type = OPTIONS_TABLE_COLOUR,
207	  .default_num = 0
208	},
209
210	{ .name = "message-command-fg",
211	  .type = OPTIONS_TABLE_COLOUR,
212	  .default_num = 3
213	},
214
215	{ .name = "message-fg",
216	  .type = OPTIONS_TABLE_COLOUR,
217	  .default_num = 0
218	},
219
220	{ .name = "message-limit",
221	  .type = OPTIONS_TABLE_NUMBER,
222	  .minimum = 0,
223	  .maximum = INT_MAX,
224	  .default_num = 20
225	},
226
227	{ .name = "mouse-resize-pane",
228	  .type = OPTIONS_TABLE_FLAG,
229	  .default_num = 0
230	},
231
232	{ .name = "mouse-select-pane",
233	  .type = OPTIONS_TABLE_FLAG,
234	  .default_num = 0
235	},
236
237	{ .name = "mouse-select-window",
238	  .type = OPTIONS_TABLE_FLAG,
239	  .default_num = 0
240	},
241
242	{ .name = "mouse-utf8",
243	  .type = OPTIONS_TABLE_FLAG,
244	  .default_num = 0
245	},
246
247	{ .name = "pane-active-border-bg",
248	  .type = OPTIONS_TABLE_COLOUR,
249	  .default_num = 8
250	},
251
252	{ .name = "pane-active-border-fg",
253	  .type = OPTIONS_TABLE_COLOUR,
254	  .default_num = 2
255	},
256
257	{ .name = "pane-border-bg",
258	  .type = OPTIONS_TABLE_COLOUR,
259	  .default_num = 8
260	},
261
262	{ .name = "pane-border-fg",
263	  .type = OPTIONS_TABLE_COLOUR,
264	  .default_num = 8
265	},
266
267	{ .name = "prefix",
268	  .type = OPTIONS_TABLE_KEY,
269	  .default_num = '\002',
270	},
271
272	{ .name = "prefix2",
273	  .type = OPTIONS_TABLE_KEY,
274	  .default_num = KEYC_NONE,
275	},
276
277	{ .name = "repeat-time",
278	  .type = OPTIONS_TABLE_NUMBER,
279	  .minimum = 0,
280	  .maximum = SHRT_MAX,
281	  .default_num = 500
282	},
283
284	{ .name = "set-remain-on-exit",
285	  .type = OPTIONS_TABLE_FLAG,
286	  .default_num = 0
287	},
288
289	{ .name = "set-titles",
290	  .type = OPTIONS_TABLE_FLAG,
291	  .default_num = 0
292	},
293
294	{ .name = "set-titles-string",
295	  .type = OPTIONS_TABLE_STRING,
296	  .default_str = "#S:#I:#W - \"#T\""
297	},
298
299	{ .name = "status",
300	  .type = OPTIONS_TABLE_FLAG,
301	  .default_num = 1
302	},
303
304	{ .name = "status-attr",
305	  .type = OPTIONS_TABLE_ATTRIBUTES,
306	  .default_num = 0
307	},
308
309	{ .name = "status-bg",
310	  .type = OPTIONS_TABLE_COLOUR,
311	  .default_num = 2
312	},
313
314	{ .name = "status-fg",
315	  .type = OPTIONS_TABLE_COLOUR,
316	  .default_num = 0
317	},
318
319	{ .name = "status-interval",
320	  .type = OPTIONS_TABLE_NUMBER,
321	  .minimum = 0,
322	  .maximum = INT_MAX,
323	  .default_num = 15
324	},
325
326	{ .name = "status-justify",
327	  .type = OPTIONS_TABLE_CHOICE,
328	  .choices = options_table_status_justify_list,
329	  .default_num = 0
330	},
331
332	{ .name = "status-keys",
333	  .type = OPTIONS_TABLE_CHOICE,
334	  .choices = options_table_status_keys_list,
335	  .default_num = MODEKEY_EMACS
336	},
337
338	{ .name = "status-left",
339	  .type = OPTIONS_TABLE_STRING,
340	  .default_str = "[#S]"
341	},
342
343	{ .name = "status-left-attr",
344	  .type = OPTIONS_TABLE_ATTRIBUTES,
345	  .default_num = 0
346	},
347
348	{ .name = "status-left-bg",
349	  .type = OPTIONS_TABLE_COLOUR,
350	  .default_num = 8
351	},
352
353	{ .name = "status-left-fg",
354	  .type = OPTIONS_TABLE_COLOUR,
355	  .default_num = 8
356	},
357
358	{ .name = "status-left-length",
359	  .type = OPTIONS_TABLE_NUMBER,
360	  .minimum = 0,
361	  .maximum = SHRT_MAX,
362	  .default_num = 10
363	},
364
365	{ .name = "status-position",
366	  .type = OPTIONS_TABLE_CHOICE,
367	  .choices = options_table_status_position_list,
368	  .default_num = 1
369	},
370
371	{ .name = "status-right",
372	  .type = OPTIONS_TABLE_STRING,
373	  .default_str = "\"#22T\" %H:%M %d-%b-%y"
374	},
375
376	{ .name = "status-right-attr",
377	  .type = OPTIONS_TABLE_ATTRIBUTES,
378	  .default_num = 0
379	},
380
381	{ .name = "status-right-bg",
382	  .type = OPTIONS_TABLE_COLOUR,
383	  .default_num = 8
384	},
385
386	{ .name = "status-right-fg",
387	  .type = OPTIONS_TABLE_COLOUR,
388	  .default_num = 8
389	},
390
391	{ .name = "status-right-length",
392	  .type = OPTIONS_TABLE_NUMBER,
393	  .minimum = 0,
394	  .maximum = SHRT_MAX,
395	  .default_num = 40
396	},
397
398	{ .name = "status-utf8",
399	  .type = OPTIONS_TABLE_FLAG,
400	  .default_num = 0 /* overridden in main() */
401	},
402
403	{ .name = "terminal-overrides",
404	  .type = OPTIONS_TABLE_STRING,
405	  .default_str = "*88col*:colors=88,*256col*:colors=256"
406	                 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
407	                 ":Cc=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
408			 ":Cs=\\E[%p1%d q:Csr=\\E[2 q,screen*:XT"
409	},
410
411	{ .name = "update-environment",
412	  .type = OPTIONS_TABLE_STRING,
413	  .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
414	                 "SSH_CONNECTION WINDOWID XAUTHORITY"
415
416	},
417
418	{ .name = "visual-activity",
419	  .type = OPTIONS_TABLE_FLAG,
420	  .default_num = 0
421	},
422
423	{ .name = "visual-bell",
424	  .type = OPTIONS_TABLE_FLAG,
425	  .default_num = 0
426	},
427
428	{ .name = "visual-content",
429	  .type = OPTIONS_TABLE_FLAG,
430	  .default_num = 0
431	},
432
433	{ .name = "visual-silence",
434	  .type = OPTIONS_TABLE_FLAG,
435	  .default_num = 0
436	},
437
438	{ .name = "word-separators",
439	  .type = OPTIONS_TABLE_STRING,
440	  .default_str = " -_@"
441	},
442
443	{ .name = NULL }
444};
445
446/* Window options. */
447const struct options_table_entry window_options_table[] = {
448	{ .name = "aggressive-resize",
449	  .type = OPTIONS_TABLE_FLAG,
450	  .default_num = 0
451	},
452
453	{ .name = "allow-rename",
454	  .type = OPTIONS_TABLE_FLAG,
455	  .default_num = 1
456	},
457
458	{ .name = "alternate-screen",
459	  .type = OPTIONS_TABLE_FLAG,
460	  .default_num = 1
461	},
462
463	{ .name = "automatic-rename",
464	  .type = OPTIONS_TABLE_FLAG,
465	  .default_num = 1
466	},
467
468	{ .name = "clock-mode-colour",
469	  .type = OPTIONS_TABLE_COLOUR,
470	  .default_num = 4
471	},
472
473	{ .name = "clock-mode-style",
474	  .type = OPTIONS_TABLE_CHOICE,
475	  .choices = options_table_clock_mode_style_list,
476	  .default_num = 1
477	},
478
479	{ .name = "force-height",
480	  .type = OPTIONS_TABLE_NUMBER,
481	  .minimum = 0,
482	  .maximum = INT_MAX,
483	  .default_num = 0
484	},
485
486	{ .name = "force-width",
487	  .type = OPTIONS_TABLE_NUMBER,
488	  .minimum = 0,
489	  .maximum = INT_MAX,
490	  .default_num = 0
491	},
492
493	{ .name = "main-pane-height",
494	  .type = OPTIONS_TABLE_NUMBER,
495	  .minimum = 1,
496	  .maximum = INT_MAX,
497	  .default_num = 24
498	},
499
500	{ .name = "main-pane-width",
501	  .type = OPTIONS_TABLE_NUMBER,
502	  .minimum = 1,
503	  .maximum = INT_MAX,
504	  .default_num = 80
505	},
506
507	{ .name = "mode-attr",
508	  .type = OPTIONS_TABLE_ATTRIBUTES,
509	  .default_num = 0
510	},
511
512	{ .name = "mode-bg",
513	  .type = OPTIONS_TABLE_COLOUR,
514	  .default_num = 3
515	},
516
517	{ .name = "mode-fg",
518	  .type = OPTIONS_TABLE_COLOUR,
519	  .default_num = 0
520	},
521
522	{ .name = "mode-keys",
523	  .type = OPTIONS_TABLE_CHOICE,
524	  .choices = options_table_mode_keys_list,
525	  .default_num = MODEKEY_EMACS
526	},
527
528	{ .name = "mode-mouse",
529	  .type = OPTIONS_TABLE_CHOICE,
530	  .choices = options_table_mode_mouse_list,
531	  .default_num = 0
532	},
533
534	{ .name = "monitor-activity",
535	  .type = OPTIONS_TABLE_FLAG,
536	  .default_num = 0
537	},
538
539	{ .name = "monitor-content",
540	  .type = OPTIONS_TABLE_STRING,
541	  .default_str = ""
542	},
543
544	{ .name = "monitor-silence",
545	  .type = OPTIONS_TABLE_NUMBER,
546	  .minimum = 0,
547	  .maximum = INT_MAX,
548	  .default_num = 0
549	},
550
551	{ .name = "other-pane-height",
552	  .type = OPTIONS_TABLE_NUMBER,
553	  .minimum = 0,
554	  .maximum = INT_MAX,
555	  .default_num = 0
556	},
557
558	{ .name = "other-pane-width",
559	  .type = OPTIONS_TABLE_NUMBER,
560	  .minimum = 0,
561	  .maximum = INT_MAX,
562	  .default_num = 0
563	},
564
565	{ .name = "pane-base-index",
566	  .type = OPTIONS_TABLE_NUMBER,
567	  .minimum = 0,
568	  .maximum = USHRT_MAX,
569	  .default_num = 0
570	},
571
572	{ .name = "remain-on-exit",
573	  .type = OPTIONS_TABLE_FLAG,
574	  .default_num = 0
575	},
576
577	{ .name = "synchronize-panes",
578	  .type = OPTIONS_TABLE_FLAG,
579	  .default_num = 0
580	},
581
582	{ .name = "utf8",
583	  .type = OPTIONS_TABLE_FLAG,
584	  .default_num = 0 /* overridden in main() */
585	},
586
587	{ .name = "window-status-bell-attr",
588	  .type = OPTIONS_TABLE_ATTRIBUTES,
589	  .default_num = GRID_ATTR_REVERSE
590	},
591
592	{ .name = "window-status-bell-bg",
593	  .type = OPTIONS_TABLE_COLOUR,
594	  .default_num = 8
595	},
596
597	{ .name = "window-status-bell-fg",
598	  .type = OPTIONS_TABLE_COLOUR,
599	  .default_num = 8
600	},
601
602	{ .name = "window-status-content-attr",
603	  .type = OPTIONS_TABLE_ATTRIBUTES,
604	  .default_num = GRID_ATTR_REVERSE
605	},
606
607	{ .name = "window-status-content-bg",
608	  .type = OPTIONS_TABLE_COLOUR,
609	  .default_num = 8
610	},
611
612	{ .name = "window-status-content-fg",
613	  .type = OPTIONS_TABLE_COLOUR,
614	  .default_num = 8
615	},
616
617	{ .name = "window-status-activity-attr",
618	  .type = OPTIONS_TABLE_ATTRIBUTES,
619	  .default_num = GRID_ATTR_REVERSE
620	},
621
622	{ .name = "window-status-activity-bg",
623	  .type = OPTIONS_TABLE_COLOUR,
624	  .default_num = 8
625	},
626
627	{ .name = "window-status-activity-fg",
628	  .type = OPTIONS_TABLE_COLOUR,
629	  .default_num = 8
630	},
631
632	{ .name = "window-status-attr",
633	  .type = OPTIONS_TABLE_ATTRIBUTES,
634	  .default_num = 0
635	},
636
637	{ .name = "window-status-bg",
638	  .type = OPTIONS_TABLE_COLOUR,
639	  .default_num = 8
640	},
641
642	{ .name = "window-status-current-attr",
643	  .type = OPTIONS_TABLE_ATTRIBUTES,
644	  .default_num = 0
645	},
646
647	{ .name = "window-status-current-bg",
648	  .type = OPTIONS_TABLE_COLOUR,
649	  .default_num = 8
650	},
651
652	{ .name = "window-status-current-fg",
653	  .type = OPTIONS_TABLE_COLOUR,
654	  .default_num = 8
655	},
656
657	{ .name = "window-status-current-format",
658	  .type = OPTIONS_TABLE_STRING,
659	  .default_str = "#I:#W#F"
660	},
661
662	{ .name = "window-status-fg",
663	  .type = OPTIONS_TABLE_COLOUR,
664	  .default_num = 8
665	},
666
667	{ .name = "window-status-format",
668	  .type = OPTIONS_TABLE_STRING,
669	  .default_str = "#I:#W#F"
670	},
671
672	{ .name = "xterm-keys",
673	  .type = OPTIONS_TABLE_FLAG,
674	  .default_num = 0
675	},
676
677	{ .name = NULL }
678};
679
680/* Populate an options tree from a table. */
681void
682options_table_populate_tree(
683    const struct options_table_entry *table, struct options *oo)
684{
685	const struct options_table_entry	*oe;
686
687	for (oe = table; oe->name != NULL; oe++) {
688		if (oe->default_str != NULL)
689			options_set_string(oo, oe->name, "%s", oe->default_str);
690		else
691			options_set_number(oo, oe->name, oe->default_num);
692	}
693}
694
695/* Print an option using its type from the table. */
696const char *
697options_table_print_entry(
698    const struct options_table_entry *oe, struct options_entry *o)
699{
700	static char	 out[BUFSIZ];
701	const char	*s;
702
703	*out = '\0';
704	switch (oe->type) {
705	case OPTIONS_TABLE_STRING:
706		xsnprintf(out, sizeof out, "\"%s\"", o->str);
707		break;
708	case OPTIONS_TABLE_NUMBER:
709		xsnprintf(out, sizeof out, "%lld", o->num);
710		break;
711	case OPTIONS_TABLE_KEY:
712		xsnprintf(out, sizeof out, "%s", key_string_lookup_key(o->num));
713		break;
714	case OPTIONS_TABLE_COLOUR:
715		s = colour_tostring(o->num);
716		xsnprintf(out, sizeof out, "%s", s);
717		break;
718	case OPTIONS_TABLE_ATTRIBUTES:
719		s = attributes_tostring(o->num);
720		xsnprintf(out, sizeof out, "%s", s);
721		break;
722	case OPTIONS_TABLE_FLAG:
723		if (o->num)
724			strlcpy(out, "on", sizeof out);
725		else
726			strlcpy(out, "off", sizeof out);
727		break;
728	case OPTIONS_TABLE_CHOICE:
729		s = oe->choices[o->num];
730		xsnprintf(out, sizeof out, "%s", s);
731		break;
732	}
733	return (out);
734}
735