aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul LeoNerd Evans <leonerd@leonerd.org.uk>2013-08-26 02:23:19 +0100
committerPaul LeoNerd Evans <leonerd@leonerd.org.uk>2013-08-26 02:23:19 +0100
commit8e503baed8b1df3ed1901b0c93398f204244c77a (patch)
tree2d0c4f980192c0cb26511c9f6d7be875622fac83
parent3b2d8eb8130a5966b28d2426585f6fb077669002 (diff)
downloadtermo-8e503baed8b1df3ed1901b0c93398f204244c77a.tar.gz
termo-8e503baed8b1df3ed1901b0c93398f204244c77a.tar.xz
termo-8e503baed8b1df3ed1901b0c93398f204244c77a.zip
Added TERMKEY_FORMAT_LOWERSPACE for strpkey() also
-rw-r--r--man/termkey_strfkey.32
-rw-r--r--man/termkey_strpkey.33
-rw-r--r--t/12strpkey.c10
-rw-r--r--termkey.c100
4 files changed, 86 insertions, 29 deletions
diff --git a/man/termkey_strfkey.3 b/man/termkey_strfkey.3
index 363e576..c30f12e 100644
--- a/man/termkey_strfkey.3
+++ b/man/termkey_strfkey.3
@@ -34,7 +34,7 @@ Use spaces instead of hyphens to separate the modifier name(s) from the base key
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").
+Use lowercase with spaces in 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/man/termkey_strpkey.3 b/man/termkey_strpkey.3
index 89efb1c..cd4f311 100644
--- a/man/termkey_strpkey.3
+++ b/man/termkey_strpkey.3
@@ -29,6 +29,9 @@ Expect spaces instead of hyphens to separate the modifer name(s) from the base k
.TP
.B TERMKEY_FORMAT_LOWERMOD
Expect lowercase for the modifier name
+.TP
+.B TERMKEY_FORMAT_LOWERSPACE
+Expect lowercase with spaces in for the key name instead of camelCase (for example "\f(CWpage down\fP" instead of "\f(CWPageDown\fP").
.PP
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
.PP
diff --git a/t/12strpkey.c b/t/12strpkey.c
index 099fe9a..c532b6c 100644
--- a/t/12strpkey.c
+++ b/t/12strpkey.c
@@ -9,7 +9,7 @@ int main(int argc, char *argv[])
#define CLEAR_KEY do { key.type = -1; key.code.codepoint = -1; key.modifiers = -1; key.utf8[0] = 0; } while(0)
- plan_tests(58);
+ plan_tests(62);
tk = termkey_new_abstract("vt100", 0);
@@ -94,6 +94,14 @@ int main(int argc, char *argv[])
is_str(endp, "", "consumed entire input for unicode/c/ALT altismeta+long/space+lowermod");
CLEAR_KEY;
+ endp = termkey_strpkey(tk, "ctrl alt page up", &key, TERMKEY_FORMAT_LONGMOD|TERMKEY_FORMAT_SPACEMOD|TERMKEY_FORMAT_LOWERMOD|TERMKEY_FORMAT_LOWERSPACE);
+ is_int(key.type, TERMKEY_TYPE_KEYSYM, "key.type for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
+ is_int(key.code.sym, TERMKEY_SYM_PAGEUP, "key.code.codepoint for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
+ is_int(key.modifiers, TERMKEY_KEYMOD_ALT | TERMKEY_KEYMOD_CTRL,
+ "key.modifiers for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
+ is_str(endp, "", "consumed entire input for sym/PageUp/CTRL+ALT long/space/lowermod+lowerspace");
+
+ CLEAR_KEY;
endp = termkey_strpkey(tk, "Up", &key, 0);
is_int(key.type, TERMKEY_TYPE_KEYSYM, "key.type for sym/Up/0");
is_int(key.code.sym, TERMKEY_SYM_UP, "key.code.codepoint for sym/Up/0");
diff --git a/termkey.c b/termkey.c
index 0dd261f..7e39050 100644
--- a/termkey.c
+++ b/termkey.c
@@ -191,6 +191,63 @@ static const char *res2str(TermKeyResult res)
}
#endif
+/* 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;
+}
+
+/* Similar to strcmp(str, strcamel, n) except that:
+ * it compares CamelCase in strcamel with space separated values in str;
+ * it takes char**s and updates them
+ * n counts bytes of str, not strcamel
+ */
+static int strpncmp_camel(const char **strp, const char **strcamelp, size_t n)
+{
+ const char *str = *strp, *strcamel = *strcamelp;
+ int prev_lower = 0;
+
+ for( ; (*str || *strcamel) && n; n--) {
+ char b = tolower(*strcamel);
+ if(isupper(*strcamel) && prev_lower) {
+ if(*str != ' ')
+ break;
+ str++;
+ if(*str != b)
+ break;
+ }
+ else
+ if(*str != b)
+ break;
+
+ prev_lower = islower(*strcamel);
+
+ str++;
+ strcamel++;
+ }
+
+ *strp = str;
+ *strcamelp = strcamel;
+ return *str - *strcamel;
+}
+
static TermKey *termkey_alloc(void)
{
TermKey *tk = malloc(sizeof(TermKey));
@@ -1114,7 +1171,7 @@ const char *termkey_get_keyname(TermKey *tk, TermKeySym sym)
return "UNKNOWN";
}
-const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym)
+static const char *termkey_lookup_keyname_format(TermKey *tk, const char *str, TermKeySym *sym, TermKeyFormat format)
{
/* We store an array, so we can't do better than a linear search. Doesn't
* matter because user won't be calling this too often */
@@ -1124,13 +1181,25 @@ const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym
if(!thiskey)
continue;
size_t len = strlen(thiskey);
- if(strncmp(str, thiskey, len) == 0)
- return (char *)str + len;
+ if(format & TERMKEY_FORMAT_LOWERSPACE) {
+ const char *thisstr = str;
+ if(strpncmp_camel(&thisstr, &thiskey, len) == 0)
+ return thisstr;
+ }
+ else {
+ if(strncmp(str, thiskey, len) == 0)
+ return (char *)str + len;
+ }
}
return NULL;
}
+const char *termkey_lookup_keyname(TermKey *tk, const char *str, TermKeySym *sym)
+{
+ return termkey_lookup_keyname_format(tk, str, sym, 0);
+}
+
TermKeySym termkey_keyname2sym(TermKey *tk, const char *keyname)
{
TermKeySym sym;
@@ -1171,29 +1240,6 @@ 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;
}
@@ -1381,7 +1427,7 @@ const char *termkey_strpkey(TermKey *tk, const char *str, TermKeyKey *key, TermK
ssize_t snbytes;
const char *endstr;
- if((endstr = termkey_lookup_keyname(tk, str, &key->code.sym))) {
+ if((endstr = termkey_lookup_keyname_format(tk, str, &key->code.sym, format))) {
key->type = TERMKEY_TYPE_KEYSYM;
str = endstr;
}