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 = <S extends Schema.Top>( schema: S, input: unknown,): Effect.Effect<Schema.Schema.Type<S>, Schema.SchemaError, never> => Schema.decodeUnknownEffect(schema as never)(input) as Effect.Effect< Schema.Schema.Type<S>, 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 parsedRightPanelToggleMaximized = yield* decode(KeybindingRule, { key: "mod+shift+m", command: "rightPanel.toggleMaximized", }); assert.strictEqual(parsedRightPanelToggleMaximized.command, "rightPanel.toggleMaximized"); 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<string, unknown>; assert.strictEqual("key" in view, false); assert.strictEqual(view.command, "terminal.toggle"); }), ),);
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 = <S extends Schema.Top>(
schema: S,
input: unknown,
): Effect.Effect<Schema.Schema.Type<S>, Schema.SchemaError, never> =>
Schema.decodeUnknownEffect(schema as never)(input) as Effect.Effect<
Schema.Schema.Type<S>,
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 parsedRightPanelToggleMaximized = yield* decode(KeybindingRule, {
key: "mod+shift+m",
command: "rightPanel.toggleMaximized",
});
assert.strictEqual(parsedRightPanelToggleMaximized.command, "rightPanel.toggleMaximized");
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<string, unknown>;
assert.strictEqual("key" in view, false);
assert.strictEqual(view.command, "terminal.toggle");
}),
),
);