import { assert, it } from "@effect/vitest"; import * as Schema from "effect/Schema"; import * as Effect from "effect/Effect"; import { KeybindingsConfig, KeybindingRule, ResolvedKeybindingRule, ResolvedKeybindingsConfig, } from "./keybindings.ts"; const decode = ( schema: S, input: unknown, ): Effect.Effect, Schema.SchemaError, never> => Schema.decodeUnknownEffect(schema as never)(input) as Effect.Effect< Schema.Schema.Type, Schema.SchemaError, never >; const decodeResolvedRule = Schema.decodeUnknownEffect(ResolvedKeybindingRule as never); const encodeResolvedKeybindings = Schema.encodeEffect(ResolvedKeybindingsConfig); it.effect("parses keybinding rules", () => Effect.gen(function* () { const parsed = yield* decode(KeybindingRule, { key: "mod+j", command: "terminal.toggle", }); assert.strictEqual(parsed.command, "terminal.toggle"); const parsedSidebarToggle = yield* decode(KeybindingRule, { key: "mod+b", command: "sidebar.toggle", }); assert.strictEqual(parsedSidebarToggle.command, "sidebar.toggle"); const parsedRightPanelToggle = yield* decode(KeybindingRule, { key: "mod+alt+b", command: "rightPanel.toggle", }); assert.strictEqual(parsedRightPanelToggle.command, "rightPanel.toggle"); const parsedClose = yield* decode(KeybindingRule, { key: "mod+w", command: "terminal.close", }); assert.strictEqual(parsedClose.command, "terminal.close"); const parsedDiffToggle = yield* decode(KeybindingRule, { key: "mod+d", command: "diff.toggle", }); assert.strictEqual(parsedDiffToggle.command, "diff.toggle"); const parsedCommandPalette = yield* decode(KeybindingRule, { key: "mod+k", command: "commandPalette.toggle", }); assert.strictEqual(parsedCommandPalette.command, "commandPalette.toggle"); const parsedFilePicker = yield* decode(KeybindingRule, { key: "mod+p", command: "filePicker.toggle", }); assert.strictEqual(parsedFilePicker.command, "filePicker.toggle"); const parsedProjectSearch = yield* decode(KeybindingRule, { key: "mod+shift+f", command: "projectSearch.toggle", }); assert.strictEqual(parsedProjectSearch.command, "projectSearch.toggle"); const parsedThemeEditor = yield* decode(KeybindingRule, { key: "mod+alt+shift+t", command: "themeEditor.toggle", }); assert.strictEqual(parsedThemeEditor.command, "themeEditor.toggle"); const parsedLocal = yield* decode(KeybindingRule, { key: "mod+shift+n", command: "chat.newLocal", }); assert.strictEqual(parsedLocal.command, "chat.newLocal"); const parsedModelPickerToggle = yield* decode(KeybindingRule, { key: "mod+shift+m", command: "modelPicker.toggle", }); assert.strictEqual(parsedModelPickerToggle.command, "modelPicker.toggle"); const parsedModelPickerJump = yield* decode(KeybindingRule, { key: "mod+1", command: "modelPicker.jump.1", }); assert.strictEqual(parsedModelPickerJump.command, "modelPicker.jump.1"); const parsedThreadPrevious = yield* decode(KeybindingRule, { key: "mod+shift+[", command: "thread.previous", }); assert.strictEqual(parsedThreadPrevious.command, "thread.previous"); }), ); it.effect("rejects invalid command values", () => Effect.gen(function* () { const result = yield* Effect.exit( decode(KeybindingRule, { key: "mod+j", command: "script.Test.run", }), ); assert.strictEqual(result._tag, "Failure"); }), ); it.effect("accepts dynamic script run commands", () => Effect.gen(function* () { const parsed = yield* decode(KeybindingRule, { key: "mod+r", command: "script.setup.run", }); assert.strictEqual(parsed.command, "script.setup.run"); }), ); it.effect("parses keybindings array payload", () => Effect.gen(function* () { const parsed = yield* decode(KeybindingsConfig, [ { key: "mod+j", command: "terminal.toggle" }, { key: "mod+d", command: "terminal.split", when: "terminalFocus" }, { key: "mod+shift+d", command: "terminal.splitVertical", when: "terminalFocus" }, ]); assert.lengthOf(parsed, 3); }), ); it.effect("parses resolved keybinding rules", () => Effect.gen(function* () { const parsed = yield* decode(ResolvedKeybindingRule, { command: "terminal.split", shortcut: { key: "d", metaKey: false, ctrlKey: false, shiftKey: false, altKey: false, modKey: true, }, whenAst: { type: "and", left: { type: "identifier", name: "terminalOpen" }, right: { type: "not", node: { type: "identifier", name: "terminalFocus" }, }, }, }); assert.strictEqual(parsed.shortcut.key, "d"); }), ); it.effect("parses resolved keybindings arrays", () => Effect.gen(function* () { const parsed = yield* decode(ResolvedKeybindingsConfig, [ { command: "terminal.toggle", shortcut: { key: "j", metaKey: false, ctrlKey: false, shiftKey: false, altKey: false, modKey: true, }, }, { command: "thread.jump.3", shortcut: { key: "3", metaKey: false, ctrlKey: false, shiftKey: false, altKey: false, modKey: true, }, }, ]); assert.lengthOf(parsed, 2); }), ); const shortcut = { key: "p", metaKey: false, ctrlKey: false, shiftKey: false, altKey: false, modKey: true, }; it.effect("drops resolved rules with commands this build does not know", () => Effect.gen(function* () { const parsed = yield* decode(ResolvedKeybindingsConfig, [ { command: "terminal.toggle", shortcut }, { command: "someFuture.toggle", shortcut }, { command: "filePicker.toggle", shortcut }, ]); assert.deepEqual( parsed.map((rule) => rule.command), ["terminal.toggle", "filePicker.toggle"], ); }), ); it.effect("drops resolved rules with unknown when-node types", () => Effect.gen(function* () { const parsed = yield* decode(ResolvedKeybindingsConfig, [ { command: "terminal.toggle", shortcut, whenAst: { type: "xor", left: 1, right: 2 }, }, { command: "terminal.split", shortcut }, ]); assert.deepEqual( parsed.map((rule) => rule.command), ["terminal.split"], ); }), ); it.effect("drops malformed resolved rule entries", () => Effect.gen(function* () { const parsed = yield* decode(ResolvedKeybindingsConfig, [ "garbage", { command: "terminal.toggle", shortcut }, null, ]); assert.deepEqual( parsed.map((rule) => rule.command), ["terminal.toggle"], ); }), ); it.effect("encodes resolved keybindings to the plain wire shape", () => Effect.gen(function* () { const rules = [{ command: "terminal.toggle" as const, shortcut }]; const encoded = yield* encodeResolvedKeybindings(rules); assert.deepEqual(encoded, rules); const roundTripped = yield* decode(ResolvedKeybindingsConfig, encoded); assert.deepEqual(roundTripped, rules); }), ); it.effect("drops unknown fields in resolved keybinding rules", () => decodeResolvedRule({ command: "terminal.toggle", shortcut: { key: "j", metaKey: false, ctrlKey: false, shiftKey: false, altKey: false, modKey: true, }, key: "mod+j", }).pipe( Effect.map((parsed) => { const view = parsed as Record; assert.strictEqual("key" in view, false); assert.strictEqual(view.command, "terminal.toggle"); }), ), );