@seljs/editor 1.0.0 → 1.0.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/CHANGELOG.md +7 -0
- package/dist/completion/completion-items.cjs +36 -0
- package/dist/completion/completion-items.mjs +32 -0
- package/dist/completion/index.cjs +1 -0
- package/dist/completion/index.d.mts +1 -0
- package/dist/completion/index.mjs +2 -0
- package/dist/completion/schema-completion.cjs +182 -0
- package/dist/completion/schema-completion.d.cts +25 -0
- package/dist/completion/schema-completion.d.mts +25 -0
- package/dist/completion/schema-completion.mjs +181 -0
- package/dist/completion/tree-context.cjs +108 -0
- package/dist/completion/tree-context.mjs +108 -0
- package/dist/editor/create-editor.cjs +16 -0
- package/dist/editor/create-editor.d.cts +7 -0
- package/dist/editor/create-editor.d.mts +7 -0
- package/dist/editor/create-editor.mjs +16 -0
- package/dist/editor/editor-config.cjs +49 -0
- package/dist/editor/editor-config.d.cts +7 -0
- package/dist/editor/editor-config.d.mts +7 -0
- package/dist/editor/editor-config.mjs +49 -0
- package/dist/editor/index.cjs +3 -0
- package/dist/editor/index.d.cts +6 -0
- package/dist/editor/index.d.mts +6 -0
- package/dist/editor/index.mjs +4 -0
- package/dist/editor/theme.cjs +35 -0
- package/dist/editor/theme.d.cts +7 -0
- package/dist/editor/theme.d.mts +7 -0
- package/dist/editor/theme.mjs +34 -0
- package/dist/editor/type-display.cjs +71 -0
- package/dist/editor/type-display.mjs +71 -0
- package/dist/editor/types.d.cts +31 -0
- package/dist/editor/types.d.mts +31 -0
- package/dist/index.cjs +20 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.mjs +11 -0
- package/dist/language/semantic-highlighter.cjs +55 -0
- package/dist/language/semantic-highlighter.mjs +55 -0
- package/dist/language/tokenizer-config.cjs +9 -0
- package/dist/language/tokenizer-config.d.cts +12 -0
- package/dist/language/tokenizer-config.d.mts +12 -0
- package/dist/language/tokenizer-config.mjs +9 -0
- package/dist/linting/diagnostic-mapper.cjs +37 -0
- package/dist/linting/{diagnostic-mapper.d.ts → diagnostic-mapper.d.cts} +7 -6
- package/dist/linting/diagnostic-mapper.d.mts +29 -0
- package/dist/linting/diagnostic-mapper.mjs +37 -0
- package/dist/linting/index.cjs +2 -0
- package/dist/linting/index.d.mts +2 -0
- package/dist/linting/index.mjs +3 -0
- package/dist/linting/sel-linter.cjs +28 -0
- package/dist/linting/sel-linter.d.cts +13 -0
- package/dist/linting/sel-linter.d.mts +13 -0
- package/dist/linting/sel-linter.mjs +28 -0
- package/package.json +29 -22
- package/dist/completion/completion-items.d.ts +0 -8
- package/dist/completion/completion-items.d.ts.map +0 -1
- package/dist/completion/completion-items.js +0 -29
- package/dist/completion/index.d.ts +0 -2
- package/dist/completion/index.d.ts.map +0 -1
- package/dist/completion/index.js +0 -1
- package/dist/completion/schema-completion.d.ts +0 -22
- package/dist/completion/schema-completion.d.ts.map +0 -1
- package/dist/completion/schema-completion.js +0 -220
- package/dist/completion/tree-context.d.ts +0 -23
- package/dist/completion/tree-context.d.ts.map +0 -1
- package/dist/completion/tree-context.js +0 -154
- package/dist/editor/create-editor.d.ts +0 -4
- package/dist/editor/create-editor.d.ts.map +0 -1
- package/dist/editor/create-editor.js +0 -14
- package/dist/editor/editor-config.d.ts +0 -4
- package/dist/editor/editor-config.d.ts.map +0 -1
- package/dist/editor/editor-config.js +0 -64
- package/dist/editor/index.d.ts +0 -6
- package/dist/editor/index.d.ts.map +0 -1
- package/dist/editor/index.js +0 -3
- package/dist/editor/theme.d.ts +0 -3
- package/dist/editor/theme.d.ts.map +0 -1
- package/dist/editor/theme.js +0 -43
- package/dist/editor/type-display.d.ts +0 -4
- package/dist/editor/type-display.d.ts.map +0 -1
- package/dist/editor/type-display.js +0 -75
- package/dist/editor/types.d.ts +0 -28
- package/dist/editor/types.d.ts.map +0 -1
- package/dist/editor/types.js +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -4
- package/dist/language/index.d.ts +0 -2
- package/dist/language/index.d.ts.map +0 -1
- package/dist/language/index.js +0 -1
- package/dist/language/semantic-highlighter.d.ts +0 -4
- package/dist/language/semantic-highlighter.d.ts.map +0 -1
- package/dist/language/semantic-highlighter.js +0 -76
- package/dist/language/tokenizer-config.d.ts +0 -9
- package/dist/language/tokenizer-config.d.ts.map +0 -1
- package/dist/language/tokenizer-config.js +0 -6
- package/dist/linting/diagnostic-mapper.d.ts.map +0 -1
- package/dist/linting/diagnostic-mapper.js +0 -46
- package/dist/linting/index.d.ts +0 -3
- package/dist/linting/index.d.ts.map +0 -1
- package/dist/linting/index.js +0 -2
- package/dist/linting/sel-linter.d.ts +0 -12
- package/dist/linting/sel-linter.d.ts.map +0 -1
- package/dist/linting/sel-linter.js +0 -28
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
let _codemirror_language = require("@codemirror/language");
|
|
2
|
+
let _codemirror_state = require("@codemirror/state");
|
|
3
|
+
let _codemirror_view = require("@codemirror/view");
|
|
4
|
+
//#region src/language/semantic-highlighter.ts
|
|
5
|
+
const LIGHT_COLORS = {
|
|
6
|
+
contract: "#00695c",
|
|
7
|
+
function: "#1565c0",
|
|
8
|
+
macro: "#6a1b9a",
|
|
9
|
+
variable: "#37474f"
|
|
10
|
+
};
|
|
11
|
+
const DARK_COLORS = {
|
|
12
|
+
contract: "#4db6ac",
|
|
13
|
+
function: "#64b5f6",
|
|
14
|
+
macro: "#ce93d8",
|
|
15
|
+
variable: "#b0bec5"
|
|
16
|
+
};
|
|
17
|
+
const createDecorations = (dark) => {
|
|
18
|
+
const colors = dark ? DARK_COLORS : LIGHT_COLORS;
|
|
19
|
+
return {
|
|
20
|
+
contract: _codemirror_view.Decoration.mark({ attributes: { style: `color: ${colors.contract}` } }),
|
|
21
|
+
function: _codemirror_view.Decoration.mark({ attributes: { style: `color: ${colors.function}` } }),
|
|
22
|
+
macro: _codemirror_view.Decoration.mark({ attributes: { style: `color: ${colors.macro}` } }),
|
|
23
|
+
variable: _codemirror_view.Decoration.mark({ attributes: { style: `color: ${colors.variable}` } })
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const buildDecorations = (view, config, decos) => {
|
|
27
|
+
const builder = new _codemirror_state.RangeSetBuilder();
|
|
28
|
+
const tree = (0, _codemirror_language.syntaxTree)(view.state);
|
|
29
|
+
for (const { from, to } of view.visibleRanges) tree.iterate({
|
|
30
|
+
from,
|
|
31
|
+
to,
|
|
32
|
+
enter(node) {
|
|
33
|
+
if (node.name !== "Identifier") return;
|
|
34
|
+
const name = view.state.doc.sliceString(node.from, node.to);
|
|
35
|
+
let deco;
|
|
36
|
+
if (config.contractNames.has(name)) deco = decos.contract;
|
|
37
|
+
else if (config.functionNames.has(name)) deco = decos.function;
|
|
38
|
+
else if (config.macroNames.has(name)) deco = decos.macro;
|
|
39
|
+
else if (config.variableNames.has(name)) deco = decos.variable;
|
|
40
|
+
if (deco) builder.add(node.from, node.to, deco);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return builder.finish();
|
|
44
|
+
};
|
|
45
|
+
const createSemanticHighlighter = function(config, dark = false) {
|
|
46
|
+
const decos = createDecorations(dark);
|
|
47
|
+
return _codemirror_view.ViewPlugin.define((view) => ({
|
|
48
|
+
decorations: buildDecorations(view, config, decos),
|
|
49
|
+
update(update) {
|
|
50
|
+
if (update.docChanged || update.viewportChanged) this.decorations = buildDecorations(update.view, config, decos);
|
|
51
|
+
}
|
|
52
|
+
}), { decorations: (v) => v.decorations });
|
|
53
|
+
};
|
|
54
|
+
//#endregion
|
|
55
|
+
exports.createSemanticHighlighter = createSemanticHighlighter;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { syntaxTree } from "@codemirror/language";
|
|
2
|
+
import { RangeSetBuilder } from "@codemirror/state";
|
|
3
|
+
import { Decoration, ViewPlugin } from "@codemirror/view";
|
|
4
|
+
//#region src/language/semantic-highlighter.ts
|
|
5
|
+
const LIGHT_COLORS = {
|
|
6
|
+
contract: "#00695c",
|
|
7
|
+
function: "#1565c0",
|
|
8
|
+
macro: "#6a1b9a",
|
|
9
|
+
variable: "#37474f"
|
|
10
|
+
};
|
|
11
|
+
const DARK_COLORS = {
|
|
12
|
+
contract: "#4db6ac",
|
|
13
|
+
function: "#64b5f6",
|
|
14
|
+
macro: "#ce93d8",
|
|
15
|
+
variable: "#b0bec5"
|
|
16
|
+
};
|
|
17
|
+
const createDecorations = (dark) => {
|
|
18
|
+
const colors = dark ? DARK_COLORS : LIGHT_COLORS;
|
|
19
|
+
return {
|
|
20
|
+
contract: Decoration.mark({ attributes: { style: `color: ${colors.contract}` } }),
|
|
21
|
+
function: Decoration.mark({ attributes: { style: `color: ${colors.function}` } }),
|
|
22
|
+
macro: Decoration.mark({ attributes: { style: `color: ${colors.macro}` } }),
|
|
23
|
+
variable: Decoration.mark({ attributes: { style: `color: ${colors.variable}` } })
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const buildDecorations = (view, config, decos) => {
|
|
27
|
+
const builder = new RangeSetBuilder();
|
|
28
|
+
const tree = syntaxTree(view.state);
|
|
29
|
+
for (const { from, to } of view.visibleRanges) tree.iterate({
|
|
30
|
+
from,
|
|
31
|
+
to,
|
|
32
|
+
enter(node) {
|
|
33
|
+
if (node.name !== "Identifier") return;
|
|
34
|
+
const name = view.state.doc.sliceString(node.from, node.to);
|
|
35
|
+
let deco;
|
|
36
|
+
if (config.contractNames.has(name)) deco = decos.contract;
|
|
37
|
+
else if (config.functionNames.has(name)) deco = decos.function;
|
|
38
|
+
else if (config.macroNames.has(name)) deco = decos.macro;
|
|
39
|
+
else if (config.variableNames.has(name)) deco = decos.variable;
|
|
40
|
+
if (deco) builder.add(node.from, node.to, deco);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return builder.finish();
|
|
44
|
+
};
|
|
45
|
+
const createSemanticHighlighter = function(config, dark = false) {
|
|
46
|
+
const decos = createDecorations(dark);
|
|
47
|
+
return ViewPlugin.define((view) => ({
|
|
48
|
+
decorations: buildDecorations(view, config, decos),
|
|
49
|
+
update(update) {
|
|
50
|
+
if (update.docChanged || update.viewportChanged) this.decorations = buildDecorations(update.view, config, decos);
|
|
51
|
+
}
|
|
52
|
+
}), { decorations: (v) => v.decorations });
|
|
53
|
+
};
|
|
54
|
+
//#endregion
|
|
55
|
+
export { createSemanticHighlighter };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/language/tokenizer-config.ts
|
|
2
|
+
const createTokenizerConfig = (schema) => ({
|
|
3
|
+
contractNames: new Set(schema.contracts.map((c) => c.name)),
|
|
4
|
+
functionNames: new Set(schema.functions.map((f) => f.name)),
|
|
5
|
+
macroNames: new Set(schema.macros.map((m) => m.name)),
|
|
6
|
+
variableNames: new Set(schema.variables.map((v) => v.name))
|
|
7
|
+
});
|
|
8
|
+
//#endregion
|
|
9
|
+
exports.createTokenizerConfig = createTokenizerConfig;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SELSchema } from "@seljs/schema";
|
|
2
|
+
|
|
3
|
+
//#region src/language/tokenizer-config.d.ts
|
|
4
|
+
interface TokenizerConfig {
|
|
5
|
+
contractNames: Set<string>;
|
|
6
|
+
functionNames: Set<string>;
|
|
7
|
+
macroNames: Set<string>;
|
|
8
|
+
variableNames: Set<string>;
|
|
9
|
+
}
|
|
10
|
+
declare const createTokenizerConfig: (schema: SELSchema) => TokenizerConfig;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { TokenizerConfig, createTokenizerConfig };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SELSchema } from "@seljs/schema";
|
|
2
|
+
|
|
3
|
+
//#region src/language/tokenizer-config.d.ts
|
|
4
|
+
interface TokenizerConfig {
|
|
5
|
+
contractNames: Set<string>;
|
|
6
|
+
functionNames: Set<string>;
|
|
7
|
+
macroNames: Set<string>;
|
|
8
|
+
variableNames: Set<string>;
|
|
9
|
+
}
|
|
10
|
+
declare const createTokenizerConfig: (schema: SELSchema) => TokenizerConfig;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { TokenizerConfig, createTokenizerConfig };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/language/tokenizer-config.ts
|
|
2
|
+
const createTokenizerConfig = (schema) => ({
|
|
3
|
+
contractNames: new Set(schema.contracts.map((c) => c.name)),
|
|
4
|
+
functionNames: new Set(schema.functions.map((f) => f.name)),
|
|
5
|
+
macroNames: new Set(schema.macros.map((m) => m.name)),
|
|
6
|
+
variableNames: new Set(schema.variables.map((v) => v.name))
|
|
7
|
+
});
|
|
8
|
+
//#endregion
|
|
9
|
+
export { createTokenizerConfig };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/linting/diagnostic-mapper.ts
|
|
2
|
+
/**
|
|
3
|
+
* Maps a TypeCheckResult-shaped object or a caught Error to SELDiagnostic[].
|
|
4
|
+
*
|
|
5
|
+
* Handles both failure modes from `@seljs/runtime`'s `env.check()`:
|
|
6
|
+
* 1. Returned result: `{ valid: false, error: TypeError }`
|
|
7
|
+
* 2. Thrown exception: `SELParseError` or `SELTypeError`
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* ```ts
|
|
11
|
+
* const validate = (expression: string): SELDiagnostic[] => {
|
|
12
|
+
* try {
|
|
13
|
+
* const result = env.check(expression);
|
|
14
|
+
* return mapCheckResult(result, expression.length);
|
|
15
|
+
* } catch (error) {
|
|
16
|
+
* return mapCheckResult(error as Error, expression.length);
|
|
17
|
+
* }
|
|
18
|
+
* };
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
const mapCheckResult = (resultOrError, docLength) => {
|
|
22
|
+
if (resultOrError instanceof Error) return [{
|
|
23
|
+
message: resultOrError.message,
|
|
24
|
+
severity: "error",
|
|
25
|
+
from: 0,
|
|
26
|
+
to: Math.max(0, docLength)
|
|
27
|
+
}];
|
|
28
|
+
if (resultOrError.valid) return [];
|
|
29
|
+
return [{
|
|
30
|
+
message: resultOrError.error?.message ?? "Invalid expression",
|
|
31
|
+
severity: "error",
|
|
32
|
+
from: 0,
|
|
33
|
+
to: Math.max(0, docLength)
|
|
34
|
+
}];
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
exports.mapCheckResult = mapCheckResult;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { SELDiagnostic } from "@seljs/checker";
|
|
2
|
+
|
|
3
|
+
//#region src/linting/diagnostic-mapper.d.ts
|
|
2
4
|
interface CheckResult {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
valid: boolean;
|
|
6
|
+
error?: Error;
|
|
5
7
|
}
|
|
6
8
|
/**
|
|
7
9
|
* Maps a TypeCheckResult-shaped object or a caught Error to SELDiagnostic[].
|
|
@@ -23,6 +25,5 @@ interface CheckResult {
|
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
27
|
declare const mapCheckResult: (resultOrError: CheckResult | Error, docLength: number) => SELDiagnostic[];
|
|
26
|
-
|
|
27
|
-
export type
|
|
28
|
-
//# sourceMappingURL=diagnostic-mapper.d.ts.map
|
|
28
|
+
//#endregion
|
|
29
|
+
export { type SELDiagnostic, mapCheckResult };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SELDiagnostic } from "@seljs/checker";
|
|
2
|
+
|
|
3
|
+
//#region src/linting/diagnostic-mapper.d.ts
|
|
4
|
+
interface CheckResult {
|
|
5
|
+
valid: boolean;
|
|
6
|
+
error?: Error;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Maps a TypeCheckResult-shaped object or a caught Error to SELDiagnostic[].
|
|
10
|
+
*
|
|
11
|
+
* Handles both failure modes from `@seljs/runtime`'s `env.check()`:
|
|
12
|
+
* 1. Returned result: `{ valid: false, error: TypeError }`
|
|
13
|
+
* 2. Thrown exception: `SELParseError` or `SELTypeError`
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```ts
|
|
17
|
+
* const validate = (expression: string): SELDiagnostic[] => {
|
|
18
|
+
* try {
|
|
19
|
+
* const result = env.check(expression);
|
|
20
|
+
* return mapCheckResult(result, expression.length);
|
|
21
|
+
* } catch (error) {
|
|
22
|
+
* return mapCheckResult(error as Error, expression.length);
|
|
23
|
+
* }
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
declare const mapCheckResult: (resultOrError: CheckResult | Error, docLength: number) => SELDiagnostic[];
|
|
28
|
+
//#endregion
|
|
29
|
+
export { type SELDiagnostic, mapCheckResult };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/linting/diagnostic-mapper.ts
|
|
2
|
+
/**
|
|
3
|
+
* Maps a TypeCheckResult-shaped object or a caught Error to SELDiagnostic[].
|
|
4
|
+
*
|
|
5
|
+
* Handles both failure modes from `@seljs/runtime`'s `env.check()`:
|
|
6
|
+
* 1. Returned result: `{ valid: false, error: TypeError }`
|
|
7
|
+
* 2. Thrown exception: `SELParseError` or `SELTypeError`
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* ```ts
|
|
11
|
+
* const validate = (expression: string): SELDiagnostic[] => {
|
|
12
|
+
* try {
|
|
13
|
+
* const result = env.check(expression);
|
|
14
|
+
* return mapCheckResult(result, expression.length);
|
|
15
|
+
* } catch (error) {
|
|
16
|
+
* return mapCheckResult(error as Error, expression.length);
|
|
17
|
+
* }
|
|
18
|
+
* };
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
const mapCheckResult = (resultOrError, docLength) => {
|
|
22
|
+
if (resultOrError instanceof Error) return [{
|
|
23
|
+
message: resultOrError.message,
|
|
24
|
+
severity: "error",
|
|
25
|
+
from: 0,
|
|
26
|
+
to: Math.max(0, docLength)
|
|
27
|
+
}];
|
|
28
|
+
if (resultOrError.valid) return [];
|
|
29
|
+
return [{
|
|
30
|
+
message: resultOrError.error?.message ?? "Invalid expression",
|
|
31
|
+
severity: "error",
|
|
32
|
+
from: 0,
|
|
33
|
+
to: Math.max(0, docLength)
|
|
34
|
+
}];
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { mapCheckResult };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
let _codemirror_lint = require("@codemirror/lint");
|
|
2
|
+
//#region src/linting/sel-linter.ts
|
|
3
|
+
const SEVERITY_MAP = {
|
|
4
|
+
error: "error",
|
|
5
|
+
warning: "warning",
|
|
6
|
+
info: "info"
|
|
7
|
+
};
|
|
8
|
+
function mapToCMDiagnostic(diag, docLength) {
|
|
9
|
+
const from = diag.from ?? 0;
|
|
10
|
+
const to = diag.to ?? docLength;
|
|
11
|
+
return {
|
|
12
|
+
from: Math.max(0, Math.min(from, docLength)),
|
|
13
|
+
to: Math.max(0, Math.min(to, docLength)),
|
|
14
|
+
severity: SEVERITY_MAP[diag.severity],
|
|
15
|
+
message: diag.message
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function createSELLinter(options) {
|
|
19
|
+
return (0, _codemirror_lint.linter)(async (view) => {
|
|
20
|
+
const doc = view.state.doc.toString();
|
|
21
|
+
if (!doc) return [];
|
|
22
|
+
const diagnostics = await options.validate(doc);
|
|
23
|
+
const docLength = doc.length;
|
|
24
|
+
return diagnostics.map((d) => mapToCMDiagnostic(d, docLength));
|
|
25
|
+
}, { delay: options.delay ?? 300 });
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
exports.createSELLinter = createSELLinter;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SELDiagnostic } from "./diagnostic-mapper.cjs";
|
|
2
|
+
import { Extension } from "@codemirror/state";
|
|
3
|
+
|
|
4
|
+
//#region src/linting/sel-linter.d.ts
|
|
5
|
+
interface SELLinterOptions {
|
|
6
|
+
/** Validate an expression, return diagnostics */
|
|
7
|
+
validate: (expression: string) => SELDiagnostic[] | Promise<SELDiagnostic[]>;
|
|
8
|
+
/** Debounce delay in ms (default: 300) */
|
|
9
|
+
delay?: number;
|
|
10
|
+
}
|
|
11
|
+
declare function createSELLinter(options: SELLinterOptions): Extension;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { type SELLinterOptions, createSELLinter };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SELDiagnostic } from "./diagnostic-mapper.mjs";
|
|
2
|
+
import { Extension } from "@codemirror/state";
|
|
3
|
+
|
|
4
|
+
//#region src/linting/sel-linter.d.ts
|
|
5
|
+
interface SELLinterOptions {
|
|
6
|
+
/** Validate an expression, return diagnostics */
|
|
7
|
+
validate: (expression: string) => SELDiagnostic[] | Promise<SELDiagnostic[]>;
|
|
8
|
+
/** Debounce delay in ms (default: 300) */
|
|
9
|
+
delay?: number;
|
|
10
|
+
}
|
|
11
|
+
declare function createSELLinter(options: SELLinterOptions): Extension;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { type SELLinterOptions, createSELLinter };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { linter } from "@codemirror/lint";
|
|
2
|
+
//#region src/linting/sel-linter.ts
|
|
3
|
+
const SEVERITY_MAP = {
|
|
4
|
+
error: "error",
|
|
5
|
+
warning: "warning",
|
|
6
|
+
info: "info"
|
|
7
|
+
};
|
|
8
|
+
function mapToCMDiagnostic(diag, docLength) {
|
|
9
|
+
const from = diag.from ?? 0;
|
|
10
|
+
const to = diag.to ?? docLength;
|
|
11
|
+
return {
|
|
12
|
+
from: Math.max(0, Math.min(from, docLength)),
|
|
13
|
+
to: Math.max(0, Math.min(to, docLength)),
|
|
14
|
+
severity: SEVERITY_MAP[diag.severity],
|
|
15
|
+
message: diag.message
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function createSELLinter(options) {
|
|
19
|
+
return linter(async (view) => {
|
|
20
|
+
const doc = view.state.doc.toString();
|
|
21
|
+
if (!doc) return [];
|
|
22
|
+
const diagnostics = await options.validate(doc);
|
|
23
|
+
const docLength = doc.length;
|
|
24
|
+
return diagnostics.map((d) => mapToCMDiagnostic(d, docLength));
|
|
25
|
+
}, { delay: options.delay ?? 300 });
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { createSELLinter };
|
package/package.json
CHANGED
|
@@ -1,30 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seljs/editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"url": "https://github.com/abinnovision/seljs"
|
|
6
|
+
},
|
|
4
7
|
"license": "Apache-2.0",
|
|
5
8
|
"author": {
|
|
6
9
|
"name": "abi group GmbH",
|
|
7
10
|
"email": "info@abigroup.io",
|
|
8
11
|
"url": "https://abigroup.io/"
|
|
9
12
|
},
|
|
10
|
-
"repository": {
|
|
11
|
-
"url": "https://github.com/abinnovision/seljs"
|
|
12
|
-
},
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
15
|
".": {
|
|
16
|
-
"import":
|
|
17
|
-
|
|
16
|
+
"import": {
|
|
17
|
+
"types": "./dist/index.d.mts",
|
|
18
|
+
"default": "./dist/index.mjs"
|
|
19
|
+
},
|
|
20
|
+
"require": {
|
|
21
|
+
"types": "./dist/index.d.cts",
|
|
22
|
+
"default": "./dist/index.cjs"
|
|
23
|
+
}
|
|
18
24
|
}
|
|
19
25
|
},
|
|
20
|
-
"main": "./dist/index.
|
|
21
|
-
"types": "./dist/index.d.
|
|
26
|
+
"main": "./dist/index.cjs",
|
|
27
|
+
"types": "./dist/index.d.cts",
|
|
22
28
|
"files": [
|
|
23
29
|
"dist",
|
|
24
30
|
"LICENSE.md"
|
|
25
31
|
],
|
|
26
32
|
"scripts": {
|
|
27
|
-
"build": "
|
|
33
|
+
"build": "tsdown",
|
|
28
34
|
"format:check": "prettier --check '{{src,test}/**/*,*}.{{t,j}s{,x},json{,5},md,y{,a}ml}'",
|
|
29
35
|
"format:fix": "prettier --write '{{src,test}/**/*,*}.{{t,j}s{,x},json{,5},md,y{,a}ml}'",
|
|
30
36
|
"lint:check": "eslint '{{src,test}/**/*,*}.{t,j}s{,x}'",
|
|
@@ -33,19 +39,6 @@
|
|
|
33
39
|
"test-unit:watch": "vitest watch",
|
|
34
40
|
"typecheck": "tsc --noEmit"
|
|
35
41
|
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"@codemirror/autocomplete": "^6.20.1",
|
|
38
|
-
"@codemirror/commands": "^6.0.0",
|
|
39
|
-
"@codemirror/language": "^6.0.0",
|
|
40
|
-
"@codemirror/lint": "^6.9.5",
|
|
41
|
-
"@codemirror/state": "^6.0.0",
|
|
42
|
-
"@codemirror/view": "^6.0.0",
|
|
43
|
-
"@lezer/common": "^1.5.1",
|
|
44
|
-
"@lezer/highlight": "^1.0.0",
|
|
45
|
-
"@seljs/cel-lezer": "1.0.0",
|
|
46
|
-
"@seljs/checker": "1.0.0",
|
|
47
|
-
"@seljs/schema": "1.0.0"
|
|
48
|
-
},
|
|
49
42
|
"lint-staged": {
|
|
50
43
|
"{{src,test}/**/*,*}.{{t,j}s{,x},json{,5},md,y{,a}ml}": [
|
|
51
44
|
"prettier --write"
|
|
@@ -54,6 +47,19 @@
|
|
|
54
47
|
"eslint --fix"
|
|
55
48
|
]
|
|
56
49
|
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@codemirror/autocomplete": "^6.20.1",
|
|
52
|
+
"@codemirror/commands": "^6.10.3",
|
|
53
|
+
"@codemirror/language": "^6.12.2",
|
|
54
|
+
"@codemirror/lint": "^6.9.5",
|
|
55
|
+
"@codemirror/state": "^6.6.0",
|
|
56
|
+
"@codemirror/view": "^6.40.0",
|
|
57
|
+
"@lezer/common": "^1.5.1",
|
|
58
|
+
"@lezer/highlight": "^1.2.3",
|
|
59
|
+
"@seljs/cel-lezer": "1.0.1",
|
|
60
|
+
"@seljs/checker": "1.0.1",
|
|
61
|
+
"@seljs/schema": "1.0.1"
|
|
62
|
+
},
|
|
57
63
|
"devDependencies": {
|
|
58
64
|
"@abinnovision/eslint-config-base": "^3.2.0",
|
|
59
65
|
"@abinnovision/prettier-config": "^2.1.5",
|
|
@@ -61,6 +67,7 @@
|
|
|
61
67
|
"eslint": "^9.39.4",
|
|
62
68
|
"jsdom": "^28.1.0",
|
|
63
69
|
"prettier": "^3.8.1",
|
|
70
|
+
"tsdown": "^0.21.3",
|
|
64
71
|
"typescript": "^5.9.3",
|
|
65
72
|
"vitest": "^4.0.18"
|
|
66
73
|
},
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Completion } from "@codemirror/autocomplete";
|
|
2
|
-
import type { ContractSchema, FunctionSchema, MacroSchema, VariableSchema } from "@seljs/schema";
|
|
3
|
-
export declare const createContractCompletions: (contracts: ContractSchema[]) => Completion[];
|
|
4
|
-
export declare const createMethodCompletions: (contract: ContractSchema) => Completion[];
|
|
5
|
-
export declare const createFunctionCompletions: (functions: FunctionSchema[]) => Completion[];
|
|
6
|
-
export declare const createMacroCompletions: (macros: MacroSchema[]) => Completion[];
|
|
7
|
-
export declare const createVariableCompletions: (variables: VariableSchema[]) => Completion[];
|
|
8
|
-
//# sourceMappingURL=completion-items.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"completion-items.d.ts","sourceRoot":"","sources":["../../src/completion/completion-items.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EACX,cAAc,EACd,cAAc,EACd,WAAW,EACX,cAAc,EACd,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,yBAAyB,GACrC,WAAW,cAAc,EAAE,KACzB,UAAU,EAKT,CAAC;AAEL,eAAO,MAAM,uBAAuB,GACnC,UAAU,cAAc,KACtB,UAAU,EAMT,CAAC;AAEL,eAAO,MAAM,yBAAyB,GACrC,WAAW,cAAc,EAAE,KACzB,UAAU,EAMT,CAAC;AAEL,eAAO,MAAM,sBAAsB,GAAI,QAAQ,WAAW,EAAE,KAAG,UAAU,EAMrE,CAAC;AAEL,eAAO,MAAM,yBAAyB,GACrC,WAAW,cAAc,EAAE,KACzB,UAAU,EAMT,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export const createContractCompletions = (contracts) => contracts.map((c) => ({
|
|
2
|
-
label: c.name,
|
|
3
|
-
type: "class",
|
|
4
|
-
detail: c.description,
|
|
5
|
-
}));
|
|
6
|
-
export const createMethodCompletions = (contract) => contract.methods.map((m) => ({
|
|
7
|
-
label: m.name,
|
|
8
|
-
type: "method",
|
|
9
|
-
detail: `(${m.params.map((p) => `${p.name}: ${p.type}`).join(", ")}): ${m.returns}`,
|
|
10
|
-
info: m.description,
|
|
11
|
-
}));
|
|
12
|
-
export const createFunctionCompletions = (functions) => functions.map((f) => ({
|
|
13
|
-
label: f.name,
|
|
14
|
-
type: "function",
|
|
15
|
-
detail: f.signature,
|
|
16
|
-
info: f.description,
|
|
17
|
-
}));
|
|
18
|
-
export const createMacroCompletions = (macros) => macros.map((m) => ({
|
|
19
|
-
label: m.name,
|
|
20
|
-
type: "keyword",
|
|
21
|
-
detail: m.pattern,
|
|
22
|
-
info: m.description,
|
|
23
|
-
}));
|
|
24
|
-
export const createVariableCompletions = (variables) => variables.map((v) => ({
|
|
25
|
-
label: v.name,
|
|
26
|
-
type: "variable",
|
|
27
|
-
detail: v.type,
|
|
28
|
-
info: v.description,
|
|
29
|
-
}));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/completion/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
package/dist/completion/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./schema-completion";
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { type CompletionContext, type CompletionResult } from "@codemirror/autocomplete";
|
|
2
|
-
import type { Extension } from "@codemirror/state";
|
|
3
|
-
import type { SELChecker } from "@seljs/checker";
|
|
4
|
-
import type { SELSchema } from "@seljs/schema";
|
|
5
|
-
export declare class SchemaCompletionProvider {
|
|
6
|
-
private topLevelCompletions;
|
|
7
|
-
private allDotCompletions;
|
|
8
|
-
private checker;
|
|
9
|
-
constructor(schema: SELSchema, checker: SELChecker);
|
|
10
|
-
completionSource: (context: CompletionContext) => CompletionResult | null;
|
|
11
|
-
private handleDotAccess;
|
|
12
|
-
private handleCallArg;
|
|
13
|
-
private handleTopLevel;
|
|
14
|
-
/**
|
|
15
|
-
* Use the checker to infer the expected type at cursor position
|
|
16
|
-
* and filter completions to only type-compatible items.
|
|
17
|
-
* Returns undefined when narrowing is not possible.
|
|
18
|
-
*/
|
|
19
|
-
private narrowByExpectedType;
|
|
20
|
-
}
|
|
21
|
-
export declare const createSchemaCompletion: (schema: SELSchema, checker: SELChecker) => Extension;
|
|
22
|
-
//# sourceMappingURL=schema-completion.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema-completion.d.ts","sourceRoot":"","sources":["../../src/completion/schema-completion.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EAErB,MAAM,0BAA0B,CAAC;AAYlC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAU/C,qBAAa,wBAAwB;IACpC,OAAO,CAAC,mBAAmB,CAAe;IAC1C,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,OAAO,CAAa;gBAET,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU;IA4DlD,gBAAgB,GACtB,SAAS,iBAAiB,KACxB,gBAAgB,GAAG,IAAI,CAWxB;IAEF,OAAO,CAAC,eAAe;IA0CvB,OAAO,CAAC,aAAa;IA6DrB,OAAO,CAAC,cAAc;IAiCtB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;CAwC5B;AAED,eAAO,MAAM,sBAAsB,GAClC,QAAQ,SAAS,EACjB,SAAS,UAAU,KACjB,SAMF,CAAC"}
|