@witchcraft/spellcraft 0.2.0 → 0.2.1
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/dist/core/createManager.js +3 -2
- package/dist/core/createShortcuts.d.ts +1 -1
- package/dist/helpers/doesShortcutConflict.js +14 -2
- package/dist/module.json +1 -1
- package/dist/runtime/utils/shortcutToId.d.ts +1 -1
- package/dist/runtime/utils/shortcutToId.js +8 -6
- package/dist/types/manager.d.ts +2 -1
- package/package.json +3 -3
- package/src/core/createManager.ts +3 -2
- package/src/core/createShortcuts.ts +1 -1
- package/src/helpers/doesShortcutConflict.ts +17 -2
- package/src/runtime/utils/shortcutToId.ts +9 -7
- package/src/types/manager.ts +2 -1
|
@@ -51,7 +51,7 @@ export function createManager(rawManager, additionalOpts = {}) {
|
|
|
51
51
|
if (!shortcuts || isArray(shortcuts)) {
|
|
52
52
|
castType(shortcuts);
|
|
53
53
|
const shortcutsList = [];
|
|
54
|
-
const m2 = { ...m, commands, keys };
|
|
54
|
+
const m2 = { ...m, commands, keys, context: rawManager.context };
|
|
55
55
|
if (shortcuts) {
|
|
56
56
|
for (const shortcut of shortcuts) {
|
|
57
57
|
const res2 = createShortcut(shortcut, m2);
|
|
@@ -62,7 +62,8 @@ export function createManager(rawManager, additionalOpts = {}) {
|
|
|
62
62
|
const res = createShortcuts(shortcutsList, {
|
|
63
63
|
keys,
|
|
64
64
|
commands,
|
|
65
|
-
options
|
|
65
|
+
options,
|
|
66
|
+
context: rawManager.context
|
|
66
67
|
}, additionalOpts?.shortcuts);
|
|
67
68
|
if (res.isError) return res;
|
|
68
69
|
shortcuts = res.value;
|
|
@@ -6,7 +6,7 @@ import type { CanHookErrors, Manager, MultipleErrors, PickManager, Shortcut, Sho
|
|
|
6
6
|
* Creates a set of shortcuts.
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
|
-
export declare function createShortcuts<THooks extends Manager["hooks"], TRawShortcuts extends Shortcut[], TCheck extends boolean | "only" = true>(shortcutsList: TRawShortcuts, manager: Pick<Manager, "keys" | "commands"> & PickManager<"options", "evaluateCondition" | "conditionEquals" | "stringifier" | "sorter" | "shortcutEqualityStrategy"> & {
|
|
9
|
+
export declare function createShortcuts<THooks extends Manager["hooks"], TRawShortcuts extends Shortcut[], TCheck extends boolean | "only" = true>(shortcutsList: TRawShortcuts, manager: Pick<Manager, "keys" | "commands" | "context"> & PickManager<"options", "evaluateCondition" | "conditionEquals" | "stringifier" | "sorter" | "shortcutEqualityStrategy"> & {
|
|
10
10
|
hooks?: THooks;
|
|
11
11
|
}, opts?: Partial<Pick<Shortcuts, "ignoreModifierConflicts" | "ignoreChainConflicts">>, { check }?: {
|
|
12
12
|
check?: boolean | "only";
|
|
@@ -16,15 +16,27 @@ export function doesShortcutConflict(shortcutA, shortcutB, manager) {
|
|
|
16
16
|
if (equalsShortcut(shortcutA, shortcutB, manager)) return true;
|
|
17
17
|
const evaluateCondition = manager.options.evaluateCondition;
|
|
18
18
|
const conditionEquals = manager.options.conditionEquals;
|
|
19
|
+
const commandA = shortcutA.command ? manager.commands.entries[shortcutA.command] : void 0;
|
|
20
|
+
const commandB = shortcutB.command ? manager.commands.entries[shortcutB.command] : void 0;
|
|
21
|
+
if ((shortcutA.condition || shortcutB.condition || commandA?.condition || commandB?.condition) && context === void 0) {
|
|
22
|
+
console.warn("Condition comparisons will not work without a context (the base conditionComparer is still used).");
|
|
23
|
+
}
|
|
19
24
|
if (context) {
|
|
20
25
|
if (shortcutA.condition && shortcutB.condition) {
|
|
21
26
|
const shortcutCondition = evaluateCondition(shortcutA.condition, context);
|
|
22
27
|
const otherCondition = evaluateCondition(shortcutB.condition, context);
|
|
23
|
-
if (shortcutCondition !== otherCondition) return false;
|
|
24
|
-
|
|
28
|
+
if (!shortcutCondition || shortcutCondition !== otherCondition) return false;
|
|
29
|
+
}
|
|
30
|
+
if (commandA?.condition && commandB?.condition) {
|
|
31
|
+
const commandCondition = evaluateCondition(commandA.condition, context);
|
|
32
|
+
const otherCondition = evaluateCondition(commandB.condition, context);
|
|
33
|
+
if (!commandCondition || commandCondition !== otherCondition) return false;
|
|
25
34
|
}
|
|
26
35
|
} else {
|
|
27
36
|
if (!conditionEquals(shortcutA.condition, shortcutB.condition, "shortcut")) return false;
|
|
37
|
+
if (commandA?.condition && commandB?.condition) {
|
|
38
|
+
if (!conditionEquals(commandA?.condition, commandB?.condition, "command")) return false;
|
|
39
|
+
}
|
|
28
40
|
}
|
|
29
41
|
const { keys } = manager;
|
|
30
42
|
if (shortcutA.chain.length === 0 || shortcutB.chain.length === 0) {
|
package/dist/module.json
CHANGED
|
@@ -2,4 +2,4 @@ import type { PickManager } from "../../types/general.js";
|
|
|
2
2
|
import type { Manager } from "../../types/manager.js";
|
|
3
3
|
import type { Shortcut } from "../../types/shortcuts.js";
|
|
4
4
|
/** Turns a shortcut into an id to use in a v-for loop. */
|
|
5
|
-
export declare
|
|
5
|
+
export declare function shortcutToId(shortcut: Shortcut, manager: PickManager<"options", "stringifier"> & Pick<Manager, "keys">): string;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export function shortcutToId(shortcut, manager) {
|
|
2
|
+
return [
|
|
3
|
+
shortcut.enabled,
|
|
4
|
+
manager.options.stringifier.stringify(shortcut.chain, manager),
|
|
5
|
+
shortcut.command ?? "",
|
|
6
|
+
shortcut.condition.text
|
|
7
|
+
].join("--");
|
|
8
|
+
}
|
package/dist/types/manager.d.ts
CHANGED
|
@@ -124,8 +124,9 @@ export type Manager<THooks extends Partial<Hooks> = Partial<Hooks>, TKeys extend
|
|
|
124
124
|
*
|
|
125
125
|
* - `ignoreCommand` (default) will ignore both shortcuts' commands. If everything else is equal, they are considered equal.
|
|
126
126
|
* - `ignoreCommandWithDifferentCondition` will ignore both commands' names and only compare their conditions. If everything else is equal, they are considered equal. Use it if you allow command conditions to equal eachother. See {@link ConditionComparer} for details.
|
|
127
|
-
* - `all` will compare everything.
|
|
127
|
+
* - `all` will compare everything. Useful for finding an exact shortcut match. Should not be used when comparing shortcuts to find conflicts as it will allow shortcuts with the same chain but different commands to not be equal.
|
|
128
128
|
*
|
|
129
|
+
* Note that regardless of this setting shortcut conflicts can arise for other reasons due to `doesShortcutConflict` which checks other conditions.
|
|
129
130
|
*/
|
|
130
131
|
shortcutEqualityStrategy: "ignoreCommand" | "ignoreCommandWithDifferentCondition" | "all";
|
|
131
132
|
/** Determines how conditions are evaluated. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@witchcraft/spellcraft",
|
|
3
3
|
"description": "A shortcut manager library for handling ALL the shortcut needs of an application.",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/core/index.js",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@witchcraft/expressit": "^0.4.2",
|
|
43
|
-
"@witchcraft/ui": "^0.3.
|
|
43
|
+
"@witchcraft/ui": "^0.3.24"
|
|
44
44
|
},
|
|
45
45
|
"peerDependenciesMeta": {
|
|
46
46
|
"@witchcraft/ui": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@alanscodelog/utils": "^6.0.2",
|
|
55
55
|
"@witchcraft/expressit": "^0.4.2",
|
|
56
|
-
"@witchcraft/ui": "^0.3.
|
|
56
|
+
"@witchcraft/ui": "^0.3.24",
|
|
57
57
|
"reka-ui": "^2.8.0",
|
|
58
58
|
"vue": "^3.5.27"
|
|
59
59
|
},
|
|
@@ -175,7 +175,7 @@ export function createManager<
|
|
|
175
175
|
if (!shortcuts || isArray(shortcuts)) {
|
|
176
176
|
castType<RawShortcut[]>(shortcuts)
|
|
177
177
|
const shortcutsList: Shortcut[] = []
|
|
178
|
-
const m2 = { ...m, commands: commands as Commands, keys: keys as Keys }
|
|
178
|
+
const m2 = { ...m, commands: commands as Commands, keys: keys as Keys, context: rawManager.context! }
|
|
179
179
|
if (shortcuts) {
|
|
180
180
|
for (const shortcut of shortcuts) {
|
|
181
181
|
const res = createShortcut(shortcut, m2)
|
|
@@ -187,7 +187,8 @@ export function createManager<
|
|
|
187
187
|
const res = createShortcuts(shortcutsList, {
|
|
188
188
|
keys: keys! as Keys,
|
|
189
189
|
commands: commands! as Commands,
|
|
190
|
-
options
|
|
190
|
+
options,
|
|
191
|
+
context: rawManager.context!
|
|
191
192
|
}, additionalOpts?.shortcuts)
|
|
192
193
|
if (res.isError) return res as any
|
|
193
194
|
shortcuts = res.value satisfies Shortcuts as any
|
|
@@ -16,7 +16,7 @@ export function createShortcuts<
|
|
|
16
16
|
TCheck extends boolean | "only" = true
|
|
17
17
|
>(
|
|
18
18
|
shortcutsList: TRawShortcuts,
|
|
19
|
-
manager: Pick<Manager, "keys" | "commands">
|
|
19
|
+
manager: Pick<Manager, "keys" | "commands" | "context">
|
|
20
20
|
& PickManager<"options", | "evaluateCondition" | "conditionEquals" | "stringifier" | "sorter" | "shortcutEqualityStrategy">
|
|
21
21
|
& { hooks?: THooks },
|
|
22
22
|
opts?: Partial<Pick<Shortcuts, "ignoreModifierConflicts" | "ignoreChainConflicts">>,
|
|
@@ -39,15 +39,30 @@ export function doesShortcutConflict<TShortcut extends Shortcut>(
|
|
|
39
39
|
if (equalsShortcut(shortcutA, shortcutB, manager)) return true
|
|
40
40
|
const evaluateCondition = manager.options.evaluateCondition
|
|
41
41
|
const conditionEquals = manager.options.conditionEquals
|
|
42
|
+
|
|
43
|
+
const commandA = shortcutA.command ? manager.commands.entries[shortcutA.command] : undefined
|
|
44
|
+
const commandB = shortcutB.command ? manager.commands.entries[shortcutB.command] : undefined
|
|
45
|
+
|
|
46
|
+
if ((shortcutA.condition || shortcutB.condition || commandA?.condition || commandB?.condition) && context === undefined) {
|
|
47
|
+
// eslint-disable-next-line no-console
|
|
48
|
+
console.warn("Condition comparisons will not work without a context (the base conditionComparer is still used).")
|
|
49
|
+
}
|
|
42
50
|
if (context) {
|
|
43
51
|
if (shortcutA.condition && shortcutB.condition) {
|
|
44
52
|
const shortcutCondition = evaluateCondition(shortcutA.condition, context)
|
|
45
53
|
const otherCondition = evaluateCondition(shortcutB.condition, context)
|
|
46
|
-
if (shortcutCondition !== otherCondition) return false
|
|
47
|
-
|
|
54
|
+
if (!shortcutCondition || shortcutCondition !== otherCondition) return false
|
|
55
|
+
}
|
|
56
|
+
if (commandA?.condition && commandB?.condition) {
|
|
57
|
+
const commandCondition = evaluateCondition(commandA.condition, context)
|
|
58
|
+
const otherCondition = evaluateCondition(commandB.condition, context)
|
|
59
|
+
if (!commandCondition || commandCondition !== otherCondition) return false
|
|
48
60
|
}
|
|
49
61
|
} else {
|
|
50
62
|
if (!conditionEquals(shortcutA.condition, shortcutB.condition, "shortcut")) return false
|
|
63
|
+
if (commandA?.condition && commandB?.condition) {
|
|
64
|
+
if (!conditionEquals(commandA?.condition, commandB?.condition, "command")) return false
|
|
65
|
+
}
|
|
51
66
|
}
|
|
52
67
|
const { keys } = manager
|
|
53
68
|
// an empty chain is always in conflict ?
|
|
@@ -3,12 +3,14 @@ import type { Manager } from "../../types/manager.js"
|
|
|
3
3
|
import type { Shortcut } from "../../types/shortcuts.js"
|
|
4
4
|
|
|
5
5
|
/** Turns a shortcut into an id to use in a v-for loop. */
|
|
6
|
-
export
|
|
6
|
+
export function shortcutToId(
|
|
7
7
|
shortcut: Shortcut,
|
|
8
8
|
manager: PickManager<"options", "stringifier"> & Pick<Manager, "keys">
|
|
9
|
-
): string
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
): string {
|
|
10
|
+
return [
|
|
11
|
+
shortcut.enabled,
|
|
12
|
+
manager.options.stringifier.stringify(shortcut.chain, manager),
|
|
13
|
+
shortcut.command ?? "",
|
|
14
|
+
shortcut.condition.text
|
|
15
|
+
].join("--")
|
|
16
|
+
}
|
package/src/types/manager.ts
CHANGED
|
@@ -222,8 +222,9 @@ export type Manager<
|
|
|
222
222
|
*
|
|
223
223
|
* - `ignoreCommand` (default) will ignore both shortcuts' commands. If everything else is equal, they are considered equal.
|
|
224
224
|
* - `ignoreCommandWithDifferentCondition` will ignore both commands' names and only compare their conditions. If everything else is equal, they are considered equal. Use it if you allow command conditions to equal eachother. See {@link ConditionComparer} for details.
|
|
225
|
-
* - `all` will compare everything.
|
|
225
|
+
* - `all` will compare everything. Useful for finding an exact shortcut match. Should not be used when comparing shortcuts to find conflicts as it will allow shortcuts with the same chain but different commands to not be equal.
|
|
226
226
|
*
|
|
227
|
+
* Note that regardless of this setting shortcut conflicts can arise for other reasons due to `doesShortcutConflict` which checks other conditions.
|
|
227
228
|
*/
|
|
228
229
|
shortcutEqualityStrategy: "ignoreCommand" | "ignoreCommandWithDifferentCondition" | "all"
|
|
229
230
|
|