Move the user-visible parts of all options (names, types, limit, default

values) together into one set of tables in options-table.c. Also clean
up and simplify cmd-set-options.c and move a common print function into
option-table.c.
This commit is contained in:
Nicholas Marriott 2011-01-01 16:51:21 +00:00
parent a4515ce138
commit 3e8124009f
7 changed files with 913 additions and 527 deletions

View File

@ -32,7 +32,7 @@ SRCS= attributes.c cfg.c client.c clock.c \
colour.c environ.c grid-view.c grid-utf8.c grid.c input-keys.c \
input.c key-bindings.c key-string.c \
layout-custom.c layout-set.c layout-string.c layout.c log.c job.c \
mode-key.c names.c options.c paste.c procname.c \
mode-key.c names.c options.c options-table.c paste.c procname.c \
resize.c screen-redraw.c screen-write.c screen.c session.c status.c \
signal.c server-fn.c server.c server-client.c server-window.c \
tmux.c tty-acs.c tty-keys.c tty-term.c tty.c utf8.c \

View File

@ -29,22 +29,25 @@
int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const char *cmd_set_option_print(
const struct set_option_entry *, struct options_entry *);
void cmd_set_option_string(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *, int);
void cmd_set_option_number(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_keys(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_colour(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_attributes(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_flag(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_choice(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
int cmd_set_option_unset(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
int cmd_set_option_set(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
struct options_entry *cmd_set_option_keys(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
struct options_entry *cmd_set_option_attributes(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
@ -57,149 +60,26 @@ const struct cmd_entry cmd_set_option_entry = {
cmd_target_print
};
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_status_justify_list[] = {
"left", "centre", "right", NULL
};
const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL
};
const struct set_option_entry set_option_table[] = {
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "escape-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "exit-unattached", SET_OPTION_FLAG, 0, 0, NULL },
{ "quiet", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_session_option_table[] = {
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "default-command", SET_OPTION_STRING, 0, 0, NULL },
{ "default-path", SET_OPTION_STRING, 0, 0, NULL },
{ "default-shell", SET_OPTION_STRING, 0, 0, NULL },
{ "default-terminal", SET_OPTION_STRING, 0, 0, NULL },
{ "destroy-unattached", SET_OPTION_FLAG, 0, 0, NULL },
{ "detach-on-destroy", SET_OPTION_FLAG, 0, 0, NULL },
{ "display-panes-active-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-command", SET_OPTION_STRING, 0, 0, NULL },
{ "lock-server", SET_OPTION_FLAG, 0, 0, NULL },
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "mouse-select-pane", SET_OPTION_FLAG, 0, 0, NULL },
{ "pane-active-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-active-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "prefix", SET_OPTION_KEYS, 0, 0, NULL },
{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles-string", SET_OPTION_STRING, 0, 0, NULL },
{ "status", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "status-justify",
SET_OPTION_CHOICE, 0, 0, set_option_status_justify_list },
{ "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list },
{ "status-left", SET_OPTION_STRING, 0, 0, NULL },
{ "status-left-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-left-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-left-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-right-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL },
{ "update-environment", SET_OPTION_STRING, 0, 0, NULL },
{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-silence", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "alternate-screen", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "monitor-silence",SET_OPTION_NUMBER, 0, INT_MAX, NULL},
{ "other-pane-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "other-pane-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-alert-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-alert-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-alert-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
{ "word-separators", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry, *opt;
struct jobs *jobs;
struct job *job, *nextjob;
u_int i;
int try_again;
struct cmd_target_data *data = self->data;
const struct options_table_entry *table, *oe, *oe_loop;
struct session *s;
struct winlink *wl;
struct client *c;
struct options *oo;
struct jobs *jobs;
struct job *job, *nextjob;
u_int i;
int try_again;
/* Work out the options tree and table to use. */
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
table = set_option_table;
table = server_options_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
table = window_options_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
@ -209,7 +89,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
table = session_options_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
@ -220,71 +100,36 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (*data->arg == '\0') {
ctx->error(ctx, "invalid option");
return (-1);
}
entry = NULL;
for (opt = table; opt->name != NULL; opt++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
/* Find the option table entry. */
oe = NULL;
for (oe_loop = table; oe_loop->name != NULL; oe_loop++) {
if (strncmp(oe_loop->name, data->arg, strlen(data->arg)) != 0)
continue;
if (entry != NULL) {
if (oe != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg);
return (-1);
}
entry = opt;
oe = oe_loop;
/* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0)
if (strcmp(oe->name, data->arg) == 0)
break;
}
if (entry == NULL) {
if (oe == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg);
return (-1);
}
/* Unset or set the option. */
if (cmd_check_flag(data->chflags, 'u')) {
if (cmd_check_flag(data->chflags, 'g')) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
if (cmd_set_option_unset(self, ctx, oe, oo) != 0)
return (-1);
}
if (data->arg2 != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
}
options_remove(oo, entry->name);
ctx->info(ctx, "unset option: %s", entry->name);
} else {
switch (entry->type) {
case SET_OPTION_STRING:
cmd_set_option_string(ctx, oo, entry,
data->arg2, cmd_check_flag(data->chflags, 'a'));
break;
case SET_OPTION_NUMBER:
cmd_set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEYS:
cmd_set_option_keys(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
cmd_set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
cmd_set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
cmd_set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
cmd_set_option_choice(ctx, oo, entry, data->arg2);
break;
}
if (cmd_set_option_set(self, ctx, oe, oo) != 0)
return (-1);
}
/* Update sizes and redraw. May not need it but meh. */
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
@ -297,11 +142,11 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
* or set-titles-string have changed. Persistent jobs are only used by
* the status line at the moment so this works XXX.
*/
if (strcmp(entry->name, "status-left") == 0 ||
strcmp(entry->name, "status-right") == 0 ||
strcmp(entry->name, "status") == 0 ||
strcmp(entry->name, "set-titles-string") == 0 ||
strcmp(entry->name, "window-status-format") == 0) {
if (strcmp(oe->name, "status-left") == 0 ||
strcmp(oe->name, "status-right") == 0 ||
strcmp(oe->name, "status") == 0 ||
strcmp(oe->name, "set-titles-string") == 0 ||
strcmp(oe->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
@ -328,242 +173,226 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
const char *
cmd_set_option_print(
const struct set_option_entry *entry, struct options_entry *o)
/* Unset an option. */
int
cmd_set_option_unset(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
static char out[BUFSIZ];
const char *s;
struct keylist *keylist;
u_int i;
struct cmd_target_data *data = self->data;
*out = '\0';
switch (entry->type) {
case SET_OPTION_STRING:
xsnprintf(out, sizeof out, "\"%s\"", o->str);
break;
case SET_OPTION_NUMBER:
xsnprintf(out, sizeof out, "%lld", o->num);
break;
case SET_OPTION_KEYS:
keylist = o->data;
for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
strlcat(out, key_string_lookup_key(
ARRAY_ITEM(keylist, i)), sizeof out);
if (i != ARRAY_LENGTH(keylist) - 1)
strlcat(out, ",", sizeof out);
}
break;
case SET_OPTION_COLOUR:
s = colour_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_ATTRIBUTES:
s = attributes_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_FLAG:
if (o->num)
strlcpy(out, "on", sizeof out);
else
strlcpy(out, "off", sizeof out);
break;
case SET_OPTION_CHOICE:
s = entry->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
if (cmd_check_flag(data->chflags, 'g')) {
ctx->error(ctx, "can't unset global option: %s", oe->name);
return (-1);
}
return (out);
if (data->arg2 != NULL) {
ctx->error(ctx, "value passed to unset option: %s", oe->name);
return (-1);
}
options_remove(oo, oe->name);
ctx->info(ctx, "unset option: %s", oe->name);
return (0);
}
void
cmd_set_option_string(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value, int append)
/* Set an option. */
int
cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct cmd_target_data *data = self->data;
struct options_entry *o;
char *oldvalue, *newvalue;
const char *s;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
if (oe->type != OPTIONS_TABLE_FLAG && data->arg2 == NULL) {
ctx->error(ctx, "empty data->arg2");
return (-1);
}
if (append) {
oldvalue = options_get_string(oo, entry->name);
xasprintf(&newvalue, "%s%s", oldvalue, value);
o = NULL;
switch (oe->type) {
case OPTIONS_TABLE_STRING:
o = cmd_set_option_string(self, ctx, oe, oo);
break;
case OPTIONS_TABLE_NUMBER:
o = cmd_set_option_number(self, ctx, oe, oo);
break;
case OPTIONS_TABLE_KEYS:
o = cmd_set_option_keys(self, ctx, oe, oo);
break;
case OPTIONS_TABLE_COLOUR:
o = cmd_set_option_colour(self, ctx, oe, oo);
break;
case OPTIONS_TABLE_ATTRIBUTES:
o = cmd_set_option_attributes(self, ctx, oe, oo);
break;
case OPTIONS_TABLE_FLAG:
o = cmd_set_option_flag(self, ctx, oe, oo);
break;
case OPTIONS_TABLE_CHOICE:
o = cmd_set_option_choice(self, ctx, oe, oo);
break;
}
if (o == NULL)
return (-1);
s = options_table_print_entry(oe, o);
ctx->info(ctx, "set option: %s -> %s", oe->name, s);
return (0);
}
/* Set a string option. */
struct options_entry *
cmd_set_option_string(struct cmd *self, unused struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct cmd_target_data *data = self->data;
struct options_entry *o;
char *oldval, *newval;
if (cmd_check_flag(data->chflags, 'a')) {
oldval = options_get_string(oo, oe->name);
xasprintf(&newval, "%s%s", oldval, data->arg2);
} else
newvalue = value;
newval = data->arg2;
o = options_set_string(oo, entry->name, "%s", newvalue);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
o = options_set_string(oo, oe->name, "%s", newval);
if (newvalue != value)
xfree(newvalue);
if (newval != data->arg2)
xfree(newval);
return (o);
}
void
cmd_set_option_number(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
/* Set a number option. */
struct options_entry *
cmd_set_option_number(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct options_entry *o;
long long number;
struct cmd_target_data *data = self->data;
long long ll;
const char *errstr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
number = strtonum(value, entry->minimum, entry->maximum, &errstr);
ll = strtonum(data->arg2, oe->minimum, oe->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
return;
ctx->error(ctx, "value is %s: %s", errstr, data->arg2);
return (NULL);
}
o = options_set_number(oo, entry->name, number);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
return (options_set_number(oo, oe->name, ll));
}
void
cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
/* Set a keys option. */
struct options_entry *
cmd_set_option_keys(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct options_entry *o;
struct cmd_target_data *data = self->data;
struct keylist *keylist;
char *copyvalue, *ptr, *str;
char *copy, *ptr, *s;
int key;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ptr = copyvalue = xstrdup(value);
while ((str = strsep(&ptr, ",")) != NULL) {
if ((key = key_string_lookup_string(str)) == KEYC_NONE) {
ptr = copy = xstrdup(data->arg2);
while ((s = strsep(&ptr, ",")) != NULL) {
if ((key = key_string_lookup_string(s)) == KEYC_NONE) {
ctx->error(ctx, "unknown key: %s", s);
xfree(copy);
xfree(keylist);
ctx->error(ctx, "unknown key: %s", str);
xfree(copyvalue);
return;
return (NULL);
}
ARRAY_ADD(keylist, key);
}
xfree(copyvalue);
xfree(copy);
o = options_set_data(oo, entry->name, keylist, xfree);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
return (options_set_data(oo, oe->name, keylist, xfree));
}
void
cmd_set_option_colour(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
/* Set a colour option. */
struct options_entry *
cmd_set_option_colour(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct options_entry *o;
struct cmd_target_data *data = self->data;
int colour;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
if ((colour = colour_fromstring(data->arg2)) == -1) {
ctx->error(ctx, "bad colour: %s", data->arg2);
return (NULL);
}
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
return;
}
o = options_set_number(oo, entry->name, colour);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
return (options_set_number(oo, oe->name, colour));
}
void
cmd_set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
/* Set an attributes option. */
struct options_entry *
cmd_set_option_attributes(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct options_entry *o;
struct cmd_target_data *data = self->data;
int attr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
if ((attr = attributes_fromstring(data->arg2)) == -1) {
ctx->error(ctx, "bad attributes: %s", data->arg2);
return (NULL);
}
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
return;
}
o = options_set_number(oo, entry->name, attr);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
return (options_set_number(oo, oe->name, attr));
}
void
cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
/* Set a flag option. */
struct options_entry *
cmd_set_option_flag(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct options_entry *o;
struct cmd_target_data *data = self->data;
int flag;
if (value == NULL || *value == '\0')
flag = !options_get_number(oo, entry->name);
if (data->arg2 == NULL || *data->arg2 == '\0')
flag = !options_get_number(oo, oe->name);
else {
if ((value[0] == '1' && value[1] == '\0') ||
strcasecmp(value, "on") == 0 ||
strcasecmp(value, "yes") == 0)
if ((data->arg2[0] == '1' && data->arg2[1] == '\0') ||
strcasecmp(data->arg2, "on") == 0 ||
strcasecmp(data->arg2, "yes") == 0)
flag = 1;
else if ((value[0] == '0' && value[1] == '\0') ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
else if ((data->arg2[0] == '0' && data->arg2[1] == '\0') ||
strcasecmp(data->arg2, "off") == 0 ||
strcasecmp(data->arg2, "no") == 0)
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
return;
ctx->error(ctx, "bad value: %s", data->arg2);
return (NULL);
}
}
o = options_set_number(oo, entry->name, flag);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
return (options_set_number(oo, oe->name, flag));
}
void
cmd_set_option_choice(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
/* Set a choice option. */
struct options_entry *
cmd_set_option_choice(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo)
{
struct options_entry *o;
struct cmd_target_data *data = self->data;
const char **choicep;
int n, choice = -1;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
n = 0;
for (choicep = entry->choices; *choicep != NULL; choicep++) {
for (choicep = oe->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
if (strncmp(*choicep, data->arg2, strlen(data->arg2)) != 0)
continue;
if (choice != -1) {
ctx->error(ctx, "ambiguous option value: %s", value);
return;
ctx->error(ctx, "ambiguous value: %s", data->arg2);
return (NULL);
}
choice = n - 1;
}
if (choice == -1) {
ctx->error(ctx, "unknown option value: %s", value);
return;
ctx->error(ctx, "unknown value: %s", data->arg2);
return (NULL);
}
o = options_set_number(oo, entry->name, choice);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
return (options_set_number(oo, oe->name, choice));
}

View File

@ -43,20 +43,19 @@ const struct cmd_entry cmd_show_options_entry = {
int
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
const char *optval;
struct cmd_target_data *data = self->data;
const struct options_table_entry *table, *oe;
struct session *s;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const char *optval;
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
table = set_option_table;
table = server_options_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
table = window_options_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
@ -66,7 +65,7 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
table = session_options_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
@ -77,11 +76,11 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
for (entry = table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
for (oe = table; oe->name != NULL; oe++) {
if ((o = options_find1(oo, oe->name)) == NULL)
continue;
optval = cmd_set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
optval = options_table_print_entry(oe, o);
ctx->print(ctx, "%s %s", oe->name, optval);
}
return (0);

639
options-table.c Normal file
View File

@ -0,0 +1,639 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include <paths.h>
#include "tmux.h"
/*
* This file has a tables with all the server, session and window
* options. These tables are the master copy of the options with their real
* (user-visible) types, range limits and default values. At start these are
* copied into the runtime global options trees (which only has number and
* string types). These tables are then used to loop up the real type when
* the user sets an option or its value needs to be shown.
*/
/* Choice option type lists. */
const char *options_table_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *options_table_clock_mode_style_list[] = {
"12", "24", NULL
};
const char *options_table_status_keys_list[] = {
"emacs", "vi", NULL
};
const char *options_table_status_justify_list[] = {
"left", "centre", "right", NULL
};
const char *options_table_bell_action_list[] = {
"none", "any", "current", NULL
};
/* Server options. */
const struct options_table_entry server_options_table[] = {
{ .name = "buffer-limit",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 1,
.maximum = INT_MAX,
.default_num = 9
},
{ .name = "escape-time",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 500
},
{ .name = "exit-unattached",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "quiet",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0 /* overridden in main() */
},
{ .name = NULL }
};
/* Session options. */
const struct options_table_entry session_options_table[] = {
{ .name = "base-index",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 0
},
{ .name = "bell-action",
.type = OPTIONS_TABLE_CHOICE,
.choices = options_table_bell_action_list,
.default_num = BELL_ANY
},
{ .name = "default-command",
.type = OPTIONS_TABLE_STRING,
.default_str = ""
},
{ .name = "default-path",
.type = OPTIONS_TABLE_STRING,
.default_str = ""
},
{ .name = "default-shell",
.type = OPTIONS_TABLE_STRING,
.default_str = _PATH_BSHELL
},
{ .name = "default-terminal",
.type = OPTIONS_TABLE_STRING,
.default_str = "screen"
},
{ .name = "destroy-unattached",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "detach-on-destroy",
.type = OPTIONS_TABLE_FLAG,
.default_num = 1
},
{ .name = "display-panes-active-colour",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 1
},
{ .name = "display-panes-colour",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 4
},
{ .name = "display-panes-time",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 1,
.maximum = INT_MAX,
.default_num = 1000
},
{ .name = "display-time",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 1,
.maximum = INT_MAX,
.default_num = 750
},
{ .name = "history-limit",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = SHRT_MAX,
.default_num = 2000
},
{ .name = "lock-after-time",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 0
},
{ .name = "lock-command",
.type = OPTIONS_TABLE_STRING,
.default_str = "lock -np"
},
{ .name = "lock-server",
.type = OPTIONS_TABLE_FLAG,
.default_num = 1
},
{ .name = "message-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "message-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 3
},
{ .name = "message-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 0
},
{ .name = "message-limit",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 20
},
{ .name = "mouse-select-pane",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "pane-active-border-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "pane-active-border-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 2
},
{ .name = "pane-border-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "pane-border-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "prefix",
.type = OPTIONS_TABLE_KEYS,
/* set in main() */
},
{ .name = "repeat-time",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = SHRT_MAX,
.default_num = 500
},
{ .name = "set-remain-on-exit",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "set-titles",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "set-titles-string",
.type = OPTIONS_TABLE_STRING,
.default_str = "#S:#I:#W - \"#T\""
},
{ .name = "status",
.type = OPTIONS_TABLE_FLAG,
.default_num = 1
},
{ .name = "status-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "status-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 2
},
{ .name = "status-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 0
},
{ .name = "status-interval",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 15
},
{ .name = "status-justify",
.type = OPTIONS_TABLE_CHOICE,
.choices = options_table_status_justify_list,
.default_num = 0
},
{ .name = "status-keys",
.type = OPTIONS_TABLE_CHOICE,
.choices = options_table_status_keys_list,
.default_num = MODEKEY_EMACS
},
{ .name = "status-left",
.type = OPTIONS_TABLE_STRING,
.default_str = "[#S]"
},
{ .name = "status-left-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "status-left-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "status-left-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "status-left-length",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = SHRT_MAX,
.default_num = 10
},
{ .name = "status-right",
.type = OPTIONS_TABLE_STRING,
.default_str = "\"#22T\" %H:%M %d-%b-%y"
},
{ .name = "status-right-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "status-right-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "status-right-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "status-right-length",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = SHRT_MAX,
.default_num = 40
},
{ .name = "status-utf8",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0 /* overridden in main() */
},
{ .name = "terminal-overrides",
.type = OPTIONS_TABLE_STRING,
.default_str = "*88col*:colors=88,*256col*:colors=256"
},
{ .name = "update-environment",
.type = OPTIONS_TABLE_STRING,
.default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
"SSH_CONNECTION WINDOWID XAUTHORITY"
},
{ .name = "visual-activity",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "visual-bell",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "visual-content",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "visual-silence",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = NULL }
};
/* Window options. */
const struct options_table_entry window_options_table[] = {
{ .name = "aggressive-resize",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "alternate-screen",
.type = OPTIONS_TABLE_FLAG,
.default_num = 1
},
{ .name = "automatic-rename",
.type = OPTIONS_TABLE_FLAG,
.default_num = 1
},
{ .name = "clock-mode-colour",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 4
},
{ .name = "clock-mode-style",
.type = OPTIONS_TABLE_CHOICE,
.choices = options_table_clock_mode_style_list,
.default_num = 1
},
{ .name = "force-height",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 0
},
{ .name = "force-width",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 0
},
{ .name = "main-pane-height",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 1,
.maximum = INT_MAX,
.default_num = 24
},
{ .name = "main-pane-width",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 1,
.maximum = INT_MAX,
.default_num = 80
},
{ .name = "mode-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "mode-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 3
},
{ .name = "mode-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 0
},
{ .name = "mode-keys",
.type = OPTIONS_TABLE_CHOICE,
.choices = options_table_mode_keys_list,
.default_num = MODEKEY_EMACS
},
{ .name = "mode-mouse",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "monitor-activity",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "monitor-content",
.type = OPTIONS_TABLE_STRING,
.default_str = ""
},
{ .name = "monitor-silence",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 0
},
{ .name = "other-pane-height",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 0
},
{ .name = "other-pane-width",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 0
},
{ .name = "remain-on-exit",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "synchronize-panes",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "utf8",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0 /* overridden in main() */
},
{ .name = "window-status-alert-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE
},
{ .name = "window-status-alert-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-alert-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "window-status-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-current-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "window-status-current-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-current-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-current-format",
.type = OPTIONS_TABLE_STRING,
.default_str = "#I:#W#F"
},
{ .name = "window-status-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-format",
.type = OPTIONS_TABLE_STRING,
.default_str = "#I:#W#F"
},
{ .name = "word-separators",
.type = OPTIONS_TABLE_STRING,
.default_str = " -_@"
},
{ .name = "xterm-keys",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = NULL }
};
/* Populate an options tree from a table. */
void
options_table_populate_tree(
const struct options_table_entry *table, struct options *oo)
{
const struct options_table_entry *oe;
for (oe = table; oe->name != NULL; oe++) {
if (oe->default_str != NULL)
options_set_string(oo, oe->name, "%s", oe->default_str);
else
options_set_number(oo, oe->name, oe->default_num);
}
}
/* Print an option using its type from the table. */
const char *
options_table_print_entry(
const struct options_table_entry *oe, struct options_entry *o)
{
static char out[BUFSIZ];
const char *s;
struct keylist *keylist;
u_int i;
*out = '\0';
switch (oe->type) {
case OPTIONS_TABLE_STRING:
xsnprintf(out, sizeof out, "\"%s\"", o->str);
break;
case OPTIONS_TABLE_NUMBER:
xsnprintf(out, sizeof out, "%lld", o->num);
break;
case OPTIONS_TABLE_KEYS:
keylist = o->data;
for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
s = key_string_lookup_key(ARRAY_ITEM(keylist, i));
strlcat(out, s, sizeof out);
if (i != ARRAY_LENGTH(keylist) - 1)
strlcat(out, ",", sizeof out);
}
break;
case OPTIONS_TABLE_COLOUR:
s = colour_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case OPTIONS_TABLE_ATTRIBUTES:
s = attributes_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case OPTIONS_TABLE_FLAG:
if (o->num)
strlcpy(out, "on", sizeof out);
else
strlcpy(out, "off", sizeof out);
break;
case OPTIONS_TABLE_CHOICE:
s = oe->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
}
return (out);
}

View File

@ -1112,12 +1112,12 @@ status_prompt_add_history(const char *line)
char *
status_prompt_complete(const char *s)
{
const struct cmd_entry **cmdent;
const struct set_option_entry *entry;
ARRAY_DECL(, const char *) list;
char *prefix, *s2;
u_int i;
size_t j;
const struct cmd_entry **cmdent;
const struct options_table_entry *oe;
ARRAY_DECL(, const char *) list;
char *prefix, *s2;
u_int i;
size_t j;
if (*s == '\0')
return (NULL);
@ -1128,17 +1128,17 @@ status_prompt_complete(const char *s)
if (strncmp((*cmdent)->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, (*cmdent)->name);
}
for (entry = set_option_table; entry->name != NULL; entry++) {
if (strncmp(entry->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, entry->name);
for (oe = server_options_table; oe->name != NULL; oe++) {
if (strncmp(oe->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, oe->name);
}
for (entry = set_session_option_table; entry->name != NULL; entry++) {
if (strncmp(entry->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, entry->name);
for (oe = session_options_table; oe->name != NULL; oe++) {
if (strncmp(oe->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, oe->name);
}
for (entry = set_window_option_table; entry->name != NULL; entry++) {
if (strncmp(entry->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, entry->name);
for (oe = window_options_table; oe->name != NULL; oe++) {
if (strncmp(oe->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, oe->name);
}
/* If none, bail now. */

125
tmux.c
View File

@ -228,7 +228,6 @@ int
main(int argc, char **argv)
{
struct passwd *pw;
struct options *oo, *so, *wo;
struct keylist *keylist;
char *s, *path, *label, *home, **var;
int opt, flags, quiet, keys;
@ -316,129 +315,39 @@ main(int argc, char **argv)
environ_put(&global_environ, *var);
options_init(&global_options, NULL);
oo = &global_options;
options_set_number(oo, "quiet", quiet);
options_set_number(oo, "escape-time", 500);
options_set_number(oo, "exit-unattached", 0);
options_set_number(oo, "buffer-limit", 9);
options_table_populate_tree(server_options_table, &global_options);
options_set_number(&global_options, "quiet", quiet);
options_init(&global_s_options, NULL);
so = &global_s_options;
options_set_number(so, "base-index", 0);
options_set_number(so, "bell-action", BELL_ANY);
options_set_string(so, "default-command", "%s", "");
options_set_string(so, "default-path", "%s", "");
options_set_string(so, "default-shell", "%s", getshell());
options_set_string(so, "default-terminal", "screen");
options_set_number(so, "destroy-unattached", 0);
options_set_number(so, "detach-on-destroy", 1);
options_set_number(so, "display-panes-active-colour", 1);
options_set_number(so, "display-panes-colour", 4);
options_set_number(so, "display-panes-time", 1000);
options_set_number(so, "display-time", 750);
options_set_number(so, "history-limit", 2000);
options_set_number(so, "lock-after-time", 0);
options_set_string(so, "lock-command", "lock -np");
options_set_number(so, "lock-server", 1);
options_set_number(so, "message-attr", 0);
options_set_number(so, "message-bg", 3);
options_set_number(so, "message-fg", 0);
options_set_number(so, "message-limit", 20);
options_set_number(so, "mouse-select-pane", 0);
options_set_number(so, "pane-active-border-bg", 8);
options_set_number(so, "pane-active-border-fg", 2);
options_set_number(so, "pane-border-bg", 8);
options_set_number(so, "pane-border-fg", 8);
options_set_number(so, "repeat-time", 500);
options_set_number(so, "set-remain-on-exit", 0);
options_set_number(so, "set-titles", 0);
options_set_string(so, "set-titles-string", "#S:#I:#W - \"#T\"");
options_set_number(so, "status", 1);
options_set_number(so, "status-attr", 0);
options_set_number(so, "status-bg", 2);
options_set_number(so, "status-fg", 0);
options_set_number(so, "status-interval", 15);
options_set_number(so, "status-justify", 0);
options_set_string(so, "status-left", "[#S]");
options_set_number(so, "status-left-attr", 0);
options_set_number(so, "status-left-bg", 8);
options_set_number(so, "status-left-fg", 8);
options_set_number(so, "status-left-length", 10);
options_set_string(so, "status-right", "\"#22T\" %%H:%%M %%d-%%b-%%y");
options_set_number(so, "status-right-attr", 0);
options_set_number(so, "status-right-bg", 8);
options_set_number(so, "status-right-fg", 8);
options_set_number(so, "status-right-length", 40);
options_set_string(so, "terminal-overrides",
"*88col*:colors=88,*256col*:colors=256");
options_set_string(so, "update-environment",
"DISPLAY "
"SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION "
"WINDOWID "
"XAUTHORITY");
options_set_number(so, "visual-activity", 0);
options_set_number(so, "visual-bell", 0);
options_set_number(so, "visual-content", 0);
options_set_number(so, "visual-silence", 0);
options_table_populate_tree(session_options_table, &global_s_options);
options_set_string(&global_s_options, "default-shell", "%s", getshell());
options_init(&global_w_options, NULL);
options_table_populate_tree(window_options_table, &global_w_options);
/* Set the prefix option (its a list, so not in the table). */
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ARRAY_ADD(keylist, '\002');
options_set_data(so, "prefix", keylist, xfree);
options_init(&global_w_options, NULL);
wo = &global_w_options;
options_set_number(wo, "aggressive-resize", 0);
options_set_number(wo, "alternate-screen", 1);
options_set_number(wo, "automatic-rename", 1);
options_set_number(wo, "clock-mode-colour", 4);
options_set_number(wo, "clock-mode-style", 1);
options_set_number(wo, "force-height", 0);
options_set_number(wo, "force-width", 0);
options_set_number(wo, "main-pane-height", 24);
options_set_number(wo, "main-pane-width", 80);
options_set_number(wo, "mode-attr", 0);
options_set_number(wo, "mode-bg", 3);
options_set_number(wo, "mode-fg", 0);
options_set_number(wo, "mode-mouse", 0);
options_set_number(wo, "monitor-activity", 0);
options_set_string(wo, "monitor-content", "%s", "");
options_set_number(wo, "monitor-silence", 0);
options_set_number(wo, "other-pane-height", 0);
options_set_number(wo, "other-pane-width", 0);
options_set_number(wo, "window-status-attr", 0);
options_set_number(wo, "window-status-bg", 8);
options_set_number(wo, "window-status-current-attr", 0);
options_set_number(wo, "window-status-current-bg", 8);
options_set_number(wo, "window-status-current-fg", 8);
options_set_number(wo, "window-status-fg", 8);
options_set_number(wo, "window-status-alert-attr", GRID_ATTR_REVERSE);
options_set_number(wo, "window-status-alert-bg", 8);
options_set_number(wo, "window-status-alert-fg", 8);
options_set_string(wo, "window-status-format", "#I:#W#F");
options_set_string(wo, "window-status-current-format", "#I:#W#F");
options_set_string(wo, "word-separators", " -_@");
options_set_number(wo, "xterm-keys", 0);
options_set_number(wo, "remain-on-exit", 0);
options_set_number(wo, "synchronize-panes", 0);
options_set_data(&global_s_options, "prefix", keylist, xfree);
/* Enable UTF-8 if the first client is on UTF-8 terminal. */
if (flags & IDENTIFY_UTF8) {
options_set_number(so, "status-utf8", 1);
options_set_number(wo, "utf8", 1);
} else {
options_set_number(so, "status-utf8", 0);
options_set_number(wo, "utf8", 0);
options_set_number(&global_s_options, "status-utf8", 1);
options_set_number(&global_w_options, "utf8", 1);
}
keys = MODEKEY_EMACS;
/* Override keys to vi if VISUAL or EDITOR are set. */
if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) {
if (strrchr(s, '/') != NULL)
s = strrchr(s, '/') + 1;
if (strstr(s, "vi") != NULL)
keys = MODEKEY_VI;
else
keys = MODEKEY_EMACS;
options_set_number(&global_s_options, "status-keys", keys);
options_set_number(&global_w_options, "mode-keys", keys);
}
options_set_number(so, "status-keys", keys);
options_set_number(wo, "mode-keys", keys);
/* Locate the configuration file. */
if (cfg_file == NULL) {

54
tmux.h
View File

@ -1270,23 +1270,31 @@ struct key_binding {
};
SPLAY_HEAD(key_bindings, key_binding);
/* Set/display option data. */
struct set_option_entry {
const char *name;
enum {
SET_OPTION_STRING,
SET_OPTION_NUMBER,
SET_OPTION_KEYS,
SET_OPTION_COLOUR,
SET_OPTION_ATTRIBUTES,
SET_OPTION_FLAG,
SET_OPTION_CHOICE
} type;
/*
* Option table entries. The option table is the user-visible part of the
* option, as opposed to the internal options (struct option) which are just
* number or string.
*/
enum options_table_type {
OPTIONS_TABLE_STRING,
OPTIONS_TABLE_NUMBER,
OPTIONS_TABLE_KEYS,
OPTIONS_TABLE_COLOUR,
OPTIONS_TABLE_ATTRIBUTES,
OPTIONS_TABLE_FLAG,
OPTIONS_TABLE_CHOICE
};
u_int minimum;
u_int maximum;
struct options_table_entry {
const char *name;
enum options_table_type type;
const char **choices;
u_int minimum;
u_int maximum;
const char **choices;
const char *default_str;
long long default_num;
};
/* List of configuration causes. */
@ -1356,6 +1364,15 @@ struct options_entry *options_set_data(
struct options *, const char *, void *, void (*)(void *));
void *options_get_data(struct options *, const char *);
/* options-table.c */
extern const struct options_table_entry server_options_table[];
extern const struct options_table_entry session_options_table[];
extern const struct options_table_entry window_options_table[];
void options_table_populate_tree(
const struct options_table_entry *, struct options *);
const char *options_table_print_entry(
const struct options_table_entry *, struct options_entry *);
/* job.c */
extern struct joblist all_jobs;
int job_cmp(struct job *, struct job *);
@ -1461,13 +1478,6 @@ char *paste_print(struct paste_buffer *, size_t);
extern const char clock_table[14][5][5];
void clock_draw(struct screen_write_ctx *, int, int);
/* cmd-set-option.c */
extern const struct set_option_entry set_option_table[];
extern const struct set_option_entry set_session_option_table[];
extern const struct set_option_entry set_window_option_table[];
const char *cmd_set_option_print(
const struct set_option_entry *, struct options_entry *);
/* cmd.c */
int cmd_pack_argv(int, char **, char *, size_t);
int cmd_unpack_argv(char *, size_t, int, char ***);