forked from pingdotgg/t3code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeybindings.ts
More file actions
140 lines (126 loc) · 4.08 KB
/
keybindings.ts
File metadata and controls
140 lines (126 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { Schema } from "effect";
import { TrimmedString } from "./baseSchemas";
export const MAX_KEYBINDING_VALUE_LENGTH = 64;
const MAX_KEYBINDING_WHEN_LENGTH = 256;
export const MAX_WHEN_EXPRESSION_DEPTH = 64;
export const MAX_SCRIPT_ID_LENGTH = 24;
export const MAX_KEYBINDINGS_COUNT = 256;
export const THREAD_JUMP_KEYBINDING_COMMANDS = [
"thread.jump.1",
"thread.jump.2",
"thread.jump.3",
"thread.jump.4",
"thread.jump.5",
"thread.jump.6",
"thread.jump.7",
"thread.jump.8",
"thread.jump.9",
] as const;
export type ThreadJumpKeybindingCommand = (typeof THREAD_JUMP_KEYBINDING_COMMANDS)[number];
export const THREAD_KEYBINDING_COMMANDS = [
"thread.previous",
"thread.next",
...THREAD_JUMP_KEYBINDING_COMMANDS,
] as const;
export type ThreadKeybindingCommand = (typeof THREAD_KEYBINDING_COMMANDS)[number];
const STATIC_KEYBINDING_COMMANDS = [
"terminal.toggle",
"terminal.split",
"terminal.new",
"terminal.close",
"diff.toggle",
"chat.new",
"chat.newLocal",
"editor.openFavorite",
...THREAD_KEYBINDING_COMMANDS,
] as const;
export const SCRIPT_RUN_COMMAND_PATTERN = Schema.TemplateLiteral([
Schema.Literal("script."),
Schema.NonEmptyString.check(
Schema.isMaxLength(MAX_SCRIPT_ID_LENGTH),
Schema.isPattern(/^[a-z0-9][a-z0-9-]*$/),
),
Schema.Literal(".run"),
]);
export const KeybindingCommand = Schema.Union([
Schema.Literals(STATIC_KEYBINDING_COMMANDS),
SCRIPT_RUN_COMMAND_PATTERN,
]);
export type KeybindingCommand = typeof KeybindingCommand.Type;
const KeybindingValue = TrimmedString.check(
Schema.isMinLength(1),
Schema.isMaxLength(MAX_KEYBINDING_VALUE_LENGTH),
);
const KeybindingWhen = TrimmedString.check(
Schema.isMinLength(1),
Schema.isMaxLength(MAX_KEYBINDING_WHEN_LENGTH),
);
export const KeybindingRule = Schema.Struct({
key: KeybindingValue,
command: KeybindingCommand,
when: Schema.optional(KeybindingWhen),
});
export type KeybindingRule = typeof KeybindingRule.Type;
export const KeybindingsConfig = Schema.Array(KeybindingRule).check(
Schema.isMaxLength(MAX_KEYBINDINGS_COUNT),
);
export type KeybindingsConfig = typeof KeybindingsConfig.Type;
export const KeybindingShortcut = Schema.Struct({
key: KeybindingValue,
metaKey: Schema.Boolean,
ctrlKey: Schema.Boolean,
shiftKey: Schema.Boolean,
altKey: Schema.Boolean,
modKey: Schema.Boolean,
});
export type KeybindingShortcut = typeof KeybindingShortcut.Type;
const KeybindingWhenNodeRef = Schema.suspend(
(): Schema.Codec<KeybindingWhenNode> => KeybindingWhenNode,
);
export const KeybindingWhenNode = Schema.Union([
Schema.Struct({
type: Schema.Literal("identifier"),
name: Schema.NonEmptyString,
}),
Schema.Struct({
type: Schema.Literal("not"),
node: KeybindingWhenNodeRef,
}),
Schema.Struct({
type: Schema.Literal("and"),
left: KeybindingWhenNodeRef,
right: KeybindingWhenNodeRef,
}),
Schema.Struct({
type: Schema.Literal("or"),
left: KeybindingWhenNodeRef,
right: KeybindingWhenNodeRef,
}),
]);
export type KeybindingWhenNode =
| { type: "identifier"; name: string }
| { type: "not"; node: KeybindingWhenNode }
| { type: "and"; left: KeybindingWhenNode; right: KeybindingWhenNode }
| { type: "or"; left: KeybindingWhenNode; right: KeybindingWhenNode };
export const ResolvedKeybindingRule = Schema.Struct({
command: KeybindingCommand,
shortcut: KeybindingShortcut,
whenAst: Schema.optional(KeybindingWhenNode),
}).annotate({ parseOptions: { onExcessProperty: "ignore" } });
export type ResolvedKeybindingRule = typeof ResolvedKeybindingRule.Type;
export const ResolvedKeybindingsConfig = Schema.Array(ResolvedKeybindingRule).check(
Schema.isMaxLength(MAX_KEYBINDINGS_COUNT),
);
export type ResolvedKeybindingsConfig = typeof ResolvedKeybindingsConfig.Type;
export class KeybindingsConfigError extends Schema.TaggedErrorClass<KeybindingsConfigError>()(
"KeybindingsConfigParseError",
{
configPath: Schema.String,
detail: Schema.String,
cause: Schema.optional(Schema.Defect),
},
) {
override get message(): string {
return `Unable to parse keybindings config at ${this.configPath}: ${this.detail}`;
}
}