@opentui/keymap 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -30
- package/chunks/index-frk6sdcd.js +409 -0
- package/chunks/index-frk6sdcd.js.map +14 -0
- package/package.json +43 -23
- package/src/addons/index.js +1130 -0
- package/src/addons/index.js.map +25 -0
- package/src/addons/opentui/edit-buffer-bindings.d.ts +6 -2
- package/src/addons/opentui/index.d.ts +2 -2
- package/src/addons/opentui/index.js +467 -0
- package/src/addons/opentui/index.js.map +12 -0
- package/src/addons/universal/binding-overrides.d.ts +6 -0
- package/src/addons/universal/dead-bindings.d.ts +1 -1
- package/src/addons/universal/default-parser.d.ts +2 -2
- package/src/addons/universal/ex-commands.d.ts +11 -8
- package/src/addons/universal/index.d.ts +3 -1
- package/src/addons/universal/leader.d.ts +1 -1
- package/src/addons/universal/metadata.d.ts +2 -2
- package/src/addons/universal/mod-bindings.d.ts +6 -0
- package/src/addons/universal/unresolved-commands.d.ts +1 -1
- package/src/extras/binding-sections.d.ts +18 -0
- package/src/extras/command-bindings.d.ts +19 -0
- package/src/extras/formatting.d.ts +27 -0
- package/src/extras/graph.d.ts +9 -0
- package/src/extras/graph.js +373 -0
- package/src/extras/graph.js.map +11 -0
- package/src/extras/index.d.ts +6 -0
- package/src/extras/index.js +239 -0
- package/src/extras/index.js.map +12 -0
- package/src/extras/lib/graph-snapshot.d.ts +14 -0
- package/src/extras/lib/graph-types.d.ts +83 -0
- package/src/html.d.ts +3 -3
- package/src/html.js +297 -0
- package/src/html.js.map +10 -0
- package/src/index.d.ts +3 -1
- package/src/index.js +4492 -0
- package/src/index.js.map +34 -0
- package/src/keymap.d.ts +23 -35
- package/src/lib/emitter.d.ts +1 -2
- package/src/lib/registry.d.ts +2 -2
- package/src/lib/runtime-utils.d.ts +34 -0
- package/src/opentui.d.ts +1 -3
- package/src/opentui.js +133 -0
- package/src/opentui.js.map +10 -0
- package/src/react/index.d.ts +5 -19
- package/{react → src/react}/index.js +3 -0
- package/src/react/index.js.map +10 -0
- package/src/runtime-modules.d.ts +20 -0
- package/src/runtime-modules.js +28 -0
- package/src/runtime-modules.js.map +10 -0
- package/src/services/activation.d.ts +7 -33
- package/src/services/active-key-cache.d.ts +29 -0
- package/src/services/command-catalog.d.ts +28 -45
- package/src/services/command-executor.d.ts +7 -13
- package/src/services/compiler.d.ts +6 -12
- package/src/services/conditions.d.ts +4 -16
- package/src/services/dispatch-decisions.d.ts +21 -0
- package/src/services/dispatch-patterns.d.ts +5 -0
- package/src/services/dispatch.d.ts +6 -42
- package/src/services/environment.d.ts +6 -21
- package/src/services/extension-context.d.ts +16 -0
- package/src/services/layer-diagnostics.d.ts +10 -0
- package/src/services/layers.d.ts +15 -23
- package/src/services/notify.d.ts +6 -8
- package/src/services/pending-sequence.d.ts +4 -0
- package/src/services/primitives/active-layers.d.ts +2 -3
- package/src/services/primitives/bindings.d.ts +4 -0
- package/src/services/primitives/command-normalization.d.ts +3 -0
- package/src/services/primitives/field-invariants.d.ts +16 -1
- package/src/services/primitives/pending-captures.d.ts +5 -0
- package/src/services/runtime-view.d.ts +5 -0
- package/src/services/runtime.d.ts +2 -7
- package/src/services/sequence-index.d.ts +24 -0
- package/src/services/state.d.ts +46 -91
- package/src/solid/index.d.ts +5 -19
- package/{solid → src/solid}/index.js +3 -0
- package/src/solid/index.js.map +10 -0
- package/src/testing/index.d.ts +90 -0
- package/src/testing/index.js +276 -0
- package/src/testing/index.js.map +10 -0
- package/src/types.d.ts +194 -126
- package/addons/index.js +0 -5240
- package/addons/opentui/index.js +0 -5632
- package/html.js +0 -5042
- package/index.js +0 -4411
- package/opentui.js +0 -4887
- package/src/services/primitives/binding-inputs.d.ts +0 -4
package/README.md
CHANGED
|
@@ -1,22 +1,52 @@
|
|
|
1
1
|
# @opentui/keymap
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
It
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
3
|
+
A host-agnostic keymap engine for terminal and DOM apps. Same core, multiple adapters.
|
|
4
|
+
|
|
5
|
+
It models keybindings as priority-ordered, focus-scoped layers attached to targets (terminal renderables or DOM elements). The core is intentionally bare; everything beyond raw key dispatch is opt-in via addons, parsers, expanders, resolvers, and field compilers.
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
|
|
9
|
+
- **Host-agnostic core** over a small `KeymapHost` interface with host metadata, focus, parent traversal, target destruction, key press/release, optional raw input, and synthetic command events.
|
|
10
|
+
- **Target-aware focus routing** for global layers plus local `focus` / `focus-within` layers that follow the active target's parent chain.
|
|
11
|
+
- **Layered bindings** with priority ordering, newest-first ties, `fallthrough`, and `preventDefault` control.
|
|
12
|
+
- **Branch-aware multi-key sequences** over flat compiled bindings, with a public pending-sequence API, synchronous `pendingSequence` events, active continuation queries, and automatic invalidation on focus changes.
|
|
13
|
+
- **Programmable exact-vs-prefix disambiguation** (e.g. `g` vs `gg`) with `runExact`, `continueSequence`, `clear`, and deferred `AbortSignal` + `sleep` decisions. Ships a Neovim-style timeout resolver.
|
|
14
|
+
- **Pluggable binding language**: stackable binding parsers, key expanders, layer-binding transformers, binding transformers, command resolvers, command transformers, and event-match resolvers.
|
|
15
|
+
- **Extensible schema and activation**: register custom fields on layers, bindings, and commands. Field compilers can emit `attrs`; all field kinds can gate activation via `require(...)` and `activeWhen(matcher)`.
|
|
16
|
+
- **Reactive matchers** with subscription-driven state notifications, plus React store and Solid signal helpers.
|
|
17
|
+
- **Raw and key intercepts** before and after normal binding dispatch, including pre-binding `consume({ preventDefault, stopPropagation })`, post-dispatch handled/no-match outcomes, and raw input `stop()` handling.
|
|
18
|
+
- **Command catalog and dispatch** with named commands, inline command handlers, command chains, namespaces, search, visibility tiers (`registered` / `reachable` / `active`), binding queries, `runCommand`, and focus-aware `dispatchCommand`.
|
|
19
|
+
- **Opt-in graph snapshots and diagnostics** for layers, commands, bindings, sequence nodes, pending paths, inactive reasons, shadowing, stable warning/error codes, and lint-style layer analyzers.
|
|
20
|
+
- **Broad key coverage** in the default parser, including function keys, navigation/editing keys, numpad keys, media keys, left/right modifiers, `super`, `hyper`, and literal `+` bindings.
|
|
21
|
+
- **Platform-aware modifier aliases** via `registerModBindings`, resolving `mod+...` from host metadata while preserving display strings.
|
|
22
|
+
|
|
23
|
+
## Addons
|
|
24
|
+
|
|
25
|
+
`@opentui/keymap/addons` ships ready-made building blocks:
|
|
26
|
+
|
|
27
|
+
- `registerDefaultKeys` — `ctrl+shift+s` style parser and event matching.
|
|
28
|
+
- `registerLeader`, `registerTimedLeader` — leader tokens with optional timeout.
|
|
29
|
+
- `registerEmacsBindings` — `ctrl+x ctrl+s` chords.
|
|
30
|
+
- `registerExCommands` — `:write`-style commands with `aliases` and `nargs`.
|
|
31
|
+
- `registerCommaBindings`, `registerModBindings`, `registerAliasesField`, `registerBindingOverrides`.
|
|
32
|
+
- `registerEnabledFields`, `registerMetadataFields` (`desc`, `group`, `title`, `category`).
|
|
33
|
+
- `registerNeovimDisambiguation`, `registerEscapeClearsPendingSequence`, `registerBackspacePopsPendingSequence`.
|
|
34
|
+
- `registerDeadBindingWarnings`, `registerUnresolvedCommandWarnings`.
|
|
35
|
+
|
|
36
|
+
`@opentui/keymap/addons/opentui` adds OpenTUI-specific pieces: layout-independent matching via `event.baseCode`, and pre-wired textarea / edit-buffer commands.
|
|
37
|
+
|
|
38
|
+
## Entry Points
|
|
39
|
+
|
|
40
|
+
- `@opentui/keymap` — core API
|
|
41
|
+
- `@opentui/keymap/addons` — universal addons
|
|
42
|
+
- `@opentui/keymap/addons/opentui` — universal + OpenTUI addons
|
|
43
|
+
- `@opentui/keymap/extras/graph` — graph snapshot helpers for debug and graph UIs
|
|
44
|
+
- `@opentui/keymap/testing` — host-agnostic fake keymap host and diagnostics for addon tests
|
|
45
|
+
- `@opentui/keymap/html` — HTML adapter
|
|
46
|
+
- `@opentui/keymap/opentui` — OpenTUI adapter
|
|
47
|
+
- `@opentui/keymap/react` — `KeymapProvider`, `useKeymap`, `useBindings`, `useActiveKeys`, `usePendingSequence`, `reactiveMatcherFromStore`
|
|
48
|
+
- `@opentui/keymap/solid` — `KeymapProvider`, `useKeymap`, `useKeymapSelector`, `useBindings`, `reactiveMatcherFromSignal`
|
|
49
|
+
- `@opentui/keymap/extras` — helpers for cheat-sheet UIs (`resolveBindingSections`, `commandBindings`, `formatCommandBindings`)
|
|
20
50
|
|
|
21
51
|
## Usage
|
|
22
52
|
|
|
@@ -35,23 +65,28 @@ createRoot(renderer).render(
|
|
|
35
65
|
)
|
|
36
66
|
```
|
|
37
67
|
|
|
38
|
-
|
|
68
|
+
Create a keymap, install the addons you want, then pass the configured instance to your app. The React and Solid entrypoints consume a pre-created OpenTUI keymap through context.
|
|
39
69
|
|
|
40
|
-
|
|
41
|
-
They do not compile into public attrs.
|
|
70
|
+
`Keymap` is the core runtime. Pass feature factories to its constructor when you need graph snapshots or layer analyzers.
|
|
42
71
|
|
|
43
|
-
|
|
44
|
-
|
|
72
|
+
## Adapters
|
|
73
|
+
|
|
74
|
+
Adapters implement a small `KeymapHost` interface (`metadata`, `rootTarget`, `getFocusedTarget`, `getParentTarget`, `onKeyPress`, `onKeyRelease`, `onFocusChange`, `onTargetDestroy`, ...). The HTML adapter normalizes DOM key names (`Escape` → `escape`, `ArrowUp` → `up`, `Meta` → `super`, `Alt` → `meta`) and tracks targets via `MutationObserver`. The OpenTUI adapter hooks `CliRenderer` `keypress`, `keyrelease`, focus, destroy, target destroy, and raw input events.
|
|
75
|
+
|
|
76
|
+
## Formatting Keys
|
|
77
|
+
|
|
78
|
+
Use `keymap.formatKey` when displaying raw binding strings. It runs them through the keymap's parsers and tokens before stringifying.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
keymap.formatKey("<leader>s", { separator: " " }) // "space s"
|
|
82
|
+
keymap.formatKey("<leader>s", { preferDisplay: true }) // "<leader>s"
|
|
83
|
+
```
|
|
45
84
|
|
|
46
85
|
## Re-entry
|
|
47
86
|
|
|
48
|
-
Runtime/data
|
|
49
|
-
handlers, intercepts, and pending-sequence listeners may read or write runtime
|
|
50
|
-
data and manage pending-sequence state.
|
|
87
|
+
Runtime/data re-entry is supported during dispatch: command handlers, intercepts, and pending-sequence listeners may read or write runtime data and pending-sequence state.
|
|
51
88
|
|
|
52
|
-
Structural re-entry is
|
|
53
|
-
layers, tokens, parsers, resolvers, or other environment-shaping state while a
|
|
54
|
-
dispatch is in flight.
|
|
89
|
+
Structural re-entry is **not** supported. Do not register or unregister layers, tokens, parsers, or resolvers while a dispatch is in flight.
|
|
55
90
|
|
|
56
91
|
## Installation
|
|
57
92
|
|
|
@@ -67,5 +102,4 @@ bun run test
|
|
|
67
102
|
bun src/keymap-benchmark.ts
|
|
68
103
|
```
|
|
69
104
|
|
|
70
|
-
|
|
71
|
-
- The HTML demo now lives in the docs app at `/demos/keymap-html/` under `packages/web`.
|
|
105
|
+
The HTML demo lives in the docs app at `/demos/keymap-html/` under `packages/web`.
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/services/keys.ts
|
|
3
|
+
function normalizeBindingTokenName(token) {
|
|
4
|
+
const normalized = token.trim().toLowerCase();
|
|
5
|
+
if (!normalized) {
|
|
6
|
+
throw new Error("Invalid keymap token: token cannot be empty");
|
|
7
|
+
}
|
|
8
|
+
return normalized;
|
|
9
|
+
}
|
|
10
|
+
function normalizeKeyName(name) {
|
|
11
|
+
const normalized = name.trim().toLowerCase();
|
|
12
|
+
if (!normalized) {
|
|
13
|
+
throw new Error("Invalid key name: key name cannot be empty");
|
|
14
|
+
}
|
|
15
|
+
return normalized;
|
|
16
|
+
}
|
|
17
|
+
function normalizeKeyStroke(input) {
|
|
18
|
+
return {
|
|
19
|
+
name: normalizeKeyName(input.name),
|
|
20
|
+
ctrl: input.ctrl ?? false,
|
|
21
|
+
shift: input.shift ?? false,
|
|
22
|
+
meta: input.meta ?? false,
|
|
23
|
+
super: input.super ?? false,
|
|
24
|
+
hyper: input.hyper || undefined
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function cloneKeyStroke(stroke) {
|
|
28
|
+
return {
|
|
29
|
+
name: stroke.name,
|
|
30
|
+
ctrl: stroke.ctrl,
|
|
31
|
+
shift: stroke.shift,
|
|
32
|
+
meta: stroke.meta,
|
|
33
|
+
super: stroke.super,
|
|
34
|
+
hyper: stroke.hyper || undefined
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function createKeySequencePart(input, options) {
|
|
38
|
+
const stroke = cloneKeyStroke(normalizeKeyStroke(input));
|
|
39
|
+
return {
|
|
40
|
+
stroke,
|
|
41
|
+
display: options?.display ?? stringifyCanonicalStroke(stroke),
|
|
42
|
+
match: options?.match ?? createKeyMatch(stroke),
|
|
43
|
+
tokenName: options?.tokenName ? normalizeBindingTokenName(options.tokenName) : undefined
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function cloneKeySequencePart(part) {
|
|
47
|
+
return {
|
|
48
|
+
stroke: cloneKeyStroke(part.stroke),
|
|
49
|
+
display: part.display,
|
|
50
|
+
match: part.match,
|
|
51
|
+
tokenName: part.tokenName,
|
|
52
|
+
patternName: part.patternName,
|
|
53
|
+
payloadKey: part.payloadKey
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function cloneKeySequence(parts) {
|
|
57
|
+
return parts.map((part) => cloneKeySequencePart(part));
|
|
58
|
+
}
|
|
59
|
+
function resolveKeyMatch(input) {
|
|
60
|
+
if ("match" in input) {
|
|
61
|
+
return input.match;
|
|
62
|
+
}
|
|
63
|
+
if ("stroke" in input) {
|
|
64
|
+
return createKeyMatch(input.stroke);
|
|
65
|
+
}
|
|
66
|
+
return createKeyMatch(input);
|
|
67
|
+
}
|
|
68
|
+
function createKeyMatch(input) {
|
|
69
|
+
return `key:${buildKeyMatchId(normalizeKeyStroke(input))}`;
|
|
70
|
+
}
|
|
71
|
+
function createTextKeyMatch(id) {
|
|
72
|
+
const normalized = id.trim();
|
|
73
|
+
if (!normalized) {
|
|
74
|
+
throw new Error("Invalid keymap match id: id cannot be empty");
|
|
75
|
+
}
|
|
76
|
+
return `text:${normalized}`;
|
|
77
|
+
}
|
|
78
|
+
function stringifyKeyStroke(input, options) {
|
|
79
|
+
if ("stroke" in input) {
|
|
80
|
+
if (options?.preferDisplay && input.display) {
|
|
81
|
+
return input.display;
|
|
82
|
+
}
|
|
83
|
+
return stringifyCanonicalStroke(input.stroke);
|
|
84
|
+
}
|
|
85
|
+
return stringifyCanonicalStroke(normalizeKeyStroke(input));
|
|
86
|
+
}
|
|
87
|
+
function stringifyKeySequence(input, options) {
|
|
88
|
+
return input.map((part) => stringifyKeyStroke(part, options)).join(options?.separator ?? "");
|
|
89
|
+
}
|
|
90
|
+
function stringifyCanonicalStroke(stroke) {
|
|
91
|
+
const parts = [];
|
|
92
|
+
if (stroke.ctrl) {
|
|
93
|
+
parts.push("ctrl");
|
|
94
|
+
}
|
|
95
|
+
if (stroke.shift) {
|
|
96
|
+
parts.push("shift");
|
|
97
|
+
}
|
|
98
|
+
if (stroke.meta) {
|
|
99
|
+
parts.push("meta");
|
|
100
|
+
}
|
|
101
|
+
if (stroke.super) {
|
|
102
|
+
parts.push("super");
|
|
103
|
+
}
|
|
104
|
+
if (stroke.hyper) {
|
|
105
|
+
parts.push("hyper");
|
|
106
|
+
}
|
|
107
|
+
parts.push(stroke.name === "return" ? "enter" : stroke.name);
|
|
108
|
+
return parts.join("+");
|
|
109
|
+
}
|
|
110
|
+
function buildKeyMatchId(stroke) {
|
|
111
|
+
return `${stroke.name}:${stroke.ctrl ? 1 : 0}:${stroke.shift ? 1 : 0}:${stroke.meta ? 1 : 0}:${stroke.super ? 1 : 0}:${stroke.hyper ? 1 : 0}`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/services/extension-context.ts
|
|
115
|
+
var KEYMAP_EXTENSION_CONTEXT = Symbol("keymap-extension-context");
|
|
116
|
+
|
|
117
|
+
// src/services/primitives/active-layers.ts
|
|
118
|
+
function getFocusedTargetIfAvailable(host) {
|
|
119
|
+
if (host.isDestroyed) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return host.getFocusedTarget();
|
|
123
|
+
}
|
|
124
|
+
function forEachActivationTarget(host, focused, visit) {
|
|
125
|
+
let current = focused ?? host.rootTarget;
|
|
126
|
+
let isFocusedTarget = focused !== null;
|
|
127
|
+
while (current) {
|
|
128
|
+
const shouldContinue = visit(current, isFocusedTarget);
|
|
129
|
+
if (shouldContinue === false) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
current = host.getParentTarget(current);
|
|
133
|
+
isFocusedTarget = false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function getActivationPath(host, focused) {
|
|
137
|
+
const path = new Set;
|
|
138
|
+
forEachActivationTarget(host, focused, (current) => {
|
|
139
|
+
path.add(current);
|
|
140
|
+
});
|
|
141
|
+
return path;
|
|
142
|
+
}
|
|
143
|
+
function getActiveLayersForFocused(layers, host, focused) {
|
|
144
|
+
const activeLayers = [];
|
|
145
|
+
const activationPath = getActivationPath(host, focused);
|
|
146
|
+
const sortedLayers = Array.isArray(layers) ? layers : getSortedLayers(layers);
|
|
147
|
+
for (const layer of sortedLayers) {
|
|
148
|
+
if (isLayerActiveForFocused(host, layer, focused, activationPath)) {
|
|
149
|
+
activeLayers.push(layer);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return activeLayers;
|
|
153
|
+
}
|
|
154
|
+
function getSortedLayers(layers) {
|
|
155
|
+
return [...layers].sort((left, right) => {
|
|
156
|
+
const priorityDiff = right.priority - left.priority;
|
|
157
|
+
return priorityDiff || right.order - left.order;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function isLayerActiveForFocused(host, layer, focused, activationPath = getActivationPath(host, focused)) {
|
|
161
|
+
const target = layer.target;
|
|
162
|
+
if (!target) {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
if (host.isTargetDestroyed(target)) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
if (layer.targetMode === "focus") {
|
|
169
|
+
return target === focused;
|
|
170
|
+
}
|
|
171
|
+
return activationPath.has(target);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/services/primitives/pending-captures.ts
|
|
175
|
+
function patternCaptureCount(capture) {
|
|
176
|
+
const part = capture.binding.sequence[capture.index];
|
|
177
|
+
if (!part?.patternName) {
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
const captured = capture.patterns?.at(-1);
|
|
181
|
+
return captured?.name === part.patternName ? captured.values.length : 0;
|
|
182
|
+
}
|
|
183
|
+
function captureHasMinimum(capture, patterns, missingPatternResult = true) {
|
|
184
|
+
const part = capture.binding.sequence[capture.index];
|
|
185
|
+
if (!part?.patternName) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
const pattern = patterns.get(part.patternName);
|
|
189
|
+
return pattern ? patternCaptureCount(capture) >= pattern.min : missingPatternResult;
|
|
190
|
+
}
|
|
191
|
+
function captureHasContinuations(capture, patterns, missingPatternMinimum = true) {
|
|
192
|
+
const part = capture.binding.sequence[capture.index];
|
|
193
|
+
if (part?.patternName) {
|
|
194
|
+
const pattern = patterns.get(part.patternName);
|
|
195
|
+
if (pattern && patternCaptureCount(capture) < pattern.max) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return captureHasMinimum(capture, patterns, missingPatternMinimum) && capture.index + 1 < capture.binding.sequence.length;
|
|
200
|
+
}
|
|
201
|
+
function captureIsExact(capture, patterns) {
|
|
202
|
+
return capture.index === capture.binding.sequence.length - 1 && captureHasMinimum(capture, patterns, false);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// src/services/sequence-index.ts
|
|
206
|
+
function createSequenceNode(parent, stroke, match, pattern) {
|
|
207
|
+
return {
|
|
208
|
+
parent,
|
|
209
|
+
depth: parent ? parent.depth + 1 : 0,
|
|
210
|
+
stroke,
|
|
211
|
+
match,
|
|
212
|
+
pattern,
|
|
213
|
+
children: new Map,
|
|
214
|
+
patternChildren: [],
|
|
215
|
+
bindings: [],
|
|
216
|
+
reachableBindings: []
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function buildSequenceTree(bindings, patterns) {
|
|
220
|
+
const root = createSequenceNode(null, null, null);
|
|
221
|
+
for (const binding of bindings) {
|
|
222
|
+
if (binding.event !== "press") {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
let node = root;
|
|
226
|
+
for (const part of binding.sequence) {
|
|
227
|
+
let child;
|
|
228
|
+
if (part.patternName) {
|
|
229
|
+
const pattern = patterns.get(part.patternName);
|
|
230
|
+
child = node.patternChildren.find((candidate) => candidate.pattern?.name === part.patternName);
|
|
231
|
+
if (!child) {
|
|
232
|
+
child = createSequenceNode(node, part.stroke, part.match, pattern);
|
|
233
|
+
node.patternChildren.push(child);
|
|
234
|
+
}
|
|
235
|
+
} else {
|
|
236
|
+
child = node.children.get(part.match);
|
|
237
|
+
if (!child) {
|
|
238
|
+
child = createSequenceNode(node, part.stroke, part.match);
|
|
239
|
+
node.children.set(part.match, child);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
child.reachableBindings.push(binding);
|
|
243
|
+
node = child;
|
|
244
|
+
}
|
|
245
|
+
node.bindings.push(binding);
|
|
246
|
+
}
|
|
247
|
+
return root;
|
|
248
|
+
}
|
|
249
|
+
function getCaptureNode(root, capture) {
|
|
250
|
+
let node = root;
|
|
251
|
+
for (let index = 0;index <= capture.index; index += 1) {
|
|
252
|
+
const part = capture.binding.sequence[index];
|
|
253
|
+
if (!part || !node) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
node = part.patternName ? node.patternChildren.find((candidate) => candidate.pattern?.name === part.patternName) : node.children.get(part.match);
|
|
257
|
+
}
|
|
258
|
+
return node;
|
|
259
|
+
}
|
|
260
|
+
function getNodeSequence(node) {
|
|
261
|
+
const parts = [];
|
|
262
|
+
let current = node;
|
|
263
|
+
while (current?.stroke && current.match) {
|
|
264
|
+
parts.push({
|
|
265
|
+
stroke: cloneKeyStroke(current.stroke),
|
|
266
|
+
display: "",
|
|
267
|
+
match: current.match
|
|
268
|
+
});
|
|
269
|
+
current = current.parent;
|
|
270
|
+
}
|
|
271
|
+
parts.reverse();
|
|
272
|
+
return parts;
|
|
273
|
+
}
|
|
274
|
+
function getNodePresentation(node) {
|
|
275
|
+
if (!node.stroke || node.depth === 0) {
|
|
276
|
+
return { display: "" };
|
|
277
|
+
}
|
|
278
|
+
const partIndex = node.depth - 1;
|
|
279
|
+
for (const binding of node.reachableBindings) {
|
|
280
|
+
const part = binding.sequence[partIndex];
|
|
281
|
+
if (part) {
|
|
282
|
+
return { display: part.display, tokenName: part.tokenName };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return { display: stringifyKeyStroke(node.stroke) };
|
|
286
|
+
}
|
|
287
|
+
function childNodes(node) {
|
|
288
|
+
return [...node.children.values(), ...node.patternChildren];
|
|
289
|
+
}
|
|
290
|
+
function activeOptionsForCaptures(captures, patterns) {
|
|
291
|
+
const options = [];
|
|
292
|
+
for (const capture of captures) {
|
|
293
|
+
if (!captureHasMinimum(capture, patterns)) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
const index = capture.index + 1;
|
|
297
|
+
const part = capture.binding.sequence[index];
|
|
298
|
+
if (part) {
|
|
299
|
+
options.push({
|
|
300
|
+
part,
|
|
301
|
+
binding: capture.binding,
|
|
302
|
+
index,
|
|
303
|
+
exact: index === capture.binding.sequence.length - 1,
|
|
304
|
+
continues: index < capture.binding.sequence.length - 1
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return options;
|
|
309
|
+
}
|
|
310
|
+
function appendPatternCapture(capture, index, part, value) {
|
|
311
|
+
const patternName = part.patternName;
|
|
312
|
+
if (!patternName) {
|
|
313
|
+
return { ...capture, index };
|
|
314
|
+
}
|
|
315
|
+
const patterns = [...capture.patterns ?? []];
|
|
316
|
+
const last = patterns.at(-1);
|
|
317
|
+
if (last?.name === patternName) {
|
|
318
|
+
patterns[patterns.length - 1] = {
|
|
319
|
+
...last,
|
|
320
|
+
values: [...last.values, value],
|
|
321
|
+
parts: [...last.parts, part]
|
|
322
|
+
};
|
|
323
|
+
} else {
|
|
324
|
+
patterns.push({
|
|
325
|
+
name: patternName,
|
|
326
|
+
payloadKey: part.payloadKey ?? patternName,
|
|
327
|
+
values: [value],
|
|
328
|
+
parts: [part]
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
layer: capture.layer,
|
|
333
|
+
binding: capture.binding,
|
|
334
|
+
index,
|
|
335
|
+
parts: [...capture.parts, part],
|
|
336
|
+
patterns
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function capturePriority(capture, matchKeys) {
|
|
340
|
+
const part = capture.parts.at(-1);
|
|
341
|
+
if (!part || part.patternName) {
|
|
342
|
+
return matchKeys.length;
|
|
343
|
+
}
|
|
344
|
+
const index = matchKeys.indexOf(part.match);
|
|
345
|
+
return index === -1 ? matchKeys.length : index;
|
|
346
|
+
}
|
|
347
|
+
function advanceSequenceBinding(layer, binding, index, parts, patterns, matchKeys, event, matchPattern, createPatternPart) {
|
|
348
|
+
const part = binding.sequence[index];
|
|
349
|
+
if (!part) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (part.patternName) {
|
|
353
|
+
const patternMatch = matchPattern(part.patternName, event);
|
|
354
|
+
if (!patternMatch) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const eventPart = createPatternPart(event, part.patternName, patternMatch);
|
|
358
|
+
return appendPatternCapture({ layer, binding, index, parts, patterns }, index, eventPart, patternMatch.value ?? event.name);
|
|
359
|
+
}
|
|
360
|
+
if (!matchKeys.includes(part.match)) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
return { layer, binding, index, parts: [...parts, part], patterns };
|
|
364
|
+
}
|
|
365
|
+
function advanceSequenceCapture(capture, matchKeys, event, patterns, matchPattern, createPatternPart) {
|
|
366
|
+
const currentPart = capture.binding.sequence[capture.index];
|
|
367
|
+
if (currentPart?.patternName) {
|
|
368
|
+
const pattern = patterns.get(currentPart.patternName);
|
|
369
|
+
if (pattern && patternCaptureCount(capture) < pattern.max) {
|
|
370
|
+
const patternMatch = matchPattern(pattern.name, event);
|
|
371
|
+
if (patternMatch) {
|
|
372
|
+
const part = createPatternPart(event, pattern.name, patternMatch);
|
|
373
|
+
return appendPatternCapture(capture, capture.index, part, patternMatch.value ?? event.name);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (!captureHasMinimum(capture, patterns, false)) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
return advanceSequenceBinding(capture.layer, capture.binding, capture.index + 1, capture.parts, capture.patterns, matchKeys, event, matchPattern, createPatternPart);
|
|
380
|
+
}
|
|
381
|
+
return advanceSequenceBinding(capture.layer, capture.binding, capture.index + 1, capture.parts, capture.patterns, matchKeys, event, matchPattern, createPatternPart);
|
|
382
|
+
}
|
|
383
|
+
function collectRootSequenceCaptures(layer, matchKeys, event, matchPattern, createPatternPart) {
|
|
384
|
+
const captures = [];
|
|
385
|
+
let bestPriority = Number.POSITIVE_INFINITY;
|
|
386
|
+
for (const binding of layer.bindings) {
|
|
387
|
+
if (binding.event !== "press") {
|
|
388
|
+
continue;
|
|
389
|
+
}
|
|
390
|
+
const capture = advanceSequenceBinding(layer, binding, 0, [], undefined, matchKeys, event, matchPattern, createPatternPart);
|
|
391
|
+
if (!capture) {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
const priority = capturePriority(capture, matchKeys);
|
|
395
|
+
if (priority < bestPriority) {
|
|
396
|
+
bestPriority = priority;
|
|
397
|
+
captures.length = 0;
|
|
398
|
+
}
|
|
399
|
+
if (priority === bestPriority) {
|
|
400
|
+
captures.push(capture);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return captures;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export { normalizeBindingTokenName, cloneKeyStroke, createKeySequencePart, cloneKeySequence, resolveKeyMatch, createTextKeyMatch, stringifyKeyStroke, stringifyKeySequence, getFocusedTargetIfAvailable, getActivationPath, getActiveLayersForFocused, getSortedLayers, isLayerActiveForFocused, captureHasContinuations, captureIsExact, buildSequenceTree, getCaptureNode, getNodeSequence, getNodePresentation, childNodes, activeOptionsForCaptures, capturePriority, advanceSequenceCapture, collectRootSequenceCaptures, KEYMAP_EXTENSION_CONTEXT };
|
|
407
|
+
|
|
408
|
+
//# debugId=0DF84866F5B467C964756E2164756E21
|
|
409
|
+
//# sourceMappingURL=index-frk6sdcd.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/services/keys.ts", "../src/services/extension-context.ts", "../src/services/primitives/active-layers.ts", "../src/services/primitives/pending-captures.ts", "../src/services/sequence-index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n KeyMatch,\n KeySequencePart,\n KeyStrokeInput,\n KeyStringifyInput,\n KeymapEvent,\n NormalizedKeyStroke,\n StringifyOptions,\n} from \"../types.js\"\n\nexport function normalizeBindingTokenName(token: string): string {\n const normalized = token.trim().toLowerCase()\n if (!normalized) {\n throw new Error(\"Invalid keymap token: token cannot be empty\")\n }\n\n return normalized\n}\n\nexport function normalizeKeyName(name: string): string {\n const normalized = name.trim().toLowerCase()\n if (!normalized) {\n throw new Error(\"Invalid key name: key name cannot be empty\")\n }\n\n return normalized\n}\n\nexport function normalizeKeyStroke(input: KeyStrokeInput): NormalizedKeyStroke {\n return {\n name: normalizeKeyName(input.name),\n ctrl: input.ctrl ?? false,\n shift: input.shift ?? false,\n meta: input.meta ?? false,\n super: input.super ?? false,\n hyper: input.hyper || undefined,\n }\n}\n\nexport function normalizeEventKeyStroke(event: KeymapEvent): NormalizedKeyStroke {\n return {\n name: normalizeKeyName(event.name),\n ctrl: event.ctrl,\n shift: event.shift,\n meta: event.meta,\n super: event.super ?? false,\n hyper: event.hyper || undefined,\n }\n}\n\nexport function cloneKeyStroke(stroke: NormalizedKeyStroke): NormalizedKeyStroke {\n return {\n name: stroke.name,\n ctrl: stroke.ctrl,\n shift: stroke.shift,\n meta: stroke.meta,\n super: stroke.super,\n hyper: stroke.hyper || undefined,\n }\n}\n\nexport function createKeySequencePart(\n input: KeyStrokeInput,\n options?: {\n display?: string\n match?: KeyMatch\n tokenName?: string\n },\n): KeySequencePart {\n const stroke = cloneKeyStroke(normalizeKeyStroke(input))\n\n return {\n stroke,\n display: options?.display ?? stringifyCanonicalStroke(stroke),\n match: options?.match ?? createKeyMatch(stroke),\n tokenName: options?.tokenName ? normalizeBindingTokenName(options.tokenName) : undefined,\n }\n}\n\nexport function cloneKeySequencePart(part: KeySequencePart): KeySequencePart {\n return {\n stroke: cloneKeyStroke(part.stroke),\n display: part.display,\n match: part.match,\n tokenName: part.tokenName,\n patternName: part.patternName,\n payloadKey: part.payloadKey,\n }\n}\n\nexport function cloneKeySequence(parts: readonly KeySequencePart[]): KeySequencePart[] {\n return parts.map((part) => cloneKeySequencePart(part))\n}\n\nexport function resolveKeyMatch(input: KeyStringifyInput): KeyMatch {\n if (\"match\" in input) {\n return input.match\n }\n\n if (\"stroke\" in input) {\n return createKeyMatch(input.stroke)\n }\n\n return createKeyMatch(input)\n}\n\nexport function createKeyMatch(input: KeyStrokeInput): KeyMatch {\n return `key:${buildKeyMatchId(normalizeKeyStroke(input))}`\n}\n\nexport function createTextKeyMatch(id: string): KeyMatch {\n const normalized = id.trim()\n if (!normalized) {\n throw new Error(\"Invalid keymap match id: id cannot be empty\")\n }\n\n return `text:${normalized}`\n}\n\nexport function stringifyKeyStroke(input: KeyStringifyInput, options?: StringifyOptions): string {\n if (\"stroke\" in input) {\n if (options?.preferDisplay && input.display) {\n return input.display\n }\n\n return stringifyCanonicalStroke(input.stroke)\n }\n\n return stringifyCanonicalStroke(normalizeKeyStroke(input))\n}\n\nexport function stringifyKeySequence(input: readonly KeyStringifyInput[], options?: StringifyOptions): string {\n return input.map((part) => stringifyKeyStroke(part, options)).join(options?.separator ?? \"\")\n}\n\nfunction stringifyCanonicalStroke(stroke: NormalizedKeyStroke): string {\n const parts: string[] = []\n if (stroke.ctrl) {\n parts.push(\"ctrl\")\n }\n\n if (stroke.shift) {\n parts.push(\"shift\")\n }\n\n if (stroke.meta) {\n parts.push(\"meta\")\n }\n\n if (stroke.super) {\n parts.push(\"super\")\n }\n\n if (stroke.hyper) {\n parts.push(\"hyper\")\n }\n\n parts.push(stroke.name === \"return\" ? \"enter\" : stroke.name)\n return parts.join(\"+\")\n}\n\nfunction buildKeyMatchId(stroke: NormalizedKeyStroke): string {\n return `${stroke.name}:${stroke.ctrl ? 1 : 0}:${stroke.shift ? 1 : 0}:${stroke.meta ? 1 : 0}:${stroke.super ? 1 : 0}:${stroke.hyper ? 1 : 0}`\n}\n",
|
|
6
|
+
"import type { ActivationService } from \"./activation.js\"\nimport type { CommandCatalogService } from \"./command-catalog.js\"\nimport type { ConditionService } from \"./conditions.js\"\nimport type { State } from \"./state.js\"\nimport type { KeymapEvent, KeymapHost } from \"../types.js\"\n\nexport const KEYMAP_EXTENSION_CONTEXT = Symbol(\"keymap-extension-context\")\n\nexport interface KeymapExtensionContext<TTarget extends object, TEvent extends KeymapEvent> {\n state: State<TTarget, TEvent>\n host: KeymapHost<TTarget, TEvent>\n conditions: ConditionService<TTarget, TEvent>\n catalog: CommandCatalogService<TTarget, TEvent>\n activation: ActivationService<TTarget, TEvent>\n}\n\nexport interface KeymapExtensionProvider<TTarget extends object, TEvent extends KeymapEvent> {\n [KEYMAP_EXTENSION_CONTEXT](): KeymapExtensionContext<TTarget, TEvent>\n}\n",
|
|
7
|
+
"import type { KeymapEvent, KeymapHost, RegisteredLayer } from \"../../types.js\"\n\nexport function getFocusedTargetIfAvailable<TTarget extends object, TEvent extends KeymapEvent>(\n host: KeymapHost<TTarget, TEvent>,\n): TTarget | null {\n if (host.isDestroyed) {\n return null\n }\n\n return host.getFocusedTarget()\n}\n\nexport function forEachActivationTarget<TTarget extends object, TEvent extends KeymapEvent>(\n host: KeymapHost<TTarget, TEvent>,\n focused: TTarget | null,\n visit: (target: TTarget, isFocusedTarget: boolean) => boolean | void,\n): void {\n let current: TTarget | null = focused ?? host.rootTarget\n let isFocusedTarget = focused !== null\n\n while (current) {\n const shouldContinue = visit(current, isFocusedTarget)\n if (shouldContinue === false) {\n return\n }\n\n current = host.getParentTarget(current)\n isFocusedTarget = false\n }\n}\n\nexport function getActivationPath<TTarget extends object, TEvent extends KeymapEvent>(\n host: KeymapHost<TTarget, TEvent>,\n focused: TTarget | null,\n): Set<TTarget> {\n const path = new Set<TTarget>()\n forEachActivationTarget(host, focused, (current) => {\n path.add(current)\n })\n\n return path\n}\n\nexport function getActiveLayersForFocused<TTarget extends object, TEvent extends KeymapEvent>(\n layers: readonly RegisteredLayer<TTarget, TEvent>[] | ReadonlySet<RegisteredLayer<TTarget, TEvent>>,\n host: KeymapHost<TTarget, TEvent>,\n focused: TTarget | null,\n): readonly RegisteredLayer<TTarget, TEvent>[] {\n const activeLayers: RegisteredLayer<TTarget, TEvent>[] = []\n const activationPath = getActivationPath(host, focused)\n const sortedLayers = Array.isArray(layers)\n ? layers\n : getSortedLayers(layers as ReadonlySet<RegisteredLayer<TTarget, TEvent>>)\n\n for (const layer of sortedLayers) {\n if (isLayerActiveForFocused(host, layer, focused, activationPath)) {\n activeLayers.push(layer)\n }\n }\n\n return activeLayers\n}\n\nexport function getSortedLayers<TTarget extends object, TEvent extends KeymapEvent>(\n layers: ReadonlySet<RegisteredLayer<TTarget, TEvent>>,\n): RegisteredLayer<TTarget, TEvent>[] {\n return [...layers].sort((left, right) => {\n const priorityDiff = right.priority - left.priority\n return priorityDiff || right.order - left.order\n })\n}\n\nexport function isLayerActiveForFocused<TTarget extends object, TEvent extends KeymapEvent>(\n host: KeymapHost<TTarget, TEvent>,\n layer: RegisteredLayer<TTarget, TEvent>,\n focused: TTarget | null,\n activationPath: ReadonlySet<TTarget> = getActivationPath(host, focused),\n): boolean {\n const target = layer.target\n if (!target) {\n return true\n }\n\n if (host.isTargetDestroyed(target)) {\n return false\n }\n\n if (layer.targetMode === \"focus\") {\n return target === focused\n }\n\n return activationPath.has(target)\n}\n",
|
|
8
|
+
"import type { KeymapEvent, PendingSequenceCapture, ResolvedSequencePattern } from \"../../types.js\"\n\nexport function patternCaptureCount<TTarget extends object, TEvent extends KeymapEvent>(\n capture: PendingSequenceCapture<TTarget, TEvent>,\n): number {\n const part = capture.binding.sequence[capture.index]\n if (!part?.patternName) {\n return 0\n }\n\n const captured = capture.patterns?.at(-1)\n return captured?.name === part.patternName ? captured.values.length : 0\n}\n\nexport function captureHasMinimum<TTarget extends object, TEvent extends KeymapEvent>(\n capture: PendingSequenceCapture<TTarget, TEvent>,\n patterns: ReadonlyMap<string, ResolvedSequencePattern<TEvent>>,\n missingPatternResult = true,\n): boolean {\n const part = capture.binding.sequence[capture.index]\n if (!part?.patternName) {\n return true\n }\n\n const pattern = patterns.get(part.patternName)\n return pattern ? patternCaptureCount(capture) >= pattern.min : missingPatternResult\n}\n\nexport function captureHasContinuations<TTarget extends object, TEvent extends KeymapEvent>(\n capture: PendingSequenceCapture<TTarget, TEvent>,\n patterns: ReadonlyMap<string, ResolvedSequencePattern<TEvent>>,\n missingPatternMinimum = true,\n): boolean {\n const part = capture.binding.sequence[capture.index]\n if (part?.patternName) {\n const pattern = patterns.get(part.patternName)\n if (pattern && patternCaptureCount(capture) < pattern.max) {\n return true\n }\n }\n\n return (\n captureHasMinimum(capture, patterns, missingPatternMinimum) && capture.index + 1 < capture.binding.sequence.length\n )\n}\n\nexport function captureIsExact<TTarget extends object, TEvent extends KeymapEvent>(\n capture: PendingSequenceCapture<TTarget, TEvent>,\n patterns: ReadonlyMap<string, ResolvedSequencePattern<TEvent>>,\n): boolean {\n return capture.index === capture.binding.sequence.length - 1 && captureHasMinimum(capture, patterns, false)\n}\n",
|
|
9
|
+
"import type {\n BindingState,\n KeymapEvent,\n KeySequencePart,\n KeyMatch,\n PendingSequenceCapture,\n PendingSequencePatternCapture,\n RegisteredLayer,\n ResolvedSequencePattern,\n SequenceNode,\n SequencePatternMatch,\n} from \"../types.js\"\nimport { cloneKeyStroke, stringifyKeyStroke } from \"./keys.js\"\nimport { captureHasMinimum, patternCaptureCount } from \"./primitives/pending-captures.js\"\n\nexport interface SequenceActiveOption<TTarget extends object, TEvent extends KeymapEvent> {\n part: KeySequencePart\n binding: BindingState<TTarget, TEvent>\n index: number\n exact: boolean\n continues: boolean\n}\n\nexport function createSequenceNode<TTarget extends object, TEvent extends KeymapEvent>(\n parent: SequenceNode<TTarget, TEvent> | null,\n stroke: KeySequencePart[\"stroke\"] | null,\n match: KeySequencePart[\"match\"] | null,\n pattern?: ResolvedSequencePattern<TEvent>,\n): SequenceNode<TTarget, TEvent> {\n return {\n parent,\n depth: parent ? parent.depth + 1 : 0,\n stroke,\n match,\n pattern,\n children: new Map(),\n patternChildren: [],\n bindings: [],\n reachableBindings: [],\n }\n}\n\nexport function buildSequenceTree<TTarget extends object, TEvent extends KeymapEvent>(\n bindings: readonly BindingState<TTarget, TEvent>[],\n patterns: ReadonlyMap<string, ResolvedSequencePattern<TEvent>>,\n): SequenceNode<TTarget, TEvent> {\n const root = createSequenceNode<TTarget, TEvent>(null, null, null)\n for (const binding of bindings) {\n if (binding.event !== \"press\") {\n continue\n }\n\n let node = root\n for (const part of binding.sequence) {\n let child: SequenceNode<TTarget, TEvent> | undefined\n if (part.patternName) {\n const pattern = patterns.get(part.patternName)\n child = node.patternChildren.find((candidate) => candidate.pattern?.name === part.patternName)\n if (!child) {\n child = createSequenceNode(node, part.stroke, part.match, pattern)\n node.patternChildren.push(child)\n }\n } else {\n child = node.children.get(part.match)\n if (!child) {\n child = createSequenceNode(node, part.stroke, part.match)\n node.children.set(part.match, child)\n }\n }\n\n child.reachableBindings.push(binding)\n node = child\n }\n\n node.bindings.push(binding)\n }\n\n return root\n}\n\nexport function getCaptureNode<TTarget extends object, TEvent extends KeymapEvent>(\n root: SequenceNode<TTarget, TEvent>,\n capture: import(\"../types.js\").PendingSequenceCapture<TTarget, TEvent>,\n): SequenceNode<TTarget, TEvent> | undefined {\n let node: SequenceNode<TTarget, TEvent> | undefined = root\n for (let index = 0; index <= capture.index; index += 1) {\n const part = capture.binding.sequence[index]\n if (!part || !node) {\n return undefined\n }\n\n node = part.patternName\n ? node.patternChildren.find((candidate) => candidate.pattern?.name === part.patternName)\n : node.children.get(part.match)\n }\n\n return node\n}\n\nexport function getNodeSequence<TTarget extends object, TEvent extends KeymapEvent>(\n node: SequenceNode<TTarget, TEvent>,\n): KeySequencePart[] {\n const parts: KeySequencePart[] = []\n let current: SequenceNode<TTarget, TEvent> | null = node\n\n while (current?.stroke && current.match) {\n parts.push({\n stroke: cloneKeyStroke(current.stroke),\n display: \"\",\n match: current.match,\n })\n current = current.parent\n }\n\n parts.reverse()\n return parts\n}\n\nexport function getNodePresentation<TTarget extends object, TEvent extends KeymapEvent>(\n node: SequenceNode<TTarget, TEvent>,\n): { display: string; tokenName?: string } {\n if (!node.stroke || node.depth === 0) {\n return { display: \"\" }\n }\n\n const partIndex = node.depth - 1\n for (const binding of node.reachableBindings) {\n const part = binding.sequence[partIndex]\n if (part) {\n return { display: part.display, tokenName: part.tokenName }\n }\n }\n\n return { display: stringifyKeyStroke(node.stroke) }\n}\n\nexport function firstNodeForMatch<TTarget extends object, TEvent extends KeymapEvent>(\n root: SequenceNode<TTarget, TEvent>,\n match: KeyMatch,\n): SequenceNode<TTarget, TEvent> | undefined {\n return root.children.get(match) ?? root.patternChildren.find((node) => node.match === match)\n}\n\nexport function childNodes<TTarget extends object, TEvent extends KeymapEvent>(\n node: SequenceNode<TTarget, TEvent>,\n): SequenceNode<TTarget, TEvent>[] {\n return [...node.children.values(), ...node.patternChildren]\n}\n\nexport function activeOptionsForBindings<TTarget extends object, TEvent extends KeymapEvent>(\n bindings: readonly BindingState<TTarget, TEvent>[],\n): SequenceActiveOption<TTarget, TEvent>[] {\n const options: SequenceActiveOption<TTarget, TEvent>[] = []\n for (const binding of bindings) {\n const part = binding.sequence[0]\n if (part) {\n options.push({\n part,\n binding,\n index: 0,\n exact: binding.sequence.length === 1,\n continues: binding.sequence.length > 1,\n })\n }\n }\n\n return options\n}\n\nexport function activeOptionsForCaptures<TTarget extends object, TEvent extends KeymapEvent>(\n captures: readonly PendingSequenceCapture<TTarget, TEvent>[],\n patterns: ReadonlyMap<string, ResolvedSequencePattern<TEvent>>,\n): SequenceActiveOption<TTarget, TEvent>[] {\n const options: SequenceActiveOption<TTarget, TEvent>[] = []\n for (const capture of captures) {\n if (!captureHasMinimum(capture, patterns)) {\n continue\n }\n\n const index = capture.index + 1\n const part = capture.binding.sequence[index]\n if (part) {\n options.push({\n part,\n binding: capture.binding,\n index,\n exact: index === capture.binding.sequence.length - 1,\n continues: index < capture.binding.sequence.length - 1,\n })\n }\n }\n\n return options\n}\n\nfunction appendPatternCapture<TTarget extends object, TEvent extends KeymapEvent>(\n capture: PendingSequenceCapture<TTarget, TEvent>,\n index: number,\n part: KeySequencePart,\n value: unknown,\n): PendingSequenceCapture<TTarget, TEvent> {\n const patternName = part.patternName\n if (!patternName) {\n return { ...capture, index }\n }\n\n const patterns = [...(capture.patterns ?? [])]\n const last = patterns.at(-1)\n\n if (last?.name === patternName) {\n patterns[patterns.length - 1] = {\n ...last,\n values: [...last.values, value],\n parts: [...last.parts, part],\n }\n } else {\n patterns.push({\n name: patternName,\n payloadKey: part.payloadKey ?? patternName,\n values: [value],\n parts: [part],\n })\n }\n\n return {\n layer: capture.layer,\n binding: capture.binding,\n index,\n parts: [...capture.parts, part],\n patterns,\n }\n}\n\nexport function capturePriority<TTarget extends object, TEvent extends KeymapEvent>(\n capture: PendingSequenceCapture<TTarget, TEvent>,\n matchKeys: readonly KeyMatch[],\n): number {\n const part = capture.parts.at(-1)\n if (!part || part.patternName) {\n return matchKeys.length\n }\n\n const index = matchKeys.indexOf(part.match)\n return index === -1 ? matchKeys.length : index\n}\n\nexport function advanceSequenceBinding<TTarget extends object, TEvent extends KeymapEvent>(\n layer: RegisteredLayer<TTarget, TEvent>,\n binding: BindingState<TTarget, TEvent>,\n index: number,\n parts: readonly KeySequencePart[],\n patterns: readonly PendingSequencePatternCapture[] | undefined,\n matchKeys: readonly KeyMatch[],\n event: TEvent,\n matchPattern: (patternName: string, event: TEvent) => SequencePatternMatch | undefined,\n createPatternPart: (event: TEvent, patternName: string, match: SequencePatternMatch) => KeySequencePart,\n): PendingSequenceCapture<TTarget, TEvent> | undefined {\n const part = binding.sequence[index]\n if (!part) {\n return undefined\n }\n\n if (part.patternName) {\n const patternMatch = matchPattern(part.patternName, event)\n if (!patternMatch) {\n return undefined\n }\n\n const eventPart = createPatternPart(event, part.patternName, patternMatch)\n return appendPatternCapture(\n { layer, binding, index, parts, patterns },\n index,\n eventPart,\n patternMatch.value ?? event.name,\n )\n }\n\n if (!matchKeys.includes(part.match)) {\n return undefined\n }\n\n return { layer, binding, index, parts: [...parts, part], patterns }\n}\n\nexport function advanceSequenceCapture<TTarget extends object, TEvent extends KeymapEvent>(\n capture: PendingSequenceCapture<TTarget, TEvent>,\n matchKeys: readonly KeyMatch[],\n event: TEvent,\n patterns: ReadonlyMap<string, ResolvedSequencePattern<TEvent>>,\n matchPattern: (patternName: string, event: TEvent) => SequencePatternMatch | undefined,\n createPatternPart: (event: TEvent, patternName: string, match: SequencePatternMatch) => KeySequencePart,\n): PendingSequenceCapture<TTarget, TEvent> | undefined {\n const currentPart = capture.binding.sequence[capture.index]\n if (currentPart?.patternName) {\n const pattern = patterns.get(currentPart.patternName)\n if (pattern && patternCaptureCount(capture) < pattern.max) {\n const patternMatch = matchPattern(pattern.name, event)\n if (patternMatch) {\n const part = createPatternPart(event, pattern.name, patternMatch)\n return appendPatternCapture(capture, capture.index, part, patternMatch.value ?? event.name)\n }\n }\n\n if (!captureHasMinimum(capture, patterns, false)) {\n return undefined\n }\n\n return advanceSequenceBinding(\n capture.layer,\n capture.binding,\n capture.index + 1,\n capture.parts,\n capture.patterns,\n matchKeys,\n event,\n matchPattern,\n createPatternPart,\n )\n }\n\n return advanceSequenceBinding(\n capture.layer,\n capture.binding,\n capture.index + 1,\n capture.parts,\n capture.patterns,\n matchKeys,\n event,\n matchPattern,\n createPatternPart,\n )\n}\n\nexport function collectRootSequenceCaptures<TTarget extends object, TEvent extends KeymapEvent>(\n layer: RegisteredLayer<TTarget, TEvent>,\n matchKeys: readonly KeyMatch[],\n event: TEvent,\n matchPattern: (patternName: string, event: TEvent) => SequencePatternMatch | undefined,\n createPatternPart: (event: TEvent, patternName: string, match: SequencePatternMatch) => KeySequencePart,\n): PendingSequenceCapture<TTarget, TEvent>[] {\n const captures: PendingSequenceCapture<TTarget, TEvent>[] = []\n let bestPriority = Number.POSITIVE_INFINITY\n for (const binding of layer.bindings) {\n if (binding.event !== \"press\") {\n continue\n }\n\n const capture = advanceSequenceBinding(\n layer,\n binding,\n 0,\n [],\n undefined,\n matchKeys,\n event,\n matchPattern,\n createPatternPart,\n )\n if (!capture) {\n continue\n }\n\n const priority = capturePriority(capture, matchKeys)\n if (priority < bestPriority) {\n bestPriority = priority\n captures.length = 0\n }\n\n if (priority === bestPriority) {\n captures.push(capture)\n }\n }\n\n return captures\n}\n"
|
|
10
|
+
],
|
|
11
|
+
"mappings": "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",
|
|
12
|
+
"debugId": "0DF84866F5B467C964756E2164756E21",
|
|
13
|
+
"names": []
|
|
14
|
+
}
|