From ca1ee217023b431bac179023c2b70e13427c4ab0 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 6 Jan 2009 14:10:32 +0000 Subject: [PATCH] Switch to splay tree for key bindings. --- CHANGES | 6 +++- TODO | 2 -- cmd-list-keys.c | 12 ++++---- key-bindings.c | 73 ++++++++++++++++++++++--------------------------- tmux.h | 13 ++++++--- 5 files changed, 51 insertions(+), 55 deletions(-) diff --git a/CHANGES b/CHANGES index 386dba16..7bcb353f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +06 January 2009 + +* Use a splay tree for key bindings. + 22 December 2008 * Use the right keys for home and end. @@ -792,7 +796,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.176 2008-12-22 17:26:51 nicm Exp $ +$Id: CHANGES,v 1.177 2009-01-06 14:10:32 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB diff --git a/TODO b/TODO index be612baf..99e56002 100644 --- a/TODO +++ b/TODO @@ -43,14 +43,12 @@ - activity/bell should be per-window not per-link? what if it is cur win in session not being watched? - tidy up window modes -- list-keys should be sorted - problems with force-width when wrapping line in emacs? - command history for command-prompt. better tab completion (use options too) - window options should be done similarly to standard options - next prev word etc in command prompt - many more info() displays for various things - vi half page scroll -- why do home/end work in emacs outside tmux but not inside? - document status line options, title bits - document mode-fg/mode-bg/message-fg/message-bg - document window options changes diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 9dba321e..299681b9 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -1,4 +1,4 @@ -/* $Id: cmd-list-keys.c,v 1.10 2008-06-05 21:25:00 nicm Exp $ */ +/* $Id: cmd-list-keys.c,v 1.11 2009-01-06 14:10:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -42,13 +42,11 @@ const struct cmd_entry cmd_list_keys_entry = { void cmd_list_keys_exec(unused struct cmd *self, struct cmd_ctx *ctx) { - struct binding *bd; - const char *key; - char s[BUFSIZ]; - u_int i; + struct key_binding *bd; + const char *key; + char s[BUFSIZ]; - for (i = 0; i < ARRAY_LENGTH(&key_bindings); i++) { - bd = ARRAY_ITEM(&key_bindings, i); + SPLAY_FOREACH(bd, key_bindings, &key_bindings) { if ((key = key_string_lookup_key(bd->key)) == NULL) continue; if (bd->cmd->entry->print == NULL) { diff --git a/key-bindings.c b/key-bindings.c index 039b855a..40f3a901 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $Id: key-bindings.c,v 1.38 2008-12-17 08:08:09 nicm Exp $ */ +/* $Id: key-bindings.c,v 1.39 2009-01-06 14:10:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,23 +24,33 @@ #include "tmux.h" -struct bindings key_bindings; +SPLAY_GENERATE(key_bindings, key_binding, entry, key_bindings_cmp); + +struct key_bindings key_bindings; + +int +key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2) +{ + return (bd1->key - bd2->key); +} + +struct key_binding * +key_bindings_lookup(int key) +{ + struct key_binding bd; + + bd.key = key; + return (SPLAY_FIND(key_bindings, &key_bindings, &bd)); +} void key_bindings_add(int key, struct cmd *cmd) { - struct binding *bd; - u_int i; + struct key_binding *bd; - bd = NULL; - for (i = 0; i < ARRAY_LENGTH(&key_bindings); i++) { - bd = ARRAY_ITEM(&key_bindings, i); - if (bd->key == key) - break; - } - if (i == ARRAY_LENGTH(&key_bindings)) { + if ((bd = key_bindings_lookup(key)) == NULL) { bd = xmalloc(sizeof *bd); - ARRAY_ADD(&key_bindings, bd); + SPLAY_INSERT(key_bindings, &key_bindings, bd); } else cmd_free(bd->cmd); @@ -51,19 +61,11 @@ key_bindings_add(int key, struct cmd *cmd) void key_bindings_remove(int key) { - struct binding *bd; - u_int i; + struct key_binding *bd; - bd = NULL; - for (i = 0; i < ARRAY_LENGTH(&key_bindings); i++) { - bd = ARRAY_ITEM(&key_bindings, i); - if (bd->key == key) - break; - } - if (i == ARRAY_LENGTH(&key_bindings)) + if ((bd = key_bindings_lookup(key)) == NULL) return; - - ARRAY_REMOVE(&key_bindings, i); + SPLAY_REMOVE(key_bindings, &key_bindings, bd); cmd_free(bd->cmd); xfree(bd); @@ -108,7 +110,7 @@ key_bindings_init(void) u_int i; struct cmd *cmd; - ARRAY_INIT(&key_bindings); + SPLAY_INIT(&key_bindings); for (i = 0; i < (sizeof table / sizeof table[0]); i++) { cmd = xmalloc(sizeof *cmd); @@ -123,17 +125,13 @@ key_bindings_init(void) void key_bindings_free(void) { - struct binding *bd; - u_int i; - - for (i = 0; i < ARRAY_LENGTH(&key_bindings); i++) { - bd = ARRAY_ITEM(&key_bindings, i); + struct key_binding *bd; + while (!SPLAY_EMPTY(&key_bindings)) { + bd = SPLAY_ROOT(&key_bindings); cmd_free(bd->cmd); xfree(bd); } - - ARRAY_FREE(&key_bindings); } void printflike2 @@ -185,17 +183,10 @@ key_bindings_info(struct cmd_ctx *ctx, const char *fmt, ...) void key_bindings_dispatch(int key, struct client *c) { - struct cmd_ctx ctx; - struct binding *bd; - u_int i; + struct cmd_ctx ctx; + struct key_binding *bd; - bd = NULL; - for (i = 0; i < ARRAY_LENGTH(&key_bindings); i++) { - bd = ARRAY_ITEM(&key_bindings, i); - if (bd->key == key) - break; - } - if (i == ARRAY_LENGTH(&key_bindings)) + if ((bd = key_bindings_lookup(key)) == NULL) return; ctx.msgdata = NULL; diff --git a/tmux.h b/tmux.h index 9d79d571..9ade8c65 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.204 2008-12-15 21:21:56 nicm Exp $ */ +/* $Id: tmux.h,v 1.205 2009-01-06 14:10:32 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -831,11 +831,13 @@ struct cmd_option_data { }; /* Key binding. */ -struct binding { +struct key_binding { int key; struct cmd *cmd; + + SPLAY_ENTRY(key_binding) entry; }; -ARRAY_DECL(bindings, struct binding *); +SPLAY_HEAD(key_bindings, key_binding); /* Set/display option data. */ struct set_option_entry { @@ -1122,7 +1124,10 @@ void client_write_server2( void client_fill_session(struct msg_command_data *); /* key-bindings.c */ -extern struct bindings key_bindings; +extern struct key_bindings key_bindings; +int key_bindings_cmp(struct key_binding *, struct key_binding *); +SPLAY_PROTOTYPE(key_bindings, key_binding, entry, key_bindings_cmp); +struct key_binding *key_bindings_lookup(int); void key_bindings_add(int, struct cmd *); void key_bindings_remove(int); void key_bindings_init(void);