mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
Permit commands to be bound to key presses without the prefix key first. The
new -n flag to bind-key and unbind-key sets or removes these bindings, and list-key shows them in []s.
This commit is contained in:
parent
ce4eb6559e
commit
5a1a106637
@ -39,7 +39,7 @@ struct cmd_bind_key_data {
|
|||||||
|
|
||||||
const struct cmd_entry cmd_bind_key_entry = {
|
const struct cmd_entry cmd_bind_key_entry = {
|
||||||
"bind-key", "bind",
|
"bind-key", "bind",
|
||||||
"[-r] key command [arguments]",
|
"[-nr] key command [arguments]",
|
||||||
0, 0,
|
0, 0,
|
||||||
NULL,
|
NULL,
|
||||||
cmd_bind_key_parse,
|
cmd_bind_key_parse,
|
||||||
@ -54,14 +54,17 @@ int
|
|||||||
cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
|
cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||||
{
|
{
|
||||||
struct cmd_bind_key_data *data;
|
struct cmd_bind_key_data *data;
|
||||||
int opt;
|
int opt, no_prefix = 0;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "r")) != -1) {
|
while ((opt = getopt(argc, argv, "nr")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'n':
|
||||||
|
no_prefix = 1;
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
data->can_repeat = 1;
|
data->can_repeat = 1;
|
||||||
break;
|
break;
|
||||||
@ -78,6 +81,8 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
|
|||||||
xasprintf(cause, "unknown key: %s", argv[0]);
|
xasprintf(cause, "unknown key: %s", argv[0]);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (!no_prefix)
|
||||||
|
data->key |= KEYC_PREFIX;
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
@ -46,27 +46,33 @@ cmd_list_keys_exec(unused struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
{
|
{
|
||||||
struct key_binding *bd;
|
struct key_binding *bd;
|
||||||
const char *key;
|
const char *key;
|
||||||
char tmp[BUFSIZ];
|
char tmp[BUFSIZ], keytmp[64];
|
||||||
int width, keywidth;
|
int width, keywidth;
|
||||||
|
|
||||||
width = 0;
|
width = 0;
|
||||||
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
|
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
|
||||||
if ((key = key_string_lookup_key(bd->key)) == NULL)
|
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
|
||||||
|
if (key == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
keywidth = strlen(key) + 1;
|
keywidth = strlen(key) + 1;
|
||||||
|
if (!(bd->key & KEYC_PREFIX))
|
||||||
|
keywidth += 2;
|
||||||
if (keywidth > width)
|
if (keywidth > width)
|
||||||
width = keywidth;
|
width = keywidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
|
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
|
||||||
if ((key = key_string_lookup_key(bd->key)) == NULL)
|
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
|
||||||
|
if (key == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*tmp = '\0';
|
*tmp = '\0';
|
||||||
cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
|
cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
|
||||||
|
if (!(bd->key & KEYC_PREFIX)) {
|
||||||
|
xsnprintf(keytmp, sizeof keytmp, "[%s]", key);
|
||||||
|
key = keytmp;
|
||||||
|
}
|
||||||
ctx->print(ctx, "%*s: %s", width, key, tmp);
|
ctx->print(ctx, "%*s: %s", width, key, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ struct cmd_unbind_key_data {
|
|||||||
|
|
||||||
const struct cmd_entry cmd_unbind_key_entry = {
|
const struct cmd_entry cmd_unbind_key_entry = {
|
||||||
"unbind-key", "unbind",
|
"unbind-key", "unbind",
|
||||||
"key",
|
"[-n] key",
|
||||||
0, 0,
|
0, 0,
|
||||||
NULL,
|
NULL,
|
||||||
cmd_unbind_key_parse,
|
cmd_unbind_key_parse,
|
||||||
@ -51,12 +51,15 @@ int
|
|||||||
cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
|
cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
|
||||||
{
|
{
|
||||||
struct cmd_unbind_key_data *data;
|
struct cmd_unbind_key_data *data;
|
||||||
int opt;
|
int opt, no_prefix = 0;
|
||||||
|
|
||||||
self->data = data = xmalloc(sizeof *data);
|
self->data = data = xmalloc(sizeof *data);
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "")) != -1) {
|
while ((opt = getopt(argc, argv, "n")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'n':
|
||||||
|
no_prefix = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
@ -70,6 +73,8 @@ cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
|
|||||||
xasprintf(cause, "unknown key: %s", argv[0]);
|
xasprintf(cause, "unknown key: %s", argv[0]);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if (!no_prefix)
|
||||||
|
data->key |= KEYC_PREFIX;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
@ -32,7 +32,18 @@ struct key_bindings dead_key_bindings;
|
|||||||
int
|
int
|
||||||
key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2)
|
key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2)
|
||||||
{
|
{
|
||||||
return (bd1->key - bd2->key);
|
int key1, key2;
|
||||||
|
|
||||||
|
key1 = bd1->key & ~KEYC_PREFIX;
|
||||||
|
key2 = bd2->key & ~KEYC_PREFIX;
|
||||||
|
if (key1 != key2)
|
||||||
|
return (key1 - key2);
|
||||||
|
|
||||||
|
if (bd1->key & KEYC_PREFIX && !(bd2->key & KEYC_PREFIX))
|
||||||
|
return (-1);
|
||||||
|
if (bd2->key & KEYC_PREFIX && !(bd1->key & KEYC_PREFIX))
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct key_binding *
|
struct key_binding *
|
||||||
@ -170,7 +181,8 @@ key_bindings_init(void)
|
|||||||
cmd->entry->init(cmd, table[i].key);
|
cmd->entry->init(cmd, table[i].key);
|
||||||
TAILQ_INSERT_HEAD(cmdlist, cmd, qentry);
|
TAILQ_INSERT_HEAD(cmdlist, cmd, qentry);
|
||||||
|
|
||||||
key_bindings_add(table[i].key, table[i].can_repeat, cmdlist);
|
key_bindings_add(
|
||||||
|
table[i].key | KEYC_PREFIX, table[i].can_repeat, cmdlist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
server.c
11
server.c
@ -802,14 +802,19 @@ server_handle_client(struct client *c)
|
|||||||
if (!(c->flags & CLIENT_PREFIX)) {
|
if (!(c->flags & CLIENT_PREFIX)) {
|
||||||
if (key == prefix)
|
if (key == prefix)
|
||||||
c->flags |= CLIENT_PREFIX;
|
c->flags |= CLIENT_PREFIX;
|
||||||
else
|
else {
|
||||||
window_pane_key(wp, c, key);
|
/* Try as a non-prefix key binding. */
|
||||||
|
if ((bd = key_bindings_lookup(key)) == NULL)
|
||||||
|
window_pane_key(wp, c, key);
|
||||||
|
else
|
||||||
|
key_bindings_dispatch(bd, c);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prefix key already pressed. Reset prefix and lookup key. */
|
/* Prefix key already pressed. Reset prefix and lookup key. */
|
||||||
c->flags &= ~CLIENT_PREFIX;
|
c->flags &= ~CLIENT_PREFIX;
|
||||||
if ((bd = key_bindings_lookup(key)) == NULL) {
|
if ((bd = key_bindings_lookup(key | KEYC_PREFIX)) == NULL) {
|
||||||
/* If repeating, treat this as a key, else ignore. */
|
/* If repeating, treat this as a key, else ignore. */
|
||||||
if (c->flags & CLIENT_REPEAT) {
|
if (c->flags & CLIENT_REPEAT) {
|
||||||
c->flags &= ~CLIENT_REPEAT;
|
c->flags &= ~CLIENT_REPEAT;
|
||||||
|
19
tmux.1
19
tmux.1
@ -617,7 +617,7 @@ 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 r
|
.Op Fl nr
|
||||||
.Ar key Ar command Op Ar arguments
|
.Ar key Ar command Op Ar arguments
|
||||||
.Xc
|
.Xc
|
||||||
.D1 (alias: Ic bind )
|
.D1 (alias: Ic bind )
|
||||||
@ -632,6 +632,13 @@ or
|
|||||||
for Ctrl keys, or
|
for Ctrl keys, or
|
||||||
.Ql M-
|
.Ql M-
|
||||||
for Alt (meta) keys.
|
for Alt (meta) keys.
|
||||||
|
If
|
||||||
|
.Fl n
|
||||||
|
is specified, it is not necessary to use the prefix key,
|
||||||
|
.Ar command
|
||||||
|
is bound to
|
||||||
|
.Ar key
|
||||||
|
alone.
|
||||||
The
|
The
|
||||||
.Fl r
|
.Fl r
|
||||||
flag indicates this key may repeat, see the
|
flag indicates this key may repeat, see the
|
||||||
@ -842,6 +849,10 @@ List the syntax of all commands supported by
|
|||||||
.Xc
|
.Xc
|
||||||
.D1 (alias: Ic lsk )
|
.D1 (alias: Ic lsk )
|
||||||
List all key bindings.
|
List all key bindings.
|
||||||
|
Keys bound without the prefix key (see
|
||||||
|
.Ic bind-key
|
||||||
|
.Fl n )
|
||||||
|
are enclosed in square brackets.
|
||||||
.It Xo Ic list-sessions
|
.It Xo Ic list-sessions
|
||||||
.Xc
|
.Xc
|
||||||
.D1 (alias: Ic ls )
|
.D1 (alias: Ic ls )
|
||||||
@ -1613,11 +1624,17 @@ 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
|
||||||
.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
|
||||||
|
.Fl n
|
||||||
|
is specified, the command bound to
|
||||||
|
.Ar key
|
||||||
|
without a prefix (if any) is removed.
|
||||||
.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
|
||||||
|
14
tmux.h
14
tmux.h
@ -102,10 +102,12 @@ struct buffer {
|
|||||||
#define BELL_CURRENT 2
|
#define BELL_CURRENT 2
|
||||||
|
|
||||||
/* Key codes. ncurses defines KEY_*. Grrr. */
|
/* Key codes. ncurses defines KEY_*. Grrr. */
|
||||||
#define KEYC_NONE 0x0fff
|
#define KEYC_NONE 0xfff
|
||||||
#define KEYC_ESCAPE 0x2000
|
/* 0x1000 is base for special keys */
|
||||||
#define KEYC_CTRL 0x4000
|
#define KEYC_ESCAPE 0x2000
|
||||||
#define KEYC_SHIFT 0x8000
|
#define KEYC_CTRL 0x4000
|
||||||
|
#define KEYC_SHIFT 0x8000
|
||||||
|
#define KEYC_PREFIX 0x10000
|
||||||
|
|
||||||
enum key_code {
|
enum key_code {
|
||||||
/* Mouse key. */
|
/* Mouse key. */
|
||||||
@ -856,8 +858,6 @@ struct client_ctx {
|
|||||||
|
|
||||||
/* Key/command line command. */
|
/* Key/command line command. */
|
||||||
struct cmd_ctx {
|
struct cmd_ctx {
|
||||||
struct client *cmdclient;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* curclient is the client where this command was executed if inside
|
* curclient is the client where this command was executed if inside
|
||||||
* tmux. This is NULL if the command came from the command-line.
|
* tmux. This is NULL if the command came from the command-line.
|
||||||
@ -869,6 +869,8 @@ struct cmd_ctx {
|
|||||||
* configuration file.
|
* configuration file.
|
||||||
*/
|
*/
|
||||||
struct client *curclient;
|
struct client *curclient;
|
||||||
|
struct client *cmdclient;
|
||||||
|
|
||||||
struct session *cursession;
|
struct session *cursession;
|
||||||
|
|
||||||
struct msg_command_data *msgdata;
|
struct msg_command_data *msgdata;
|
||||||
|
Loading…
Reference in New Issue
Block a user