diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c index bd713a49..99aa1bac 100644 --- a/cmd-send-prefix.c +++ b/cmd-send-prefix.c @@ -28,8 +28,8 @@ int cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_send_prefix_entry = { "send-prefix", NULL, - "t:", 0, 0, - CMD_TARGET_PANE_USAGE, + "2t:", 0, 0, + "[-2] " CMD_TARGET_PANE_USAGE, 0, NULL, NULL, @@ -42,13 +42,16 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx) struct args *args = self->args; struct session *s; struct window_pane *wp; - struct keylist *keylist; + int key; if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL) return (-1); - keylist = options_get_data(&s->options, "prefix"); - window_pane_key(wp, s, ARRAY_FIRST(keylist)); + if (args_has(args, '2')) + key = options_get_number(&s->options, "prefix2"); + else + key = options_get_number(&s->options, "prefix"); + window_pane_key(wp, s, key); return (0); } diff --git a/cmd-set-option.c b/cmd-set-option.c index c19f0235..5db70f63 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -45,7 +45,7 @@ struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_ctx *, struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_ctx *, const struct options_table_entry *, struct options *, const char *); -struct options_entry *cmd_set_option_keys(struct cmd *, struct cmd_ctx *, +struct options_entry *cmd_set_option_key(struct cmd *, struct cmd_ctx *, const struct options_table_entry *, struct options *, const char *); struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_ctx *, @@ -236,8 +236,8 @@ cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx, case OPTIONS_TABLE_NUMBER: o = cmd_set_option_number(self, ctx, oe, oo, value); break; - case OPTIONS_TABLE_KEYS: - o = cmd_set_option_keys(self, ctx, oe, oo, value); + case OPTIONS_TABLE_KEY: + o = cmd_set_option_key(self, ctx, oe, oo, value); break; case OPTIONS_TABLE_COLOUR: o = cmd_set_option_colour(self, ctx, oe, oo, value); @@ -298,31 +298,19 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_ctx *ctx, return (options_set_number(oo, oe->name, ll)); } -/* Set a keys option. */ +/* Set a key option. */ struct options_entry * -cmd_set_option_keys(unused struct cmd *self, struct cmd_ctx *ctx, +cmd_set_option_key(unused struct cmd *self, struct cmd_ctx *ctx, const struct options_table_entry *oe, struct options *oo, const char *value) { - struct keylist *keylist; - char *copy, *ptr, *s; - int key; + int key; - keylist = xmalloc(sizeof *keylist); - ARRAY_INIT(keylist); - - ptr = copy = xstrdup(value); - 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); - return (NULL); - } - ARRAY_ADD(keylist, key); + if ((key = key_string_lookup_string(value)) == KEYC_NONE) { + ctx->error(ctx, "bad key: %s", value); + return (NULL); } - xfree(copy); - return (options_set_data(oo, oe->name, keylist, xfree)); + return (options_set_number(oo, oe->name, key)); } /* Set a colour option. */ diff --git a/key-string.c b/key-string.c index ea51ab26..e2224d18 100644 --- a/key-string.c +++ b/key-string.c @@ -188,6 +188,10 @@ key_string_lookup_key(int key) *out = '\0'; + /* Handle no key. */ + if (key == KEYC_NONE) + return ("none"); + /* * Special case: display C-@ as C-Space. Could do this below in * the (key >= 0 && key <= 32), but this way we let it be found diff --git a/options-table.c b/options-table.c index 778d5ed5..36544707 100644 --- a/options-table.c +++ b/options-table.c @@ -261,8 +261,13 @@ const struct options_table_entry session_options_table[] = { }, { .name = "prefix", - .type = OPTIONS_TABLE_KEYS, - /* set in main() */ + .type = OPTIONS_TABLE_KEY, + .default_num = '\002', + }, + + { .name = "prefix2", + .type = OPTIONS_TABLE_KEY, + .default_num = KEYC_NONE, }, { .name = "repeat-time", @@ -682,10 +687,8 @@ 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; + static char out[BUFSIZ]; + const char *s; *out = '\0'; switch (oe->type) { @@ -695,14 +698,8 @@ options_table_print_entry( 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); - } + case OPTIONS_TABLE_KEY: + xsnprintf(out, sizeof out, "%s", key_string_lookup_key(o->num)); break; case OPTIONS_TABLE_COLOUR: s = colour_tostring(o->num); diff --git a/options.c b/options.c index 490e48ae..bfcc6672 100644 --- a/options.c +++ b/options.c @@ -54,8 +54,6 @@ options_free(struct options *oo) xfree(o->name); if (o->type == OPTIONS_STRING) xfree(o->str); - else if (o->type == OPTIONS_DATA) - o->freefn(o->data); xfree(o); } } @@ -97,8 +95,6 @@ options_remove(struct options *oo, const char *name) xfree(o->name); if (o->type == OPTIONS_STRING) xfree(o->str); - else if (o->type == OPTIONS_DATA) - o->freefn(o->data); xfree(o); } @@ -114,8 +110,6 @@ options_set_string(struct options *oo, const char *name, const char *fmt, ...) SPLAY_INSERT(options_tree, &oo->tree, o); } else if (o->type == OPTIONS_STRING) xfree(o->str); - else if (o->type == OPTIONS_DATA) - o->freefn(o->data); va_start(ap, fmt); o->type = OPTIONS_STRING; @@ -147,8 +141,6 @@ options_set_number(struct options *oo, const char *name, long long value) SPLAY_INSERT(options_tree, &oo->tree, o); } else if (o->type == OPTIONS_STRING) xfree(o->str); - else if (o->type == OPTIONS_DATA) - o->freefn(o->data); o->type = OPTIONS_NUMBER; o->num = value; @@ -166,36 +158,3 @@ options_get_number(struct options *oo, const char *name) fatalx("option not a number"); return (o->num); } - -struct options_entry * -options_set_data( - struct options *oo, const char *name, void *value, void (*freefn)(void *)) -{ - struct options_entry *o; - - if ((o = options_find1(oo, name)) == NULL) { - o = xmalloc(sizeof *o); - o->name = xstrdup(name); - SPLAY_INSERT(options_tree, &oo->tree, o); - } else if (o->type == OPTIONS_STRING) - xfree(o->str); - else if (o->type == OPTIONS_DATA) - o->freefn(o->data); - - o->type = OPTIONS_DATA; - o->data = value; - o->freefn = freefn; - return (o); -} - -void * -options_get_data(struct options *oo, const char *name) -{ - struct options_entry *o; - - if ((o = options_find(oo, name)) == NULL) - fatalx("missing option"); - if (o->type != OPTIONS_DATA) - fatalx("option not data"); - return (o->data); -} diff --git a/server-client.c b/server-client.c index 40655748..3ba4ed1f 100644 --- a/server-client.c +++ b/server-client.c @@ -272,9 +272,7 @@ server_client_handle_key(int key, struct mouse_event *mouse, void *data) struct options *oo; struct timeval tv; struct key_binding *bd; - struct keylist *keylist; int xtimeout, isprefix; - u_int i; /* Check the client is good to accept input. */ if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) @@ -359,14 +357,12 @@ server_client_handle_key(int key, struct mouse_event *mouse, void *data) } /* Is this a prefix key? */ - keylist = options_get_data(&c->session->options, "prefix"); - isprefix = 0; - for (i = 0; i < ARRAY_LENGTH(keylist); i++) { - if (key == ARRAY_ITEM(keylist, i)) { - isprefix = 1; - break; - } - } + if (key == options_get_number(&c->session->options, "prefix")) + isprefix = 1; + else if (key == options_get_number(&c->session->options, "prefix2")) + isprefix = 1; + else + isprefix = 0; /* No previous prefix key. */ if (!(c->flags & CLIENT_PREFIX)) { diff --git a/tmux.1 b/tmux.1 index 5cee0f72..85c85496 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1656,9 +1656,13 @@ All arguments are sent sequentially from first to last. The .Fl R flag causes the terminal state to be reset. -.It Ic send-prefix Op Fl t Ar target-pane -Send the prefix key to a window as if it was pressed. -If multiple prefix keys are configured, only the first is sent. +.It Xo Ic send-prefix +.Op Fl 2 +.Op Fl t Ar target-pane +.Xc +Send the prefix key, or with +.Fl 2 +the secondary prefix key, to a window as if it was pressed. .It Xo Ic unbind-key .Op Fl acn .Op Fl t Ar key-table @@ -2033,11 +2037,10 @@ Set the pane border colour for the currently active pane. .It Ic pane-border-bg Ar colour .It Ic pane-border-fg Ar colour Set the pane border colour for panes aside from the active pane. -.It Ic prefix Ar keys -Set the keys accepted as a prefix key. -.Ar keys -is a comma-separated list of key names, each of which individually behave as -the prefix key. +.It Ic prefix Ar key +Set the key accepted as a prefix key. +.It Ic prefix2 Ar key +Set a secondary key accepted as a prefix key. .It Ic repeat-time Ar time Allow multiple commands to be entered without pressing the prefix-key again in the specified diff --git a/tmux.c b/tmux.c index 76e808e0..7ec8c20f 100644 --- a/tmux.c +++ b/tmux.c @@ -235,7 +235,6 @@ int main(int argc, char **argv) { struct passwd *pw; - struct keylist *keylist; char *s, *path, *label, *home, **var; int opt, flags, quiet, keys; @@ -335,12 +334,6 @@ main(int argc, char **argv) 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(&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(&global_s_options, "status-utf8", 1); diff --git a/tmux.h b/tmux.h index b52f1b66..22d7af65 100644 --- a/tmux.h +++ b/tmux.h @@ -669,9 +669,6 @@ struct options_entry { char *str; long long num; - void *data; - - void (*freefn)(void *); SPLAY_ENTRY(options_entry) entry; }; @@ -681,9 +678,6 @@ struct options { struct options *parent; }; -/* Key list for prefix option. */ -ARRAY_DECL(keylist, int); - /* Scheduled job. */ struct job { char *cmd; @@ -1290,7 +1284,7 @@ SPLAY_HEAD(key_bindings, key_binding); enum options_table_type { OPTIONS_TABLE_STRING, OPTIONS_TABLE_NUMBER, - OPTIONS_TABLE_KEYS, + OPTIONS_TABLE_KEY, OPTIONS_TABLE_COLOUR, OPTIONS_TABLE_ATTRIBUTES, OPTIONS_TABLE_FLAG, @@ -1409,9 +1403,6 @@ char *options_get_string(struct options *, const char *); struct options_entry *options_set_number( struct options *, const char *, long long); long long options_get_number(struct options *, const char *); -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[];