mirror of
https://github.com/tmux/tmux.git
synced 2025-09-03 14:27:09 +00:00
Add a customize mode where keys and options may be browsed and changed,
includes adding a brief description of each option. Bound to "C" by default.
This commit is contained in:
216
cmd-set-option.c
216
cmd-set-option.c
@ -30,15 +30,6 @@
|
||||
|
||||
static enum cmd_retval cmd_set_option_exec(struct cmd *, struct cmdq_item *);
|
||||
|
||||
static int cmd_set_option_set(struct cmd *, struct cmdq_item *,
|
||||
struct options *, struct options_entry *, const char *);
|
||||
static int cmd_set_option_flag(struct cmdq_item *,
|
||||
const struct options_table_entry *, struct options *,
|
||||
const char *);
|
||||
static int cmd_set_option_choice(struct cmdq_item *,
|
||||
const struct options_table_entry *, struct options *,
|
||||
const char *);
|
||||
|
||||
const struct cmd_entry cmd_set_option_entry = {
|
||||
.name = "set-option",
|
||||
.alias = "set",
|
||||
@ -84,10 +75,6 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct args *args = cmd_get_args(self);
|
||||
int append = args_has(args, 'a');
|
||||
struct cmd_find_state *target = cmdq_get_target(item);
|
||||
struct client *loop;
|
||||
struct session *s = target->s;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
struct options *oo;
|
||||
struct options_entry *parent, *o;
|
||||
char *name, *argument, *value = NULL, *cause;
|
||||
@ -138,7 +125,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
|
||||
parent = options_get(oo, name);
|
||||
|
||||
/* Check that array options and indexes match up. */
|
||||
if (idx != -1 && (*name == '@' || !options_isarray(parent))) {
|
||||
if (idx != -1 && (*name == '@' || !options_is_array(parent))) {
|
||||
cmdq_error(item, "not an array: %s", argument);
|
||||
goto fail;
|
||||
}
|
||||
@ -185,10 +172,15 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
|
||||
goto fail;
|
||||
}
|
||||
options_set_string(oo, name, append, "%s", value);
|
||||
} else if (idx == -1 && !options_isarray(parent)) {
|
||||
error = cmd_set_option_set(self, item, oo, parent, value);
|
||||
if (error != 0)
|
||||
} else if (idx == -1 && !options_is_array(parent)) {
|
||||
error = options_from_string(oo, options_table_entry(parent),
|
||||
options_table_entry(parent)->name, value,
|
||||
args_has(args, 'a'), &cause);
|
||||
if (error != 0) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
free(cause);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if (value == NULL) {
|
||||
cmdq_error(item, "empty value");
|
||||
@ -212,51 +204,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
|
||||
}
|
||||
}
|
||||
|
||||
/* Update timers and so on for various options. */
|
||||
if (strcmp(name, "automatic-rename") == 0) {
|
||||
RB_FOREACH(w, windows, &windows) {
|
||||
if (w->active == NULL)
|
||||
continue;
|
||||
if (options_get_number(w->options, "automatic-rename"))
|
||||
w->active->flags |= PANE_CHANGED;
|
||||
}
|
||||
}
|
||||
if (strcmp(name, "key-table") == 0) {
|
||||
TAILQ_FOREACH(loop, &clients, entry)
|
||||
server_client_set_key_table(loop, NULL);
|
||||
}
|
||||
if (strcmp(name, "user-keys") == 0) {
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
if (loop->tty.flags & TTY_OPENED)
|
||||
tty_keys_build(&loop->tty);
|
||||
}
|
||||
}
|
||||
if (strcmp(name, "status") == 0 ||
|
||||
strcmp(name, "status-interval") == 0)
|
||||
status_timer_start_all();
|
||||
if (strcmp(name, "monitor-silence") == 0)
|
||||
alerts_reset_all();
|
||||
if (strcmp(name, "window-style") == 0 ||
|
||||
strcmp(name, "window-active-style") == 0) {
|
||||
RB_FOREACH(wp, window_pane_tree, &all_window_panes)
|
||||
wp->flags |= PANE_STYLECHANGED;
|
||||
}
|
||||
if (strcmp(name, "pane-border-status") == 0) {
|
||||
RB_FOREACH(w, windows, &windows)
|
||||
layout_fix_panes(w);
|
||||
}
|
||||
RB_FOREACH(s, sessions, &sessions)
|
||||
status_update_cache(s);
|
||||
|
||||
/*
|
||||
* Update sizes and redraw. May not always be necessary but do it
|
||||
* anyway.
|
||||
*/
|
||||
recalculate_sizes();
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
if (loop->session != NULL)
|
||||
server_redraw_client(loop);
|
||||
}
|
||||
options_push_changes(name);
|
||||
|
||||
out:
|
||||
free(argument);
|
||||
@ -270,147 +218,3 @@ fail:
|
||||
free(name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_set_option_check_string(const struct options_table_entry *oe,
|
||||
const char *value, char **cause)
|
||||
{
|
||||
struct style sy;
|
||||
|
||||
if (strcmp(oe->name, "default-shell") == 0 && !checkshell(value)) {
|
||||
xasprintf(cause, "not a suitable shell: %s", value);
|
||||
return (-1);
|
||||
}
|
||||
if (oe->pattern != NULL && fnmatch(oe->pattern, value, 0) != 0) {
|
||||
xasprintf(cause, "value is invalid: %s", value);
|
||||
return (-1);
|
||||
}
|
||||
if ((oe->flags & OPTIONS_TABLE_IS_STYLE) &&
|
||||
strstr(value, "#{") == NULL &&
|
||||
style_parse(&sy, &grid_default_cell, value) != 0) {
|
||||
xasprintf(cause, "invalid style: %s", value);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_set_option_set(struct cmd *self, struct cmdq_item *item, struct options *oo,
|
||||
struct options_entry *parent, const char *value)
|
||||
{
|
||||
const struct options_table_entry *oe;
|
||||
struct args *args = cmd_get_args(self);
|
||||
int append = args_has(args, 'a');
|
||||
long long number;
|
||||
const char *errstr, *new;
|
||||
char *old, *cause;
|
||||
key_code key;
|
||||
|
||||
oe = options_table_entry(parent);
|
||||
if (value == NULL &&
|
||||
oe->type != OPTIONS_TABLE_FLAG &&
|
||||
oe->type != OPTIONS_TABLE_CHOICE) {
|
||||
cmdq_error(item, "empty value");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
switch (oe->type) {
|
||||
case OPTIONS_TABLE_STRING:
|
||||
old = xstrdup(options_get_string(oo, oe->name));
|
||||
options_set_string(oo, oe->name, append, "%s", value);
|
||||
new = options_get_string(oo, oe->name);
|
||||
if (cmd_set_option_check_string(oe, new, &cause) != 0) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
free(cause);
|
||||
|
||||
options_set_string(oo, oe->name, 0, "%s", old);
|
||||
free(old);
|
||||
return (-1);
|
||||
}
|
||||
free(old);
|
||||
return (0);
|
||||
case OPTIONS_TABLE_NUMBER:
|
||||
number = strtonum(value, oe->minimum, oe->maximum, &errstr);
|
||||
if (errstr != NULL) {
|
||||
cmdq_error(item, "value is %s: %s", errstr, value);
|
||||
return (-1);
|
||||
}
|
||||
options_set_number(oo, oe->name, number);
|
||||
return (0);
|
||||
case OPTIONS_TABLE_KEY:
|
||||
key = key_string_lookup_string(value);
|
||||
if (key == KEYC_UNKNOWN) {
|
||||
cmdq_error(item, "bad key: %s", value);
|
||||
return (-1);
|
||||
}
|
||||
options_set_number(oo, oe->name, key);
|
||||
return (0);
|
||||
case OPTIONS_TABLE_COLOUR:
|
||||
if ((number = colour_fromstring(value)) == -1) {
|
||||
cmdq_error(item, "bad colour: %s", value);
|
||||
return (-1);
|
||||
}
|
||||
options_set_number(oo, oe->name, number);
|
||||
return (0);
|
||||
case OPTIONS_TABLE_FLAG:
|
||||
return (cmd_set_option_flag(item, oe, oo, value));
|
||||
case OPTIONS_TABLE_CHOICE:
|
||||
return (cmd_set_option_choice(item, oe, oo, value));
|
||||
case OPTIONS_TABLE_COMMAND:
|
||||
break;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_set_option_flag(struct cmdq_item *item,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
int flag;
|
||||
|
||||
if (value == NULL || *value == '\0')
|
||||
flag = !options_get_number(oo, oe->name);
|
||||
else if (strcmp(value, "1") == 0 ||
|
||||
strcasecmp(value, "on") == 0 ||
|
||||
strcasecmp(value, "yes") == 0)
|
||||
flag = 1;
|
||||
else if (strcmp(value, "0") == 0 ||
|
||||
strcasecmp(value, "off") == 0 ||
|
||||
strcasecmp(value, "no") == 0)
|
||||
flag = 0;
|
||||
else {
|
||||
cmdq_error(item, "bad value: %s", value);
|
||||
return (-1);
|
||||
}
|
||||
options_set_number(oo, oe->name, flag);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
cmd_set_option_choice(struct cmdq_item *item,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
const char **cp;
|
||||
int n, choice = -1;
|
||||
|
||||
if (value == NULL) {
|
||||
choice = options_get_number(oo, oe->name);
|
||||
if (choice < 2)
|
||||
choice = !choice;
|
||||
} else {
|
||||
n = 0;
|
||||
for (cp = oe->choices; *cp != NULL; cp++) {
|
||||
if (strcmp(*cp, value) == 0)
|
||||
choice = n;
|
||||
n++;
|
||||
}
|
||||
if (choice == -1) {
|
||||
cmdq_error(item, "unknown value: %s", value);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
options_set_number(oo, oe->name, choice);
|
||||
return (0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user