diff --git a/config/reaper.ts b/config/reaper.ts index ec630446e860bde309457964262d0da16d641140..7d30219fe6cfc463d7622c02d74806539ed4d174 100644 --- a/config/reaper.ts +++ b/config/reaper.ts @@ -1,58 +1,74 @@ +import * as config from "#config"; import { Reaper } from "@clo/creative-control/Reaper.ts"; import { SpeedEditor } from "@clo/creative-control/SpeedEditor.ts"; -import * as config from "#config"; -export default config.forApp("com.cockos.reaper", ({ speededitor: se, mac }) => { - const reaper = new Reaper(); +export default config.forApp( + "com.cockos.reaper", + ({ speededitor: se, mac }) => { + const reaper = new Reaper(); - // Sync state to LEDs - reaper.on("transport", (transport) => { - console.info(transport); - se.leds.audioOnly = transport.recording; - }); - mac.on("window", (window) => { - se.leds.videoOnly = Boolean(window?.title.startsWith("FX:")); - }); + // Sync state to LEDs + reaper.on("transport", (transport) => { + se.leds.cut = transport.recording; + se.leds.dissolve = transport.recording; + se.leds.smoothCut = transport.recording; + }); + mac.on("window", (window) => { + se.leds.videoOnly = Boolean(window?.title.startsWith("FX:")); + }); - // Keyboard Actions - SpeedEditor.camNumbersToNumpad(se, mac); - se.onPress("stopPlay", () => { - if(reaper.transport.recording) { - reaper.runAction('transport-stop-save-all-recorded-media'); - } else { - reaper.runAction('transport-play-stop'); - } - }); - se.onPress("smartInsert", () => { - mac.toast("Add Komplete Kontrol") - reaper.runScript("insert_komplete_kontrol_track"); - }); - se.onPress("append", () => { - mac.toast("Add Addictive Drums") - reaper.runScript("insert_addictive_drums_track"); - }); - se.onPress("rippleOverwrite", () => { - mac.toast("Blank Track") - reaper.runScript("insert_blank_track"); - }); - se.onPress("audioOnly", () => { - if(reaper.transport.recording) { - reaper.runAction('transport-stop-delete-all-recorded-media'); - reaper.runAction('transport-record'); - } else { - reaper.runAction('transport-record'); - } - }); - se.onPress("videoOnly", () => { - if (mac.window?.title.startsWith("FX:") && mac.mainWindow) { - mac.focusMainWindow(); - return; - } - reaper.runAction("track-view-fx-chain-for-current-last-touched-track"); - }); + // Keyboard Actions + SpeedEditor.camNumbersToNumpad(se, mac); + se.onPress("stopPlay", () => { + if (reaper.transport.recording) { + reaper.runAction("transport-stop-save-all-recorded-media"); + } else { + reaper.runAction("transport-play-stop"); + } + }); + se.onPress("smartInsert", () => { + mac.toast("Add Komplete Kontrol"); + reaper.runScript("insert_komplete_kontrol_track"); + }); + se.onPress("append", () => { + mac.toast("Add Addictive Drums"); + reaper.runScript("insert_addictive_drums_track"); + }); + se.onPress("rippleOverwrite", () => { + mac.toast("Blank Track"); + reaper.runScript("insert_blank_track"); + }); + se.onPress("cut", () => { + if (reaper.transport.recording) { + reaper.runAction("transport-stop-delete-all-recorded-media"); + reaper.runAction("transport-record"); + } else { + reaper.runAction("transport-record"); + } + }); + se.onPress("dissolve", () => { + reaper.runAction("transport-stop-delete-all-recorded-media"); + }); + se.onPress("smoothCut", () => { + if (reaper.transport.recording) { + reaper.runAction("transport-stop-save-all-recorded-media"); + reaper.runAction("transport-record"); + } + }); + se.onPress("videoOnly", () => { + if (mac.window?.title.startsWith("FX:") && mac.mainWindow) { + mac.focusMainWindow(); + return; + } + reaper.runAction("track-view-fx-chain-for-current-last-touched-track"); + }); + se.onPress("fullView", () => { + mac.pressKey("x"); + }); - // TODO: stabilize / find a better use-case for the knob - se.on("jog", ({ value = 0 }) => { - reaper.scrub(value / 20); - }); -}); + // TODO: stabilize / find a better use-case for the knob + // se.on("jog", ({ value = 0 }) => { + // reaper.scrub(value / 20); + // }); + }, +); diff --git a/dprint.json b/dprint.json new file mode 100644 index 0000000000000000000000000000000000000000..20b9dd328d6ee052b7b91d06be91d1b26ead7efa --- /dev/null +++ b/dprint.json @@ -0,0 +1,17 @@ +{ + "typescript": { + }, + "json": { + }, + "markdown": { + }, + "excludes": [ + "**/node_modules", + "**/*-lock.json" + ], + "plugins": [ + "https://plugins.dprint.dev/typescript-0.95.15.wasm", + "https://plugins.dprint.dev/json-0.21.1.wasm", + "https://plugins.dprint.dev/markdown-0.21.1.wasm" + ] +} diff --git a/examples/event-listener.ts b/examples/event-listener.ts index fec0c4218388a490abd72679798b188e8665acbb..1d55fdbab0c1a1906dd910f34d256abbc9c073a7 100644 --- a/examples/event-listener.ts +++ b/examples/event-listener.ts @@ -15,7 +15,7 @@ editor.on("keypress", (key) => { } }); editor.onDoublePress("transition", () => { - console.info('(double press) "Title"'); + console.info("(double press) \"Title\""); }); console.info("init"); diff --git a/readme.md b/readme.md index 5c1d5a4c2b04e476e9e41bd3eaaaa90bf5d53e44..f2881a72aaeac9f7cc7aa7b053fc10c77f59a84c 100644 --- a/readme.md +++ b/readme.md @@ -10,7 +10,8 @@ These tools only work on macOS. I don't have interest in maintaining other confi ## Hardware -TODO: +TODO: + - generic keyboard / karabiner elements integration? - custom trackpad integration? @@ -55,8 +56,8 @@ reaper.on("transport", (transport) => { transport.recording ? "You are recording" : transport.playing - ? "Playing" - : "Stopped" + ? "Playing" + : "Stopped", ); }); ``` diff --git a/src/Mac.ts b/src/Mac.ts index 65156b17908fa60da604a4f8730dba4bae7ade19..934eeb0ba7f885eaec4064b0d168edca250d1f89 100644 --- a/src/Mac.ts +++ b/src/Mac.ts @@ -32,13 +32,13 @@ const FRONTMOST_APP_HELPER_FRAMEWORKS = [ "ApplicationServices", ] as const; const KEYBOARD_EVENT_SCRIPT = [ - 'ObjC.import("ApplicationServices");', + "ObjC.import(\"ApplicationServices\");", "function run(argv) {", " const payload = JSON.parse(argv[0] ?? '{}');", " const actions = Array.isArray(payload.actions) ? payload.actions : [];", " for (const action of actions) {", " if (!Number.isInteger(action.keyCode)) {", - ' throw new Error(`Invalid key code: ${JSON.stringify(action)}`);', + " throw new Error(`Invalid key code: ${JSON.stringify(action)}`);", " }", " const event = $.CGEventCreateKeyboardEvent(", " null,", @@ -46,139 +46,141 @@ const KEYBOARD_EVENT_SCRIPT = [ " Boolean(action.isDown),", " );", " if (!event) {", - ' throw new Error(`Failed to create keyboard event for key code ${action.keyCode}`);', + " throw new Error(`Failed to create keyboard event for key code ${action.keyCode}`);", " }", " $.CGEventPost($.kCGHIDEventTap, event);", " $.CFRelease(event);", " }", - ' return "";', + " return \"\";", "}", ].join("\n"); let frontmostAppHelperBinaryPromise: Promise | null = null; let toastHelperBinaryPromise: Promise | null = null; // Key codes from Carbon/HIToolbox Events.h (virtual key codes on ANSI/US layouts). -const KEY_CODES = Object.freeze({ - a: 0x00, - s: 0x01, - d: 0x02, - f: 0x03, - h: 0x04, - g: 0x05, - z: 0x06, - x: 0x07, - c: 0x08, - v: 0x09, - isoSection: 0x0A, - b: 0x0B, - q: 0x0C, - w: 0x0D, - e: 0x0E, - r: 0x0F, - y: 0x10, - t: 0x11, - "1": 0x12, - "2": 0x13, - "3": 0x14, - "4": 0x15, - "6": 0x16, - "5": 0x17, - equal: 0x18, - "9": 0x19, - "7": 0x1A, - minus: 0x1B, - "8": 0x1C, - "0": 0x1D, - rightBracket: 0x1E, - o: 0x1F, - u: 0x20, - leftBracket: 0x21, - i: 0x22, - p: 0x23, - return: 0x24, - l: 0x25, - j: 0x26, - quote: 0x27, - k: 0x28, - semicolon: 0x29, - backslash: 0x2A, - comma: 0x2B, - slash: 0x2C, - n: 0x2D, - m: 0x2E, - period: 0x2F, - tab: 0x30, - space: 0x31, - grave: 0x32, - delete: 0x33, - escape: 0x35, - rightCommand: 0x36, - command: 0x37, - shift: 0x38, - capsLock: 0x39, - option: 0x3A, - control: 0x3B, - rightShift: 0x3C, - rightOption: 0x3D, - rightControl: 0x3E, - function: 0x3F, - f17: 0x40, - numpadDecimal: 0x41, - numpadMultiply: 0x43, - numpadPlus: 0x45, - numpadClear: 0x47, - volumeUp: 0x48, - volumeDown: 0x49, - mute: 0x4A, - numpadDivide: 0x4B, - numpadEnter: 0x4C, - numpadMinus: 0x4E, - f18: 0x4F, - f19: 0x50, - numpadEquals: 0x51, - numpad0: 0x52, - numpad1: 0x53, - numpad2: 0x54, - numpad3: 0x55, - numpad4: 0x56, - numpad5: 0x57, - numpad6: 0x58, - numpad7: 0x59, - f20: 0x5A, - numpad8: 0x5B, - numpad9: 0x5C, - jisYen: 0x5D, - jisUnderscore: 0x5E, - jisKeypadComma: 0x5F, - f5: 0x60, - f6: 0x61, - f7: 0x62, - f3: 0x63, - f8: 0x64, - f9: 0x65, - jisEisu: 0x66, - f11: 0x67, - jisKana: 0x68, - f13: 0x69, - f16: 0x6A, - f14: 0x6B, - f10: 0x6D, - f12: 0x6F, - f15: 0x71, - help: 0x72, - home: 0x73, - pageUp: 0x74, - forwardDelete: 0x75, - f4: 0x76, - end: 0x77, - f2: 0x78, - pageDown: 0x79, - f1: 0x7A, - leftArrow: 0x7B, - rightArrow: 0x7C, - downArrow: 0x7D, - upArrow: 0x7E, -} as const); +const KEY_CODES = Object.freeze( + { + a: 0x00, + s: 0x01, + d: 0x02, + f: 0x03, + h: 0x04, + g: 0x05, + z: 0x06, + x: 0x07, + c: 0x08, + v: 0x09, + isoSection: 0x0A, + b: 0x0B, + q: 0x0C, + w: 0x0D, + e: 0x0E, + r: 0x0F, + y: 0x10, + t: 0x11, + "1": 0x12, + "2": 0x13, + "3": 0x14, + "4": 0x15, + "6": 0x16, + "5": 0x17, + equal: 0x18, + "9": 0x19, + "7": 0x1A, + minus: 0x1B, + "8": 0x1C, + "0": 0x1D, + rightBracket: 0x1E, + o: 0x1F, + u: 0x20, + leftBracket: 0x21, + i: 0x22, + p: 0x23, + return: 0x24, + l: 0x25, + j: 0x26, + quote: 0x27, + k: 0x28, + semicolon: 0x29, + backslash: 0x2A, + comma: 0x2B, + slash: 0x2C, + n: 0x2D, + m: 0x2E, + period: 0x2F, + tab: 0x30, + space: 0x31, + grave: 0x32, + delete: 0x33, + escape: 0x35, + rightCommand: 0x36, + command: 0x37, + shift: 0x38, + capsLock: 0x39, + option: 0x3A, + control: 0x3B, + rightShift: 0x3C, + rightOption: 0x3D, + rightControl: 0x3E, + function: 0x3F, + f17: 0x40, + numpadDecimal: 0x41, + numpadMultiply: 0x43, + numpadPlus: 0x45, + numpadClear: 0x47, + volumeUp: 0x48, + volumeDown: 0x49, + mute: 0x4A, + numpadDivide: 0x4B, + numpadEnter: 0x4C, + numpadMinus: 0x4E, + f18: 0x4F, + f19: 0x50, + numpadEquals: 0x51, + numpad0: 0x52, + numpad1: 0x53, + numpad2: 0x54, + numpad3: 0x55, + numpad4: 0x56, + numpad5: 0x57, + numpad6: 0x58, + numpad7: 0x59, + f20: 0x5A, + numpad8: 0x5B, + numpad9: 0x5C, + jisYen: 0x5D, + jisUnderscore: 0x5E, + jisKeypadComma: 0x5F, + f5: 0x60, + f6: 0x61, + f7: 0x62, + f3: 0x63, + f8: 0x64, + f9: 0x65, + jisEisu: 0x66, + f11: 0x67, + jisKana: 0x68, + f13: 0x69, + f16: 0x6A, + f14: 0x6B, + f10: 0x6D, + f12: 0x6F, + f15: 0x71, + help: 0x72, + home: 0x73, + pageUp: 0x74, + forwardDelete: 0x75, + f4: 0x76, + end: 0x77, + f2: 0x78, + pageDown: 0x79, + f1: 0x7A, + leftArrow: 0x7B, + rightArrow: 0x7C, + downArrow: 0x7D, + upArrow: 0x7E, + } as const, +); type MacKeyName = keyof typeof KEY_CODES; const KEY_NAMES = Object.freeze(Object.keys(KEY_CODES) as MacKeyName[]); @@ -732,12 +734,12 @@ function parseFrontmostStateLine(line: string): FrontmostState { function normalizeBundleId(value: unknown) { const directBundleId = typeof value === "string" ? value.trim() : ""; - const bundleId = BUNDLE_ID_PATTERN.exec(directBundleId)?.[0] ?? - directBundleId; + const bundleId = BUNDLE_ID_PATTERN.exec(directBundleId)?.[0] + ?? directBundleId; if ( - bundleId === "" || - bundleId === "undefined" || - bundleId === "[id nil]" + bundleId === "" + || bundleId === "undefined" + || bundleId === "[id nil]" ) { return null; } @@ -837,10 +839,10 @@ function windowEquals(left: Mac.Window | null, right: Mac.Window | null) { if (!left || !right) { return left === right; } - return left.id === right.id && - left.title === right.title && - left.main === right.main && - left.focused === right.focused; + return left.id === right.id + && left.title === right.title + && left.main === right.main + && left.focused === right.focused; } function normalizeDelayMs(value: number, name: string) { @@ -884,9 +886,9 @@ function resolveKeyCode(key: Mac.Key): number { function normalizeKeyCode(keyCode: number) { if ( - !Number.isInteger(keyCode) || - keyCode < 0 || - keyCode > 0xFFFF + !Number.isInteger(keyCode) + || keyCode < 0 + || keyCode > 0xFFFF ) { throw new Error(`Mac keyCode must be an integer between 0 and 65535`); } @@ -946,9 +948,9 @@ function formatKeyboardDispatchError(error: unknown) { const details = extractCommandErrorOutput(error); const suffix = details ? ` ${details}` : ""; return ( - "Failed to send a macOS keyboard event via osascript. " + - "Make sure this process is allowed in System Settings > Privacy & Security > Accessibility." + - suffix + "Failed to send a macOS keyboard event via osascript. " + + "Make sure this process is allowed in System Settings > Privacy & Security > Accessibility." + + suffix ); } diff --git a/src/Reaper.ts b/src/Reaper.ts index 21c3afa493b5e3c896aae19858df8a1342f1a0c2..25e6039125b734560303b69bd5435e2b88f6820d 100644 --- a/src/Reaper.ts +++ b/src/Reaper.ts @@ -1,6 +1,5 @@ import { Events } from "@clo/lib/Events.ts"; import * as log from "@clo/lib/log.ts"; -import { REAPER_ACTIONS, type ReaperActionId } from "./Reaper/actions.ts"; import { execFile } from "node:child_process"; import { createSocket, type Socket } from "node:dgram"; import { readFileSync } from "node:fs"; @@ -9,6 +8,7 @@ import { basename, dirname, join } from "node:path"; import process from "node:process"; import { fileURLToPath } from "node:url"; import { promisify } from "node:util"; +import { REAPER_ACTIONS, type ReaperActionId } from "./Reaper/actions.ts"; const console = log.scoped("reaper"); export type { ReaperActionId } from "./Reaper/actions.ts"; @@ -94,10 +94,10 @@ const DEFAULT_REAPER_OSC_TARGET_DIR = join( DEFAULT_REAPER_RESOURCE_DIR, "OSC", ); -const REAPER_SCRIPT_TARGET_DIR = process.env.REAPER_SCRIPTS_DIR ?? - DEFAULT_REAPER_SCRIPT_TARGET_DIR; -const REAPER_OSC_TARGET_DIR = process.env.REAPER_OSC_DIR ?? - DEFAULT_REAPER_OSC_TARGET_DIR; +const REAPER_SCRIPT_TARGET_DIR = process.env.REAPER_SCRIPTS_DIR + ?? DEFAULT_REAPER_SCRIPT_TARGET_DIR; +const REAPER_OSC_TARGET_DIR = process.env.REAPER_OSC_DIR + ?? DEFAULT_REAPER_OSC_TARGET_DIR; const OSC_PATTERN_FILE = "CloverAutomation.ReaperOSC"; const OSC_PATTERN_NAME = stripReaperOscExtension(OSC_PATTERN_FILE); const OSC_PATTERN_CONFIG = `# OSC pattern config file for Clover Creative Control's REAPER integration. @@ -174,10 +174,10 @@ export class Reaper extends Events { } console.info( - `${OSC_PATTERN_FILE} is not registered yet. ` + - `Add an OSC control surface manually using the "${OSC_PATTERN_NAME}" pattern, set REAPER's local listen port to ` + - `${this.#oscPort}, and send to ${this.#oscHost}:${this.#oscBindPort}. ` + - "The REAPER web interface is not required for this config." + `${OSC_PATTERN_FILE} is not registered yet. ` + + `Add an OSC control surface manually using the "${OSC_PATTERN_NAME}" pattern, set REAPER's local listen port to ` + + `${this.#oscPort}, and send to ${this.#oscHost}:${this.#oscBindPort}. ` + + "The REAPER web interface is not required for this config.", ); } @@ -475,13 +475,13 @@ function sameTransportState( left: ReaperTransportState, right: ReaperTransportState, ) { - return left.playing === right.playing && - left.paused === right.paused && - left.recording === right.recording && - left.repeatOn === right.repeatOn && - left.positionSeconds === right.positionSeconds && - left.positionString === right.positionString && - left.positionBeatsString === right.positionBeatsString; + return left.playing === right.playing + && left.paused === right.paused + && left.recording === right.recording + && left.repeatOn === right.repeatOn + && left.positionSeconds === right.positionSeconds + && left.positionString === right.positionString + && left.positionBeatsString === right.positionBeatsString; } function optimisticTransportPatchForAction( @@ -615,8 +615,8 @@ function hasManagedOscSurface(config: string) { const normalizedTokens = tokens.map((token) => unquoteReaperToken(token)); if ( - normalizedTokens.includes(OSC_PATTERN_FILE) || - normalizedTokens.includes(OSC_PATTERN_NAME) + normalizedTokens.includes(OSC_PATTERN_FILE) + || normalizedTokens.includes(OSC_PATTERN_NAME) ) { return true; } @@ -645,8 +645,8 @@ function formatError(error: unknown) { function unquoteReaperToken(token: string) { if ( - (token.startsWith("'") && token.endsWith("'")) || - (token.startsWith("\"") && token.endsWith("\"")) + (token.startsWith("'") && token.endsWith("'")) + || (token.startsWith("\"") && token.endsWith("\"")) ) { return token.slice(1, -1); } diff --git a/src/Reaper/actions.ts b/src/Reaper/actions.ts index 828048efd852259db4f8c453021f0e81cc516a92..f19b0367ee93f1f626f44ed38e5f9164e91d39e1 100644 --- a/src/Reaper/actions.ts +++ b/src/Reaper/actions.ts @@ -52,7 +52,8 @@ export const REAPER_ACTIONS = { "action-skip-next-action-if-cc-parameter-0-mid-2017": 2017, "action-skip-next-action-if-cc-parameter-0-mid-2018": 2018, "action-skip-next-action-set-cc-parameter-to-relative-plus-1-if-action-armed-0-otherwise": 2023, - "action-skip-next-action-set-cc-parameter-to-relative-plus-1-if-action-toggle-state-enabled-1-if-disabled-0-if-toggle-state-unavailable": 2022, + "action-skip-next-action-set-cc-parameter-to-relative-plus-1-if-action-toggle-state-enabled-1-if-disabled-0-if-toggle-state-unavailable": + 2022, "action-toggle-arm-of-next-action": 2021, "action-wait-0-1-seconds-before-next-action": 2008, "action-wait-0-5-seconds-before-next-action": 2009, @@ -625,7 +626,8 @@ export const REAPER_ACTIONS = { "file-open-render-queue": 40929, "file-open-render-statistics-charts-from-most-recent-render-in-web-browser": 42497, "file-open-render-statistics-charts-from-most-recent-render-in-web-browser-hide-file-paths": 42510, - "file-open-render-statistics-charts-from-most-recent-render-in-web-browser-hide-file-paths-and-project-regions-markers": 43343, + "file-open-render-statistics-charts-from-most-recent-render-in-web-browser-hide-file-paths-and-project-regions-markers": + 43343, "file-open-render-statistics-charts-from-most-recent-render-in-web-browser-hide-project-regions-markers": 43342, "file-project-settings": 40021, "file-quit-reaper": 40004, @@ -1203,7 +1205,8 @@ export const REAPER_ACTIONS = { "item-open-items-in-secondary-external-editor": 40202, "item-paste-items-tracks": 42398, "item-paste-items-tracks-at-mouse-position": 41221, - "item-paste-items-tracks-creating-pooled-ghost-midi-items-and-automation-items-regardless-of-preferences-media-midi-and-preferences-media-automation-settings": 41072, + "item-paste-items-tracks-creating-pooled-ghost-midi-items-and-automation-items-regardless-of-preferences-media-midi-and-preferences-media-automation-settings": + 41072, "item-paste-items-tracks-old-style-handling-of-hidden-tracks": 40058, "item-propagate-to-all-similarly-named-items": 41979, "item-propagate-to-similarly-named-items-on-track": 41977, @@ -1256,9 +1259,12 @@ export const REAPER_ACTIONS = { "item-properties-set-item-timebase-to-beats-position-only": 40485, "item-properties-set-item-timebase-to-project-track-default": 40380, "item-properties-set-item-timebase-to-time": 40433, - "item-properties-set-midi-items-to-follow-project-tempo-changes-set-item-timebase-to-beats-position-length-rate": 43095, - "item-properties-set-midi-items-to-use-current-tempo-and-ignore-project-tempo-changes-set-item-timebase-to-beats-position-only": 43096, - "item-properties-set-midi-items-to-use-current-tempo-and-ignore-project-tempo-changes-set-item-timebase-to-time": 43094, + "item-properties-set-midi-items-to-follow-project-tempo-changes-set-item-timebase-to-beats-position-length-rate": + 43095, + "item-properties-set-midi-items-to-use-current-tempo-and-ignore-project-tempo-changes-set-item-timebase-to-beats-position-only": + 43096, + "item-properties-set-midi-items-to-use-current-tempo-and-ignore-project-tempo-changes-set-item-timebase-to-time": + 43094, "item-properties-set-take-channel-mode-to-mono-channel-03": 41388, "item-properties-set-take-channel-mode-to-mono-channel-04": 41389, "item-properties-set-take-channel-mode-to-mono-channel-05": 41390, @@ -1812,12 +1818,14 @@ export const REAPER_ACTIONS = { "options-add-edge-points-when-moving-envelope-points-with-items": 40648, "options-add-edge-points-when-moving-multiple-envelope-points": 42030, "options-add-envelope-edge-points-when-ripple-editing-or-inserting-time": 40649, - "options-allow-drag-drop-media-import-to-target-the-top-part-of-a-track-to-insert-a-new-track-to-receive-the-media": 42477, + "options-allow-drag-drop-media-import-to-target-the-top-part-of-a-track-to-insert-a-new-track-to-receive-the-media": + 42477, "options-allow-selecting-empty-takes": 41355, "options-always-record-to-automation-items": 42212, "options-always-trim-content-behind-razor-edits-otherwise-follow-media-item-editing-preferences": 42421, "options-auto-crossfade-media-items-when-editing": 40041, - "options-automatically-insert-automation-item-when-activating-envelope-that-is-bypassed-outside-of-automation-items-and-not-displayed-in-envelope-lane": 42220, + "options-automatically-insert-automation-item-when-activating-envelope-that-is-bypassed-outside-of-automation-items-and-not-displayed-in-envelope-lane": + 42220, "options-automation-item-baseline-amplitude-edits-affect-pooled-copies": 42194, "options-automation-items-connect-to-the-underlying-envelope-on-both-sides": 42205, "options-automation-items-connect-to-the-underlying-envelope-on-the-right-side": 42204, @@ -2307,8 +2315,10 @@ export const REAPER_ACTIONS = { "sws-aw-play-stop-automatically-group-simultaneously-recorded-items-deprecated": 53503, "sws-aw-record-automatically-group-simultaneously-recorded-items-deprecated": 53500, "sws-aw-record-conditional-normal-or-time-selection-only": 53497, - "sws-aw-record-conditional-normal-or-time-selection-only-automatically-group-simultaneously-recorded-items-deprecated": 53501, - "sws-aw-record-conditional-normal-time-selection-item-selection-automatically-group-simultaneously-recorded-items-deprecated": 53502, + "sws-aw-record-conditional-normal-or-time-selection-only-automatically-group-simultaneously-recorded-items-deprecated": + 53501, + "sws-aw-record-conditional-normal-time-selection-item-selection-automatically-group-simultaneously-recorded-items-deprecated": + 53502, "sws-aw-record-conditional-normal-time-selection-or-item-selection": 53498, "sws-aw-remove-overlaps-in-selected-items-preserving-item-starts": 53496, "sws-aw-remove-tracks-items-env-obeying-time-selection-and-leaving-children": 53554, @@ -2383,24 +2393,34 @@ export const REAPER_ACTIONS = { "sws-br-apply-next-action-to-all-visible-envelopes-in-selected-tracks": 54100, "sws-br-apply-next-action-to-all-visible-envelopes-in-selected-tracks-if-there-is-no-track-envelope-selected": 54102, "sws-br-apply-next-action-to-all-visible-record-armed-envelopes-in-selected-tracks": 54101, - "sws-br-apply-next-action-to-all-visible-record-armed-envelopes-in-selected-tracks-if-there-is-no-track-envelope-selected": 54103, + "sws-br-apply-next-action-to-all-visible-record-armed-envelopes-in-selected-tracks-if-there-is-no-track-envelope-selected": + 54103, "sws-br-check-for-new-sws-version": 55821, "sws-br-contextual-toolbars": 53938, "sws-br-convert-project-markers-to-tempo-markers": 54846, - "sws-br-convert-selected-envelope-s-curve-in-time-selection-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor": 54051, - "sws-br-convert-selected-envelope-s-curve-in-time-selection-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor-clear-existing-events": 54052, - "sws-br-convert-selected-points-in-selected-envelope-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor": 54049, - "sws-br-convert-selected-points-in-selected-envelope-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor-clear-existing-events": 54050, + "sws-br-convert-selected-envelope-s-curve-in-time-selection-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor": + 54051, + "sws-br-convert-selected-envelope-s-curve-in-time-selection-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor-clear-existing-events": + 54052, + "sws-br-convert-selected-points-in-selected-envelope-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor": + 54049, + "sws-br-convert-selected-points-in-selected-envelope-to-cc-events-in-last-clicked-cc-lane-in-last-active-midi-editor-clear-existing-events": + 54050, "sws-br-copy-points-in-time-selection-in-selected-envelope-to-all-visible-envelopes-in-selected-tracks": 54072, - "sws-br-copy-points-in-time-selection-in-selected-envelope-to-all-visible-envelopes-in-selected-tracks-paste-at-edit-cursor": 54076, - "sws-br-copy-points-in-time-selection-in-selected-envelope-to-all-visible-record-armed-in-envelopes-of-selected-tracks": 54073, - "sws-br-copy-points-in-time-selection-in-selected-envelope-to-all-visible-record-armed-in-envelopes-of-selected-tracks-paste-at-edit-cursor": 54077, + "sws-br-copy-points-in-time-selection-in-selected-envelope-to-all-visible-envelopes-in-selected-tracks-paste-at-edit-cursor": + 54076, + "sws-br-copy-points-in-time-selection-in-selected-envelope-to-all-visible-record-armed-in-envelopes-of-selected-tracks": + 54073, + "sws-br-copy-points-in-time-selection-in-selected-envelope-to-all-visible-record-armed-in-envelopes-of-selected-tracks-paste-at-edit-cursor": + 54077, "sws-br-copy-points-in-time-selection-in-selected-envelope-to-envelope-at-mouse-cursor": 54079, "sws-br-copy-points-in-time-selection-in-selected-envelope-to-envelope-at-mouse-cursor-paste-at-edit-cursor": 54081, "sws-br-copy-selected-points-in-selected-envelope-to-all-visible-envelopes-in-selected-tracks": 54070, - "sws-br-copy-selected-points-in-selected-envelope-to-all-visible-envelopes-in-selected-tracks-paste-at-edit-cursor": 54074, + "sws-br-copy-selected-points-in-selected-envelope-to-all-visible-envelopes-in-selected-tracks-paste-at-edit-cursor": + 54074, "sws-br-copy-selected-points-in-selected-envelope-to-all-visible-record-armed-envelopes-in-selected-tracks": 54071, - "sws-br-copy-selected-points-in-selected-envelope-to-all-visible-record-armed-envelopes-in-selected-tracks-paste-at-edit-cursor": 54075, + "sws-br-copy-selected-points-in-selected-envelope-to-all-visible-record-armed-envelopes-in-selected-tracks-paste-at-edit-cursor": + 54075, "sws-br-copy-selected-points-in-selected-envelope-to-envelope-at-mouse-cursor": 54078, "sws-br-copy-selected-points-in-selected-envelope-to-to-envelope-at-mouse-cursor-paste-at-edit-cursor": 54080, "sws-br-copy-take-media-source-file-path-of-selected-items-to-clipboard": 54503, @@ -2437,7 +2457,8 @@ export const REAPER_ACTIONS = { "sws-br-delete-tempo-marker-preserve-overall-tempo-and-positions-if-possible": 54838, "sws-br-disable-ignore-project-tempo-for-selected-midi-items": 54465, "sws-br-disable-ignore-project-tempo-for-selected-midi-items-preserving-time-position-of-midi-events": 54466, - "sws-br-enable-ignore-project-tempo-for-selected-midi-items-preserving-time-position-of-midi-events-use-tempo-at-item-s-start": 54468, + "sws-br-enable-ignore-project-tempo-for-selected-midi-items-preserving-time-position-of-midi-events-use-tempo-at-item-s-start": + 54468, "sws-br-enable-ignore-project-tempo-for-selected-midi-items-use-tempo-at-item-s-start": 54467, "sws-br-exclusive-toggle-contextual-toolbar-under-mouse-cursor-preset-1": 53979, "sws-br-exclusive-toggle-contextual-toolbar-under-mouse-cursor-preset-2": 53984, @@ -2594,12 +2615,16 @@ export const REAPER_ACTIONS = { "sws-br-options-toggle-scroll-view-to-edit-cursor-on-stop": 54713, "sws-br-options-toggle-send-all-notes-off-on-stop-play": 54691, "sws-br-options-toggle-stop-repeat-playback-at-end-of-project": 54712, - "sws-br-play-from-edit-cursor-position-and-solo-item-and-track-under-mouse-for-the-duration-perform-until-shortcut-released": 54863, - "sws-br-play-from-edit-cursor-position-and-solo-track-under-mouse-for-the-duration-perform-until-shortcut-released": 54862, + "sws-br-play-from-edit-cursor-position-and-solo-item-and-track-under-mouse-for-the-duration-perform-until-shortcut-released": + 54863, + "sws-br-play-from-edit-cursor-position-and-solo-track-under-mouse-for-the-duration-perform-until-shortcut-released": + 54862, "sws-br-play-from-edit-cursor-position-perform-until-shortcut-released": 54861, "sws-br-play-from-mouse-cursor-position": 54459, - "sws-br-play-from-mouse-cursor-position-and-solo-item-and-track-under-mouse-for-the-duration-perform-until-shortcut-released": 54860, - "sws-br-play-from-mouse-cursor-position-and-solo-track-under-mouse-for-the-duration-perform-until-shortcut-released": 54859, + "sws-br-play-from-mouse-cursor-position-and-solo-item-and-track-under-mouse-for-the-duration-perform-until-shortcut-released": + 54860, + "sws-br-play-from-mouse-cursor-position-and-solo-track-under-mouse-for-the-duration-perform-until-shortcut-released": + 54859, "sws-br-play-from-mouse-cursor-position-perform-until-shortcut-released": 54858, "sws-br-play-pause-from-mouse-cursor-position": 54460, "sws-br-play-stop-from-mouse-cursor-position": 54461, @@ -2608,14 +2633,16 @@ export const REAPER_ACTIONS = { "sws-br-preview-media-item-under-mouse-and-pause-during-preview-start-from-mouse-cursor-position": 54726, "sws-br-preview-media-item-under-mouse-at-track-fader-volume": 54727, "sws-br-preview-media-item-under-mouse-at-track-fader-volume-and-pause-during-preview": 54730, - "sws-br-preview-media-item-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": 54731, + "sws-br-preview-media-item-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": + 54731, "sws-br-preview-media-item-under-mouse-at-track-fader-volume-start-from-mouse-position": 54728, "sws-br-preview-media-item-under-mouse-at-track-fader-volume-sync-with-next-measure": 54729, "sws-br-preview-media-item-under-mouse-start-from-mouse-cursor-position": 54723, "sws-br-preview-media-item-under-mouse-sync-with-next-measure": 54724, "sws-br-preview-media-item-under-mouse-through-track": 54732, "sws-br-preview-media-item-under-mouse-through-track-and-pause-during-preview": 54735, - "sws-br-preview-media-item-under-mouse-through-track-and-pause-during-preview-start-from-mouse-cursor-position": 54736, + "sws-br-preview-media-item-under-mouse-through-track-and-pause-during-preview-start-from-mouse-cursor-position": + 54736, "sws-br-preview-media-item-under-mouse-through-track-start-from-mouse-position": 54733, "sws-br-preview-media-item-under-mouse-through-track-sync-with-next-measure": 54734, "sws-br-preview-take-under-mouse": 54752, @@ -2623,7 +2650,8 @@ export const REAPER_ACTIONS = { "sws-br-preview-take-under-mouse-and-pause-during-preview-start-from-mouse-cursor-position": 54756, "sws-br-preview-take-under-mouse-at-track-fader-volume": 54757, "sws-br-preview-take-under-mouse-at-track-fader-volume-and-pause-during-preview": 54760, - "sws-br-preview-take-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": 54761, + "sws-br-preview-take-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": + 54761, "sws-br-preview-take-under-mouse-at-track-fader-volume-start-from-mouse-position": 54758, "sws-br-preview-take-under-mouse-at-track-fader-volume-sync-with-next-measure": 54759, "sws-br-preview-take-under-mouse-start-from-mouse-cursor-position": 54753, @@ -2851,9 +2879,12 @@ export const REAPER_ACTIONS = { "sws-br-select-dips-in-envelope": 54058, "sws-br-select-dips-in-envelope-add-to-selection": 54057, "sws-br-select-envelope-at-mouse-cursor": 54094, - "sws-br-select-envelope-at-mouse-cursor-and-freehand-draw-envelope-while-snapping-points-to-left-side-grid-line-perform-until-shortcut-released": 54857, - "sws-br-select-envelope-at-mouse-cursor-and-set-closest-envelope-point-s-value-to-mouse-cursor-perform-until-shortcut-released": 54855, - "sws-br-select-envelope-at-mouse-cursor-and-set-closest-left-side-envelope-point-s-value-to-mouse-cursor-perform-until-shortcut-released": 54856, + "sws-br-select-envelope-at-mouse-cursor-and-freehand-draw-envelope-while-snapping-points-to-left-side-grid-line-perform-until-shortcut-released": + 54857, + "sws-br-select-envelope-at-mouse-cursor-and-set-closest-envelope-point-s-value-to-mouse-cursor-perform-until-shortcut-released": + 54855, + "sws-br-select-envelope-at-mouse-cursor-and-set-closest-left-side-envelope-point-s-value-to-mouse-cursor-perform-until-shortcut-released": + 54856, "sws-br-select-envelope-point-at-mouse-cursor": 54096, "sws-br-select-envelope-point-at-mouse-cursor-selected-envelope-only": 54095, "sws-br-select-envelope-points-between-grid": 54037, @@ -2909,14 +2940,16 @@ export const REAPER_ACTIONS = { "sws-br-toggle-preview-media-item-under-mouse-and-pause-during-preview-start-from-mouse-cursor-position": 54741, "sws-br-toggle-preview-media-item-under-mouse-at-track-fader-volume": 54742, "sws-br-toggle-preview-media-item-under-mouse-at-track-fader-volume-and-pause-during-preview": 54745, - "sws-br-toggle-preview-media-item-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": 54746, + "sws-br-toggle-preview-media-item-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": + 54746, "sws-br-toggle-preview-media-item-under-mouse-at-track-fader-volume-start-from-mouse-position": 54743, "sws-br-toggle-preview-media-item-under-mouse-at-track-fader-volume-sync-with-next-measure": 54744, "sws-br-toggle-preview-media-item-under-mouse-start-from-mouse-position": 54738, "sws-br-toggle-preview-media-item-under-mouse-sync-with-next-measure": 54739, "sws-br-toggle-preview-media-item-under-mouse-through-track": 54747, "sws-br-toggle-preview-media-item-under-mouse-through-track-and-pause-during-preview": 54750, - "sws-br-toggle-preview-media-item-under-mouse-through-track-and-pause-during-preview-start-from-mouse-cursor-position": 54751, + "sws-br-toggle-preview-media-item-under-mouse-through-track-and-pause-during-preview-start-from-mouse-cursor-position": + 54751, "sws-br-toggle-preview-media-item-under-mouse-through-track-start-from-mouse-position": 54748, "sws-br-toggle-preview-media-item-under-mouse-through-track-sync-with-next-measure": 54749, "sws-br-toggle-preview-take-under-mouse": 54767, @@ -2924,14 +2957,16 @@ export const REAPER_ACTIONS = { "sws-br-toggle-preview-take-under-mouse-and-pause-during-preview-start-from-mouse-cursor-position": 54771, "sws-br-toggle-preview-take-under-mouse-at-track-fader-volume": 54772, "sws-br-toggle-preview-take-under-mouse-at-track-fader-volume-and-pause-during-preview": 54775, - "sws-br-toggle-preview-take-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": 54776, + "sws-br-toggle-preview-take-under-mouse-at-track-fader-volume-and-pause-during-preview-start-from-mouse-cursor-position": + 54776, "sws-br-toggle-preview-take-under-mouse-at-track-fader-volume-start-from-mouse-position": 54773, "sws-br-toggle-preview-take-under-mouse-at-track-fader-volume-sync-with-next-measure": 54774, "sws-br-toggle-preview-take-under-mouse-start-from-mouse-position": 54768, "sws-br-toggle-preview-take-under-mouse-sync-with-next-measure": 54769, "sws-br-toggle-preview-take-under-mouse-through-track": 54777, "sws-br-toggle-preview-take-under-mouse-through-track-and-pause-during-preview": 54780, - "sws-br-toggle-preview-take-under-mouse-through-track-and-pause-during-preview-start-from-mouse-cursor-position": 54781, + "sws-br-toggle-preview-take-under-mouse-through-track-and-pause-during-preview-start-from-mouse-cursor-position": + 54781, "sws-br-toggle-preview-take-under-mouse-through-track-start-from-mouse-position": 54778, "sws-br-toggle-preview-take-under-mouse-through-track-sync-with-next-measure": 54779, "sws-br-toggle-show-active-mute-send-envelopes-for-selected-tracks": 54153, @@ -4405,13 +4440,16 @@ export const REAPER_ACTIONS = { "sws-wait-for-next-beat-if-playing": 53664, "sws-wait-until-end-of-loop-if-playing": 53665, "sws-wol-adjust-envelope-or-track-height-under-mouse-cursor-midi-cc-relative-mousewheel": 54892, - "sws-wol-adjust-envelope-or-track-height-under-mouse-cursor-zoom-center-to-mouse-cursor-midi-cc-relative-mousewheel": 54893, + "sws-wol-adjust-envelope-or-track-height-under-mouse-cursor-zoom-center-to-mouse-cursor-midi-cc-relative-mousewheel": + 54893, "sws-wol-adjust-selected-envelope-height-midi-cc-relative-mousewheel": 54886, "sws-wol-adjust-selected-envelope-height-zoom-center-to-middle-arrange-midi-cc-relative-mousewheel": 54887, "sws-wol-adjust-selected-envelope-height-zoom-center-to-mouse-cursor-midi-cc-relative-mousewheel": 54888, "sws-wol-adjust-selected-envelope-or-last-touched-track-height-midi-cc-relative-mousewheel": 54889, - "sws-wol-adjust-selected-envelope-or-last-touched-track-height-zoom-center-to-middle-arrange-midi-cc-relative-mousewheel": 54890, - "sws-wol-adjust-selected-envelope-or-last-touched-track-height-zoom-center-to-mouse-cursor-midi-cc-relative-mousewheel": 54891, + "sws-wol-adjust-selected-envelope-or-last-touched-track-height-zoom-center-to-middle-arrange-midi-cc-relative-mousewheel": + 54890, + "sws-wol-adjust-selected-envelope-or-last-touched-track-height-zoom-center-to-mouse-cursor-midi-cc-relative-mousewheel": + 54891, "sws-wol-apply-height-to-selected-envelope-slot-1": 54912, "sws-wol-apply-height-to-selected-envelope-slot-2": 54913, "sws-wol-apply-height-to-selected-envelope-slot-3": 54914, @@ -4794,8 +4832,10 @@ export const REAPER_ACTIONS = { "toolbars-switch-to-toolbar-9": 41948, "track-2nd-pass-render-selected-area-of-tracks-to-mono-post-fader-stem-tracks-and-mute-originals": 42415, "track-2nd-pass-render-selected-area-of-tracks-to-mono-stem-tracks-and-mute-originals": 42418, - "track-2nd-pass-render-selected-area-of-tracks-to-multichannel-parent-send-only-post-fader-stem-tracks-and-mute-originals": 42593, - "track-2nd-pass-render-selected-area-of-tracks-to-multichannel-parent-send-only-stem-tracks-and-mute-originals": 42594, + "track-2nd-pass-render-selected-area-of-tracks-to-multichannel-parent-send-only-post-fader-stem-tracks-and-mute-originals": + 42593, + "track-2nd-pass-render-selected-area-of-tracks-to-multichannel-parent-send-only-stem-tracks-and-mute-originals": + 42594, "track-2nd-pass-render-selected-area-of-tracks-to-multichannel-post-fader-stem-tracks-and-mute-originals": 42414, "track-2nd-pass-render-selected-area-of-tracks-to-multichannel-stem-tracks-and-mute-originals": 42417, "track-2nd-pass-render-selected-area-of-tracks-to-stereo-post-fader-stem-tracks-and-mute-originals": 42413, @@ -5012,7 +5052,8 @@ export const REAPER_ACTIONS = { "track-rename-last-touched-track": 40696, "track-render-selected-area-of-tracks-to-mono-post-fader-stem-tracks-and-mute-originals": 41718, "track-render-selected-area-of-tracks-to-mono-stem-tracks-and-mute-originals": 41721, - "track-render-selected-area-of-tracks-to-multichannel-parent-send-only-post-fader-stem-tracks-and-mute-originals": 42591, + "track-render-selected-area-of-tracks-to-multichannel-parent-send-only-post-fader-stem-tracks-and-mute-originals": + 42591, "track-render-selected-area-of-tracks-to-multichannel-parent-send-only-stem-tracks-and-mute-originals": 42592, "track-render-selected-area-of-tracks-to-multichannel-post-fader-stem-tracks-and-mute-originals": 41717, "track-render-selected-area-of-tracks-to-multichannel-stem-tracks-and-mute-originals": 41720, diff --git a/src/Reaper/generate-actions.ts b/src/Reaper/generate-actions.ts index ca67651081c7e40998446d2c088b2e83ade74066..8109dc1f5c08327fd57f0d76e94d46e40d9bc387 100644 --- a/src/Reaper/generate-actions.ts +++ b/src/Reaper/generate-actions.ts @@ -1,12 +1,5 @@ import { execFile } from "node:child_process"; -import { - access, - mkdir, - mkdtemp, - readFile, - rm, - writeFile, -} from "node:fs/promises"; +import { access, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { dirname, join, resolve } from "node:path"; import process from "node:process"; @@ -76,10 +69,10 @@ function parseRawActions(value: unknown): RawReaperAction[] { return value.flatMap((entry) => { if ( - !entry || - typeof entry !== "object" || - !("commandId" in entry) || - !("name" in entry) + !entry + || typeof entry !== "object" + || !("commandId" in entry) + || !("name" in entry) ) { return []; } @@ -147,9 +140,7 @@ function renderActionsFile(actions: ReadonlyArray) { "// Source: REAPER main action section via kbd_enumerateActions()/kbd_getTextFromCmd().", "", "export const REAPER_ACTIONS = {", - ...actions.map((action) => - ` ${JSON.stringify(action.actionId)}: ${action.commandId},` - ), + ...actions.map((action) => ` ${JSON.stringify(action.actionId)}: ${action.commandId},`), "} as const satisfies Record;", "", "export type ReaperActionId = keyof typeof REAPER_ACTIONS;", diff --git a/src/SpeedEditor.ts b/src/SpeedEditor.ts index 8271497e25aeaa916b83f3485244f6bbffab3357..6638c3abc3a17e8d532a187ec048c71f7bddf17a 100644 --- a/src/SpeedEditor.ts +++ b/src/SpeedEditor.ts @@ -1,8 +1,8 @@ import { Events } from "@clo/lib/Events.ts"; +import * as log from "@clo/lib/log.ts"; import { defer } from "@clo/lib/ts.ts"; import type { Dispose, Timer } from "@clo/lib/ts.ts"; import type { Mac } from "./Mac"; -import * as log from "@clo/lib/log.ts"; const SPEED_EDITOR_VENDOR_ID = 0x1edb; const SPEED_EDITOR_PRODUCT_ID = 0xda0e; @@ -215,8 +215,8 @@ export class SpeedEditor extends Events { } onDoublePress(key: SpeedEditor.Key, listener: () => void): Dispose { - const listeners = this.#doublePressListeners.get(key) ?? - new Set<() => void>(); + const listeners = this.#doublePressListeners.get(key) + ?? new Set<() => void>(); listeners.add(listener); this.#doublePressListeners.set(key, listeners); @@ -236,7 +236,7 @@ export class SpeedEditor extends Events { this.#ready = false; this.#refreshRequested = false; this.#stopHotplugMonitoring?.(); - this.#stopHotplugMonitoring = null + this.#stopHotplugMonitoring = null; this.#disconnect(false); this.emit("close"); } @@ -267,8 +267,8 @@ export class SpeedEditor extends Events { #matchesHotplugDevice(device: import("usb").Device) { const descriptor = device.deviceDescriptor; - return descriptor.idVendor === this.#options.vendorId && - descriptor.idProduct === this.#options.productId; + return descriptor.idVendor === this.#options.vendorId + && descriptor.idProduct === this.#options.productId; } async #refreshConnection() { @@ -309,8 +309,8 @@ export class SpeedEditor extends Events { } const currentKey = getDeviceKey(this.#deviceInfo); - const currentStillPresent = currentKey !== null && - devices.some((device) => getDeviceKey(device) === currentKey); + const currentStillPresent = currentKey !== null + && devices.some((device) => getDeviceKey(device) === currentKey); if (this.#device && !currentStillPresent) { this.#disconnect(true); @@ -330,8 +330,8 @@ export class SpeedEditor extends Events { #selectDevice(devices: ReadonlyArray) { if (this.#options.path) { - return devices.find((device) => device.path === this.#options.path) ?? - null; + return devices.find((device) => device.path === this.#options.path) + ?? null; } return devices[0] ?? null; @@ -611,16 +611,16 @@ export class SpeedEditor extends Events { } static camNumbersToNumpad(speededitor: Pick, mac: Pick) { - speededitor.onPress("cam1", () => mac.pressKey('numpad1')); - speededitor.onPress("cam2", () => mac.pressKey('numpad2')); - speededitor.onPress("cam3", () => mac.pressKey('numpad3')); - speededitor.onPress("cam4", () => mac.pressKey('numpad4')); - speededitor.onPress("cam5", () => mac.pressKey('numpad5')); - speededitor.onPress("cam6", () => mac.pressKey('numpad6')); - speededitor.onPress("cam7", () => mac.pressKey('numpad7')); - speededitor.onPress("cam8", () => mac.pressKey('numpad8')); - speededitor.onPress("cam9", () => mac.pressKey('numpad9')); - speededitor.onPress("liveOverwrite", () => mac.pressKey('numpad0')); + speededitor.onPress("cam1", () => mac.pressKey("numpad1")); + speededitor.onPress("cam2", () => mac.pressKey("numpad2")); + speededitor.onPress("cam3", () => mac.pressKey("numpad3")); + speededitor.onPress("cam4", () => mac.pressKey("numpad4")); + speededitor.onPress("cam5", () => mac.pressKey("numpad5")); + speededitor.onPress("cam6", () => mac.pressKey("numpad6")); + speededitor.onPress("cam7", () => mac.pressKey("numpad7")); + speededitor.onPress("cam8", () => mac.pressKey("numpad8")); + speededitor.onPress("cam9", () => mac.pressKey("numpad9")); + speededitor.onPress("liveOverwrite", () => mac.pressKey("numpad0")); } } @@ -909,8 +909,8 @@ function getDeviceKey(device: SpeedEditor.DeviceInfo | null) { return null; } - return device.path ?? - [ + return device.path + ?? [ device.vendorId, device.productId, device.serialNumber ?? "", diff --git a/src/config.ts b/src/config.ts index 2d808f914dabd84804d133487bc6680290e21339..adb4f2fb9f8536da12c865b8eda0d3560beb5946 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,5 @@ +import { Events } from "@clo/lib/Events.ts"; +import * as console from "@clo/lib/log.ts"; import * as ts from "@clo/lib/ts.ts"; import type { Dispose } from "@clo/lib/ts.ts"; import * as fs from "node:fs/promises"; @@ -5,8 +7,6 @@ import * as path from "node:path"; import * as url from "node:url"; import { Mac } from "./Mac.ts"; import { SpeedEditor } from "./SpeedEditor.ts"; -import { Events } from "@clo/lib/Events.ts"; -import * as console from "@clo/lib/log.ts"; export interface Configure { /** Events are only active when the application is active. */ @@ -34,9 +34,9 @@ interface AppDefinition { } export type AppEvents = { - "focus": [], - "blur": [], -} + "focus": []; + "blur": []; +}; export function forApp( bundle: Mac.BundleId, @@ -151,8 +151,8 @@ export class AppSpeedEditor extends Events { onDoublePress(key: SpeedEditor.Key, listener: () => void): Dispose { const pair = { key, listener }; this.#doubleKeyEvents.add(pair); - this.#enabled && - this.#enabledStack.use(this.#source.onDoublePress(key, listener)); + this.#enabled + && this.#enabledStack.use(this.#source.onDoublePress(key, listener)); return ts.defer(() => { throw new Error("TODO"); }); @@ -199,12 +199,12 @@ export async function runConfigs(dir: string) { if (!speededitor.connected) { console.warn("Speed Editor is not connected"); } - speededitor.on('connect', () => { + speededitor.on("connect", () => { console.info("Speed Editor connected"); - }) - speededitor.on('disconnect', () => { + }); + speededitor.on("disconnect", () => { console.warn("Speed Editor lost connection"); - }) + }); const instances = new Map(); const pendingInstances = new Map>();