Added TERMKEY_FORMAT_LOWERSPACE for strpkey() also
This commit is contained in:
parent
3b2d8eb813
commit
8e503baed8
|
@ -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.
|
Use lowercase for the modifier name.
|
||||||
.TP
|
.TP
|
||||||
.B TERMKEY_FORMAT_LOWERSPACE
|
.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
|
.TP
|
||||||
.B TERMKEY_FORMAT_MOUSE_POS
|
.B TERMKEY_FORMAT_MOUSE_POS
|
||||||
If the event is a mouse event, include the position rendered as "\f(CW@ (col,line)\fP".
|
If the event is a mouse event, include the position rendered as "\f(CW@ (col,line)\fP".
|
||||||
|
|
|
@ -29,6 +29,9 @@ Expect spaces instead of hyphens to separate the modifer name(s) from the base k
|
||||||
.TP
|
.TP
|
||||||
.B TERMKEY_FORMAT_LOWERMOD
|
.B TERMKEY_FORMAT_LOWERMOD
|
||||||
Expect lowercase for the modifier name
|
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
|
.PP
|
||||||
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
|
Before returning, this function canonicalises the \fIkey\fP structure according to the rules given for \fBtermkey_canonicalise\fP(3).
|
||||||
.PP
|
.PP
|
||||||
|
|
|
@ -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)
|
#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);
|
tk = termkey_new_abstract("vt100", 0);
|
||||||
|
|
||||||
|
@ -93,6 +93,14 @@ int main(int argc, char *argv[])
|
||||||
is_str(key.utf8, "c", "key.utf8 for unicode/c/ALT altismeta+long/space_lowermod");
|
is_str(key.utf8, "c", "key.utf8 for unicode/c/ALT altismeta+long/space_lowermod");
|
||||||
is_str(endp, "", "consumed entire input for unicode/c/ALT altismeta+long/space+lowermod");
|
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;
|
CLEAR_KEY;
|
||||||
endp = termkey_strpkey(tk, "Up", &key, 0);
|
endp = termkey_strpkey(tk, "Up", &key, 0);
|
||||||
is_int(key.type, TERMKEY_TYPE_KEYSYM, "key.type for sym/Up/0");
|
is_int(key.type, TERMKEY_TYPE_KEYSYM, "key.type for sym/Up/0");
|
||||||
|
|
100
termkey.c
100
termkey.c
|
@ -191,6 +191,63 @@ static const char *res2str(TermKeyResult res)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
static TermKey *termkey_alloc(void)
|
||||||
{
|
{
|
||||||
TermKey *tk = malloc(sizeof(TermKey));
|
TermKey *tk = malloc(sizeof(TermKey));
|
||||||
|
@ -1114,7 +1171,7 @@ const char *termkey_get_keyname(TermKey *tk, TermKeySym sym)
|
||||||
return "UNKNOWN";
|
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
|
/* 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 */
|
* 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)
|
if(!thiskey)
|
||||||
continue;
|
continue;
|
||||||
size_t len = strlen(thiskey);
|
size_t len = strlen(thiskey);
|
||||||
if(strncmp(str, thiskey, len) == 0)
|
if(format & TERMKEY_FORMAT_LOWERSPACE) {
|
||||||
return (char *)str + len;
|
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;
|
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 termkey_keyname2sym(TermKey *tk, const char *keyname)
|
||||||
{
|
{
|
||||||
TermKeySym sym;
|
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);
|
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 {
|
static struct modnames {
|
||||||
const char *shift, *alt, *ctrl;
|
const char *shift, *alt, *ctrl;
|
||||||
}
|
}
|
||||||
|
@ -1381,7 +1427,7 @@ const char *termkey_strpkey(TermKey *tk, const char *str, TermKeyKey *key, TermK
|
||||||
ssize_t snbytes;
|
ssize_t snbytes;
|
||||||
const char *endstr;
|
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;
|
key->type = TERMKEY_TYPE_KEYSYM;
|
||||||
str = endstr;
|
str = endstr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue