diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-28 17:05:11 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-07-28 17:05:11 +0000 |
commit | fdac46d6f899b49d104690311de0ac64162d89c7 (patch) | |
tree | 6fe1930e84dcda9cec807062c454025470bc2b10 | |
parent | e08be4259306569ce6c3e59161bc8478e4dd2f56 (diff) |
Final pieces of mode key rebinding: bind-key and unbind-key now accept a -t
argument to modify a table.
-rw-r--r-- | usr.bin/tmux/cmd-bind-key.c | 72 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-list-keys.c | 8 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-unbind-key.c | 44 | ||||
-rw-r--r-- | usr.bin/tmux/mode-key.c | 32 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 48 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 |
6 files changed, 185 insertions, 23 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); } diff --git a/usr.bin/tmux/cmd-list-keys.c b/usr.bin/tmux/cmd-list-keys.c index 31129f30dd7..f4b73e9017c 100644 --- a/usr.bin/tmux/cmd-list-keys.c +++ b/usr.bin/tmux/cmd-list-keys.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-list-keys.c,v 1.6 2009/07/28 07:03:32 nicm Exp $ */ +/* $OpenBSD: cmd-list-keys.c,v 1.7 2009/07/28 17:05:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -92,11 +92,7 @@ cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx) const char *key, *cmdstr, *mode; int width, keywidth; - for (mtab = mode_key_tables; mtab->name != NULL; mtab++) { - if (strcasecmp(data->target, mtab->name) == 0) - break; - } - if (mtab->name == NULL) { + if ((mtab = mode_key_findtable(data->target)) == NULL) { ctx->error(ctx, "unknown key table: %s", data->target); return (-1); } diff --git a/usr.bin/tmux/cmd-unbind-key.c b/usr.bin/tmux/cmd-unbind-key.c index 63b8aa0f998..16eb94982a4 100644 --- a/usr.bin/tmux/cmd-unbind-key.c +++ b/usr.bin/tmux/cmd-unbind-key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-unbind-key.c,v 1.4 2009/07/26 12:58:44 nicm Exp $ */ +/* $OpenBSD: cmd-unbind-key.c,v 1.5 2009/07/28 17:05:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -28,13 +28,18 @@ int cmd_unbind_key_parse(struct cmd *, int, char **, char **); int cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *); void cmd_unbind_key_free(struct cmd *); +int cmd_unbind_key_table(struct cmd *, struct cmd_ctx *); + struct cmd_unbind_key_data { int key; + + int command_key; + char *tablename; }; const struct cmd_entry cmd_unbind_key_entry = { "unbind-key", "unbind", - "[-n] key", + "[-cn] [-t key-table] key", 0, 0, NULL, cmd_unbind_key_parse, @@ -50,12 +55,20 @@ cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause) int opt, no_prefix = 0; self->data = data = xmalloc(sizeof *data); + data->command_key = 0; + data->tablename = NULL; - while ((opt = getopt(argc, argv, "n")) != -1) { + while ((opt = getopt(argc, argv, "cnt:")) != -1) { switch (opt) { + case 'c': + data->command_key = 1; + break; case 'n': no_prefix = 1; break; + case 't': + data->tablename = xstrdup(optarg); + break; default: goto usage; } @@ -89,16 +102,41 @@ cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx) if (data == NULL) return (0); + if (data->tablename != NULL) + return (cmd_unbind_key_table(self, ctx)); key_bindings_remove(data->key); return (0); } +int +cmd_unbind_key_table(struct cmd *self, struct cmd_ctx *ctx) +{ + struct cmd_unbind_key_data *data = self->data; + const struct mode_key_table *mtab; + struct mode_key_binding *mbind, mtmp; + + if ((mtab = mode_key_findtable(data->tablename)) == NULL) { + ctx->error(ctx, "unknown key table: %s", data->tablename); + 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) { + SPLAY_REMOVE(mode_key_tree, mtab->tree, mbind); + xfree(mbind); + } + return (0); +} + void cmd_unbind_key_free(struct cmd *self) { struct cmd_unbind_key_data *data = self->data; + if (data->tablename != NULL) + xfree(data->tablename); xfree(data); } diff --git a/usr.bin/tmux/mode-key.c b/usr.bin/tmux/mode-key.c index df0c6e66fc4..74ec7f7e554 100644 --- a/usr.bin/tmux/mode-key.c +++ b/usr.bin/tmux/mode-key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mode-key.c,v 1.10 2009/07/28 07:03:32 nicm Exp $ */ +/* $OpenBSD: mode-key.c,v 1.11 2009/07/28 17:05:10 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> @@ -18,6 +18,8 @@ #include <sys/types.h> +#include <string.h> + #include "tmux.h" /* @@ -54,6 +56,8 @@ struct mode_key_cmdstr mode_key_cmdstr_edit[] = { { MODEKEYEDIT_STARTOFLINE, "start-of-line" }, { MODEKEYEDIT_SWITCHMODE, "switch-mode" }, { MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" }, + + { 0, NULL } }; /* Choice keys command strings. */ @@ -64,6 +68,8 @@ struct mode_key_cmdstr mode_key_cmdstr_choice[] = { { MODEKEYCHOICE_PAGEDOWN, "page-down" }, { MODEKEYCHOICE_PAGEUP, "page-up" }, { MODEKEYCHOICE_UP, "up" }, + + { 0, NULL } }; /* Copy keys command strings. */ @@ -83,6 +89,8 @@ struct mode_key_cmdstr mode_key_cmdstr_copy[] = { { MODEKEYCOPY_STARTOFLINE, "start-of-line" }, { MODEKEYCOPY_STARTSELECTION, "begin-selection" }, { MODEKEYCOPY_UP, "cursor-up" }, + + { 0, NULL } }; /* vi editing keys. */ @@ -278,6 +286,28 @@ mode_key_tostring(struct mode_key_cmdstr *cmdstr, enum mode_key_cmd cmd) return (NULL); } +enum mode_key_cmd +mode_key_fromstring(struct mode_key_cmdstr *cmdstr, const char *name) +{ + for (; cmdstr->name != NULL; cmdstr++) { + if (strcasecmp(cmdstr->name, name) == 0) + return (cmdstr->cmd); + } + return (MODEKEY_NONE); +} + +const struct mode_key_table * +mode_key_findtable(const char *name) +{ + const struct mode_key_table *mtab; + + for (mtab = mode_key_tables; mtab->name != NULL; mtab++) { + if (strcasecmp(name, mtab->name) == 0) + return (mtab); + } + return (NULL); +} + void mode_key_init_trees(void) { diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 80d8a2ff869..b5fa1eddd17 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.48 2009/07/28 07:03:32 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.49 2009/07/28 17:05:10 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" @@ -352,7 +352,10 @@ and used in copy and scroll modes. The tables may be viewed with the .Ic list-keys -command. +command and keys modified or removed with +.Ic bind-key +and +.Ic unbind-key . .Pp The paste buffer key pastes the first line from the top paste buffer on the stack. @@ -637,7 +640,8 @@ If no server is started, will attempt to start it; this will fail unless sessions are created in the configuration file. .It Xo Ic bind-key -.Op Fl nr +.Op Fl cnr +.Op Fl t Ar key-table .Ar key Ar command Op Ar arguments .Xc .D1 (alias: Ic bind ) @@ -652,7 +656,11 @@ or for Ctrl keys, or .Ql M- for Alt (meta) keys. -If +.Pp +By default (without +.Fl t ) +the primary key bindings are modified (those normally activated with the prefix +key); in this case, if .Fl n is specified, it is not necessary to use the prefix key, .Ar command @@ -664,6 +672,19 @@ The flag indicates this key may repeat, see the .Ic repeat-time option. +.Pp +If +.Fl t +is present, +.Ar key +is bound in +.Ar key-table : +the binding for command mode with +.Fl c +or for normal mode without. +To view the default bindings and possible commands, see the +.Ic list-keys +command. .It Xo Ic break-pane .Op Fl d .Op Fl p Ar pane-index @@ -866,7 +887,7 @@ List all clients attached to the server. List the syntax of all commands supported by .Nm . .It Xo Ic list-keys -.Op Ar Fl t Ar key-table +.Op Fl t Ar key-table .Xc .D1 (alias: Ic lsk ) List all key bindings. @@ -1665,17 +1686,30 @@ Switch the current session for client to .Ar target-session . .It Xo Ic unbind-key -.Op Fl n +.Op Fl cn +.Op Fl t Ar key-table .Ar key .Xc .D1 (alias: Ic unbind ) Unbind the command bound to .Ar key . -If +Without +.Fl t +the primary key bindings are modified; in this case, if .Fl n is specified, the command bound to .Ar key without a prefix (if any) is removed. +.Pp +If +.Fl t +is present, +.Ar key +in +.Ar key-table +is unbound: the binding for command mode with +.Fl c +or for normal mode without. .It Xo Ic unlink-window .Op Fl k .Op Fl t Ar target-window diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 598c6d0dcc5..cb63215d196 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.62 2009/07/28 07:03:32 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.63 2009/07/28 17:05:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1098,6 +1098,8 @@ extern struct mode_key_tree mode_key_tree_emacs_copy; int mode_key_cmp(struct mode_key_binding *, struct mode_key_binding *); SPLAY_PROTOTYPE(mode_key_tree, mode_key_binding, entry, mode_key_cmp); const char *mode_key_tostring(struct mode_key_cmdstr *r, enum mode_key_cmd); +enum mode_key_cmd mode_key_fromstring(struct mode_key_cmdstr *, const char *); +const struct mode_key_table *mode_key_findtable(const char *); void mode_key_init_trees(void); void mode_key_free_trees(void); void mode_key_init(struct mode_key_data *, struct mode_key_tree *); |