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