diff --git a/data/keyd.1.gz b/data/keyd.1.gz index 966eaa5..c392f1f 100644 Binary files a/data/keyd.1.gz and b/data/keyd.1.gz differ diff --git a/docs/keyd.scdoc b/docs/keyd.scdoc index 9268034..24047c7 100644 --- a/docs/keyd.scdoc +++ b/docs/keyd.scdoc @@ -697,9 +697,9 @@ A key may optionally be bound to an _action_ which accepts zero or more argument Identical to overloadt, but additionally resolves as a hold in the event of an intervening key tap. -*overloadi(, , )* - Activate \ if the last non-action (i.e symbol) key was struck less - than \ milliseconds ago, otherwise activate \. +*overloadi(, , )* + Activate if the last non-action (i.e symbol) key was struck less + than milliseconds ago, otherwise activate . This can be used in combination with other overload timeouts and is particularly useful for overloading letter keys (often called 'homerow mods'). @@ -707,17 +707,26 @@ A key may optionally be bound to an _action_ which accepts zero or more argument For example: ``` - a = overloadi(a, overloadt(control, a, 200), 150) + a = overloadi(a, overloadt2(control, a, 200), 150) ``` - will produce _a_ if: + will produce _a_ if and only if: - _a_ is struck within 150ms of another non-action key. - - _a_ is struck more than 150ms after a non-action key but held for less than 200ms. + - _a_ is struck more than 150ms after the last non-action key but held for less than 200ms + and there are no intervening key taps. This reduces the visual latency by immediately resolving the key as a letter when - typed midword but also facilitates its use as a modifier if it is held for long - enough with no preceding symbol. + typed midword, but also facilitates its use as a layer trigger if it is held for a long + enough period with no intervening symbols. + + Since this is a common usecase, a macro called *lettermod* (defined below) has been + defined to facilitate such definitions. + +*lettermod(, , , )* + An alias for: + + *overloadi(, overloadt2(, , ), )* *timeout(, , )* If the key is held in isolation for more than _ ms_, activate the second diff --git a/src/config.c b/src/config.c index cf4fa73..44a67d3 100644 --- a/src/config.c +++ b/src/config.c @@ -399,7 +399,7 @@ static int config_add_layer(struct config *config, const char *s) /* Modifies the input string */ static int parse_fn(char *s, char **name, - char *args[MAX_DESCRIPTOR_ARGS], + char *args[5], size_t *nargs) { char *c, *arg; @@ -453,7 +453,7 @@ exit: return -1; if (arg != c) { - assert(*nargs < MAX_DESCRIPTOR_ARGS); + assert(*nargs < 5); args[(*nargs)++] = arg; } @@ -541,7 +541,7 @@ static int parse_descriptor(char *s, struct config *config) { char *fn = NULL; - char *args[MAX_DESCRIPTOR_ARGS]; + char *args[5]; size_t nargs = 0; uint8_t code, mods; int ret; @@ -615,6 +615,24 @@ static int parse_descriptor(char *s, } else if (!parse_fn(s, &fn, args, &nargs)) { int i; + if (!strcmp(fn, "lettermod")) { + char buf[1024]; + + if (nargs != 4) { + err("%s requires 4 arguments", fn); + return -1; + } + + snprintf(buf, sizeof buf, + "overloadi(%s, overloadt2(%s, %s, %s), %s)", + args[1], args[0], args[1], args[3], args[2]); + + if (parse_fn(buf, &fn, args, &nargs)) { + err("failed to parse %s", buf); + return -1; + } + } + for (i = 0; i < ARRAY_SIZE(actions); i++) { if (!strcmp(actions[i].name, fn)) { int j;