Sync OpenBSD patchset 194:

Final pieces of mode key rebinding: bind-key and unbind-key now accept a -t
argument to modify a table.
This commit is contained in:
Tiago Cunha 2009-07-28 23:19:06 +00:00
parent deaba44835
commit 522fc94d12
6 changed files with 185 additions and 23 deletions

View File

@ -1,4 +1,4 @@
/* $Id: cmd-bind-key.c,v 1.24 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-bind-key.c,v 1.25 2009-07-28 23:19:06 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -18,6 +18,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include "tmux.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 *); void cmd_bind_key_free(struct cmd *);
size_t cmd_bind_key_print(struct cmd *, char *, size_t); 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 { struct cmd_bind_key_data {
int key; int key;
int can_repeat; int can_repeat;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
int command_key;
char *tablename;
char *modecmd;
}; };
const struct cmd_entry cmd_bind_key_entry = { const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind", "bind-key", "bind",
"[-nr] key command [arguments]", "[-cnr] [-t key-table] key command [arguments]",
0, 0, 0, 0,
NULL, NULL,
cmd_bind_key_parse, 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); self->data = data = xmalloc(sizeof *data);
data->can_repeat = 0; data->can_repeat = 0;
data->cmdlist = NULL; 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) { switch (opt) {
case 'c':
data->command_key = 1;
break;
case 'n': case 'n':
no_prefix = 1; no_prefix = 1;
break; break;
case 'r': case 'r':
data->can_repeat = 1; data->can_repeat = 1;
break; break;
case 't':
data->tablename = xstrdup(optarg);
break;
default: default:
goto usage; goto usage;
} }
@ -82,8 +99,14 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
argc--; argc--;
argv++; argv++;
if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL) if (data->tablename != NULL) {
goto error; 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); return (0);
@ -102,6 +125,8 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
if (data == NULL) if (data == NULL)
return (0); return (0);
if (data->tablename != NULL)
return (cmd_bind_key_table(self, ctx));
key_bindings_add(data->key, data->can_repeat, data->cmdlist); key_bindings_add(data->key, data->can_repeat, data->cmdlist);
data->cmdlist = NULL; /* avoid free */ data->cmdlist = NULL; /* avoid free */
@ -109,6 +134,39 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
return (0); 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 void
cmd_bind_key_free(struct cmd *self) cmd_bind_key_free(struct cmd *self)
{ {
@ -116,6 +174,10 @@ cmd_bind_key_free(struct cmd *self)
if (data->cmdlist != NULL) if (data->cmdlist != NULL)
cmd_list_free(data->cmdlist); cmd_list_free(data->cmdlist);
if (data->tablename != NULL)
xfree(data->tablename);
if (data->modecmd != NULL)
xfree(data->modecmd);
xfree(data); xfree(data);
} }

View File

@ -1,4 +1,4 @@
/* $Id: cmd-list-keys.c,v 1.19 2009-07-28 23:11:18 tcunha Exp $ */ /* $Id: cmd-list-keys.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * 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; const char *key, *cmdstr, *mode;
int width, keywidth; int width, keywidth;
for (mtab = mode_key_tables; mtab->name != NULL; mtab++) { if ((mtab = mode_key_findtable(data->target)) == NULL) {
if (strcasecmp(data->target, mtab->name) == 0)
break;
}
if (mtab->name == NULL) {
ctx->error(ctx, "unknown key table: %s", data->target); ctx->error(ctx, "unknown key table: %s", data->target);
return (-1); return (-1);
} }

View File

@ -1,4 +1,4 @@
/* $Id: cmd-unbind-key.c,v 1.19 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-unbind-key.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * 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 *); int cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *);
void cmd_unbind_key_free(struct cmd *); void cmd_unbind_key_free(struct cmd *);
int cmd_unbind_key_table(struct cmd *, struct cmd_ctx *);
struct cmd_unbind_key_data { struct cmd_unbind_key_data {
int key; int key;
int command_key;
char *tablename;
}; };
const struct cmd_entry cmd_unbind_key_entry = { const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind", "unbind-key", "unbind",
"[-n] key", "[-cn] [-t key-table] key",
0, 0, 0, 0,
NULL, NULL,
cmd_unbind_key_parse, 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; int opt, no_prefix = 0;
self->data = data = xmalloc(sizeof *data); 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) { switch (opt) {
case 'c':
data->command_key = 1;
break;
case 'n': case 'n':
no_prefix = 1; no_prefix = 1;
break; break;
case 't':
data->tablename = xstrdup(optarg);
break;
default: default:
goto usage; goto usage;
} }
@ -89,16 +102,41 @@ cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
if (data == NULL) if (data == NULL)
return (0); return (0);
if (data->tablename != NULL)
return (cmd_unbind_key_table(self, ctx));
key_bindings_remove(data->key); key_bindings_remove(data->key);
return (0); 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 void
cmd_unbind_key_free(struct cmd *self) cmd_unbind_key_free(struct cmd *self)
{ {
struct cmd_unbind_key_data *data = self->data; struct cmd_unbind_key_data *data = self->data;
if (data->tablename != NULL)
xfree(data->tablename);
xfree(data); xfree(data);
} }

View File

@ -1,4 +1,4 @@
/* $Id: mode-key.c,v 1.21 2009-07-28 23:11:18 tcunha Exp $ */ /* $Id: mode-key.c,v 1.22 2009-07-28 23:19:06 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -18,6 +18,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
/* /*
@ -54,6 +56,8 @@ struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
{ MODEKEYEDIT_STARTOFLINE, "start-of-line" }, { MODEKEYEDIT_STARTOFLINE, "start-of-line" },
{ MODEKEYEDIT_SWITCHMODE, "switch-mode" }, { MODEKEYEDIT_SWITCHMODE, "switch-mode" },
{ MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" }, { MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" },
{ 0, NULL }
}; };
/* Choice keys command strings. */ /* Choice keys command strings. */
@ -64,6 +68,8 @@ struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ MODEKEYCHOICE_PAGEDOWN, "page-down" }, { MODEKEYCHOICE_PAGEDOWN, "page-down" },
{ MODEKEYCHOICE_PAGEUP, "page-up" }, { MODEKEYCHOICE_PAGEUP, "page-up" },
{ MODEKEYCHOICE_UP, "up" }, { MODEKEYCHOICE_UP, "up" },
{ 0, NULL }
}; };
/* Copy keys command strings. */ /* Copy keys command strings. */
@ -83,6 +89,8 @@ struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
{ MODEKEYCOPY_STARTOFLINE, "start-of-line" }, { MODEKEYCOPY_STARTOFLINE, "start-of-line" },
{ MODEKEYCOPY_STARTSELECTION, "begin-selection" }, { MODEKEYCOPY_STARTSELECTION, "begin-selection" },
{ MODEKEYCOPY_UP, "cursor-up" }, { MODEKEYCOPY_UP, "cursor-up" },
{ 0, NULL }
}; };
/* vi editing keys. */ /* vi editing keys. */
@ -278,6 +286,28 @@ mode_key_tostring(struct mode_key_cmdstr *cmdstr, enum mode_key_cmd cmd)
return (NULL); 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 void
mode_key_init_trees(void) mode_key_init_trees(void)
{ {

48
tmux.1
View File

@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.134 2009-07-28 23:11:18 tcunha Exp $ .\" $Id: tmux.1,v 1.135 2009-07-28 23:19:06 tcunha Exp $
.\" .\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\" .\"
@ -352,7 +352,10 @@ and
used in copy and scroll modes. used in copy and scroll modes.
The tables may be viewed with the The tables may be viewed with the
.Ic list-keys .Ic list-keys
command. command and keys modified or removed with
.Ic bind-key
and
.Ic unbind-key .
.Pp .Pp
The paste buffer key pastes the first line from the top paste buffer on the The paste buffer key pastes the first line from the top paste buffer on the
stack. stack.
@ -637,7 +640,8 @@ If no server is started,
will attempt to start it; this will fail unless sessions are created in the will attempt to start it; this will fail unless sessions are created in the
configuration file. configuration file.
.It Xo Ic bind-key .It Xo Ic bind-key
.Op Fl nr .Op Fl cnr
.Op Fl t Ar key-table
.Ar key Ar command Op Ar arguments .Ar key Ar command Op Ar arguments
.Xc .Xc
.D1 (alias: Ic bind ) .D1 (alias: Ic bind )
@ -652,7 +656,11 @@ or
for Ctrl keys, or for Ctrl keys, or
.Ql M- .Ql M-
for Alt (meta) keys. 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 .Fl n
is specified, it is not necessary to use the prefix key, is specified, it is not necessary to use the prefix key,
.Ar command .Ar command
@ -664,6 +672,19 @@ The
flag indicates this key may repeat, see the flag indicates this key may repeat, see the
.Ic repeat-time .Ic repeat-time
option. 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 .It Xo Ic break-pane
.Op Fl d .Op Fl d
.Op Fl p Ar pane-index .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 List the syntax of all commands supported by
.Nm . .Nm .
.It Xo Ic list-keys .It Xo Ic list-keys
.Op Ar Fl t Ar key-table .Op Fl t Ar key-table
.Xc .Xc
.D1 (alias: Ic lsk ) .D1 (alias: Ic lsk )
List all key bindings. List all key bindings.
@ -1665,17 +1686,30 @@ Switch the current session for client
to to
.Ar target-session . .Ar target-session .
.It Xo Ic unbind-key .It Xo Ic unbind-key
.Op Fl n .Op Fl cn
.Op Fl t Ar key-table
.Ar key .Ar key
.Xc .Xc
.D1 (alias: Ic unbind ) .D1 (alias: Ic unbind )
Unbind the command bound to Unbind the command bound to
.Ar key . .Ar key .
If Without
.Fl t
the primary key bindings are modified; in this case, if
.Fl n .Fl n
is specified, the command bound to is specified, the command bound to
.Ar key .Ar key
without a prefix (if any) is removed. 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 .It Xo Ic unlink-window
.Op Fl k .Op Fl k
.Op Fl t Ar target-window .Op Fl t Ar target-window

4
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.397 2009-07-28 23:11:18 tcunha Exp $ */ /* $Id: tmux.h,v 1.398 2009-07-28 23:19:06 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1097,6 +1097,8 @@ extern struct mode_key_tree mode_key_tree_emacs_copy;
int mode_key_cmp(struct mode_key_binding *, struct mode_key_binding *); int mode_key_cmp(struct mode_key_binding *, struct mode_key_binding *);
SPLAY_PROTOTYPE(mode_key_tree, mode_key_binding, entry, mode_key_cmp); 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); 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_init_trees(void);
void mode_key_free_trees(void); void mode_key_free_trees(void);
void mode_key_init(struct mode_key_data *, struct mode_key_tree *); void mode_key_init(struct mode_key_data *, struct mode_key_tree *);