@rohal12/spindle-lsp 0.15.34 → 0.15.35
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/bin.js +154 -58
- package/dist/bin.js.map +4 -4
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -55,7 +55,7 @@ var VERSION;
|
|
|
55
55
|
var init_version = __esm({
|
|
56
56
|
"src/version.ts"() {
|
|
57
57
|
"use strict";
|
|
58
|
-
VERSION = false ? pkg.version : "0.15.
|
|
58
|
+
VERSION = false ? pkg.version : "0.15.35";
|
|
59
59
|
}
|
|
60
60
|
});
|
|
61
61
|
|
|
@@ -14056,6 +14056,9 @@ function peg$parse(input2, options) {
|
|
|
14056
14056
|
if (peg$success) return peg$result;
|
|
14057
14057
|
else peg$throw();
|
|
14058
14058
|
}
|
|
14059
|
+
function isOptionClause(name) {
|
|
14060
|
+
return name.toLowerCase() === OPTION_CLAUSE;
|
|
14061
|
+
}
|
|
14059
14062
|
function consumesOptionClauses(macro) {
|
|
14060
14063
|
const name = macro.name.toLowerCase();
|
|
14061
14064
|
return macro.source === "builtin" && !macro.widget && (name === "listbox" || name === "cycle");
|
|
@@ -21872,6 +21875,71 @@ function blockLookup(macros, includeRuntime = true) {
|
|
|
21872
21875
|
for (const macro of effectiveToolingMacros(macros)) definitions.set(macro.name, macro.block);
|
|
21873
21876
|
return (name) => includeRuntime && isRegisteredBlockMacro(name) || (definitions.get(name) ?? (includeRuntime ? isBlockMacro(name) : isBuiltinBlockMacro(name)));
|
|
21874
21877
|
}
|
|
21878
|
+
function macroCalls(source, macros = []) {
|
|
21879
|
+
const all = effectiveToolingMacros(macros);
|
|
21880
|
+
const definitions = new NameMap(all.map((macro) => [macro.name, macro]));
|
|
21881
|
+
const parametersOf2 = parameterLookup(all);
|
|
21882
|
+
const options = tokenizationOptions({
|
|
21883
|
+
macros: all,
|
|
21884
|
+
hooks: { isBlock: blockLookup(all, false) }
|
|
21885
|
+
});
|
|
21886
|
+
const hooks = options.hooks;
|
|
21887
|
+
const tokens2 = tokenizeMarkupTolerant$1(source, options).tokens;
|
|
21888
|
+
const calls = [];
|
|
21889
|
+
const classify2 = (tokens3) => {
|
|
21890
|
+
const found = /* @__PURE__ */ new Map();
|
|
21891
|
+
const pending = pairMarkup(tokens3, hooks).nodes.map((node2) => ({ node: node2 }));
|
|
21892
|
+
while (pending.length) {
|
|
21893
|
+
const { node: node2, parent } = pending.pop();
|
|
21894
|
+
const token = node2.token;
|
|
21895
|
+
if (token.type === "macro") {
|
|
21896
|
+
const definition2 = parent && definitions.get(parent.name);
|
|
21897
|
+
const value = definition2 && consumesOptionClauses(definition2) && isOptionClause(token.name);
|
|
21898
|
+
found.set(token, {
|
|
21899
|
+
token,
|
|
21900
|
+
kind: value ? "value" : "invocation",
|
|
21901
|
+
...value && { owner: parent }
|
|
21902
|
+
});
|
|
21903
|
+
}
|
|
21904
|
+
if (!node2.body) continue;
|
|
21905
|
+
const owner = token.type === "macro" ? token : void 0;
|
|
21906
|
+
for (const child of node2.body.children) pending.push({
|
|
21907
|
+
node: child,
|
|
21908
|
+
parent: owner
|
|
21909
|
+
});
|
|
21910
|
+
for (const branch of node2.body.branches) {
|
|
21911
|
+
found.set(branch.tag, {
|
|
21912
|
+
token: branch.tag,
|
|
21913
|
+
kind: "branch",
|
|
21914
|
+
owner
|
|
21915
|
+
});
|
|
21916
|
+
for (const child of branch.children) pending.push({
|
|
21917
|
+
node: child,
|
|
21918
|
+
parent: owner
|
|
21919
|
+
});
|
|
21920
|
+
}
|
|
21921
|
+
}
|
|
21922
|
+
for (const token of tokens3) {
|
|
21923
|
+
if (token.type !== "macro" || token.isClose) continue;
|
|
21924
|
+
const call = found.get(token) ?? {
|
|
21925
|
+
token,
|
|
21926
|
+
kind: "branch"
|
|
21927
|
+
};
|
|
21928
|
+
calls.push(call);
|
|
21929
|
+
}
|
|
21930
|
+
};
|
|
21931
|
+
classify2(tokens2);
|
|
21932
|
+
for (const piece of passagePiecesOf(source, tokens2, parametersOf2, { isBlock: hooks.isBlock })) {
|
|
21933
|
+
if (piece.kind !== "text" || !piece.tokens.length) continue;
|
|
21934
|
+
classify2(piece.tokens);
|
|
21935
|
+
}
|
|
21936
|
+
let literalEnd = -1;
|
|
21937
|
+
return calls.sort((a, b) => a.token.start - b.token.start).filter((call) => {
|
|
21938
|
+
if (call.token.start < literalEnd) return false;
|
|
21939
|
+
if (call.kind === "value" || call.kind === "branch") literalEnd = call.token.argsEnd;
|
|
21940
|
+
return true;
|
|
21941
|
+
});
|
|
21942
|
+
}
|
|
21875
21943
|
function passagePieces(source, macros = []) {
|
|
21876
21944
|
const all = effectiveToolingMacros(macros);
|
|
21877
21945
|
const parametersOf2 = parameterLookup(all);
|
|
@@ -33216,6 +33284,7 @@ var init_passage_markup = __esm({
|
|
|
33216
33284
|
cachedTokens;
|
|
33217
33285
|
cachedPairing;
|
|
33218
33286
|
cachedPieces;
|
|
33287
|
+
cachedInvocations;
|
|
33219
33288
|
cachedDeclarations;
|
|
33220
33289
|
/** The document offset of `contentOffset`. */
|
|
33221
33290
|
docOffset(contentOffset) {
|
|
@@ -33268,6 +33337,16 @@ var init_passage_markup = __esm({
|
|
|
33268
33337
|
get pieces() {
|
|
33269
33338
|
return this.cachedPieces ??= this.isMarkup ? passagePieces(this.content, this.doc.context.macros) : [];
|
|
33270
33339
|
}
|
|
33340
|
+
/** Contextual calls, excluding parent-owned clauses and widget registration heads. */
|
|
33341
|
+
get invocations() {
|
|
33342
|
+
if (!this.cachedInvocations) {
|
|
33343
|
+
const macros = this.doc.context.macros;
|
|
33344
|
+
const definitions = widgetDefinitions([{ ...this.passage, content: this.content }], macros);
|
|
33345
|
+
const registration = new Set(definitions.map((definition2) => definition2.start));
|
|
33346
|
+
this.cachedInvocations = this.isMarkup ? macroCalls(this.content, macros).filter((call) => call.kind === "invocation" && !registration.has(call.token.start)).map((call) => call.token) : [];
|
|
33347
|
+
}
|
|
33348
|
+
return this.cachedInvocations;
|
|
33349
|
+
}
|
|
33271
33350
|
/** Whether the cursor is executable, with decoded code mapped back to `content`. */
|
|
33272
33351
|
completionAt(offset2) {
|
|
33273
33352
|
return this.isMarkup ? completionContext(this.content, offset2, this.doc.context.macros) : { kind: "literal" };
|
|
@@ -33607,24 +33686,6 @@ var init_variable_tracker = __esm({
|
|
|
33607
33686
|
}
|
|
33608
33687
|
});
|
|
33609
33688
|
|
|
33610
|
-
// src/core/markup/tokens.ts
|
|
33611
|
-
function* markupTokens(passage) {
|
|
33612
|
-
yield* passage.tokens;
|
|
33613
|
-
for (const piece of passage.pieces) {
|
|
33614
|
-
if (piece.kind === "text") yield* piece.tokens;
|
|
33615
|
-
}
|
|
33616
|
-
}
|
|
33617
|
-
function* macroTokens(passage) {
|
|
33618
|
-
for (const token of markupTokens(passage)) {
|
|
33619
|
-
if (token.type === "macro") yield token;
|
|
33620
|
-
}
|
|
33621
|
-
}
|
|
33622
|
-
var init_tokens = __esm({
|
|
33623
|
-
"src/core/markup/tokens.ts"() {
|
|
33624
|
-
"use strict";
|
|
33625
|
-
}
|
|
33626
|
-
});
|
|
33627
|
-
|
|
33628
33689
|
// src/core/markup/widgets.ts
|
|
33629
33690
|
function widgetSources(passages, macros) {
|
|
33630
33691
|
const sources = /* @__PURE__ */ new Map();
|
|
@@ -33650,7 +33711,6 @@ var init_widget_registry = __esm({
|
|
|
33650
33711
|
"src/core/workspace/widget-registry.ts"() {
|
|
33651
33712
|
"use strict";
|
|
33652
33713
|
init_tooling();
|
|
33653
|
-
init_tokens();
|
|
33654
33714
|
init_widgets();
|
|
33655
33715
|
WidgetRegistry = class {
|
|
33656
33716
|
/** Widgets keyed by lower-cased name; Spindle resolves widgets case-insensitively. */
|
|
@@ -33729,8 +33789,8 @@ var init_widget_registry = __esm({
|
|
|
33729
33789
|
recordInvocations(uri, passages) {
|
|
33730
33790
|
const names = /* @__PURE__ */ new Set();
|
|
33731
33791
|
for (const passage of passages) {
|
|
33732
|
-
for (const macro of
|
|
33733
|
-
|
|
33792
|
+
for (const macro of passage.invocations) {
|
|
33793
|
+
names.add(macro.name.toLowerCase());
|
|
33734
33794
|
}
|
|
33735
33795
|
}
|
|
33736
33796
|
this.invokedByUri.set(uri, names);
|
|
@@ -34759,7 +34819,9 @@ var init_diagnostic_codes = __esm({
|
|
|
34759
34819
|
UnsupportedSpindleVersion: "SP001",
|
|
34760
34820
|
/** A fatal Twee source error reported by the public compiler parser. */
|
|
34761
34821
|
TweeSyntaxError: "SP002",
|
|
34762
|
-
/**
|
|
34822
|
+
/** Compiler-owned errors decoding StoryData metadata. */
|
|
34823
|
+
InvalidStoryData: "SP003",
|
|
34824
|
+
/** The selected entry passage is absent or omitted from compiled story data. */
|
|
34763
34825
|
MissingEntryPassage: "SP004",
|
|
34764
34826
|
/** `unknown-macro`: a macro that is none of the built-in, configured or defined ones. */
|
|
34765
34827
|
UndefinedMacro: "SP100",
|
|
@@ -34815,6 +34877,7 @@ var init_diagnostic_codes = __esm({
|
|
|
34815
34877
|
severityMap = {
|
|
34816
34878
|
[DiagnosticCode.UnsupportedSpindleVersion]: "warning",
|
|
34817
34879
|
[DiagnosticCode.TweeSyntaxError]: "error",
|
|
34880
|
+
[DiagnosticCode.InvalidStoryData]: "error",
|
|
34818
34881
|
[DiagnosticCode.MissingEntryPassage]: "error",
|
|
34819
34882
|
[DiagnosticCode.UndefinedMacro]: "warning",
|
|
34820
34883
|
[DiagnosticCode.MalformedContainer]: "error",
|
|
@@ -34853,6 +34916,24 @@ var init_diagnostic_codes = __esm({
|
|
|
34853
34916
|
}
|
|
34854
34917
|
});
|
|
34855
34918
|
|
|
34919
|
+
// src/core/markup/tokens.ts
|
|
34920
|
+
function* markupTokens(passage) {
|
|
34921
|
+
yield* passage.tokens;
|
|
34922
|
+
for (const piece of passage.pieces) {
|
|
34923
|
+
if (piece.kind === "text") yield* piece.tokens;
|
|
34924
|
+
}
|
|
34925
|
+
}
|
|
34926
|
+
function* macroTokens(passage) {
|
|
34927
|
+
for (const token of markupTokens(passage)) {
|
|
34928
|
+
if (token.type === "macro") yield token;
|
|
34929
|
+
}
|
|
34930
|
+
}
|
|
34931
|
+
var init_tokens = __esm({
|
|
34932
|
+
"src/core/markup/tokens.ts"() {
|
|
34933
|
+
"use strict";
|
|
34934
|
+
}
|
|
34935
|
+
});
|
|
34936
|
+
|
|
34856
34937
|
// src/core/markup/source-view.ts
|
|
34857
34938
|
function viewIndex(view, offset2) {
|
|
34858
34939
|
if (!view.sourceOffsets) return offset2 - view.offset;
|
|
@@ -35215,8 +35296,8 @@ function buildReport(documents, workspace) {
|
|
|
35215
35296
|
const invoked = /* @__PURE__ */ new Set();
|
|
35216
35297
|
for (const passage of passages) {
|
|
35217
35298
|
if (!passage.isMarkup) continue;
|
|
35218
|
-
for (const token of
|
|
35219
|
-
|
|
35299
|
+
for (const token of passage.invocations) {
|
|
35300
|
+
invoked.add(token.name.toLowerCase());
|
|
35220
35301
|
}
|
|
35221
35302
|
}
|
|
35222
35303
|
return {
|
|
@@ -35235,17 +35316,33 @@ function buildReport(documents, workspace) {
|
|
|
35235
35316
|
}
|
|
35236
35317
|
function storyDataDiagnostics(documents, workspace) {
|
|
35237
35318
|
const found = /* @__PURE__ */ new Map();
|
|
35238
|
-
const
|
|
35239
|
-
|
|
35319
|
+
const data2 = workspace.passages.getEffectivePassage("StoryData");
|
|
35320
|
+
const implicit = workspace.passages.getEffectivePassage("Start");
|
|
35321
|
+
if (!data2 && (!implicit || isRuntimePassage(implicit))) return found;
|
|
35322
|
+
const { parseTwee, StoryBuilder, startPassageDiagnostics } = createCompilerRequire3(import.meta.url)("@rohal12/twee-ts");
|
|
35323
|
+
const builder = new StoryBuilder();
|
|
35324
|
+
const sources = new Map(documents.flatMap((doc) => doc.passages.map((passage) => [passage.passage, passage])));
|
|
35325
|
+
const parsed = new Map(documents.map((doc) => [doc, new Map(parseTwee(doc.text).passages.map((passage) => [passage.source?.line, passage]))]));
|
|
35326
|
+
const effective = workspace.passages.getEffectivePassages();
|
|
35327
|
+
for (const source of effective) {
|
|
35328
|
+
const passage = sources.get(source);
|
|
35329
|
+
if (!passage) continue;
|
|
35330
|
+
const input2 = parsed.get(passage.doc)?.get(source.headerEnd.start.line + 1);
|
|
35331
|
+
if (!input2) continue;
|
|
35240
35332
|
const diagnostics = [];
|
|
35241
|
-
|
|
35242
|
-
|
|
35243
|
-
|
|
35244
|
-
if (data2.start && !workspace.passages.getEffectivePassage(data2.start)) {
|
|
35245
|
-
diagnostics.push(makeDiag(passage.passage.nameRange, DiagnosticCode.MissingEntryPassage, `Starting passage "${data2.start}" not found.`));
|
|
35246
|
-
}
|
|
35333
|
+
builder.add(input2, diagnostics);
|
|
35334
|
+
if (source.name === "StoryData") {
|
|
35335
|
+
found.set(passage.doc, diagnostics.filter((d) => d.level === "error").map((d) => makeDiag(passage.range(0, passage.content.trimEnd().length), DiagnosticCode.InvalidStoryData, d.message)));
|
|
35247
35336
|
}
|
|
35248
|
-
|
|
35337
|
+
}
|
|
35338
|
+
const story = builder.build();
|
|
35339
|
+
const entry = workspace.passages.getEffectivePassage(story.twine2.start || "Start");
|
|
35340
|
+
const owner = story.twine2.start ? workspace.passages.getEffectivePassage("StoryData") : entry;
|
|
35341
|
+
const markup = owner && sources.get(owner);
|
|
35342
|
+
if (markup) {
|
|
35343
|
+
const diagnostics = found.get(markup.doc) ?? [];
|
|
35344
|
+
diagnostics.push(...startPassageDiagnostics(story).map((d) => makeDiag(markup.passage.nameRange, DiagnosticCode.MissingEntryPassage, d.message)));
|
|
35345
|
+
found.set(markup.doc, diagnostics);
|
|
35249
35346
|
}
|
|
35250
35347
|
return found;
|
|
35251
35348
|
}
|
|
@@ -35597,8 +35694,7 @@ function widgetDiagnostics(passage, story, workspace) {
|
|
|
35597
35694
|
if (!passage.isMarkup) return [];
|
|
35598
35695
|
const diagnostics = [];
|
|
35599
35696
|
const macros = [...macroTokens(passage)];
|
|
35600
|
-
for (const token of
|
|
35601
|
-
if (token.isClose) continue;
|
|
35697
|
+
for (const token of passage.invocations) {
|
|
35602
35698
|
if (workspace.getEffectiveMacro(token.name)) continue;
|
|
35603
35699
|
const widget = story.widgets.get(token.name.toLowerCase());
|
|
35604
35700
|
if (!widget) continue;
|
|
@@ -35732,7 +35828,6 @@ var init_diagnostics = __esm({
|
|
|
35732
35828
|
init_link_parser();
|
|
35733
35829
|
init_passage_parser();
|
|
35734
35830
|
init_story_variables_owner();
|
|
35735
|
-
init_story_data();
|
|
35736
35831
|
init_macro_sources();
|
|
35737
35832
|
init_spindle_version();
|
|
35738
35833
|
tweeReports = /* @__PURE__ */ new WeakMap();
|
|
@@ -87432,7 +87527,7 @@ function linkable(name) {
|
|
|
87432
87527
|
return tokens2.length === 1 && link.type === "link" && link.target === name && !bracketLinkMismatch("label", name);
|
|
87433
87528
|
}
|
|
87434
87529
|
function getPassageNameCompletions(workspace) {
|
|
87435
|
-
return workspace.passages.getEffectivePassages().filter((p) => isRuntimePassage(p) && linkable(p.name)).map((p) => ({
|
|
87530
|
+
return workspace.passages.getEffectivePassages().filter((p) => isRuntimePassage(p) && !isSpecialPassage(p.name) && linkable(p.name)).map((p) => ({
|
|
87436
87531
|
label: p.name,
|
|
87437
87532
|
kind: 18,
|
|
87438
87533
|
// CompletionItemKind.Reference
|
|
@@ -87745,14 +87840,14 @@ var init_signature = __esm({
|
|
|
87745
87840
|
function* pairedHeads(paired, tokens2) {
|
|
87746
87841
|
const unclosed = [];
|
|
87747
87842
|
for (const node2 of walkNodes(paired.nodes)) {
|
|
87748
|
-
if (node2.token.type === "macro") yield { name: node2.token.name, closing: false, start: node2.token.nameStart, end: node2.token.nameEnd };
|
|
87843
|
+
if (node2.token.type === "macro") yield { name: node2.token.name, closing: false, opener: node2.token.start, start: node2.token.nameStart, end: node2.token.nameEnd };
|
|
87749
87844
|
for (const branch of node2.body?.branches ?? []) {
|
|
87750
|
-
yield { name: branch.tag.name, closing: false, start: branch.tag.nameStart, end: branch.tag.nameEnd };
|
|
87845
|
+
yield { name: branch.tag.name, closing: false, opener: branch.tag.start, start: branch.tag.nameStart, end: branch.tag.nameEnd };
|
|
87751
87846
|
}
|
|
87752
87847
|
const close = node2.body?.close;
|
|
87753
87848
|
if (node2.token.type !== "macro") continue;
|
|
87754
87849
|
if (close?.type === "macro" && close.name.toLowerCase() === node2.token.name.toLowerCase()) {
|
|
87755
|
-
yield { name: close.name, closing: true, start: close.nameStart, end: close.nameEnd };
|
|
87850
|
+
yield { name: close.name, closing: true, opener: node2.token.start, start: close.nameStart, end: close.nameEnd };
|
|
87756
87851
|
} else if (node2.body && !close) {
|
|
87757
87852
|
unclosed.push({ name: node2.token.name.toLowerCase(), start: node2.token.start });
|
|
87758
87853
|
}
|
|
@@ -87762,8 +87857,9 @@ function* pairedHeads(paired, tokens2) {
|
|
|
87762
87857
|
const token = byStart.get(error62.start);
|
|
87763
87858
|
if (error62.code !== "stray-closer" || token?.type !== "macro" || !token.isClose) continue;
|
|
87764
87859
|
const name = token.name.toLowerCase();
|
|
87765
|
-
|
|
87766
|
-
|
|
87860
|
+
const open2 = unclosed.find((open3) => open3.name === name && open3.start < error62.start);
|
|
87861
|
+
if (open2) {
|
|
87862
|
+
yield { name: token.name, closing: true, opener: open2.start, start: token.nameStart, end: token.nameEnd };
|
|
87767
87863
|
}
|
|
87768
87864
|
}
|
|
87769
87865
|
}
|
|
@@ -87776,7 +87872,8 @@ function passageMacroHeads(passage) {
|
|
|
87776
87872
|
if (piece.kind !== "text") continue;
|
|
87777
87873
|
found.push(...pairedHeads(pairMarkup(piece.tokens, { isBlock }), piece.tokens));
|
|
87778
87874
|
}
|
|
87779
|
-
|
|
87875
|
+
const invocations = new Set(passage.invocations.map((token) => token.start));
|
|
87876
|
+
heads = found.sort((a, b) => a.start - b.start).map(({ opener, ...head }) => ({ ...head, invocation: invocations.has(opener), passage, range: passage.range(head.start, head.end) }));
|
|
87780
87877
|
kept2.set(passage, heads);
|
|
87781
87878
|
return heads;
|
|
87782
87879
|
}
|
|
@@ -87824,7 +87921,7 @@ function getPassageRefDefinition(uri, position, workspace) {
|
|
|
87824
87921
|
function getWidgetDefinition(uri, position, workspace) {
|
|
87825
87922
|
const doc = workspace.markup.get(uri);
|
|
87826
87923
|
const head = doc && macroHeadAt(doc, position);
|
|
87827
|
-
if (!head) return null;
|
|
87924
|
+
if (!head?.invocation) return null;
|
|
87828
87925
|
if (workspace.getEffectiveMacro(head.name)) return null;
|
|
87829
87926
|
const widget = workspace.widgets.getWidget(head.name);
|
|
87830
87927
|
return widget ? { uri: widget.uri, range: widget.range } : null;
|
|
@@ -87887,7 +87984,7 @@ function findReferences(uri, position, workspace, includeDeclaration) {
|
|
|
87887
87984
|
if (declaration) return findWidgetReferences(declaration.name, workspace, includeDeclaration);
|
|
87888
87985
|
const doc = workspace.markup.get(uri);
|
|
87889
87986
|
const head = doc && macroHeadAt(doc, position);
|
|
87890
|
-
if (head) {
|
|
87987
|
+
if (head?.invocation) {
|
|
87891
87988
|
const widget = workspace.widgets.getWidget(head.name);
|
|
87892
87989
|
if (!workspace.getEffectiveMacro(head.name) && widget && (!head.closing || workspace.isContainer(head.name))) {
|
|
87893
87990
|
return findWidgetReferences(head.name, workspace, includeDeclaration);
|
|
@@ -87957,17 +88054,11 @@ function findWidgetReferences(widgetName2, workspace, includeDeclaration, includ
|
|
|
87957
88054
|
if (workspace.getEffectiveMacro(widgetName2)) return locations;
|
|
87958
88055
|
const lowerName2 = widgetName2.toLowerCase();
|
|
87959
88056
|
const isBlock = workspace.isContainer(widgetName2);
|
|
87960
|
-
|
|
87961
|
-
const doc = workspace.markup.get(
|
|
87962
|
-
|
|
87963
|
-
|
|
87964
|
-
|
|
87965
|
-
if (head.name.toLowerCase() === lowerName2) {
|
|
87966
|
-
locations.push({ uri: docUri, range: head.range });
|
|
87967
|
-
}
|
|
87968
|
-
}
|
|
87969
|
-
}
|
|
87970
|
-
return locations;
|
|
88057
|
+
const calls = workspace.documents.getUris().flatMap((uri) => {
|
|
88058
|
+
const doc = workspace.markup.get(uri);
|
|
88059
|
+
return doc ? documentMacroHeads(doc).filter((head) => head.invocation && head.name.toLowerCase() === lowerName2 && (!head.closing || isBlock && includeClosingTags)).map((head) => ({ uri, range: head.range })) : [];
|
|
88060
|
+
});
|
|
88061
|
+
return locations.concat(calls);
|
|
87971
88062
|
}
|
|
87972
88063
|
function toLspRange3(r) {
|
|
87973
88064
|
return {
|
|
@@ -88292,7 +88383,7 @@ function resolveSymbolAtCursor(uri, position, workspace) {
|
|
|
88292
88383
|
if (declaration) return { kind: "widget", name: declaration.name, range: declaration.nameRange };
|
|
88293
88384
|
const doc = workspace.markup.get(uri);
|
|
88294
88385
|
const head = doc && macroHeadAt(doc, position);
|
|
88295
|
-
if (head) {
|
|
88386
|
+
if (head?.invocation) {
|
|
88296
88387
|
const widget = workspace.widgets.getWidget(head.name);
|
|
88297
88388
|
if (!workspace.getEffectiveMacro(head.name) && widget && (!head.closing || workspace.isContainer(head.name))) {
|
|
88298
88389
|
return { kind: "widget", name: head.name, range: head.range };
|
|
@@ -88685,9 +88776,13 @@ var init_semantic_tokens = __esm({
|
|
|
88685
88776
|
import { readFileSync as readFileSync7 } from "node:fs";
|
|
88686
88777
|
import { basename as basename2, dirname as dirname5, join as join4 } from "node:path";
|
|
88687
88778
|
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
88779
|
+
import { isDeepStrictEqual } from "node:util";
|
|
88688
88780
|
function computeCodeActions(uri, diagnostics, workspace, options = {}) {
|
|
88689
88781
|
const actions = [];
|
|
88782
|
+
const current2 = computeDiagnostics(uri, workspace);
|
|
88690
88783
|
for (const diag of diagnostics) {
|
|
88784
|
+
const fresh = current2.find((candidate) => candidate.code === diag.code && isDeepStrictEqual(candidate.range, diag.range) && isDeepStrictEqual(candidate.data, diag.data));
|
|
88785
|
+
if (!fresh && diag.code !== DiagnosticCode.NoStoryVariables) continue;
|
|
88691
88786
|
switch (diag.code) {
|
|
88692
88787
|
case DiagnosticCode.UndefinedMacro:
|
|
88693
88788
|
actions.push(...fixUndefinedMacro(uri, diag, workspace, options));
|
|
@@ -89017,6 +89112,7 @@ var init_code_actions = __esm({
|
|
|
89017
89112
|
"use strict";
|
|
89018
89113
|
import_yaml3 = __toESM(require_dist(), 1);
|
|
89019
89114
|
init_diagnostic_codes();
|
|
89115
|
+
init_diagnostics();
|
|
89020
89116
|
init_config_loader();
|
|
89021
89117
|
init_story_variables_owner();
|
|
89022
89118
|
init_macro_sources();
|