aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--key-bindings.c59
-rw-r--r--tmux.h2
-rw-r--r--window-customize.c32
3 files changed, 77 insertions, 16 deletions
diff --git a/key-bindings.c b/key-bindings.c
index d6a72297..fc083db4 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -89,9 +89,8 @@ key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2)
}
static void
-key_bindings_free(struct key_table *table, struct key_binding *bd)
+key_bindings_free(struct key_binding *bd)
{
- RB_REMOVE(key_bindings, &table->key_bindings, bd);
cmd_list_free(bd->cmdlist);
free((void *)bd->note);
free(bd);
@@ -110,6 +109,7 @@ key_bindings_get_table(const char *name, int create)
table = xmalloc(sizeof *table);
table->name = xstrdup(name);
RB_INIT(&table->key_bindings);
+ RB_INIT(&table->default_key_bindings);
table->references = 1; /* one reference in key_tables */
RB_INSERT(key_tables, &key_tables, table);
@@ -138,8 +138,14 @@ key_bindings_unref_table(struct key_table *table)
if (--table->references != 0)
return;
- RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1)
- key_bindings_free(table, bd);
+ RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1) {
+ RB_REMOVE(key_bindings, &table->key_bindings, bd);
+ key_bindings_free(bd);
+ }
+ RB_FOREACH_SAFE(bd, key_bindings, &table->default_key_bindings, bd1) {
+ RB_REMOVE(key_bindings, &table->default_key_bindings, bd);
+ key_bindings_free(bd);
+ }
free((void *)table->name);
free(table);
@@ -155,6 +161,15 @@ key_bindings_get(struct key_table *table, key_code key)
}
struct key_binding *
+key_bindings_get_default(struct key_table *table, key_code key)
+{
+ struct key_binding bd;
+
+ bd.key = key;
+ return (RB_FIND(key_bindings, &table->default_key_bindings, &bd));
+}
+
+struct key_binding *
key_bindings_first(struct key_table *table)
{
return (RB_MIN(key_bindings, &table->key_bindings));
@@ -176,8 +191,10 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat,
table = key_bindings_get_table(name, 1);
bd = key_bindings_get(table, key & ~KEYC_XTERM);
- if (bd != NULL)
- key_bindings_free(table, bd);
+ if (bd != NULL) {
+ RB_REMOVE(key_bindings, &table->key_bindings, bd);
+ key_bindings_free(bd);
+ }
bd = xcalloc(1, sizeof *bd);
bd->key = key;
@@ -203,9 +220,12 @@ key_bindings_remove(const char *name, key_code key)
bd = key_bindings_get(table, key & ~KEYC_XTERM);
if (bd == NULL)
return;
- key_bindings_free(table, bd);
- if (RB_EMPTY(&table->key_bindings)) {
+ RB_REMOVE(key_bindings, &table->key_bindings, bd);
+ key_bindings_free(bd);
+
+ if (RB_EMPTY(&table->key_bindings) &&
+ RB_EMPTY(&table->default_key_bindings)) {
RB_REMOVE(key_tables, &key_tables, table);
key_bindings_unref_table(table);
}
@@ -228,6 +248,28 @@ key_bindings_remove_table(const char *name)
}
}
+static enum cmd_retval
+key_bindings_init_done(__unused struct cmdq_item *item, __unused void *data)
+{
+ struct key_table *table;
+ struct key_binding *bd, *new_bd;
+
+ RB_FOREACH(table, key_tables, &key_tables) {
+ RB_FOREACH(bd, key_bindings, &table->key_bindings) {
+ new_bd = xcalloc(1, sizeof *bd);
+ new_bd->key = bd->key;
+ if (bd->note != NULL)
+ new_bd->note = xstrdup(bd->note);
+ new_bd->flags = bd->flags;
+ new_bd->cmdlist = bd->cmdlist;
+ new_bd->cmdlist->references++;
+ RB_INSERT(key_bindings, &table->default_key_bindings,
+ new_bd);
+ }
+ }
+ return (CMD_RETURN_NORMAL);
+}
+
void
key_bindings_init(void)
{
@@ -525,6 +567,7 @@ key_bindings_init(void)
cmdq_append(NULL, cmdq_get_command(pr->cmdlist, NULL));
cmd_list_free(pr->cmdlist);
}
+ cmdq_append(NULL, cmdq_get_callback(key_bindings_init_done, NULL));
}
static enum cmd_retval
diff --git a/tmux.h b/tmux.h
index 4b6bacf2..f2675345 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1669,6 +1669,7 @@ RB_HEAD(key_bindings, key_binding);
struct key_table {
const char *name;
struct key_bindings key_bindings;
+ struct key_bindings default_key_bindings;
u_int references;
@@ -2245,6 +2246,7 @@ struct key_table *key_bindings_first_table(void);
struct key_table *key_bindings_next_table(struct key_table *);
void key_bindings_unref_table(struct key_table *);
struct key_binding *key_bindings_get(struct key_table *, key_code);
+struct key_binding *key_bindings_get_default(struct key_table *, key_code);
struct key_binding *key_bindings_first(struct key_table *);
struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
void key_bindings_add(const char *, key_code, const char *, int,
diff --git a/window-customize.c b/window-customize.c
index ee4bf4ba..c74884d6 100644
--- a/window-customize.c
+++ b/window-customize.c
@@ -564,9 +564,12 @@ window_customize_build(void *modedata,
i = 0;
kt = key_bindings_first_table();
while (kt != NULL) {
- window_customize_build_keys(data, kt, ft, filter, &fs, i);
- if (++i == 256)
- break;
+ if (!RB_EMPTY(&kt->key_bindings)) {
+ window_customize_build_keys(data, kt, ft, filter, &fs,
+ i);
+ if (++i == 256)
+ break;
+ }
kt = key_bindings_next_table(kt);
}
@@ -581,9 +584,9 @@ window_customize_draw_key(__unused struct window_customize_modedata *data,
struct screen *s = ctx->s;
u_int cx = s->cx, cy = s->cy;
struct key_table *kt;
- struct key_binding *bd;
+ struct key_binding *bd, *default_bd;
const char *note, *period = "";
- char *tmp;
+ char *cmd, *default_cmd;
if (item == NULL || !window_customize_get_key(item, &kt, &bd))
return;
@@ -611,12 +614,25 @@ window_customize_draw_key(__unused struct window_customize_modedata *data,
if (s->cy >= cy + sy - 1)
return;
- tmp = cmd_list_print(bd->cmdlist, 0);
+ cmd = cmd_list_print(bd->cmdlist, 0);
if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
- &grid_default_cell, "Command: %s", tmp)) {
- free(tmp);
+ &grid_default_cell, "Command: %s", cmd)) {
+ free(cmd);
return;
}
+ default_bd = key_bindings_get_default(kt, bd->key);
+ if (default_bd != NULL) {
+ default_cmd = cmd_list_print(default_bd->cmdlist, 0);
+ if (strcmp(cmd, default_cmd) != 0 &&
+ !screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0,
+ &grid_default_cell, "The default is: %s", default_cmd)) {
+ free(default_cmd);
+ free(cmd);
+ return;
+ }
+ free(default_cmd);
+ }
+ free(cmd);
}
static void