Add lettermod

master
Raheman Vaiya 2 years ago
parent 68ac5ab664
commit a188b6ee1a
  1. BIN
      data/keyd.1.gz
  2. 25
      docs/keyd.scdoc
  3. 24
      src/config.c

Binary file not shown.

@ -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 Identical to overloadt, but additionally resolves as a hold in the
event of an intervening key tap. event of an intervening key tap.
*overloadi(<action 1>, <action 2>, <timeout>)* *overloadi(<action 1>, <action 2>, <idle timeout>)*
Activate \<action 1\> if the last non-action (i.e symbol) key was struck less Activate <action 1> if the last non-action (i.e symbol) key was struck less
than \<timeout\> milliseconds ago, otherwise activate \<action 2\>. than <timeout> milliseconds ago, otherwise activate <action 2>.
This can be used in combination with other overload timeouts and is particularly This can be used in combination with other overload timeouts and is particularly
useful for overloading letter keys (often called 'homerow mods'). 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: 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 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 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 typed midword, but also facilitates its use as a layer trigger if it is held for a long
enough with no preceding symbol. 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(<layer>, <key>, <idle timeout>, <hold timeout>)*
An alias for:
*overloadi(<key>, overloadt2(<layer>, <key>, <hold timeout>), <idle timeout>)*
*timeout(<action 1>, <timeout>, <action 2>)* *timeout(<action 1>, <timeout>, <action 2>)*
If the key is held in isolation for more than _<timeout> ms_, activate the second If the key is held in isolation for more than _<timeout> ms_, activate the second

@ -399,7 +399,7 @@ static int config_add_layer(struct config *config, const char *s)
/* Modifies the input string */ /* Modifies the input string */
static int parse_fn(char *s, static int parse_fn(char *s,
char **name, char **name,
char *args[MAX_DESCRIPTOR_ARGS], char *args[5],
size_t *nargs) size_t *nargs)
{ {
char *c, *arg; char *c, *arg;
@ -453,7 +453,7 @@ exit:
return -1; return -1;
if (arg != c) { if (arg != c) {
assert(*nargs < MAX_DESCRIPTOR_ARGS); assert(*nargs < 5);
args[(*nargs)++] = arg; args[(*nargs)++] = arg;
} }
@ -541,7 +541,7 @@ static int parse_descriptor(char *s,
struct config *config) struct config *config)
{ {
char *fn = NULL; char *fn = NULL;
char *args[MAX_DESCRIPTOR_ARGS]; char *args[5];
size_t nargs = 0; size_t nargs = 0;
uint8_t code, mods; uint8_t code, mods;
int ret; int ret;
@ -615,6 +615,24 @@ static int parse_descriptor(char *s,
} else if (!parse_fn(s, &fn, args, &nargs)) { } else if (!parse_fn(s, &fn, args, &nargs)) {
int i; 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++) { for (i = 0; i < ARRAY_SIZE(actions); i++) {
if (!strcmp(actions[i].name, fn)) { if (!strcmp(actions[i].name, fn)) {
int j; int j;

Loading…
Cancel
Save