UNPKG

karabiner.ts-greg-mods

Version:
128 lines (127 loc) 4.26 kB
"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(); }