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