@spyglassmc/mcfunction 0.2.9 → 0.2.10
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/lib/completer/index.d.ts +2 -2
- package/lib/completer/index.js +3 -1
- package/lib/node/command.d.ts +6 -1
- package/lib/node/command.js +2 -2
- package/lib/parser/argument.d.ts +2 -1
- package/lib/parser/command.d.ts +2 -2
- package/lib/parser/command.js +16 -2
- package/lib/parser/entry.d.ts +7 -10
- package/lib/parser/entry.js +6 -11
- package/lib/parser/macro.js +1 -1
- package/package.json +3 -3
package/lib/completer/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
|
-
import type { McfunctionNode } from '../node/index.js';
|
|
2
|
+
import type { CommandChildNode, McfunctionNode } from '../node/index.js';
|
|
3
3
|
import { CommandNode } from '../node/index.js';
|
|
4
4
|
import type { ArgumentTreeNode, RootTreeNode } from '../tree/index.js';
|
|
5
|
-
export type MockNodesGetter = (treeNode: ArgumentTreeNode, range: core.CompleterContext) => core.Arrayable<core.AstNode>;
|
|
5
|
+
export type MockNodesGetter = (treeNode: ArgumentTreeNode, prevNodes: CommandChildNode[], range: core.CompleterContext) => core.Arrayable<core.AstNode>;
|
|
6
6
|
/**
|
|
7
7
|
* @param getMockNodes A function that returns a mock AST Node from given {@link ArgumentTreeNode}. These mock nodes
|
|
8
8
|
* will be used for completing the argument.
|
package/lib/completer/index.js
CHANGED
|
@@ -34,9 +34,11 @@ export function command(tree, getMockNodes) {
|
|
|
34
34
|
return [];
|
|
35
35
|
}
|
|
36
36
|
const { literalTreeNodes, argumentTreeNodes } = categorizeTreeChildren(parentTreeNode.children);
|
|
37
|
+
const lastIndex = node.children.indexOf(lastChildNode);
|
|
38
|
+
const prevNodes = node.children.slice(0, lastIndex + 1);
|
|
37
39
|
return [
|
|
38
40
|
...literalTreeNodes.map(([name]) => core.CompletionItem.create(name, ctx.offset, { kind: 14 /* core.CompletionKind.Keyword */ })),
|
|
39
|
-
...argumentTreeNodes.flatMap(([_name, treeNode]) => core.Arrayable.toArray(getMockNodes(treeNode, ctx)).flatMap((n) => core.completer.dispatch(n, ctx))),
|
|
41
|
+
...argumentTreeNodes.flatMap(([_name, treeNode]) => core.Arrayable.toArray(getMockNodes(treeNode, prevNodes, ctx)).flatMap((n) => core.completer.dispatch(n, ctx))),
|
|
40
42
|
];
|
|
41
43
|
};
|
|
42
44
|
}
|
package/lib/node/command.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
|
+
export interface CommandOptions {
|
|
3
|
+
slash?: 'allowed' | 'required';
|
|
4
|
+
maxLength?: number;
|
|
5
|
+
}
|
|
2
6
|
export interface CommandNode extends core.SequenceNode<CommandChildNode> {
|
|
3
7
|
type: 'mcfunction:command';
|
|
8
|
+
readonly options: CommandOptions;
|
|
4
9
|
slash?: core.Range;
|
|
5
10
|
}
|
|
6
11
|
export declare namespace CommandNode {
|
|
7
12
|
function is<T extends core.DeepReadonly<core.AstNode> | undefined>(node: T): node is core.InheritReadonly<CommandNode, T>;
|
|
8
|
-
function mock(range: core.RangeLike): CommandNode;
|
|
13
|
+
function mock(range: core.RangeLike, options?: CommandOptions): CommandNode;
|
|
9
14
|
}
|
|
10
15
|
export interface CommandChildNode extends core.AstNode {
|
|
11
16
|
type: 'mcfunction:command_child';
|
package/lib/node/command.js
CHANGED
|
@@ -6,8 +6,8 @@ export var CommandNode;
|
|
|
6
6
|
return node?.type === 'mcfunction:command';
|
|
7
7
|
}
|
|
8
8
|
CommandNode.is = is;
|
|
9
|
-
function mock(range) {
|
|
10
|
-
return { type: 'mcfunction:command', range: core.Range.get(range), children: [] };
|
|
9
|
+
function mock(range, options = {}) {
|
|
10
|
+
return { type: 'mcfunction:command', range: core.Range.get(range), children: [], options };
|
|
11
11
|
}
|
|
12
12
|
CommandNode.mock = mock;
|
|
13
13
|
})(CommandNode || (CommandNode = {}));
|
package/lib/parser/argument.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type * as core from '@spyglassmc/core';
|
|
2
|
+
import type { CommandChildNode } from '../node/command.js';
|
|
2
3
|
import type { ArgumentTreeNode } from '../tree/index.js';
|
|
3
4
|
/**
|
|
4
5
|
* A function that returns a parser for the provided tree node.
|
|
@@ -7,6 +8,6 @@ import type { ArgumentTreeNode } from '../tree/index.js';
|
|
|
7
8
|
*
|
|
8
9
|
* @returns The parser corresponding to that tree node, or `undefined` if such parser doesn't exist.
|
|
9
10
|
*/
|
|
10
|
-
export type ArgumentParserGetter = (treeNode: ArgumentTreeNode) => core.Parser | undefined;
|
|
11
|
+
export type ArgumentParserGetter = (treeNode: ArgumentTreeNode, prevNodes: CommandChildNode[]) => core.Parser | undefined;
|
|
11
12
|
export declare function argumentTreeNodeToString(name: string, treeNode: ArgumentTreeNode): string;
|
|
12
13
|
//# sourceMappingURL=argument.d.ts.map
|
package/lib/parser/command.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
|
-
import type { CommandNode } from '../node/index.js';
|
|
2
|
+
import type { CommandNode, CommandOptions } from '../node/index.js';
|
|
3
3
|
import type { RootTreeNode, TreeNode } from '../tree/type.js';
|
|
4
4
|
import type { ArgumentParserGetter } from './argument.js';
|
|
5
5
|
/**
|
|
6
6
|
* @returns A parser that always takes a whole line (excluding line turn characters) and tries to parse it as a command.
|
|
7
7
|
*/
|
|
8
|
-
export declare function command(tree: RootTreeNode, argument: ArgumentParserGetter): core.InfallibleParser<CommandNode>;
|
|
8
|
+
export declare function command(tree: RootTreeNode, argument: ArgumentParserGetter, options?: CommandOptions): core.InfallibleParser<CommandNode>;
|
|
9
9
|
export declare function treeNodeChildrenToStringArray(children: Exclude<TreeNode['children'], undefined>, executable?: boolean): string[];
|
|
10
10
|
export declare function treeNodeChildrenToString(children: Exclude<TreeNode['children'], undefined>): string;
|
|
11
11
|
export declare function treeNodeToString(name: string, treeNode: TreeNode): string;
|
package/lib/parser/command.js
CHANGED
|
@@ -7,16 +7,24 @@ import { literal } from './literal.js';
|
|
|
7
7
|
/**
|
|
8
8
|
* @returns A parser that always takes a whole line (excluding line turn characters) and tries to parse it as a command.
|
|
9
9
|
*/
|
|
10
|
-
export function command(tree, argument) {
|
|
10
|
+
export function command(tree, argument, options = {}) {
|
|
11
11
|
return (src, ctx) => {
|
|
12
12
|
const ans = {
|
|
13
13
|
type: 'mcfunction:command',
|
|
14
14
|
range: core.Range.create(src),
|
|
15
15
|
children: [],
|
|
16
|
+
options,
|
|
16
17
|
};
|
|
17
18
|
const start = src.cursor;
|
|
19
|
+
const innerStart = src.innerCursor;
|
|
18
20
|
if (src.trySkip('/')) {
|
|
19
21
|
ans.slash = core.Range.create(start, src.cursor);
|
|
22
|
+
if (!options.slash) {
|
|
23
|
+
ctx.err.report(localize('mcfunction.parser.leading-slash.unexpected'), ans.slash);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (options.slash === 'required') {
|
|
27
|
+
ctx.err.report(localize('expected', localize('mcfunction.parser.leading-slash')), core.Range.create(start, start + 1));
|
|
20
28
|
}
|
|
21
29
|
dispatch(ans.children, src, ctx, [], tree, tree, argument);
|
|
22
30
|
if (src.canReadInLine()) {
|
|
@@ -30,6 +38,12 @@ export function command(tree, argument) {
|
|
|
30
38
|
});
|
|
31
39
|
}
|
|
32
40
|
ans.range.end = src.cursor;
|
|
41
|
+
if (options.maxLength) {
|
|
42
|
+
const commandLength = src.innerCursor - innerStart;
|
|
43
|
+
if (commandLength > options.maxLength) {
|
|
44
|
+
ctx.err.report(localize('mcfunction.parser.command-too-long', commandLength, options.maxLength), ans);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
33
47
|
return ans;
|
|
34
48
|
};
|
|
35
49
|
}
|
|
@@ -48,7 +62,7 @@ function dispatch(ans, src, ctx, path, rootTreeNode, parentTreeNode, argument) {
|
|
|
48
62
|
return false;
|
|
49
63
|
}
|
|
50
64
|
const { literalTreeNodes, argumentTreeNodes } = categorizeTreeChildren(children);
|
|
51
|
-
const argumentParsers = argumentTreeNodes.map(([name, treeNode]) => ({ name, parser: argument(treeNode) ?? unknown(treeNode) }));
|
|
65
|
+
const argumentParsers = argumentTreeNodes.map(([name, treeNode]) => ({ name, parser: argument(treeNode, ans) ?? unknown(treeNode) }));
|
|
52
66
|
const literalParser = literalTreeNodes.length
|
|
53
67
|
? literal(literalTreeNodes.map(([name, _treeNode]) => name), parent.type === 'root')
|
|
54
68
|
: undefined;
|
package/lib/parser/entry.d.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
|
-
import type { McfunctionNode } from '../node/index.js';
|
|
2
|
+
import type { CommandOptions, McfunctionNode } from '../node/index.js';
|
|
3
3
|
import type { RootTreeNode } from '../tree/index.js';
|
|
4
4
|
import type { ArgumentParserGetter } from './argument.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export declare const entry: (commandTree: RootTreeNode, argument: ArgumentParserGetter,
|
|
11
|
-
supportsBackslashContinuation?: boolean | undefined;
|
|
12
|
-
supportsMacros?: boolean | undefined;
|
|
13
|
-
}) => core.Parser<McfunctionNode>;
|
|
5
|
+
export interface McfunctionOptions {
|
|
6
|
+
lineContinuation?: boolean;
|
|
7
|
+
macros?: boolean;
|
|
8
|
+
commandOptions?: CommandOptions;
|
|
9
|
+
}
|
|
10
|
+
export declare const entry: (commandTree: RootTreeNode, argument: ArgumentParserGetter, options?: McfunctionOptions) => core.Parser<McfunctionNode>;
|
|
14
11
|
//# sourceMappingURL=entry.d.ts.map
|
package/lib/parser/entry.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as core from '@spyglassmc/core';
|
|
2
2
|
import { command } from './command.js';
|
|
3
3
|
import { macro } from './macro.js';
|
|
4
|
-
function mcfunction(commandTree, argument,
|
|
4
|
+
function mcfunction(commandTree, argument, options) {
|
|
5
5
|
return (src, ctx) => {
|
|
6
6
|
const ans = {
|
|
7
7
|
type: 'mcfunction:entry',
|
|
@@ -14,10 +14,10 @@ function mcfunction(commandTree, argument, { supportsMacros }) {
|
|
|
14
14
|
result = comment(src, ctx);
|
|
15
15
|
}
|
|
16
16
|
else if (src.peek() === '$') {
|
|
17
|
-
result = macro(
|
|
17
|
+
result = macro(options.macros ?? false)(src, ctx);
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
|
-
result = command(commandTree, argument)(src, ctx);
|
|
20
|
+
result = command(commandTree, argument, options.commandOptions)(src, ctx);
|
|
21
21
|
}
|
|
22
22
|
ans.children.push(result);
|
|
23
23
|
src.nextLine();
|
|
@@ -27,13 +27,8 @@ function mcfunction(commandTree, argument, { supportsMacros }) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
const comment = core.comment({ singleLinePrefixes: new Set(['#']) });
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* Disabled by default.
|
|
34
|
-
*/
|
|
35
|
-
export const entry = (commandTree, argument, { supportsBackslashContinuation = false, supportsMacros = false } = {}) => {
|
|
36
|
-
const parser = mcfunction(commandTree, argument, { supportsMacros });
|
|
37
|
-
return supportsBackslashContinuation ? core.concatOnTrailingBackslash(parser) : parser;
|
|
30
|
+
export const entry = (commandTree, argument, options = {}) => {
|
|
31
|
+
const parser = mcfunction(commandTree, argument, options);
|
|
32
|
+
return options.lineContinuation ? core.concatOnTrailingBackslash(parser) : parser;
|
|
38
33
|
};
|
|
39
34
|
//# sourceMappingURL=entry.js.map
|
package/lib/parser/macro.js
CHANGED
|
@@ -74,7 +74,7 @@ function validateMacroArgument(src, ctx, start) {
|
|
|
74
74
|
src.skip(2);
|
|
75
75
|
const keyStart = src.cursor;
|
|
76
76
|
src.skipUntilOrEnd(core.LF, core.CR, ')');
|
|
77
|
-
if (src.peek()
|
|
77
|
+
if (src.peek() !== ')') {
|
|
78
78
|
// Macro key was not closed
|
|
79
79
|
ctx.err.report(localize('expected', localeQuote(')')), core.Range.create(keyStart, src.cursor));
|
|
80
80
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spyglassmc/mcfunction",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"url": "https://github.com/SpyglassMC/Spyglass/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@spyglassmc/core": "0.4.
|
|
29
|
-
"@spyglassmc/locales": "0.3.
|
|
28
|
+
"@spyglassmc/core": "0.4.8",
|
|
29
|
+
"@spyglassmc/locales": "0.3.8"
|
|
30
30
|
}
|
|
31
31
|
}
|