summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/cmd-bind-key.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2009-07-28 17:05:11 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2009-07-28 17:05:11 +0000
commitfdac46d6f899b49d104690311de0ac64162d89c7 (patch)
tree6fe1930e84dcda9cec807062c454025470bc2b10 /usr.bin/tmux/cmd-bind-key.c
parente08be4259306569ce6c3e59161bc8478e4dd2f56 (diff)
Final pieces of mode key rebinding: bind-key and unbind-key now accept a -t
argument to modify a table.
Diffstat (limited to 'usr.bin/tmux/cmd-bind-key.c')
-rw-r--r--usr.bin/tmux/cmd-bind-key.c72
1 files changed, 67 insertions, 5 deletions
diff --git a/usr.bin/tmux/cmd-bind-key.c b/usr.bin/tmux/cmd-bind-key.c
index 74f1db566e5..4b075c19e34 100644
--- a/usr.bin/tmux/cmd-bind-key.c
+++ b/usr.bin/tmux/cmd-bind-key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-bind-key.c,v 1.4 2009/07/26 12:58:44 nicm Exp $ */
+/* $OpenBSD: cmd-bind-key.c,v 1.5 2009/07/28 17:05:10 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,8 @@
#include <sys/types.h>
+#include <string.h>
+
#include "tmux.h"
/*
@@ -29,15 +31,21 @@ int cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
void cmd_bind_key_free(struct cmd *);
size_t cmd_bind_key_print(struct cmd *, char *, size_t);
+int cmd_bind_key_table(struct cmd *, struct cmd_ctx *);
+
struct cmd_bind_key_data {
int key;
int can_repeat;
struct cmd_list *cmdlist;
+
+ int command_key;
+ char *tablename;
+ char *modecmd;
};
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
- "[-nr] key command [arguments]",
+ "[-cnr] [-t key-table] key command [arguments]",
0, 0,
NULL,
cmd_bind_key_parse,
@@ -55,15 +63,24 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
self->data = data = xmalloc(sizeof *data);
data->can_repeat = 0;
data->cmdlist = NULL;
+ data->command_key = 0;
+ data->tablename = NULL;
+ data->modecmd = NULL;
- while ((opt = getopt(argc, argv, "nr")) != -1) {
+ while ((opt = getopt(argc, argv, "cnrt:")) != -1) {
switch (opt) {
+ case 'c':
+ data->command_key = 1;
+ break;
case 'n':
no_prefix = 1;
break;
case 'r':
data->can_repeat = 1;
break;
+ case 't':
+ data->tablename = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -82,8 +99,14 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
argc--;
argv++;
- if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
- goto error;
+ if (data->tablename != NULL) {
+ if (argc != 1)
+ goto usage;
+ data->modecmd = xstrdup(argv[0]);
+ } else {
+ if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
+ goto error;
+ }
return (0);
@@ -102,6 +125,8 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
if (data == NULL)
return (0);
+ if (data->tablename != NULL)
+ return (cmd_bind_key_table(self, ctx));
key_bindings_add(data->key, data->can_repeat, data->cmdlist);
data->cmdlist = NULL; /* avoid free */
@@ -109,6 +134,39 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
return (0);
}
+int
+cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
+{
+ struct cmd_bind_key_data *data = self->data;
+ const struct mode_key_table *mtab;
+ struct mode_key_binding *mbind, mtmp;
+ enum mode_key_cmd cmd;
+
+ if ((mtab = mode_key_findtable(data->tablename)) == NULL) {
+ ctx->error(ctx, "unknown key table: %s", data->tablename);
+ return (-1);
+ }
+
+ cmd = mode_key_fromstring(mtab->cmdstr, data->modecmd);
+ if (cmd == MODEKEY_NONE) {
+ ctx->error(ctx, "unknown command: %s", data->modecmd);
+ return (-1);
+ }
+
+ mtmp.key = data->key & ~KEYC_PREFIX;
+ mtmp.mode = data->command_key ? 1 : 0;
+ if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
+ mbind->cmd = cmd;
+ return (0);
+ }
+ mbind = xmalloc(sizeof *mbind);
+ mbind->key = mtmp.key;
+ mbind->mode = mtmp.mode;
+ mbind->cmd = cmd;
+ SPLAY_INSERT(mode_key_tree, mtab->tree, mbind);
+ return (0);
+}
+
void
cmd_bind_key_free(struct cmd *self)
{
@@ -116,6 +174,10 @@ cmd_bind_key_free(struct cmd *self)
if (data->cmdlist != NULL)
cmd_list_free(data->cmdlist);
+ if (data->tablename != NULL)
+ xfree(data->tablename);
+ if (data->modecmd != NULL)
+ xfree(data->modecmd);
xfree(data);
}