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