From 5ed17e84faed0a7655ec1eb3de291b60839dcb12 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 12 Dec 2015 18:32:24 +0000 Subject: [PATCH] Add key-table option to set the default key table for a session, allows different key bindings for different sessions and a few other things. --- cmd-attach-session.c | 2 ++ cmd-new-session.c | 1 + cmd-set-option.c | 4 ++++ cmd-switch-client.c | 1 + format.c | 4 +++- options-table.c | 6 ++++++ server-client.c | 36 +++++++++++++++++++++++++++--------- server-fn.c | 1 + tmux.1 | 5 +++++ tmux.h | 2 ++ 10 files changed, 52 insertions(+), 10 deletions(-) diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 73c82248..00ced9df 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -119,6 +119,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, } c->session = s; + server_client_set_key_table(c, NULL); status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s, NULL); @@ -150,6 +151,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, } c->session = s; + server_client_set_key_table(c, NULL); status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s, NULL); diff --git a/cmd-new-session.c b/cmd-new-session.c index aee69e12..341399be 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -262,6 +262,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) } else if (c->session != NULL) c->last_session = c->session; c->session = s; + server_client_set_key_table(c, NULL); status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s, NULL); diff --git a/cmd-set-option.c b/cmd-set-option.c index e2a4768c..daee62ac 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -183,6 +183,10 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) w->active->flags |= PANE_CHANGED; } } + if (strcmp(oe->name, "key-table") == 0) { + TAILQ_FOREACH(c, &clients, entry) + server_client_set_key_table(c, NULL); + } if (strcmp(oe->name, "status") == 0 || strcmp(oe->name, "status-interval") == 0) status_timer_start_all(); diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 85cbce78..4746b15a 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -124,6 +124,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq) if (c->session != NULL && c->session != s) c->last_session = c->session; c->session = s; + server_client_set_key_table(c, NULL); status_timer_start(c); session_update_activity(s, NULL); gettimeofday(&s->last_attached_time, NULL); diff --git a/format.c b/format.c index 3e666330..79445936 100644 --- a/format.c +++ b/format.c @@ -1035,6 +1035,7 @@ void format_defaults_client(struct format_tree *ft, struct client *c) { struct session *s; + const char *name; if (ft->s == NULL) ft->s = c->session; @@ -1052,7 +1053,8 @@ format_defaults_client(struct format_tree *ft, struct client *c) format_add_tv(ft, "client_created", &c->creation_time); format_add_tv(ft, "client_activity", &c->activity_time); - if (strcmp(c->keytable->name, "root") == 0) + name = server_client_get_key_table(c); + if (strcmp(c->keytable->name, name) == 0) format_add(ft, "client_prefix", "%d", 0); else format_add(ft, "client_prefix", "%d", 1); diff --git a/options-table.c b/options-table.c index 0dab0c0e..63e7ab61 100644 --- a/options-table.c +++ b/options-table.c @@ -211,6 +211,12 @@ const struct options_table_entry options_table[] = { .default_num = 2000 }, + { .name = "key-table", + .type = OPTIONS_TABLE_STRING, + .scope = OPTIONS_TABLE_SESSION, + .default_str = "root" + }, + { .name = "lock-after-time", .type = OPTIONS_TABLE_NUMBER, .scope = OPTIONS_TABLE_SESSION, diff --git a/server-client.c b/server-client.c index ed0eefdd..c2b43f38 100644 --- a/server-client.c +++ b/server-client.c @@ -32,7 +32,6 @@ #include "tmux.h" -void server_client_key_table(struct client *, const char *); void server_client_free(int, short, void *); void server_client_check_focus(struct window_pane *); void server_client_check_resize(struct window_pane *); @@ -72,13 +71,32 @@ server_client_check_nested(struct client *c) /* Set client key table. */ void -server_client_key_table(struct client *c, const char *name) +server_client_set_key_table(struct client *c, const char *name) { + if (name == NULL) + name = server_client_get_key_table(c); + key_bindings_unref_table(c->keytable); c->keytable = key_bindings_get_table(name, 1); c->keytable->references++; } +/* Get default key table. */ +const char * +server_client_get_key_table(struct client *c) +{ + struct session *s = c->session; + const char *name; + + if (s == NULL) + return ("root"); + + name = options_get_string(s->options, "key-table"); + if (*name == '\0') + return ("root"); + return (name); +} + /* Create a new client. */ void server_client_create(int fd) @@ -598,7 +616,7 @@ retry: * again in the root table. */ if ((c->flags & CLIENT_REPEAT) && !bd->can_repeat) { - server_client_key_table(c, "root"); + server_client_set_key_table(c, NULL); c->flags &= ~CLIENT_REPEAT; server_status_client(c); goto retry; @@ -625,7 +643,7 @@ retry: evtimer_add(&c->repeat_timer, &tv); } else { c->flags &= ~CLIENT_REPEAT; - server_client_key_table(c, "root"); + server_client_set_key_table(c, NULL); } server_status_client(c); @@ -640,15 +658,15 @@ retry: * root table and try again. */ if (c->flags & CLIENT_REPEAT) { - server_client_key_table(c, "root"); + server_client_set_key_table(c, NULL); c->flags &= ~CLIENT_REPEAT; server_status_client(c); goto retry; } /* If no match and we're not in the root table, that's it. */ - if (strcmp(c->keytable->name, "root") != 0) { - server_client_key_table(c, "root"); + if (strcmp(c->keytable->name, server_client_get_key_table(c)) != 0) { + server_client_set_key_table(c, NULL); server_status_client(c); return; } @@ -659,7 +677,7 @@ retry: */ if (key == (key_code)options_get_number(s->options, "prefix") || key == (key_code)options_get_number(s->options, "prefix2")) { - server_client_key_table(c, "prefix"); + server_client_set_key_table(c, "prefix"); server_status_client(c); return; } @@ -834,7 +852,7 @@ server_client_repeat_timer(__unused int fd, __unused short events, void *data) struct client *c = data; if (c->flags & CLIENT_REPEAT) { - server_client_key_table(c, "root"); + server_client_set_key_table(c, NULL); c->flags &= ~CLIENT_REPEAT; server_status_client(c); } diff --git a/server-fn.c b/server-fn.c index 07ade08c..a4c2dfea 100644 --- a/server-fn.c +++ b/server-fn.c @@ -384,6 +384,7 @@ server_destroy_session(struct session *s) } else { c->last_session = NULL; c->session = s_new; + server_client_set_key_table(c, NULL); status_timer_start(c); notify_attached_session_changed(c); session_update_activity(s_new, NULL); diff --git a/tmux.1 b/tmux.1 index b02237f1..39e9bd4b 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2572,6 +2572,11 @@ is in milliseconds. Set the maximum number of lines held in window history. This setting applies only to new windows - existing window histories are not resized and retain the limit at the point they were created. +.It Ic key-table Ar key-table +Set the default key table to +.Ar key-table +instead of +.Em root . .It Ic lock-after-time Ar number Lock the session (like the .Ic lock-session diff --git a/tmux.h b/tmux.h index d5e5d822..e10fbcdf 100644 --- a/tmux.h +++ b/tmux.h @@ -1800,6 +1800,8 @@ void server_update_socket(void); void server_add_accept(int); /* server-client.c */ +void server_client_set_key_table(struct client *, const char *); +const char *server_client_get_key_table(struct client *); int server_client_check_nested(struct client *); void server_client_handle_key(struct client *, key_code); void server_client_create(int);