options-table.c revision 1.148
1/* $OpenBSD: options-table.c,v 1.148 2021/08/06 09:19:02 nicm Exp $ */
2
3/*
4 * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
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 look up the real type when the
32 * user sets an option or its value needs to be shown.
33 */
34
35/* Choice option type lists. */
36static const char *options_table_mode_keys_list[] = {
37	"emacs", "vi", NULL
38};
39static const char *options_table_clock_mode_style_list[] = {
40	"12", "24", NULL
41};
42static const char *options_table_status_list[] = {
43	"off", "on", "2", "3", "4", "5", NULL
44};
45static const char *options_table_status_keys_list[] = {
46	"emacs", "vi", NULL
47};
48static const char *options_table_status_justify_list[] = {
49	"left", "centre", "right", "absolute-centre", NULL
50};
51static const char *options_table_status_position_list[] = {
52	"top", "bottom", NULL
53};
54static const char *options_table_bell_action_list[] = {
55	"none", "any", "current", "other", NULL
56};
57static const char *options_table_visual_bell_list[] = {
58	"off", "on", "both", NULL
59};
60static const char *options_table_pane_status_list[] = {
61	"off", "top", "bottom", NULL
62};
63static const char *options_table_pane_lines_list[] = {
64	"single", "double", "heavy", "simple", "number", NULL
65};
66static const char *options_table_set_clipboard_list[] = {
67	"off", "external", "on", NULL
68};
69static const char *options_table_window_size_list[] = {
70	"largest", "smallest", "manual", "latest", NULL
71};
72static const char *options_table_remain_on_exit_list[] = {
73	"off", "on", "failed", NULL
74};
75static const char *options_table_detach_on_destroy_list[] = {
76	"off", "on", "no-detached", NULL
77};
78static const char *options_table_extended_keys_list[] = {
79	"off", "on", "always", NULL
80};
81
82/* Status line format. */
83#define OPTIONS_TABLE_STATUS_FORMAT1 \
84	"#[align=left range=left #{status-left-style}]" \
85	"#[push-default]" \
86	"#{T;=/#{status-left-length}:status-left}" \
87	"#[pop-default]" \
88	"#[norange default]" \
89	"#[list=on align=#{status-justify}]" \
90	"#[list=left-marker]<#[list=right-marker]>#[list=on]" \
91	"#{W:" \
92		"#[range=window|#{window_index} " \
93			"#{window-status-style}" \
94			"#{?#{&&:#{window_last_flag}," \
95				"#{!=:#{window-status-last-style},default}}, " \
96				"#{window-status-last-style}," \
97			"}" \
98			"#{?#{&&:#{window_bell_flag}," \
99				"#{!=:#{window-status-bell-style},default}}, " \
100				"#{window-status-bell-style}," \
101				"#{?#{&&:#{||:#{window_activity_flag}," \
102					     "#{window_silence_flag}}," \
103					"#{!=:" \
104					"#{window-status-activity-style}," \
105					"default}}, " \
106					"#{window-status-activity-style}," \
107				"}" \
108			"}" \
109		"]" \
110		"#[push-default]" \
111		"#{T:window-status-format}" \
112		"#[pop-default]" \
113		"#[norange default]" \
114		"#{?window_end_flag,,#{window-status-separator}}" \
115	"," \
116		"#[range=window|#{window_index} list=focus " \
117			"#{?#{!=:#{window-status-current-style},default}," \
118				"#{window-status-current-style}," \
119				"#{window-status-style}" \
120			"}" \
121			"#{?#{&&:#{window_last_flag}," \
122				"#{!=:#{window-status-last-style},default}}, " \
123				"#{window-status-last-style}," \
124			"}" \
125			"#{?#{&&:#{window_bell_flag}," \
126				"#{!=:#{window-status-bell-style},default}}, " \
127				"#{window-status-bell-style}," \
128				"#{?#{&&:#{||:#{window_activity_flag}," \
129					     "#{window_silence_flag}}," \
130					"#{!=:" \
131					"#{window-status-activity-style}," \
132					"default}}, " \
133					"#{window-status-activity-style}," \
134				"}" \
135			"}" \
136		"]" \
137		"#[push-default]" \
138		"#{T:window-status-current-format}" \
139		"#[pop-default]" \
140		"#[norange list=on default]" \
141		"#{?window_end_flag,,#{window-status-separator}}" \
142	"}" \
143	"#[nolist align=right range=right #{status-right-style}]" \
144	"#[push-default]" \
145	"#{T;=/#{status-right-length}:status-right}" \
146	"#[pop-default]" \
147	"#[norange default]"
148#define OPTIONS_TABLE_STATUS_FORMAT2 \
149	"#[align=centre]#{P:#{?pane_active,#[reverse],}" \
150	"#{pane_index}[#{pane_width}x#{pane_height}]#[default] }"
151static const char *options_table_status_format_default[] = {
152	OPTIONS_TABLE_STATUS_FORMAT1, OPTIONS_TABLE_STATUS_FORMAT2, NULL
153};
154
155/* Helpers for hook options. */
156#define OPTIONS_TABLE_HOOK(hook_name, default_value) \
157	{ .name = hook_name, \
158	  .type = OPTIONS_TABLE_COMMAND, \
159	  .scope = OPTIONS_TABLE_SESSION, \
160	  .flags = OPTIONS_TABLE_IS_ARRAY|OPTIONS_TABLE_IS_HOOK, \
161	  .default_str = default_value,	\
162	  .separator = "" \
163	}
164
165#define OPTIONS_TABLE_PANE_HOOK(hook_name, default_value) \
166	{ .name = hook_name, \
167	  .type = OPTIONS_TABLE_COMMAND, \
168	  .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, \
169	  .flags = OPTIONS_TABLE_IS_ARRAY|OPTIONS_TABLE_IS_HOOK, \
170	  .default_str = default_value,	\
171	  .separator = "" \
172	}
173
174#define OPTIONS_TABLE_WINDOW_HOOK(hook_name, default_value) \
175	{ .name = hook_name, \
176	  .type = OPTIONS_TABLE_COMMAND, \
177	  .scope = OPTIONS_TABLE_WINDOW, \
178	  .flags = OPTIONS_TABLE_IS_ARRAY|OPTIONS_TABLE_IS_HOOK, \
179	  .default_str = default_value,	\
180	  .separator = "" \
181	}
182
183/* Map of name conversions. */
184const struct options_name_map options_other_names[] = {
185	{ "display-panes-color", "display-panes-colour" },
186	{ "display-panes-active-color", "display-panes-active-colour" },
187	{ "clock-mode-color", "clock-mode-colour" },
188	{ NULL, NULL }
189};
190
191/* Top-level options. */
192const struct options_table_entry options_table[] = {
193	/* Server options. */
194	{ .name = "backspace",
195	  .type = OPTIONS_TABLE_KEY,
196	  .scope = OPTIONS_TABLE_SERVER,
197	  .default_num = '\177',
198	  .text = "The key to send for backspace."
199	},
200
201	{ .name = "buffer-limit",
202	  .type = OPTIONS_TABLE_NUMBER,
203	  .scope = OPTIONS_TABLE_SERVER,
204	  .minimum = 1,
205	  .maximum = INT_MAX,
206	  .default_num = 50,
207	  .text = "The maximum number of automatic buffers. "
208		  "When this is reached, the oldest buffer is deleted."
209	},
210
211	{ .name = "command-alias",
212	  .type = OPTIONS_TABLE_STRING,
213	  .scope = OPTIONS_TABLE_SERVER,
214	  .flags = OPTIONS_TABLE_IS_ARRAY,
215	  .default_str = "split-pane=split-window,"
216			 "splitp=split-window,"
217			 "server-info=show-messages -JT,"
218			 "info=show-messages -JT,"
219			 "choose-window=choose-tree -w,"
220			 "choose-session=choose-tree -s",
221	  .separator = ",",
222	  .text = "Array of command aliases. "
223		  "Each entry is an alias and a command separated by '='."
224	},
225
226	{ .name = "copy-command",
227	  .type = OPTIONS_TABLE_STRING,
228	  .scope = OPTIONS_TABLE_SERVER,
229	  .default_str = "",
230	  .text = "Shell command run when text is copied. "
231		  "If empty, no command is run."
232	},
233
234	{ .name = "default-terminal",
235	  .type = OPTIONS_TABLE_STRING,
236	  .scope = OPTIONS_TABLE_SERVER,
237	  .default_str = TMUX_TERM,
238	  .text = "Default for the 'TERM' environment variable."
239	},
240
241	{ .name = "editor",
242	  .type = OPTIONS_TABLE_STRING,
243	  .scope = OPTIONS_TABLE_SERVER,
244	  .default_str = _PATH_VI,
245	  .text = "Editor run to edit files."
246	},
247
248	{ .name = "escape-time",
249	  .type = OPTIONS_TABLE_NUMBER,
250	  .scope = OPTIONS_TABLE_SERVER,
251	  .minimum = 0,
252	  .maximum = INT_MAX,
253	  .default_num = 500,
254	  .text = "Time to wait before assuming a key is Escape."
255	},
256
257	{ .name = "exit-empty",
258	  .type = OPTIONS_TABLE_FLAG,
259	  .scope = OPTIONS_TABLE_SERVER,
260	  .default_num = 1,
261	  .text = "Whether the server should exit if there are no sessions."
262	},
263
264	{ .name = "exit-unattached",
265	  .type = OPTIONS_TABLE_FLAG,
266	  .scope = OPTIONS_TABLE_SERVER,
267	  .default_num = 0,
268	  .text = "Whether the server should exit if there are no attached "
269		  "clients."
270	},
271
272	{ .name = "extended-keys",
273	  .type = OPTIONS_TABLE_CHOICE,
274	  .scope = OPTIONS_TABLE_SERVER,
275	  .choices = options_table_extended_keys_list,
276	  .default_num = 0,
277	  .text = "Whether to request extended key sequences from terminals "
278	          "that support it."
279	},
280
281	{ .name = "focus-events",
282	  .type = OPTIONS_TABLE_FLAG,
283	  .scope = OPTIONS_TABLE_SERVER,
284	  .default_num = 0,
285	  .text = "Whether to send focus events to applications."
286	},
287
288	{ .name = "history-file",
289	  .type = OPTIONS_TABLE_STRING,
290	  .scope = OPTIONS_TABLE_SERVER,
291	  .default_str = "",
292	  .text = "Location of the command prompt history file. "
293		  "Empty does not write a history file."
294	},
295
296	{ .name = "message-limit",
297	  .type = OPTIONS_TABLE_NUMBER,
298	  .scope = OPTIONS_TABLE_SERVER,
299	  .minimum = 0,
300	  .maximum = INT_MAX,
301	  .default_num = 1000,
302	  .text = "Maximum number of server messages to keep."
303	},
304
305	{ .name = "prompt-history-limit",
306	  .type = OPTIONS_TABLE_NUMBER,
307	  .scope = OPTIONS_TABLE_SERVER,
308	  .minimum = 0,
309	  .maximum = INT_MAX,
310	  .default_num = 100,
311	  .text = "Maximum number of commands to keep in history."
312	},
313
314	{ .name = "set-clipboard",
315	  .type = OPTIONS_TABLE_CHOICE,
316	  .scope = OPTIONS_TABLE_SERVER,
317	  .choices = options_table_set_clipboard_list,
318	  .default_num = 1,
319	  .text = "Whether to attempt to set the system clipboard ('on' or "
320		  "'external') and whether to allow applications to create "
321		  "paste buffers with an escape sequence ('on' only)."
322	},
323
324	{ .name = "terminal-overrides",
325	  .type = OPTIONS_TABLE_STRING,
326	  .scope = OPTIONS_TABLE_SERVER,
327	  .flags = OPTIONS_TABLE_IS_ARRAY,
328	  .default_str = "",
329	  .separator = ",",
330	  .text = "List of terminal capabilities overrides."
331	},
332
333	{ .name = "terminal-features",
334	  .type = OPTIONS_TABLE_STRING,
335	  .scope = OPTIONS_TABLE_SERVER,
336	  .flags = OPTIONS_TABLE_IS_ARRAY,
337	  .default_str = "xterm*:clipboard:ccolour:cstyle:focus:title,"
338			 "screen*:title",
339	  .separator = ",",
340	  .text = "List of terminal features, used if they cannot be "
341		  "automatically detected."
342	},
343
344	{ .name = "user-keys",
345	  .type = OPTIONS_TABLE_STRING,
346	  .scope = OPTIONS_TABLE_SERVER,
347	  .flags = OPTIONS_TABLE_IS_ARRAY,
348	  .default_str = "",
349	  .separator = ",",
350	  .text = "User key assignments. "
351		  "Each sequence in the list is translated into a key: "
352		  "'User0', 'User1' and so on."
353	},
354
355	/* Session options. */
356	{ .name = "activity-action",
357	  .type = OPTIONS_TABLE_CHOICE,
358	  .scope = OPTIONS_TABLE_SESSION,
359	  .choices = options_table_bell_action_list,
360	  .default_num = ALERT_OTHER,
361	  .text = "Action to take on an activity alert."
362	},
363
364	{ .name = "assume-paste-time",
365	  .type = OPTIONS_TABLE_NUMBER,
366	  .scope = OPTIONS_TABLE_SESSION,
367	  .minimum = 0,
368	  .maximum = INT_MAX,
369	  .default_num = 1,
370	  .unit = "milliseconds",
371	  .text = "Maximum time between input to assume it is pasting rather "
372		  "than typing."
373	},
374
375	{ .name = "base-index",
376	  .type = OPTIONS_TABLE_NUMBER,
377	  .scope = OPTIONS_TABLE_SESSION,
378	  .minimum = 0,
379	  .maximum = INT_MAX,
380	  .default_num = 0,
381	  .text = "Default index of the first window in each session."
382	},
383
384	{ .name = "bell-action",
385	  .type = OPTIONS_TABLE_CHOICE,
386	  .scope = OPTIONS_TABLE_SESSION,
387	  .choices = options_table_bell_action_list,
388	  .default_num = ALERT_ANY,
389	  .text = "Action to take on a bell alert."
390	},
391
392	{ .name = "default-command",
393	  .type = OPTIONS_TABLE_STRING,
394	  .scope = OPTIONS_TABLE_SESSION,
395	  .default_str = "",
396	  .text = "Default command to run in new panes. If empty, a shell is "
397		  "started."
398	},
399
400	{ .name = "default-shell",
401	  .type = OPTIONS_TABLE_STRING,
402	  .scope = OPTIONS_TABLE_SESSION,
403	  .default_str = _PATH_BSHELL,
404	  .text = "Location of default shell."
405	},
406
407	{ .name = "default-size",
408	  .type = OPTIONS_TABLE_STRING,
409	  .scope = OPTIONS_TABLE_SESSION,
410	  .pattern = "[0-9]*x[0-9]*",
411	  .default_str = "80x24",
412	  .text = "Initial size of new sessions."
413	},
414
415	{ .name = "destroy-unattached",
416	  .type = OPTIONS_TABLE_FLAG,
417	  .scope = OPTIONS_TABLE_SESSION,
418	  .default_num = 0,
419	  .text = "Whether to destroy sessions when they have no attached "
420		  "clients."
421	},
422
423	{ .name = "detach-on-destroy",
424	  .type = OPTIONS_TABLE_CHOICE,
425	  .scope = OPTIONS_TABLE_SESSION,
426	  .choices = options_table_detach_on_destroy_list,
427	  .default_num = 1,
428	  .text = "Whether to detach when a session is destroyed, or switch "
429		  "the client to another session if any exist."
430	},
431
432	{ .name = "display-panes-active-colour",
433	  .type = OPTIONS_TABLE_COLOUR,
434	  .scope = OPTIONS_TABLE_SESSION,
435	  .default_num = 1,
436	  .text = "Colour of the active pane for 'display-panes'."
437	},
438
439	{ .name = "display-panes-colour",
440	  .type = OPTIONS_TABLE_COLOUR,
441	  .scope = OPTIONS_TABLE_SESSION,
442	  .default_num = 4,
443	  .text = "Colour of not active panes for 'display-panes'."
444	},
445
446	{ .name = "display-panes-time",
447	  .type = OPTIONS_TABLE_NUMBER,
448	  .scope = OPTIONS_TABLE_SESSION,
449	  .minimum = 1,
450	  .maximum = INT_MAX,
451	  .default_num = 1000,
452	  .unit = "milliseconds",
453	  .text = "Time for which 'display-panes' should show pane numbers."
454	},
455
456	{ .name = "display-time",
457	  .type = OPTIONS_TABLE_NUMBER,
458	  .scope = OPTIONS_TABLE_SESSION,
459	  .minimum = 0,
460	  .maximum = INT_MAX,
461	  .default_num = 750,
462	  .unit = "milliseconds",
463	  .text = "Time for which status line messages should appear."
464	},
465
466	{ .name = "history-limit",
467	  .type = OPTIONS_TABLE_NUMBER,
468	  .scope = OPTIONS_TABLE_SESSION,
469	  .minimum = 0,
470	  .maximum = INT_MAX,
471	  .default_num = 2000,
472	  .unit = "lines",
473	  .text = "Maximum number of lines to keep in the history for each "
474		  "pane. "
475		  "If changed, the new value applies only to new panes."
476	},
477
478	{ .name = "key-table",
479	  .type = OPTIONS_TABLE_STRING,
480	  .scope = OPTIONS_TABLE_SESSION,
481	  .default_str = "root",
482	  .text = "Default key table. "
483		  "Key presses are first looked up in this table."
484	},
485
486	{ .name = "lock-after-time",
487	  .type = OPTIONS_TABLE_NUMBER,
488	  .scope = OPTIONS_TABLE_SESSION,
489	  .minimum = 0,
490	  .maximum = INT_MAX,
491	  .default_num = 0,
492	  .unit = "seconds",
493	  .text = "Time after which a client is locked if not used."
494	},
495
496	{ .name = "lock-command",
497	  .type = OPTIONS_TABLE_STRING,
498	  .scope = OPTIONS_TABLE_SESSION,
499	  .default_str = "lock -np",
500	  .text = "Shell command to run to lock a client."
501	},
502
503	{ .name = "message-command-style",
504	  .type = OPTIONS_TABLE_STRING,
505	  .scope = OPTIONS_TABLE_SESSION,
506	  .default_str = "bg=black,fg=yellow",
507	  .flags = OPTIONS_TABLE_IS_STYLE,
508	  .separator = ",",
509	  .text = "Style of the command prompt when in command mode, if "
510		  "'mode-keys' is set to 'vi'."
511	},
512
513	{ .name = "message-style",
514	  .type = OPTIONS_TABLE_STRING,
515	  .scope = OPTIONS_TABLE_SESSION,
516	  .default_str = "bg=yellow,fg=black",
517	  .flags = OPTIONS_TABLE_IS_STYLE,
518	  .separator = ",",
519	  .text = "Style of the command prompt."
520	},
521
522	{ .name = "mouse",
523	  .type = OPTIONS_TABLE_FLAG,
524	  .scope = OPTIONS_TABLE_SESSION,
525	  .default_num = 0,
526	  .text = "Whether the mouse is recognised and mouse key bindings are "
527		  "executed. "
528		  "Applications inside panes can use the mouse even when 'off'."
529	},
530
531	{ .name = "prefix",
532	  .type = OPTIONS_TABLE_KEY,
533	  .scope = OPTIONS_TABLE_SESSION,
534	  .default_num = '\002',
535	  .text = "The prefix key."
536	},
537
538	{ .name = "prefix2",
539	  .type = OPTIONS_TABLE_KEY,
540	  .scope = OPTIONS_TABLE_SESSION,
541	  .default_num = KEYC_NONE,
542	  .text = "A second prefix key."
543	},
544
545	{ .name = "renumber-windows",
546	  .type = OPTIONS_TABLE_FLAG,
547	  .scope = OPTIONS_TABLE_SESSION,
548	  .default_num = 0,
549	  .text = "Whether windows are automatically renumbered rather than "
550		  "leaving gaps."
551	},
552
553	{ .name = "repeat-time",
554	  .type = OPTIONS_TABLE_NUMBER,
555	  .scope = OPTIONS_TABLE_SESSION,
556	  .minimum = 0,
557	  .maximum = SHRT_MAX,
558	  .default_num = 500,
559	  .unit = "milliseconds",
560	  .text = "Time to wait for a key binding to repeat, if it is bound "
561		  "with the '-r' flag."
562	},
563
564	{ .name = "set-titles",
565	  .type = OPTIONS_TABLE_FLAG,
566	  .scope = OPTIONS_TABLE_SESSION,
567	  .default_num = 0,
568	  .text = "Whether to set the terminal title, if supported."
569	},
570
571	{ .name = "set-titles-string",
572	  .type = OPTIONS_TABLE_STRING,
573	  .scope = OPTIONS_TABLE_SESSION,
574	  .default_str = "#S:#I:#W - \"#T\" #{session_alerts}",
575	  .text = "Format of the terminal title to set."
576	},
577
578	{ .name = "silence-action",
579	  .type = OPTIONS_TABLE_CHOICE,
580	  .scope = OPTIONS_TABLE_SESSION,
581	  .choices = options_table_bell_action_list,
582	  .default_num = ALERT_OTHER,
583	  .text = "Action to take on a silence alert."
584	},
585
586	{ .name = "status",
587	  .type = OPTIONS_TABLE_CHOICE,
588	  .scope = OPTIONS_TABLE_SESSION,
589	  .choices = options_table_status_list,
590	  .default_num = 1,
591	  .text = "Number of lines in the status line."
592	},
593
594	{ .name = "status-bg",
595	  .type = OPTIONS_TABLE_COLOUR,
596	  .scope = OPTIONS_TABLE_SESSION,
597	  .default_num = 8,
598	  .text = "Background colour of the status line. This option is "
599		  "deprecated, use 'status-style' instead."
600	},
601
602	{ .name = "status-fg",
603	  .type = OPTIONS_TABLE_COLOUR,
604	  .scope = OPTIONS_TABLE_SESSION,
605	  .default_num = 8,
606	  .text = "Foreground colour of the status line. This option is "
607		  "deprecated, use 'status-style' instead."
608	},
609
610	{ .name = "status-format",
611	  .type = OPTIONS_TABLE_STRING,
612	  .scope = OPTIONS_TABLE_SESSION,
613	  .flags = OPTIONS_TABLE_IS_ARRAY,
614	  .default_arr = options_table_status_format_default,
615	  .text = "Formats for the status lines. "
616		  "Each array member is the format for one status line. "
617		  "The default status line is made up of several components "
618		  "which may be configured individually with other options such "
619		  "as 'status-left'."
620	},
621
622	{ .name = "status-interval",
623	  .type = OPTIONS_TABLE_NUMBER,
624	  .scope = OPTIONS_TABLE_SESSION,
625	  .minimum = 0,
626	  .maximum = INT_MAX,
627	  .default_num = 15,
628	  .unit = "seconds",
629	  .text = "Number of seconds between status line updates."
630	},
631
632	{ .name = "status-justify",
633	  .type = OPTIONS_TABLE_CHOICE,
634	  .scope = OPTIONS_TABLE_SESSION,
635	  .choices = options_table_status_justify_list,
636	  .default_num = 0,
637	  .text = "Position of the window list in the status line."
638	},
639
640	{ .name = "status-keys",
641	  .type = OPTIONS_TABLE_CHOICE,
642	  .scope = OPTIONS_TABLE_SESSION,
643	  .choices = options_table_status_keys_list,
644	  .default_num = MODEKEY_EMACS,
645	  .text = "Key set to use at the command prompt."
646	},
647
648	{ .name = "status-left",
649	  .type = OPTIONS_TABLE_STRING,
650	  .scope = OPTIONS_TABLE_SESSION,
651	  .default_str = "[#{session_name}] ",
652	  .text = "Contents of the left side of the status line."
653	},
654
655	{ .name = "status-left-length",
656	  .type = OPTIONS_TABLE_NUMBER,
657	  .scope = OPTIONS_TABLE_SESSION,
658	  .minimum = 0,
659	  .maximum = SHRT_MAX,
660	  .default_num = 10,
661	  .text = "Maximum width of the left side of the status line."
662	},
663
664	{ .name = "status-left-style",
665	  .type = OPTIONS_TABLE_STRING,
666	  .scope = OPTIONS_TABLE_SESSION,
667	  .default_str = "default",
668	  .flags = OPTIONS_TABLE_IS_STYLE,
669	  .separator = ",",
670	  .text = "Style of the left side of the status line."
671	},
672
673	{ .name = "status-position",
674	  .type = OPTIONS_TABLE_CHOICE,
675	  .scope = OPTIONS_TABLE_SESSION,
676	  .choices = options_table_status_position_list,
677	  .default_num = 1,
678	  .text = "Position of the status line."
679	},
680
681	{ .name = "status-right",
682	  .type = OPTIONS_TABLE_STRING,
683	  .scope = OPTIONS_TABLE_SESSION,
684	  .default_str = "#{?window_bigger,"
685			 "[#{window_offset_x}#,#{window_offset_y}] ,}"
686			 "\"#{=21:pane_title}\" %H:%M %d-%b-%y",
687	  .text = "Contents of the right side of the status line."
688
689	},
690
691	{ .name = "status-right-length",
692	  .type = OPTIONS_TABLE_NUMBER,
693	  .scope = OPTIONS_TABLE_SESSION,
694	  .minimum = 0,
695	  .maximum = SHRT_MAX,
696	  .default_num = 40,
697	  .text = "Maximum width of the right side of the status line."
698	},
699
700	{ .name = "status-right-style",
701	  .type = OPTIONS_TABLE_STRING,
702	  .scope = OPTIONS_TABLE_SESSION,
703	  .default_str = "default",
704	  .flags = OPTIONS_TABLE_IS_STYLE,
705	  .separator = ",",
706	  .text = "Style of the right side of the status line."
707	},
708
709	{ .name = "status-style",
710	  .type = OPTIONS_TABLE_STRING,
711	  .scope = OPTIONS_TABLE_SESSION,
712	  .default_str = "bg=green,fg=black",
713	  .flags = OPTIONS_TABLE_IS_STYLE,
714	  .separator = ",",
715	  .text = "Style of the status line."
716	},
717
718	{ .name = "update-environment",
719	  .type = OPTIONS_TABLE_STRING,
720	  .scope = OPTIONS_TABLE_SESSION,
721	  .flags = OPTIONS_TABLE_IS_ARRAY,
722	  .default_str = "DISPLAY KRB5CCNAME SSH_ASKPASS SSH_AUTH_SOCK "
723			 "SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY",
724	  .text = "List of environment variables to update in the session "
725		  "environment when a client is attached."
726	},
727
728	{ .name = "visual-activity",
729	  .type = OPTIONS_TABLE_CHOICE,
730	  .scope = OPTIONS_TABLE_SESSION,
731	  .choices = options_table_visual_bell_list,
732	  .default_num = VISUAL_OFF,
733	  .text = "How activity alerts should be shown: a message ('on'), "
734		  "a message and a bell ('both') or nothing ('off')."
735	},
736
737	{ .name = "visual-bell",
738	  .type = OPTIONS_TABLE_CHOICE,
739	  .scope = OPTIONS_TABLE_SESSION,
740	  .choices = options_table_visual_bell_list,
741	  .default_num = VISUAL_OFF,
742	  .text = "How bell alerts should be shown: a message ('on'), "
743		  "a message and a bell ('both') or nothing ('off')."
744	},
745
746	{ .name = "visual-silence",
747	  .type = OPTIONS_TABLE_CHOICE,
748	  .scope = OPTIONS_TABLE_SESSION,
749	  .choices = options_table_visual_bell_list,
750	  .default_num = VISUAL_OFF,
751	  .text = "How silence alerts should be shown: a message ('on'), "
752		  "a message and a bell ('both') or nothing ('off')."
753	},
754
755	{ .name = "word-separators",
756	  .type = OPTIONS_TABLE_STRING,
757	  .scope = OPTIONS_TABLE_SESSION,
758	  /*
759	   * The set of non-alphanumeric printable ASCII characters minus the
760	   * underscore.
761	   */
762	  .default_str = "!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~",
763	  .text = "Characters considered to separate words."
764	},
765
766	/* Window options. */
767	{ .name = "aggressive-resize",
768	  .type = OPTIONS_TABLE_FLAG,
769	  .scope = OPTIONS_TABLE_WINDOW,
770	  .default_num = 0,
771	  .text = "When 'window-size' is 'smallest', whether the maximum size "
772		  "of a window is the smallest attached session where it is "
773		  "the current window ('on') or the smallest session it is "
774		  "linked to ('off')."
775	},
776
777	{ .name = "allow-rename",
778	  .type = OPTIONS_TABLE_FLAG,
779	  .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
780	  .default_num = 0,
781	  .text = "Whether applications are allowed to use the escape sequence "
782		  "to rename windows."
783	},
784
785	{ .name = "alternate-screen",
786	  .type = OPTIONS_TABLE_FLAG,
787	  .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
788	  .default_num = 1,
789	  .text = "Whether applications are allowed to use the alternate "
790		  "screen."
791	},
792
793	{ .name = "automatic-rename",
794	  .type = OPTIONS_TABLE_FLAG,
795	  .scope = OPTIONS_TABLE_WINDOW,
796	  .default_num = 1,
797	  .text = "Whether windows are automatically renamed."
798	},
799
800	{ .name = "automatic-rename-format",
801	  .type = OPTIONS_TABLE_STRING,
802	  .scope = OPTIONS_TABLE_WINDOW,
803	  .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}"
804			 "#{?pane_dead,[dead],}",
805	  .text = "Format used to automatically rename windows."
806	},
807
808	{ .name = "clock-mode-colour",
809	  .type = OPTIONS_TABLE_COLOUR,
810	  .scope = OPTIONS_TABLE_WINDOW,
811	  .default_num = 4,
812	  .text = "Colour of the clock in clock mode."
813	},
814
815	{ .name = "clock-mode-style",
816	  .type = OPTIONS_TABLE_CHOICE,
817	  .scope = OPTIONS_TABLE_WINDOW,
818	  .choices = options_table_clock_mode_style_list,
819	  .default_num = 1,
820	  .text = "Time format of the clock in clock mode."
821	},
822
823	{ .name = "copy-mode-match-style",
824	  .type = OPTIONS_TABLE_STRING,
825	  .scope = OPTIONS_TABLE_WINDOW,
826	  .default_str = "bg=cyan,fg=black",
827	  .flags = OPTIONS_TABLE_IS_STYLE,
828	  .separator = ",",
829	  .text = "Style of search matches in copy mode."
830	},
831
832	{ .name = "copy-mode-current-match-style",
833	  .type = OPTIONS_TABLE_STRING,
834	  .scope = OPTIONS_TABLE_WINDOW,
835	  .default_str = "bg=magenta,fg=black",
836	  .flags = OPTIONS_TABLE_IS_STYLE,
837	  .separator = ",",
838	  .text = "Style of the current search match in copy mode."
839	},
840
841	{ .name = "copy-mode-mark-style",
842	  .type = OPTIONS_TABLE_STRING,
843	  .scope = OPTIONS_TABLE_WINDOW,
844	  .default_str = "bg=red,fg=black",
845	  .flags = OPTIONS_TABLE_IS_STYLE,
846	  .separator = ",",
847	  .text = "Style of the marked line in copy mode."
848	},
849
850	{ .name = "main-pane-height",
851	  .type = OPTIONS_TABLE_STRING,
852	  .scope = OPTIONS_TABLE_WINDOW,
853	  .default_str = "24",
854	  .text = "Height of the main pane in the 'main-horizontal' layout. "
855		  "This may be a percentage, for example '10%'."
856	},
857
858	{ .name = "main-pane-width",
859	  .type = OPTIONS_TABLE_STRING,
860	  .scope = OPTIONS_TABLE_WINDOW,
861	  .default_str = "80",
862	  .text = "Width of the main pane in the 'main-vertical' layout. "
863		  "This may be a percentage, for example '10%'."
864	},
865
866	{ .name = "mode-keys",
867	  .type = OPTIONS_TABLE_CHOICE,
868	  .scope = OPTIONS_TABLE_WINDOW,
869	  .choices = options_table_mode_keys_list,
870	  .default_num = MODEKEY_EMACS,
871	  .text = "Key set used in copy mode."
872	},
873
874	{ .name = "mode-style",
875	  .type = OPTIONS_TABLE_STRING,
876	  .scope = OPTIONS_TABLE_WINDOW,
877	  .default_str = "bg=yellow,fg=black",
878	  .flags = OPTIONS_TABLE_IS_STYLE,
879	  .separator = ",",
880	  .text = "Style of indicators and highlighting in modes."
881	},
882
883	{ .name = "monitor-activity",
884	  .type = OPTIONS_TABLE_FLAG,
885	  .scope = OPTIONS_TABLE_WINDOW,
886	  .default_num = 0,
887	  .text = "Whether an alert is triggered by activity."
888	},
889
890	{ .name = "monitor-bell",
891	  .type = OPTIONS_TABLE_FLAG,
892	  .scope = OPTIONS_TABLE_WINDOW,
893	  .default_num = 1,
894	  .text = "Whether an alert is triggered by a bell."
895	},
896
897	{ .name = "monitor-silence",
898	  .type = OPTIONS_TABLE_NUMBER,
899	  .scope = OPTIONS_TABLE_WINDOW,
900	  .minimum = 0,
901	  .maximum = INT_MAX,
902	  .default_num = 0,
903	  .text = "Time after which an alert is triggered by silence. "
904		  "Zero means no alert."
905
906	},
907
908	{ .name = "other-pane-height",
909	  .type = OPTIONS_TABLE_STRING,
910	  .scope = OPTIONS_TABLE_WINDOW,
911	  .default_str = "0",
912	  .text = "Height of the other panes in the 'main-horizontal' layout. "
913		  "This may be a percentage, for example '10%'."
914	},
915
916	{ .name = "other-pane-width",
917	  .type = OPTIONS_TABLE_STRING,
918	  .scope = OPTIONS_TABLE_WINDOW,
919	  .default_str = "0",
920	  .text = "Height of the other panes in the 'main-vertical' layout. "
921		  "This may be a percentage, for example '10%'."
922	},
923
924	{ .name = "pane-active-border-style",
925	  .type = OPTIONS_TABLE_STRING,
926	  .scope = OPTIONS_TABLE_WINDOW,
927	  .default_str = "#{?pane_in_mode,fg=yellow,#{?synchronize-panes,fg=red,fg=green}}",
928	  .flags = OPTIONS_TABLE_IS_STYLE,
929	  .separator = ",",
930	  .text = "Style of the active pane border."
931	},
932
933	{ .name = "pane-base-index",
934	  .type = OPTIONS_TABLE_NUMBER,
935	  .scope = OPTIONS_TABLE_WINDOW,
936	  .minimum = 0,
937	  .maximum = USHRT_MAX,
938	  .default_num = 0,
939	  .text = "Index of the first pane in each window."
940	},
941
942	{ .name = "pane-border-format",
943	  .type = OPTIONS_TABLE_STRING,
944	  .scope = OPTIONS_TABLE_WINDOW,
945	  .default_str = "#{?pane_active,#[reverse],}#{pane_index}#[default] "
946			 "\"#{pane_title}\"",
947	  .text = "Format of text in the pane status lines."
948	},
949
950	{ .name = "pane-border-lines",
951	  .type = OPTIONS_TABLE_CHOICE,
952	  .scope = OPTIONS_TABLE_WINDOW,
953	  .choices = options_table_pane_lines_list,
954	  .default_num = PANE_LINES_SINGLE,
955	  .text = "Type of characters used to draw pane border lines. Some of "
956	          "these are only supported on terminals with UTF-8 support."
957	},
958
959	{ .name = "pane-border-status",
960	  .type = OPTIONS_TABLE_CHOICE,
961	  .scope = OPTIONS_TABLE_WINDOW,
962	  .choices = options_table_pane_status_list,
963	  .default_num = PANE_STATUS_OFF,
964	  .text = "Position of the pane status lines."
965	},
966
967	{ .name = "pane-border-style",
968	  .type = OPTIONS_TABLE_STRING,
969	  .scope = OPTIONS_TABLE_WINDOW,
970	  .default_str = "default",
971	  .flags = OPTIONS_TABLE_IS_STYLE,
972	  .separator = ",",
973	  .text = "Style of the pane status lines."
974	},
975
976	{ .name = "remain-on-exit",
977	  .type = OPTIONS_TABLE_CHOICE,
978	  .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
979	  .choices = options_table_remain_on_exit_list,
980	  .default_num = 0,
981	  .text = "Whether panes should remain ('on') or be automatically "
982		  "killed ('off' or 'failed') when the program inside exits."
983	},
984
985	{ .name = "synchronize-panes",
986	  .type = OPTIONS_TABLE_FLAG,
987	  .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
988	  .default_num = 0,
989	  .text = "Whether typing should be sent to all panes simultaneously."
990	},
991
992	{ .name = "window-active-style",
993	  .type = OPTIONS_TABLE_STRING,
994	  .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
995	  .default_str = "default",
996	  .flags = OPTIONS_TABLE_IS_STYLE,
997	  .separator = ",",
998	  .text = "Default style of the active pane."
999	},
1000
1001	{ .name = "window-size",
1002	  .type = OPTIONS_TABLE_CHOICE,
1003	  .scope = OPTIONS_TABLE_WINDOW,
1004	  .choices = options_table_window_size_list,
1005	  .default_num = WINDOW_SIZE_LATEST,
1006	  .text = "How window size is calculated. "
1007		  "'latest' uses the size of the most recently used client, "
1008		  "'largest' the largest client, 'smallest' the smallest "
1009		  "client and 'manual' a size set by the 'resize-window' "
1010		  "command."
1011	},
1012
1013	{ .name = "window-style",
1014	  .type = OPTIONS_TABLE_STRING,
1015	  .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
1016	  .default_str = "default",
1017	  .flags = OPTIONS_TABLE_IS_STYLE,
1018	  .separator = ",",
1019	  .text = "Default style of panes that are not the active pane."
1020	},
1021
1022	{ .name = "window-status-activity-style",
1023	  .type = OPTIONS_TABLE_STRING,
1024	  .scope = OPTIONS_TABLE_WINDOW,
1025	  .default_str = "reverse",
1026	  .flags = OPTIONS_TABLE_IS_STYLE,
1027	  .separator = ",",
1028	  .text = "Style of windows in the status line with an activity alert."
1029	},
1030
1031	{ .name = "window-status-bell-style",
1032	  .type = OPTIONS_TABLE_STRING,
1033	  .scope = OPTIONS_TABLE_WINDOW,
1034	  .default_str = "reverse",
1035	  .flags = OPTIONS_TABLE_IS_STYLE,
1036	  .separator = ",",
1037	  .text = "Style of windows in the status line with a bell alert."
1038	},
1039
1040	{ .name = "window-status-current-format",
1041	  .type = OPTIONS_TABLE_STRING,
1042	  .scope = OPTIONS_TABLE_WINDOW,
1043	  .default_str = "#I:#W#{?window_flags,#{window_flags}, }",
1044	  .text = "Format of the current window in the status line."
1045	},
1046
1047	{ .name = "window-status-current-style",
1048	  .type = OPTIONS_TABLE_STRING,
1049	  .scope = OPTIONS_TABLE_WINDOW,
1050	  .default_str = "default",
1051	  .flags = OPTIONS_TABLE_IS_STYLE,
1052	  .separator = ",",
1053	  .text = "Style of the current window in the status line."
1054	},
1055
1056	{ .name = "window-status-format",
1057	  .type = OPTIONS_TABLE_STRING,
1058	  .scope = OPTIONS_TABLE_WINDOW,
1059	  .default_str = "#I:#W#{?window_flags,#{window_flags}, }",
1060	  .text = "Format of windows in the status line, except the current "
1061		  "window."
1062	},
1063
1064	{ .name = "window-status-last-style",
1065	  .type = OPTIONS_TABLE_STRING,
1066	  .scope = OPTIONS_TABLE_WINDOW,
1067	  .default_str = "default",
1068	  .flags = OPTIONS_TABLE_IS_STYLE,
1069	  .separator = ",",
1070	  .text = "Style of the last window in the status line."
1071	},
1072
1073	{ .name = "window-status-separator",
1074	  .type = OPTIONS_TABLE_STRING,
1075	  .scope = OPTIONS_TABLE_WINDOW,
1076	  .default_str = " ",
1077	  .text = "Separator between windows in the status line."
1078	},
1079
1080	{ .name = "window-status-style",
1081	  .type = OPTIONS_TABLE_STRING,
1082	  .scope = OPTIONS_TABLE_WINDOW,
1083	  .default_str = "default",
1084	  .flags = OPTIONS_TABLE_IS_STYLE,
1085	  .separator = ",",
1086	  .text = "Style of windows in the status line, except the current and "
1087		  "last windows."
1088	},
1089
1090	{ .name = "wrap-search",
1091	  .type = OPTIONS_TABLE_FLAG,
1092	  .scope = OPTIONS_TABLE_WINDOW,
1093	  .default_num = 1,
1094	  .text = "Whether searching in copy mode should wrap at the top or "
1095		  "bottom."
1096	},
1097
1098	{ .name = "xterm-keys", /* no longer used */
1099	  .type = OPTIONS_TABLE_FLAG,
1100	  .scope = OPTIONS_TABLE_WINDOW,
1101	  .default_num = 1,
1102	  .text = "Whether xterm-style function key sequences should be sent. "
1103	          "This option is no longer used."
1104	},
1105
1106	/* Hook options. */
1107	OPTIONS_TABLE_HOOK("after-bind-key", ""),
1108	OPTIONS_TABLE_HOOK("after-capture-pane", ""),
1109	OPTIONS_TABLE_HOOK("after-copy-mode", ""),
1110	OPTIONS_TABLE_HOOK("after-display-message", ""),
1111	OPTIONS_TABLE_HOOK("after-display-panes", ""),
1112	OPTIONS_TABLE_HOOK("after-kill-pane", ""),
1113	OPTIONS_TABLE_HOOK("after-list-buffers", ""),
1114	OPTIONS_TABLE_HOOK("after-list-clients", ""),
1115	OPTIONS_TABLE_HOOK("after-list-keys", ""),
1116	OPTIONS_TABLE_HOOK("after-list-panes", ""),
1117	OPTIONS_TABLE_HOOK("after-list-sessions", ""),
1118	OPTIONS_TABLE_HOOK("after-list-windows", ""),
1119	OPTIONS_TABLE_HOOK("after-load-buffer", ""),
1120	OPTIONS_TABLE_HOOK("after-lock-server", ""),
1121	OPTIONS_TABLE_HOOK("after-new-session", ""),
1122	OPTIONS_TABLE_HOOK("after-new-window", ""),
1123	OPTIONS_TABLE_HOOK("after-paste-buffer", ""),
1124	OPTIONS_TABLE_HOOK("after-pipe-pane", ""),
1125	OPTIONS_TABLE_HOOK("after-queue", ""),
1126	OPTIONS_TABLE_HOOK("after-refresh-client", ""),
1127	OPTIONS_TABLE_HOOK("after-rename-session", ""),
1128	OPTIONS_TABLE_HOOK("after-rename-window", ""),
1129	OPTIONS_TABLE_HOOK("after-resize-pane", ""),
1130	OPTIONS_TABLE_HOOK("after-resize-window", ""),
1131	OPTIONS_TABLE_HOOK("after-save-buffer", ""),
1132	OPTIONS_TABLE_HOOK("after-select-layout", ""),
1133	OPTIONS_TABLE_HOOK("after-select-pane", ""),
1134	OPTIONS_TABLE_HOOK("after-select-window", ""),
1135	OPTIONS_TABLE_HOOK("after-send-keys", ""),
1136	OPTIONS_TABLE_HOOK("after-set-buffer", ""),
1137	OPTIONS_TABLE_HOOK("after-set-environment", ""),
1138	OPTIONS_TABLE_HOOK("after-set-hook", ""),
1139	OPTIONS_TABLE_HOOK("after-set-option", ""),
1140	OPTIONS_TABLE_HOOK("after-show-environment", ""),
1141	OPTIONS_TABLE_HOOK("after-show-messages", ""),
1142	OPTIONS_TABLE_HOOK("after-show-options", ""),
1143	OPTIONS_TABLE_HOOK("after-split-window", ""),
1144	OPTIONS_TABLE_HOOK("after-unbind-key", ""),
1145	OPTIONS_TABLE_HOOK("alert-activity", ""),
1146	OPTIONS_TABLE_HOOK("alert-bell", ""),
1147	OPTIONS_TABLE_HOOK("alert-silence", ""),
1148	OPTIONS_TABLE_HOOK("client-active", ""),
1149	OPTIONS_TABLE_HOOK("client-attached", ""),
1150	OPTIONS_TABLE_HOOK("client-detached", ""),
1151 	OPTIONS_TABLE_HOOK("client-focus-in", ""),
1152 	OPTIONS_TABLE_HOOK("client-focus-out", ""),
1153	OPTIONS_TABLE_HOOK("client-resized", ""),
1154	OPTIONS_TABLE_HOOK("client-session-changed", ""),
1155	OPTIONS_TABLE_PANE_HOOK("pane-died", ""),
1156	OPTIONS_TABLE_PANE_HOOK("pane-exited", ""),
1157	OPTIONS_TABLE_PANE_HOOK("pane-focus-in", ""),
1158	OPTIONS_TABLE_PANE_HOOK("pane-focus-out", ""),
1159	OPTIONS_TABLE_PANE_HOOK("pane-mode-changed", ""),
1160	OPTIONS_TABLE_PANE_HOOK("pane-set-clipboard", ""),
1161	OPTIONS_TABLE_PANE_HOOK("pane-title-changed", ""),
1162	OPTIONS_TABLE_HOOK("session-closed", ""),
1163	OPTIONS_TABLE_HOOK("session-created", ""),
1164	OPTIONS_TABLE_HOOK("session-renamed", ""),
1165	OPTIONS_TABLE_HOOK("session-window-changed", ""),
1166	OPTIONS_TABLE_WINDOW_HOOK("window-layout-changed", ""),
1167	OPTIONS_TABLE_HOOK("window-linked", ""),
1168	OPTIONS_TABLE_WINDOW_HOOK("window-pane-changed", ""),
1169	OPTIONS_TABLE_WINDOW_HOOK("window-renamed", ""),
1170	OPTIONS_TABLE_HOOK("window-unlinked", ""),
1171
1172	{ .name = NULL }
1173};
1174