summaryrefslogtreecommitdiff
path: root/usr.bin/tmux
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2009-09-22 12:38:11 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2009-09-22 12:38:11 +0000
commit1f7e7007af7bfef7a9dc88c2a09832a90603076f (patch)
tree1aacba34d320ef343052c32237caa928513afd82 /usr.bin/tmux
parent849dd7297d7a8729f4fc89b9322ebaad270aa091 (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.c8
-rw-r--r--usr.bin/tmux/cmd-set-option.c8
-rw-r--r--usr.bin/tmux/cmd-set-window-option.c6
-rw-r--r--usr.bin/tmux/options-cmd.c39
-rw-r--r--usr.bin/tmux/options.c43
-rw-r--r--usr.bin/tmux/server.c24
-rw-r--r--usr.bin/tmux/tmux.112
-rw-r--r--usr.bin/tmux/tmux.c9
-rw-r--r--usr.bin/tmux/tmux.h16
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 *);