options-table.c revision 1.2
1/* $OpenBSD: options-table.c,v 1.2 2011/01/03 23:35:21 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 = 9
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 = SHRT_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-select-pane",
197	  .type = OPTIONS_TABLE_FLAG,
198	  .default_num = 0
199	},
200
201	{ .name = "mouse-utf8",
202	  .type = OPTIONS_TABLE_FLAG,
203	  .default_num = 0
204	},
205
206	{ .name = "pane-active-border-bg",
207	  .type = OPTIONS_TABLE_COLOUR,
208	  .default_num = 8
209	},
210
211	{ .name = "pane-active-border-fg",
212	  .type = OPTIONS_TABLE_COLOUR,
213	  .default_num = 2
214	},
215
216	{ .name = "pane-border-bg",
217	  .type = OPTIONS_TABLE_COLOUR,
218	  .default_num = 8
219	},
220
221	{ .name = "pane-border-fg",
222	  .type = OPTIONS_TABLE_COLOUR,
223	  .default_num = 8
224	},
225
226	{ .name = "prefix",
227	  .type = OPTIONS_TABLE_KEYS,
228	  /* set in main() */
229	},
230
231	{ .name = "repeat-time",
232	  .type = OPTIONS_TABLE_NUMBER,
233	  .minimum = 0,
234	  .maximum = SHRT_MAX,
235	  .default_num = 500
236	},
237
238	{ .name = "set-remain-on-exit",
239	  .type = OPTIONS_TABLE_FLAG,
240	  .default_num = 0
241	},
242
243	{ .name = "set-titles",
244	  .type = OPTIONS_TABLE_FLAG,
245	  .default_num = 0
246	},
247
248	{ .name = "set-titles-string",
249	  .type = OPTIONS_TABLE_STRING,
250	  .default_str = "#S:#I:#W - \"#T\""
251	},
252
253	{ .name = "status",
254	  .type = OPTIONS_TABLE_FLAG,
255	  .default_num = 1
256	},
257
258	{ .name = "status-attr",
259	  .type = OPTIONS_TABLE_ATTRIBUTES,
260	  .default_num = 0
261	},
262
263	{ .name = "status-bg",
264	  .type = OPTIONS_TABLE_COLOUR,
265	  .default_num = 2
266	},
267
268	{ .name = "status-fg",
269	  .type = OPTIONS_TABLE_COLOUR,
270	  .default_num = 0
271	},
272
273	{ .name = "status-interval",
274	  .type = OPTIONS_TABLE_NUMBER,
275	  .minimum = 0,
276	  .maximum = INT_MAX,
277	  .default_num = 15
278	},
279
280	{ .name = "status-justify",
281	  .type = OPTIONS_TABLE_CHOICE,
282	  .choices = options_table_status_justify_list,
283	  .default_num = 0
284	},
285
286	{ .name = "status-keys",
287	  .type = OPTIONS_TABLE_CHOICE,
288	  .choices = options_table_status_keys_list,
289	  .default_num = MODEKEY_EMACS
290	},
291
292	{ .name = "status-left",
293	  .type = OPTIONS_TABLE_STRING,
294	  .default_str = "[#S]"
295	},
296
297	{ .name = "status-left-attr",
298	  .type = OPTIONS_TABLE_ATTRIBUTES,
299	  .default_num = 0
300	},
301
302	{ .name = "status-left-bg",
303	  .type = OPTIONS_TABLE_COLOUR,
304	  .default_num = 8
305	},
306
307	{ .name = "status-left-fg",
308	  .type = OPTIONS_TABLE_COLOUR,
309	  .default_num = 8
310	},
311
312	{ .name = "status-left-length",
313	  .type = OPTIONS_TABLE_NUMBER,
314	  .minimum = 0,
315	  .maximum = SHRT_MAX,
316	  .default_num = 10
317	},
318
319	{ .name = "status-right",
320	  .type = OPTIONS_TABLE_STRING,
321	  .default_str = "\"#22T\" %H:%M %d-%b-%y"
322	},
323
324	{ .name = "status-right-attr",
325	  .type = OPTIONS_TABLE_ATTRIBUTES,
326	  .default_num = 0
327	},
328
329	{ .name = "status-right-bg",
330	  .type = OPTIONS_TABLE_COLOUR,
331	  .default_num = 8
332	},
333
334	{ .name = "status-right-fg",
335	  .type = OPTIONS_TABLE_COLOUR,
336	  .default_num = 8
337	},
338
339	{ .name = "status-right-length",
340	  .type = OPTIONS_TABLE_NUMBER,
341	  .minimum = 0,
342	  .maximum = SHRT_MAX,
343	  .default_num = 40
344	},
345
346	{ .name = "status-utf8",
347	  .type = OPTIONS_TABLE_FLAG,
348	  .default_num = 0 /* overridden in main() */
349	},
350
351	{ .name = "terminal-overrides",
352	  .type = OPTIONS_TABLE_STRING,
353	  .default_str = "*88col*:colors=88,*256col*:colors=256"
354	},
355
356	{ .name = "update-environment",
357	  .type = OPTIONS_TABLE_STRING,
358	  .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
359	                    "SSH_CONNECTION WINDOWID XAUTHORITY"
360
361	},
362
363	{ .name = "visual-activity",
364	  .type = OPTIONS_TABLE_FLAG,
365	  .default_num = 0
366	},
367
368	{ .name = "visual-bell",
369	  .type = OPTIONS_TABLE_FLAG,
370	  .default_num = 0
371	},
372
373	{ .name = "visual-content",
374	  .type = OPTIONS_TABLE_FLAG,
375	  .default_num = 0
376	},
377
378	{ .name = "visual-silence",
379	  .type = OPTIONS_TABLE_FLAG,
380	  .default_num = 0
381	},
382
383	{ .name = NULL }
384};
385
386/* Window options. */
387const struct options_table_entry window_options_table[] = {
388	{ .name = "aggressive-resize",
389	  .type = OPTIONS_TABLE_FLAG,
390	  .default_num = 0
391	},
392
393	{ .name = "alternate-screen",
394	  .type = OPTIONS_TABLE_FLAG,
395	  .default_num = 1
396	},
397
398	{ .name = "automatic-rename",
399	  .type = OPTIONS_TABLE_FLAG,
400	  .default_num = 1
401	},
402
403	{ .name = "clock-mode-colour",
404	  .type = OPTIONS_TABLE_COLOUR,
405	  .default_num = 4
406	},
407
408	{ .name = "clock-mode-style",
409	  .type = OPTIONS_TABLE_CHOICE,
410	  .choices = options_table_clock_mode_style_list,
411	  .default_num = 1
412	},
413
414	{ .name = "force-height",
415	  .type = OPTIONS_TABLE_NUMBER,
416	  .minimum = 0,
417	  .maximum = INT_MAX,
418	  .default_num = 0
419	},
420
421	{ .name = "force-width",
422	  .type = OPTIONS_TABLE_NUMBER,
423	  .minimum = 0,
424	  .maximum = INT_MAX,
425	  .default_num = 0
426	},
427
428	{ .name = "main-pane-height",
429	  .type = OPTIONS_TABLE_NUMBER,
430	  .minimum = 1,
431	  .maximum = INT_MAX,
432	  .default_num = 24
433	},
434
435	{ .name = "main-pane-width",
436	  .type = OPTIONS_TABLE_NUMBER,
437	  .minimum = 1,
438	  .maximum = INT_MAX,
439	  .default_num = 80
440	},
441
442	{ .name = "mode-attr",
443	  .type = OPTIONS_TABLE_ATTRIBUTES,
444	  .default_num = 0
445	},
446
447	{ .name = "mode-bg",
448	  .type = OPTIONS_TABLE_COLOUR,
449	  .default_num = 3
450	},
451
452	{ .name = "mode-fg",
453	  .type = OPTIONS_TABLE_COLOUR,
454	  .default_num = 0
455	},
456
457	{ .name = "mode-keys",
458	  .type = OPTIONS_TABLE_CHOICE,
459	  .choices = options_table_mode_keys_list,
460	  .default_num = MODEKEY_EMACS
461	},
462
463	{ .name = "mode-mouse",
464	  .type = OPTIONS_TABLE_FLAG,
465	  .default_num = 0
466	},
467
468	{ .name = "monitor-activity",
469	  .type = OPTIONS_TABLE_FLAG,
470	  .default_num = 0
471	},
472
473	{ .name = "monitor-content",
474	  .type = OPTIONS_TABLE_STRING,
475	  .default_str = ""
476	},
477
478	{ .name = "monitor-silence",
479	  .type = OPTIONS_TABLE_NUMBER,
480	  .minimum = 0,
481	  .maximum = INT_MAX,
482	  .default_num = 0
483	},
484
485	{ .name = "other-pane-height",
486	  .type = OPTIONS_TABLE_NUMBER,
487	  .minimum = 0,
488	  .maximum = INT_MAX,
489	  .default_num = 0
490	},
491
492	{ .name = "other-pane-width",
493	  .type = OPTIONS_TABLE_NUMBER,
494	  .minimum = 0,
495	  .maximum = INT_MAX,
496	  .default_num = 0
497	},
498
499	{ .name = "remain-on-exit",
500	  .type = OPTIONS_TABLE_FLAG,
501	  .default_num = 0
502	},
503
504	{ .name = "synchronize-panes",
505	  .type = OPTIONS_TABLE_FLAG,
506	  .default_num = 0
507	},
508
509	{ .name = "utf8",
510	  .type = OPTIONS_TABLE_FLAG,
511	  .default_num = 0 /* overridden in main() */
512	},
513
514	{ .name = "window-status-alert-attr",
515	  .type = OPTIONS_TABLE_ATTRIBUTES,
516	  .default_num = GRID_ATTR_REVERSE
517	},
518
519	{ .name = "window-status-alert-bg",
520	  .type = OPTIONS_TABLE_COLOUR,
521	  .default_num = 8
522	},
523
524	{ .name = "window-status-alert-fg",
525	  .type = OPTIONS_TABLE_COLOUR,
526	  .default_num = 8
527	},
528
529	{ .name = "window-status-attr",
530	  .type = OPTIONS_TABLE_ATTRIBUTES,
531	  .default_num = 0
532	},
533
534	{ .name = "window-status-bg",
535	  .type = OPTIONS_TABLE_COLOUR,
536	  .default_num = 8
537	},
538
539	{ .name = "window-status-current-attr",
540	  .type = OPTIONS_TABLE_ATTRIBUTES,
541	  .default_num = 0
542	},
543
544	{ .name = "window-status-current-bg",
545	  .type = OPTIONS_TABLE_COLOUR,
546	  .default_num = 8
547	},
548
549	{ .name = "window-status-current-fg",
550	  .type = OPTIONS_TABLE_COLOUR,
551	  .default_num = 8
552	},
553
554	{ .name = "window-status-current-format",
555	  .type = OPTIONS_TABLE_STRING,
556	  .default_str = "#I:#W#F"
557	},
558
559	{ .name = "window-status-fg",
560	  .type = OPTIONS_TABLE_COLOUR,
561	  .default_num = 8
562	},
563
564	{ .name = "window-status-format",
565	  .type = OPTIONS_TABLE_STRING,
566	  .default_str = "#I:#W#F"
567	},
568
569	{ .name = "word-separators",
570	  .type = OPTIONS_TABLE_STRING,
571	  .default_str = " -_@"
572	},
573
574	{ .name = "xterm-keys",
575	  .type = OPTIONS_TABLE_FLAG,
576	  .default_num = 0
577	},
578
579	{ .name = NULL }
580};
581
582/* Populate an options tree from a table. */
583void
584options_table_populate_tree(
585    const struct options_table_entry *table, struct options *oo)
586{
587	const struct options_table_entry	*oe;
588
589	for (oe = table; oe->name != NULL; oe++) {
590		if (oe->default_str != NULL)
591			options_set_string(oo, oe->name, "%s", oe->default_str);
592		else
593			options_set_number(oo, oe->name, oe->default_num);
594	}
595}
596
597/* Print an option using its type from the table. */
598const char *
599options_table_print_entry(
600    const struct options_table_entry *oe, struct options_entry *o)
601{
602	static char				 out[BUFSIZ];
603	const char				*s;
604	struct keylist				*keylist;
605	u_int					 i;
606
607	*out = '\0';
608	switch (oe->type) {
609	case OPTIONS_TABLE_STRING:
610		xsnprintf(out, sizeof out, "\"%s\"", o->str);
611		break;
612	case OPTIONS_TABLE_NUMBER:
613		xsnprintf(out, sizeof out, "%lld", o->num);
614		break;
615	case OPTIONS_TABLE_KEYS:
616		keylist = o->data;
617		for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
618			s = key_string_lookup_key(ARRAY_ITEM(keylist, i));
619			strlcat(out, s, sizeof out);
620			if (i != ARRAY_LENGTH(keylist) - 1)
621				strlcat(out, ",", sizeof out);
622		}
623		break;
624	case OPTIONS_TABLE_COLOUR:
625		s = colour_tostring(o->num);
626		xsnprintf(out, sizeof out, "%s", s);
627		break;
628	case OPTIONS_TABLE_ATTRIBUTES:
629		s = attributes_tostring(o->num);
630		xsnprintf(out, sizeof out, "%s", s);
631		break;
632	case OPTIONS_TABLE_FLAG:
633		if (o->num)
634			strlcpy(out, "on", sizeof out);
635		else
636			strlcpy(out, "off", sizeof out);
637		break;
638	case OPTIONS_TABLE_CHOICE:
639		s = oe->choices[o->num];
640		xsnprintf(out, sizeof out, "%s", s);
641		break;
642	}
643	return (out);
644}
645