karabiner.ts-greg-mods
Version:
Powerful mods for karabiner.ts.
128 lines (127 loc) • 4.26 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModTapBuilder = void 0;
exports.modTap = modTap;
// Mod-tap turns a key in a dual-function mod-tap one.
//
// A mod-tap key can work in two modes:
//
// - Non-permissive requires waiting for the tapping term to pass before
// activating the modifier.
// - Permissive activates the modifier as soon as another key is pressed.
//
// ## Flaws & limitations
//
// Mod-tap non-permissive keys require waiting for the tapping term to be over. This is
// cumbersome as the tapping term needs to be large enough to avoid accidental
// activation (above 100 ms).
//
// Mod-tap permissive keys spuriously activate during roll overs.
const karabiner_ts_1 = require("karabiner.ts");
class ModTapBuilder {
fromEvent;
originalEvents = [];
isPermissive = false;
mods;
simultaneousThresholdMs;
tappingTermMs;
constructor() { }
build() {
let m = (0, karabiner_ts_1.map)(this.fromEvent).toIfAlone(this.copyAndAddHaltToFirstToEvent(this.originalEvents));
if (this.isPermissive) {
m.to({
...this.mods,
lazy: true,
});
}
else {
m.toDelayedAction([], this.originalEvents).toIfHeldDown({
...this.mods,
halt: true,
});
}
m.parameters({
"basic.to_if_held_down_threshold_milliseconds": this.tappingTermMs,
"basic.simultaneous_threshold_milliseconds": this.simultaneousThresholdMs,
});
return m.build();
}
from(keyCodeAlias, mandatoryModifiers, optionalModifiers) {
if (Array.isArray(keyCodeAlias)) {
const keyCodes = keyCodeAlias.map(function (keyCodeAlias) {
return { key_code: (0, karabiner_ts_1.getKeyWithAlias)(keyCodeAlias) };
});
this.fromEvent = {
simultaneous: keyCodes,
simultaneous_options: { key_down_order: "strict" },
modifiers: (0, karabiner_ts_1.parseFromModifierParams)(mandatoryModifiers, optionalModifiers),
};
this.originalEvents = keyCodes;
}
else {
const keyCode = (0, karabiner_ts_1.getKeyWithAlias)(keyCodeAlias);
this.fromEvent = {
key_code: keyCode,
modifiers: (0, karabiner_ts_1.parseFromModifierParams)(mandatoryModifiers, optionalModifiers),
};
this.originalEvents = [
{
key_code: keyCode,
modifiers: (0, karabiner_ts_1.parseModifierParam)(mandatoryModifiers),
},
];
}
return this;
}
/**
* Sets the mod-tap key to be permissive or non-permissive.
*
* A permissive mod-tap key activates the modifier as soon as another key is pressed.
* A non-permissive mod-tap key requires the tapping term to pass before activating.
*/
permissive(val) {
this.isPermissive = val;
return this;
}
modifiers(modifiers) {
this.mods = modifiers;
return this;
}
/**
* Sets the simultaneous threshold in milliseconds.
*
* Simultaneous threshold is the maximum time in milliseconds Karabiner will wait for a simultaneous
* chord to appear.
*/
simultaneousThreshold(simultaneousThresholdMs) {
this.simultaneousThresholdMs = simultaneousThresholdMs;
return this;
}
/**
* Sets the tapping term in milliseconds.
*
* The tapping term is the time in milliseconds that the key must be held
* down in order to be fully active for non-permissive mod-tap keys.
*/
tappingTerm(tappingTermMs) {
this.tappingTermMs = tappingTermMs;
return this;
}
copyAndAddHaltToFirstToEvent(toEvents) {
if (toEvents.length === 0) {
return [];
}
const firstEvent = toEvents[0];
return [
{
...firstEvent,
halt: true,
},
...toEvents.slice(1),
];
}
}
exports.ModTapBuilder = ModTapBuilder;
function modTap() {
return new ModTapBuilder();
}