diff --git a/man/termkey_strfkey.3 b/man/termkey_strfkey.3 index 99780b6..363e576 100644 --- a/man/termkey_strfkey.3 +++ b/man/termkey_strfkey.3 @@ -31,7 +31,10 @@ If the key event is a special key instead of unmodified Unicode, wrap it in "\f( Use spaces instead of hyphens to separate the modifier name(s) from the base key name. .TP .B TERMKEY_FORMAT_LOWERMOD -Use lowercase for the modifier name +Use lowercase for the modifier name. +.TP +.B TERMKEY_FORMAT_LOWERSPACE +Use lowercase for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP"). .TP .B TERMKEY_FORMAT_MOUSE_POS If the event is a mouse event, include the position rendered as "\f(CW@ (col,line)\fP". diff --git a/t/11strfkey.c b/t/11strfkey.c index 3125553..d271ead 100644 --- a/t/11strfkey.c +++ b/t/11strfkey.c @@ -8,7 +8,7 @@ int main(int argc, char *argv[]) char buffer[16]; size_t len; - plan_tests(36); + plan_tests(40); tk = termkey_new_abstract("vt100", 0); @@ -102,6 +102,10 @@ int main(int argc, char *argv[]) is_int(len, 6, "length for sym/PageUp/0"); is_str(buffer, "PageUp", "buffer for sym/PageUp/0"); + len = termkey_strfkey(tk, buffer, sizeof buffer, &key, TERMKEY_FORMAT_LOWERSPACE); + is_int(len, 7, "length for sym/PageUp/0 lowerspace"); + is_str(buffer, "page up", "buffer for sym/PageUp/0 lowerspace"); + key.type = TERMKEY_TYPE_FUNCTION; key.code.number = 5; key.modifiers = 0; @@ -114,6 +118,10 @@ int main(int argc, char *argv[]) is_int(len, 4, "length for func/5/0 wrapbracket"); is_str(buffer, "", "buffer for func/5/0 wrapbracket"); + len = termkey_strfkey(tk, buffer, sizeof buffer, &key, TERMKEY_FORMAT_LOWERSPACE); + is_int(len, 2, "length for func/5/0 lowerspace"); + is_str(buffer, "f5", "buffer for func/5/0 lowerspace"); + termkey_destroy(tk); return exit_status(); diff --git a/termkey.c b/termkey.c index c8388df..0dd261f 100644 --- a/termkey.c +++ b/termkey.c @@ -1,6 +1,7 @@ #include "termkey.h" #include "termkey-internal.h" +#include #include #include #include @@ -1170,6 +1171,29 @@ size_t termkey_snprint_key(TermKey *tk, char *buffer, size_t len, TermKeyKey *ke return termkey_strfkey(tk, buffer, len, key, format); } +/* Similar to snprintf(str, size, "%s", src) except it turns CamelCase into + * space separated values + */ +static int snprint_cameltospaces(char *str, size_t size, const char *src) +{ + int prev_lower = 0; + size_t l = 0; + while(*src && l < size) { + if(isupper(*src) && prev_lower) { + if(str) + str[l++] = ' '; + if(l >= size) + return -1; + } + prev_lower = islower(*src); + str[l++] = tolower(*src++); + } + if(l >= size) + return -1; + str[l] = 0; + return l; +} + static struct modnames { const char *shift, *alt, *ctrl; } @@ -1250,10 +1274,17 @@ size_t termkey_strfkey(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, T l = snprintf(buffer + pos, len - pos, "%s", key->utf8); break; case TERMKEY_TYPE_KEYSYM: - l = snprintf(buffer + pos, len - pos, "%s", termkey_get_keyname(tk, key->code.sym)); + { + const char *name = termkey_get_keyname(tk, key->code.sym); + if(format & TERMKEY_FORMAT_LOWERSPACE) + l = snprint_cameltospaces(buffer + pos, len - pos, name); + else + l = snprintf(buffer + pos, len - pos, "%s", name); + } break; case TERMKEY_TYPE_FUNCTION: - l = snprintf(buffer + pos, len - pos, "F%d", key->code.number); + l = snprintf(buffer + pos, len - pos, "%c%d", + (format & TERMKEY_FORMAT_LOWERSPACE ? 'f' : 'F'), key->code.number); break; case TERMKEY_TYPE_MOUSE: { diff --git a/termkey.h.in b/termkey.h.in index 04e0418..fe37cc7 100644 --- a/termkey.h.in +++ b/termkey.h.in @@ -217,6 +217,7 @@ typedef enum { TERMKEY_FORMAT_WRAPBRACKET = 1 << 3, /* Wrap special keys in brackets like */ TERMKEY_FORMAT_SPACEMOD = 1 << 4, /* M Foo instead of M-Foo */ TERMKEY_FORMAT_LOWERMOD = 1 << 5, /* meta or m instead of Meta or M */ + TERMKEY_FORMAT_LOWERSPACE = 1 << 6, /* page down instead of PageDown */ TERMKEY_FORMAT_MOUSE_POS = 1 << 8 /* Include mouse position if relevant; @ col,line */ } TermKeyFormat;