options-table.c revision 1.15
1/* $OpenBSD: options-table.c,v 1.15 2011/11/05 09:06:31 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 = NULL }
425};
426
427/* Window options. */
428const struct options_table_entry window_options_table[] = {
429	{ .name = "aggressive-resize",
430	  .type = OPTIONS_TABLE_FLAG,
431	  .default_num = 0
432	},
433
434	{ .name = "alternate-screen",
435	  .type = OPTIONS_TABLE_FLAG,
436	  .default_num = 1
437	},
438
439	{ .name = "automatic-rename",
440	  .type = OPTIONS_TABLE_FLAG,
441	  .default_num = 1
442	},
443
444	{ .name = "clock-mode-colour",
445	  .type = OPTIONS_TABLE_COLOUR,
446	  .default_num = 4
447	},
448
449	{ .name = "clock-mode-style",
450	  .type = OPTIONS_TABLE_CHOICE,
451	  .choices = options_table_clock_mode_style_list,
452	  .default_num = 1
453	},
454
455	{ .name = "force-height",
456	  .type = OPTIONS_TABLE_NUMBER,
457	  .minimum = 0,
458	  .maximum = INT_MAX,
459	  .default_num = 0
460	},
461
462	{ .name = "force-width",
463	  .type = OPTIONS_TABLE_NUMBER,
464	  .minimum = 0,
465	  .maximum = INT_MAX,
466	  .default_num = 0
467	},
468
469	{ .name = "main-pane-height",
470	  .type = OPTIONS_TABLE_NUMBER,
471	  .minimum = 1,
472	  .maximum = INT_MAX,
473	  .default_num = 24
474	},
475
476	{ .name = "main-pane-width",
477	  .type = OPTIONS_TABLE_NUMBER,
478	  .minimum = 1,
479	  .maximum = INT_MAX,
480	  .default_num = 80
481	},
482
483	{ .name = "mode-attr",
484	  .type = OPTIONS_TABLE_ATTRIBUTES,
485	  .default_num = 0
486	},
487
488	{ .name = "mode-bg",
489	  .type = OPTIONS_TABLE_COLOUR,
490	  .default_num = 3
491	},
492
493	{ .name = "mode-fg",
494	  .type = OPTIONS_TABLE_COLOUR,
495	  .default_num = 0
496	},
497
498	{ .name = "mode-keys",
499	  .type = OPTIONS_TABLE_CHOICE,
500	  .choices = options_table_mode_keys_list,
501	  .default_num = MODEKEY_EMACS
502	},
503
504	{ .name = "mode-mouse",
505	  .type = OPTIONS_TABLE_CHOICE,
506	  .choices = options_table_mode_mouse_list,
507	  .default_num = 0
508	},
509
510	{ .name = "monitor-activity",
511	  .type = OPTIONS_TABLE_FLAG,
512	  .default_num = 0
513	},
514
515	{ .name = "monitor-content",
516	  .type = OPTIONS_TABLE_STRING,
517	  .default_str = ""
518	},
519
520	{ .name = "monitor-silence",
521	  .type = OPTIONS_TABLE_NUMBER,
522	  .minimum = 0,
523	  .maximum = INT_MAX,
524	  .default_num = 0
525	},
526
527	{ .name = "other-pane-height",
528	  .type = OPTIONS_TABLE_NUMBER,
529	  .minimum = 0,
530	  .maximum = INT_MAX,
531	  .default_num = 0
532	},
533
534	{ .name = "other-pane-width",
535	  .type = OPTIONS_TABLE_NUMBER,
536	  .minimum = 0,
537	  .maximum = INT_MAX,
538	  .default_num = 0
539	},
540
541	{ .name = "pane-base-index",
542	  .type = OPTIONS_TABLE_NUMBER,
543	  .minimum = 0,
544	  .maximum = USHRT_MAX,
545	  .default_num = 0
546	},
547
548	{ .name = "remain-on-exit",
549	  .type = OPTIONS_TABLE_FLAG,
550	  .default_num = 0
551	},
552
553	{ .name = "synchronize-panes",
554	  .type = OPTIONS_TABLE_FLAG,
555	  .default_num = 0
556	},
557
558	{ .name = "utf8",
559	  .type = OPTIONS_TABLE_FLAG,
560	  .default_num = 0 /* overridden in main() */
561	},
562
563	{ .name = "window-status-alert-attr",
564	  .type = OPTIONS_TABLE_ATTRIBUTES,
565	  .default_num = GRID_ATTR_REVERSE
566	},
567
568	{ .name = "window-status-alert-bg",
569	  .type = OPTIONS_TABLE_COLOUR,
570	  .default_num = 8
571	},
572
573	{ .name = "window-status-alert-fg",
574	  .type = OPTIONS_TABLE_COLOUR,
575	  .default_num = 8
576	},
577
578	{ .name = "window-status-attr",
579	  .type = OPTIONS_TABLE_ATTRIBUTES,
580	  .default_num = 0
581	},
582
583	{ .name = "window-status-bg",
584	  .type = OPTIONS_TABLE_COLOUR,
585	  .default_num = 8
586	},
587
588	{ .name = "window-status-current-attr",
589	  .type = OPTIONS_TABLE_ATTRIBUTES,
590	  .default_num = 0
591	},
592
593	{ .name = "window-status-current-bg",
594	  .type = OPTIONS_TABLE_COLOUR,
595	  .default_num = 8
596	},
597
598	{ .name = "window-status-current-fg",
599	  .type = OPTIONS_TABLE_COLOUR,
600	  .default_num = 8
601	},
602
603	{ .name = "window-status-current-format",
604	  .type = OPTIONS_TABLE_STRING,
605	  .default_str = "#I:#W#F"
606	},
607
608	{ .name = "window-status-fg",
609	  .type = OPTIONS_TABLE_COLOUR,
610	  .default_num = 8
611	},
612
613	{ .name = "window-status-format",
614	  .type = OPTIONS_TABLE_STRING,
615	  .default_str = "#I:#W#F"
616	},
617
618	{ .name = "word-separators",
619	  .type = OPTIONS_TABLE_STRING,
620	  .default_str = " -_@"
621	},
622
623	{ .name = "xterm-keys",
624	  .type = OPTIONS_TABLE_FLAG,
625	  .default_num = 0
626	},
627
628	{ .name = NULL }
629};
630
631/* Populate an options tree from a table. */
632void
633options_table_populate_tree(
634    const struct options_table_entry *table, struct options *oo)
635{
636	const struct options_table_entry	*oe;
637
638	for (oe = table; oe->name != NULL; oe++) {
639		if (oe->default_str != NULL)
640			options_set_string(oo, oe->name, "%s", oe->default_str);
641		else
642			options_set_number(oo, oe->name, oe->default_num);
643	}
644}
645
646/* Print an option using its type from the table. */
647const char *
648options_table_print_entry(
649    const struct options_table_entry *oe, struct options_entry *o)
650{
651	static char				 out[BUFSIZ];
652	const char				*s;
653	struct keylist				*keylist;
654	u_int					 i;
655
656	*out = '\0';
657	switch (oe->type) {
658	case OPTIONS_TABLE_STRING:
659		xsnprintf(out, sizeof out, "\"%s\"", o->str);
660		break;
661	case OPTIONS_TABLE_NUMBER:
662		xsnprintf(out, sizeof out, "%lld", o->num);
663		break;
664	case OPTIONS_TABLE_KEYS:
665		keylist = o->data;
666		for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
667			s = key_string_lookup_key(ARRAY_ITEM(keylist, i));
668			strlcat(out, s, sizeof out);
669			if (i != ARRAY_LENGTH(keylist) - 1)
670				strlcat(out, ",", sizeof out);
671		}
672		break;
673	case OPTIONS_TABLE_COLOUR:
674		s = colour_tostring(o->num);
675		xsnprintf(out, sizeof out, "%s", s);
676		break;
677	case OPTIONS_TABLE_ATTRIBUTES:
678		s = attributes_tostring(o->num);
679		xsnprintf(out, sizeof out, "%s", s);
680		break;
681	case OPTIONS_TABLE_FLAG:
682		if (o->num)
683			strlcpy(out, "on", sizeof out);
684		else
685			strlcpy(out, "off", sizeof out);
686		break;
687	case OPTIONS_TABLE_CHOICE:
688		s = oe->choices[o->num];
689		xsnprintf(out, sizeof out, "%s", s);
690		break;
691	}
692	return (out);
693}
694