On 2014-05-16 09:48 +0100, Balazs Kezes wrote: > Now that I managed to reproduce this on my machine, I realized that > the fix is a bit more complicated than I expected. I can try to gather > some time in the future to fix it unless you beat me to it. :)
OK, I've actually managed to create a working fix. Please review and test. It contains some low level buffer manipulation so be extra vigilant! Let me know if you want things differently. Thanks! diff --git a/xterm-keys.c b/xterm-keys.c index af3f1e7..317c15b 100644 --- a/xterm-keys.c +++ b/xterm-keys.c @@ -34,6 +34,9 @@ * 7 Alt + Ctrl * 8 Shift + Alt + Ctrl * + * Note that tmux does not support sending the Meta modifier. When a Meta is + * encountered, it is converted to an Alt. + * * Rather than parsing them, just match against a table. * * There are three forms for F1-F4 (\\033O_P and \\033O1;_P and \\033[1;_P). @@ -119,7 +122,8 @@ const struct xterm_keys_entry xterm_keys_table[] = { /* * Match key against buffer, treating _ as a wildcard. Return -1 for no match, - * 0 for match, 1 if the end of the buffer is reached (need more data). + * -2 if the end of the buffer is reached (need more data), otherwise the length + * of the match. */ int xterm_keys_match(const char *template, const char *buf, size_t len) @@ -131,16 +135,22 @@ xterm_keys_match(const char *template, const char *buf, size_t len) pos = 0; do { - if (*template == '_' && buf[pos] >= '1' && buf[pos] <= '8') + if (*template == '_' && buf[pos] >= '1' && buf[pos] <= '9') { + if (pos+1 != len) { + // Handle two digit modifiers. + if (buf[pos+1] >= '0' && buf[pos+1] <= '9') + pos += 1; + } continue; + } if (buf[pos] != *template) return (-1); } while (*++template != '\0' && ++pos != len); if (*template != '\0') /* partial */ - return (1); + return (-2); - return (0); + return (pos+1); } /* Find modifiers based on template. */ @@ -153,8 +163,11 @@ xterm_keys_modifiers(const char *template, const char *buf, size_t len) idx = strcspn(template, "_"); if (idx >= len) return (0); - param = buf[idx] - '1'; + param = buf[idx] - '0'; + if (idx+1 < len && buf[idx+1] >= '0' && buf[idx+1] <= '9') + param = param*10 + buf[idx+1] - '0'; + param -= 1; modifiers = 0; if (param & 1) modifiers |= KEYC_SHIFT; @@ -176,17 +189,18 @@ xterm_keys_find(const char *buf, size_t len, size_t *size, int *key) { const struct xterm_keys_entry *entry; u_int i; + int match_result; for (i = 0; i < nitems(xterm_keys_table); i++) { entry = &xterm_keys_table[i]; - switch (xterm_keys_match(entry->template, buf, len)) { - case 0: - *size = strlen(entry->template); + match_result = xterm_keys_match(entry->template, buf, len); + if (match_result == -2) { + return (1); + } else if (match_result >= 0) { + *size = match_result; *key = entry->key; *key |= xterm_keys_modifiers(entry->template, buf, len); return (0); - case 1: - return (1); } } return (-1); -- Balazs ------------------------------------------------------------------------------ "Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE Instantly run your Selenium tests across 300+ browser/OS combos. Get unparalleled scalability from the best Selenium testing platform available Simple to use. Nothing to install. Get started now for free." http://p.sf.net/sfu/SauceLabs _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users