diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-09-22 12:38:11 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-09-22 12:38:11 +0000 |
commit | 1f7e7007af7bfef7a9dc88c2a09832a90603076f (patch) | |
tree | 1aacba34d320ef343052c32237caa928513afd82 /usr.bin/tmux | |
parent | 849dd7297d7a8729f4fc89b9322ebaad270aa091 (diff) |
Permit multiple prefix keys to be defined, separated by commas, for example:
set -g prefix ^a,^b
Any key in the list acts as the prefix. The send-prefix command always sends
the first key in the list.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/cmd-send-prefix.c | 8 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-set-option.c | 8 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-set-window-option.c | 6 | ||||
-rw-r--r-- | usr.bin/tmux/options-cmd.c | 39 | ||||
-rw-r--r-- | usr.bin/tmux/options.c | 43 | ||||
-rw-r--r-- | usr.bin/tmux/server.c | 24 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 12 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.c | 9 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 16 |
9 files changed, 127 insertions, 38 deletions
diff --git a/usr.bin/tmux/cmd-send-prefix.c b/usr.bin/tmux/cmd-send-prefix.c index e5bd7754522..fdf9a93405e 100644 --- a/usr.bin/tmux/cmd-send-prefix.c +++ b/usr.bin/tmux/cmd-send-prefix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-send-prefix.c,v 1.4 2009/08/18 16:21:04 nicm Exp $ */ +/* $OpenBSD: cmd-send-prefix.c,v 1.5 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -43,13 +43,13 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx) struct cmd_target_data *data = self->data; struct session *s; struct window_pane *wp; - int key; + struct keylist *keylist; if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL) return (-1); - key = options_get_number(&s->options, "prefix"); - window_pane_key(wp, ctx->curclient, key); + keylist = options_get_data(&s->options, "prefix"); + window_pane_key(wp, ctx->curclient, ARRAY_FIRST(keylist)); return (0); } diff --git a/usr.bin/tmux/cmd-set-option.c b/usr.bin/tmux/cmd-set-option.c index 6d57ba36d72..3e8cf8de9b5 100644 --- a/usr.bin/tmux/cmd-set-option.c +++ b/usr.bin/tmux/cmd-set-option.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-set-option.c,v 1.18 2009/09/18 15:19:27 nicm Exp $ */ +/* $OpenBSD: cmd-set-option.c,v 1.19 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -65,7 +65,7 @@ const struct set_option_entry set_option_table[] = { { "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "message-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "message-fg", SET_OPTION_COLOUR, 0, 0, NULL }, - { "prefix", SET_OPTION_KEY, 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 }, @@ -162,8 +162,8 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) case SET_OPTION_NUMBER: set_option_number(ctx, oo, entry, data->arg2); break; - case SET_OPTION_KEY: - set_option_key(ctx, oo, entry, data->arg2); + case SET_OPTION_KEYS: + set_option_keys(ctx, oo, entry, data->arg2); break; case SET_OPTION_COLOUR: set_option_colour(ctx, oo, entry, data->arg2); diff --git a/usr.bin/tmux/cmd-set-window-option.c b/usr.bin/tmux/cmd-set-window-option.c index 132a1d83e5f..89f0c44f967 100644 --- a/usr.bin/tmux/cmd-set-window-option.c +++ b/usr.bin/tmux/cmd-set-window-option.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-set-window-option.c,v 1.11 2009/08/11 12:53:37 nicm Exp $ */ +/* $OpenBSD: cmd-set-window-option.c,v 1.12 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -140,8 +140,8 @@ cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx) case SET_OPTION_NUMBER: set_option_number(ctx, oo, entry, data->arg2); break; - case SET_OPTION_KEY: - set_option_key(ctx, oo, entry, data->arg2); + case SET_OPTION_KEYS: + set_option_keys(ctx, oo, entry, data->arg2); break; case SET_OPTION_COLOUR: set_option_colour(ctx, oo, entry, data->arg2); diff --git a/usr.bin/tmux/options-cmd.c b/usr.bin/tmux/options-cmd.c index e6107f9b3c1..7aeae3b63d1 100644 --- a/usr.bin/tmux/options-cmd.c +++ b/usr.bin/tmux/options-cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options-cmd.c,v 1.4 2009/09/21 14:56:03 nicm Exp $ */ +/* $OpenBSD: options-cmd.c,v 1.5 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -28,6 +28,8 @@ set_option_print(const struct set_option_entry *entry, struct options_entry *o) { static char out[BUFSIZ]; const char *s; + struct keylist *keylist; + u_int i; *out = '\0'; switch (entry->type) { @@ -37,9 +39,14 @@ set_option_print(const struct set_option_entry *entry, struct options_entry *o) case SET_OPTION_NUMBER: xsnprintf(out, sizeof out, "%lld", o->num); break; - case SET_OPTION_KEY: - s = key_string_lookup_key(o->num); - xsnprintf(out, sizeof out, "%s", s); + 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); @@ -114,23 +121,35 @@ set_option_number(struct cmd_ctx *ctx, struct options *oo, } void -set_option_key(struct cmd_ctx *ctx, struct options *oo, +set_option_keys(struct cmd_ctx *ctx, struct options *oo, const struct set_option_entry *entry, char *value) { struct options_entry *o; - int key; + struct keylist *keylist; + char *copyvalue, *ptr, *str; + int key; if (value == NULL) { ctx->error(ctx, "empty value"); return; } - if ((key = key_string_lookup_string(value)) == KEYC_NONE) { - ctx->error(ctx, "unknown key: %s", 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) { + xfree(keylist); + ctx->error(ctx, "unknown key: %s", str); + xfree(copyvalue); + return; + } + ARRAY_ADD(keylist, key); } + xfree(copyvalue); - o = options_set_number(oo, entry->name, key); + o = options_set_data(oo, entry->name, keylist, xfree); ctx->info( ctx, "set option: %s -> %s", o->name, set_option_print(entry, o)); } diff --git a/usr.bin/tmux/options.c b/usr.bin/tmux/options.c index 055745b9edb..cc40545598e 100644 --- a/usr.bin/tmux/options.c +++ b/usr.bin/tmux/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.4 2009/09/21 14:56:03 nicm Exp $ */ +/* $OpenBSD: options.c,v 1.5 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -54,6 +54,8 @@ 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); } } @@ -95,6 +97,8 @@ 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); } @@ -110,6 +114,8 @@ 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; @@ -141,6 +147,8 @@ 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; @@ -158,3 +166,36 @@ 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/usr.bin/tmux/server.c b/usr.bin/tmux/server.c index de6a5e257ef..f873427f184 100644 --- a/usr.bin/tmux/server.c +++ b/usr.bin/tmux/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.39 2009/09/20 14:58:12 nicm Exp $ */ +/* $OpenBSD: server.c,v 1.40 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -798,8 +798,9 @@ server_handle_client(struct client *c) struct screen *s; struct timeval tv; struct key_binding *bd; - int key, prefix, status, xtimeout; - int mode; + struct keylist *keylist; + int key, status, xtimeout, mode, isprefix; + u_int i; u_char mouse[3]; xtimeout = options_get_number(&c->session->options, "repeat-time"); @@ -811,7 +812,7 @@ server_handle_client(struct client *c) } /* Process keys. */ - prefix = options_get_number(&c->session->options, "prefix"); + keylist = options_get_data(&c->session->options, "prefix"); while (tty_keys_next(&c->tty, &key, mouse) == 0) { server_activity = time(NULL); @@ -844,9 +845,18 @@ server_handle_client(struct client *c) continue; } + /* Is this a prefix key? */ + isprefix = 0; + for (i = 0; i < ARRAY_LENGTH(keylist); i++) { + if (key == ARRAY_ITEM(keylist, i)) { + isprefix = 1; + break; + } + } + /* No previous prefix key. */ if (!(c->flags & CLIENT_PREFIX)) { - if (key == prefix) + if (isprefix) c->flags |= CLIENT_PREFIX; else { /* Try as a non-prefix key binding. */ @@ -864,7 +874,7 @@ server_handle_client(struct client *c) /* If repeating, treat this as a key, else ignore. */ if (c->flags & CLIENT_REPEAT) { c->flags &= ~CLIENT_REPEAT; - if (key == prefix) + if (isprefix) c->flags |= CLIENT_PREFIX; else window_pane_key(wp, c, key); @@ -875,7 +885,7 @@ server_handle_client(struct client *c) /* If already repeating, but this key can't repeat, skip it. */ if (c->flags & CLIENT_REPEAT && !bd->can_repeat) { c->flags &= ~CLIENT_REPEAT; - if (key == prefix) + if (isprefix) c->flags |= CLIENT_PREFIX; else window_pane_key(wp, c, key); diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 8e9dd4e1697..23e448e4e41 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.88 2009/09/21 07:45:10 jmc Exp $ +.\" $OpenBSD: tmux.1,v 1.89 2009/09/22 12:38:10 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 21 2009 $ +.Dd $Mdocdate: September 22 2009 $ .Dt TMUX 1 .Os .Sh NAME @@ -1048,6 +1048,7 @@ characters. All arguments are sent sequentially from first to last. .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 unbind-key .Op Fl cn .Op Fl t Ar key-table @@ -1258,8 +1259,11 @@ from the 256-colour palette, or .Ic default . .It Ic message-fg Ar colour Set status line message foreground colour. -.It Ic prefix Ar key -Set the current prefix key. +.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 repeat-time Ar time Allow multiple commands to be entered without pressing the prefix-key again in the specified diff --git a/usr.bin/tmux/tmux.c b/usr.bin/tmux/tmux.c index c42d8c8cc8b..f940b7d68b3 100644 --- a/usr.bin/tmux/tmux.c +++ b/usr.bin/tmux/tmux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.c,v 1.43 2009/09/18 15:19:27 nicm Exp $ */ +/* $OpenBSD: tmux.c,v 1.44 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -309,6 +309,7 @@ main(int argc, char **argv) enum msgtype msg; struct passwd *pw; struct options *so, *wo; + struct keylist *keylist; char *s, *path, *label, *home, *cause, **var; char cwd[MAXPATHLEN]; void *buf; @@ -409,7 +410,6 @@ main(int argc, char **argv) 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, "prefix", '\002'); options_set_number(so, "repeat-time", 500); options_set_number(so, "set-remain-on-exit", 0); options_set_number(so, "set-titles", 0); @@ -439,6 +439,11 @@ main(int argc, char **argv) options_set_number(so, "visual-bell", 0); options_set_number(so, "visual-content", 0); + 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); diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index c87c6ca44c1..75b9bec94ae 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.111 2009/09/21 14:56:03 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.112 2009/09/22 12:38:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -544,10 +544,14 @@ struct options_entry { enum { OPTIONS_STRING, OPTIONS_NUMBER, + OPTIONS_DATA, } type; char *str; long long num; + void *data; + + void (*freefn)(void *); SPLAY_ENTRY(options_entry) entry; }; @@ -557,6 +561,9 @@ struct options { struct options *parent; }; +/* Key list for prefix option. */ +ARRAY_DECL(keylist, int); + /* Screen selection. */ struct screen_sel { int flag; @@ -1085,7 +1092,7 @@ struct set_option_entry { enum { SET_OPTION_STRING, SET_OPTION_NUMBER, - SET_OPTION_KEY, + SET_OPTION_KEYS, SET_OPTION_COLOUR, SET_OPTION_ATTRIBUTES, SET_OPTION_FLAG, @@ -1165,6 +1172,9 @@ 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 *); /* environ.c */ int environ_cmp(struct environ_entry *, struct environ_entry *); @@ -1245,7 +1255,7 @@ void set_option_string(struct cmd_ctx *, struct options *, const struct set_option_entry *, char *, int); void set_option_number(struct cmd_ctx *, struct options *, const struct set_option_entry *, char *); -void set_option_key(struct cmd_ctx *, +void set_option_keys(struct cmd_ctx *, struct options *, const struct set_option_entry *, char *); void set_option_colour(struct cmd_ctx *, struct options *, const struct set_option_entry *, char *); |