@rohal12/spindle-lsp 0.14.2 → 0.14.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/dist/bin.js +144 -181
- package/dist/bin.js.map +4 -4
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -3039,6 +3039,40 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
|
|
|
3039
3039
|
}
|
|
3040
3040
|
});
|
|
3041
3041
|
|
|
3042
|
+
// src/core/workspace/file-inputs.ts
|
|
3043
|
+
import { readFileSync, statSync } from "node:fs";
|
|
3044
|
+
import { resolve } from "node:path";
|
|
3045
|
+
async function resolveFiles(pattern, cwd) {
|
|
3046
|
+
let input = pattern;
|
|
3047
|
+
let directory = cwd;
|
|
3048
|
+
const literal3 = resolve(cwd, pattern);
|
|
3049
|
+
try {
|
|
3050
|
+
const stat = statSync(literal3);
|
|
3051
|
+
if (stat.isFile()) return [literal3];
|
|
3052
|
+
if (stat.isDirectory()) {
|
|
3053
|
+
directory = literal3;
|
|
3054
|
+
input = "**/*.{tw,twee}";
|
|
3055
|
+
}
|
|
3056
|
+
} catch (error48) {
|
|
3057
|
+
const code = error48.code;
|
|
3058
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") throw error48;
|
|
3059
|
+
}
|
|
3060
|
+
return [...new Set(await Ze(input, { cwd: directory, absolute: true, nodir: true }))];
|
|
3061
|
+
}
|
|
3062
|
+
function readFileContents(files) {
|
|
3063
|
+
return new Map(files.map((file2) => [file2, readFileSync(file2, "utf8")]));
|
|
3064
|
+
}
|
|
3065
|
+
async function resolveInputs(patterns, cwd) {
|
|
3066
|
+
const files = await Promise.all(patterns.map((pattern) => resolveFiles(pattern, cwd)));
|
|
3067
|
+
return [...new Set(files.flat())];
|
|
3068
|
+
}
|
|
3069
|
+
var init_file_inputs = __esm({
|
|
3070
|
+
"src/core/workspace/file-inputs.ts"() {
|
|
3071
|
+
"use strict";
|
|
3072
|
+
init_index_min();
|
|
3073
|
+
}
|
|
3074
|
+
});
|
|
3075
|
+
|
|
3042
3076
|
// node_modules/@rohal12/spindle/dist/pkg/story-variables.js
|
|
3043
3077
|
function isSigil(c) {
|
|
3044
3078
|
return c !== void 0 && SIGIL_CHARS.has(c);
|
|
@@ -16619,7 +16653,7 @@ var init_tooling = __esm({
|
|
|
16619
16653
|
|
|
16620
16654
|
// src/core/workspace/document-store.ts
|
|
16621
16655
|
import { EventEmitter } from "node:events";
|
|
16622
|
-
import { readFileSync } from "node:fs";
|
|
16656
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
16623
16657
|
import { pathToFileURL } from "node:url";
|
|
16624
16658
|
function stripBom(text2) {
|
|
16625
16659
|
return text2.charCodeAt(0) === 65279 ? text2.slice(1) : text2;
|
|
@@ -16667,7 +16701,7 @@ var init_document_store = __esm({
|
|
|
16667
16701
|
loadFromDisk(paths) {
|
|
16668
16702
|
for (const filePath of paths) {
|
|
16669
16703
|
try {
|
|
16670
|
-
const text2 =
|
|
16704
|
+
const text2 = readFileSync2(filePath, "utf-8");
|
|
16671
16705
|
const uri = pathToFileURL(filePath).href;
|
|
16672
16706
|
this.open(uri, text2);
|
|
16673
16707
|
} catch {
|
|
@@ -16681,32 +16715,32 @@ var init_document_store = __esm({
|
|
|
16681
16715
|
// src/core/parsing/passage-parser.ts
|
|
16682
16716
|
function parsePassageHeader(line, lineNumber) {
|
|
16683
16717
|
const bomLength = lineNumber === 0 && line.charCodeAt(0) === 65279 ? 1 : 0;
|
|
16684
|
-
const escaped = line.
|
|
16685
|
-
const
|
|
16686
|
-
if (!
|
|
16687
|
-
const
|
|
16688
|
-
const
|
|
16689
|
-
|
|
16690
|
-
const
|
|
16691
|
-
const
|
|
16692
|
-
const
|
|
16693
|
-
const name = line.substring(nameStart, nameEnd).trim();
|
|
16718
|
+
const escaped = line.replace(/\\./g, "ec");
|
|
16719
|
+
const prefix = /^::\s*/.exec(escaped.slice(bomLength));
|
|
16720
|
+
if (!prefix) return null;
|
|
16721
|
+
const nameStart = bomLength + prefix[0].length;
|
|
16722
|
+
const delimiter = /[\[\]{}]/g;
|
|
16723
|
+
delimiter.lastIndex = nameStart;
|
|
16724
|
+
const first = delimiter.exec(escaped);
|
|
16725
|
+
const nameEnd = first?.index ?? line.length;
|
|
16726
|
+
const name = line.slice(nameStart, nameEnd).trim();
|
|
16694
16727
|
if (!name) return null;
|
|
16695
|
-
|
|
16696
|
-
if (/[\[\]\{\}]/.test(escapedName)) return null;
|
|
16697
|
-
const tagsStr = line.slice(nameEnd, nameEnd + rawTags.length).trim();
|
|
16728
|
+
let rest = nameEnd;
|
|
16698
16729
|
let tags = [];
|
|
16699
|
-
if (
|
|
16700
|
-
const
|
|
16701
|
-
if (/[\[
|
|
16702
|
-
const decoded =
|
|
16730
|
+
if (escaped[rest] === "[") {
|
|
16731
|
+
const end = escaped.indexOf("]", rest + 1);
|
|
16732
|
+
if (end === -1 || /[\[{}]/.test(escaped.slice(rest + 1, end))) return null;
|
|
16733
|
+
const decoded = line.slice(rest + 1, end).replace(/\\(.)/g, "$1").trim();
|
|
16703
16734
|
tags = decoded ? decoded.split(/\s+/) : [];
|
|
16735
|
+
rest = end + 1;
|
|
16736
|
+
while (rest < line.length && /\s/.test(escaped[rest])) rest++;
|
|
16704
16737
|
}
|
|
16705
16738
|
let meta3;
|
|
16706
|
-
|
|
16707
|
-
|
|
16739
|
+
if (rest < line.length) {
|
|
16740
|
+
const raw = line.slice(rest).trim();
|
|
16741
|
+
if (escaped[rest] !== "{" || !raw.endsWith("}")) return null;
|
|
16708
16742
|
try {
|
|
16709
|
-
meta3 = JSON.parse(
|
|
16743
|
+
meta3 = JSON.parse(raw);
|
|
16710
16744
|
} catch {
|
|
16711
16745
|
return null;
|
|
16712
16746
|
}
|
|
@@ -16739,11 +16773,10 @@ function isScriptOrStylesheetPassage(passage) {
|
|
|
16739
16773
|
function isMarkupPassage(passage) {
|
|
16740
16774
|
return !(passage.name !== void 0 && NON_MARKUP_PASSAGES.has(passage.name)) && !isScriptOrStylesheetPassage(passage);
|
|
16741
16775
|
}
|
|
16742
|
-
var
|
|
16776
|
+
var SPECIAL_PASSAGES, CODE_PASSAGE_TAGS, RESERVED_PASSAGE_NAMES, NON_MARKUP_PASSAGES;
|
|
16743
16777
|
var init_passage_parser = __esm({
|
|
16744
16778
|
"src/core/parsing/passage-parser.ts"() {
|
|
16745
16779
|
"use strict";
|
|
16746
|
-
passageHeaderRegex = /^(::\s*)(.*?)(\[.*?\]\s*)?(\{.*?\}\s*)?\r?$/;
|
|
16747
16780
|
SPECIAL_PASSAGES = /* @__PURE__ */ new Set([
|
|
16748
16781
|
"StoryVariables",
|
|
16749
16782
|
"StoryInit",
|
|
@@ -24256,8 +24289,8 @@ var require_dist = __commonJS({
|
|
|
24256
24289
|
});
|
|
24257
24290
|
|
|
24258
24291
|
// src/core/workspace/config-loader.ts
|
|
24259
|
-
import { readFileSync as
|
|
24260
|
-
import { join, resolve } from "node:path";
|
|
24292
|
+
import { readFileSync as readFileSync3, existsSync } from "node:fs";
|
|
24293
|
+
import { join, resolve as resolve2 } from "node:path";
|
|
24261
24294
|
function parseConfig(content, format) {
|
|
24262
24295
|
if (!content.trim()) {
|
|
24263
24296
|
return { macros: {} };
|
|
@@ -24317,7 +24350,7 @@ function findConfigRoot(directory) {
|
|
|
24317
24350
|
let search = directory;
|
|
24318
24351
|
for (let i2 = 0; i2 < 10; i2++) {
|
|
24319
24352
|
if (findConfigFile(search)) return search;
|
|
24320
|
-
const parent =
|
|
24353
|
+
const parent = resolve2(search, "..");
|
|
24321
24354
|
if (parent === search) break;
|
|
24322
24355
|
search = parent;
|
|
24323
24356
|
}
|
|
@@ -24326,7 +24359,7 @@ function findConfigRoot(directory) {
|
|
|
24326
24359
|
function loadConfigFile(configPath) {
|
|
24327
24360
|
let content;
|
|
24328
24361
|
try {
|
|
24329
|
-
content =
|
|
24362
|
+
content = readFileSync3(configPath, "utf-8");
|
|
24330
24363
|
} catch (err) {
|
|
24331
24364
|
const reason = err?.code === "ENOENT" ? "file not found" : err instanceof Error ? err.message : String(err);
|
|
24332
24365
|
throw new Error(`Cannot read config file '${configPath}': ${reason}`);
|
|
@@ -24344,7 +24377,7 @@ function loadConfigFromDisk(workspaceRoot) {
|
|
|
24344
24377
|
if (!configPath) {
|
|
24345
24378
|
return { ...EMPTY_CONFIG };
|
|
24346
24379
|
}
|
|
24347
|
-
const content =
|
|
24380
|
+
const content = readFileSync3(configPath, "utf-8");
|
|
24348
24381
|
const format = configPath.endsWith(".json") ? "json" : "yaml";
|
|
24349
24382
|
return parseConfig(content, format);
|
|
24350
24383
|
}
|
|
@@ -25088,6 +25121,7 @@ var init_widget_registry = __esm({
|
|
|
25088
25121
|
const { name, tags } = markup.passage;
|
|
25089
25122
|
for (const definition of widgetDefinitions([{ name, tags, content: markup.content }], known)) {
|
|
25090
25123
|
this.widgets.set(definition.name.toLowerCase(), {
|
|
25124
|
+
tooling: definition,
|
|
25091
25125
|
name: definition.name,
|
|
25092
25126
|
params: definition.params,
|
|
25093
25127
|
uri: markup.passage.uri,
|
|
@@ -25175,7 +25209,7 @@ var init_markup_index = __esm({
|
|
|
25175
25209
|
});
|
|
25176
25210
|
|
|
25177
25211
|
// src/core/workspace/macro-sources.ts
|
|
25178
|
-
import { existsSync as existsSync2, readFileSync as
|
|
25212
|
+
import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
25179
25213
|
import { dirname, isAbsolute, join as join2, relative } from "node:path";
|
|
25180
25214
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
25181
25215
|
function isExcludedSegment(segment) {
|
|
@@ -25224,7 +25258,7 @@ async function addProjectMacroSources(contents, dir) {
|
|
|
25224
25258
|
const uri = pathToFileURL2(filePath).toString();
|
|
25225
25259
|
if (contents.has(uri)) continue;
|
|
25226
25260
|
try {
|
|
25227
|
-
contents.set(uri,
|
|
25261
|
+
contents.set(uri, readFileSync4(filePath, "utf-8"));
|
|
25228
25262
|
} catch {
|
|
25229
25263
|
}
|
|
25230
25264
|
}
|
|
@@ -25243,8 +25277,8 @@ var init_macro_sources = __esm({
|
|
|
25243
25277
|
});
|
|
25244
25278
|
|
|
25245
25279
|
// src/core/workspace/spindle-version.ts
|
|
25246
|
-
import { existsSync as existsSync3, readFileSync as
|
|
25247
|
-
import { dirname as dirname2, join as join3, resolve as
|
|
25280
|
+
import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
25281
|
+
import { dirname as dirname2, join as join3, resolve as resolve3 } from "node:path";
|
|
25248
25282
|
function parseSpindleVersion(text2) {
|
|
25249
25283
|
const m = /^\s*v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?\s*$/.exec(text2);
|
|
25250
25284
|
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : void 0;
|
|
@@ -25258,12 +25292,12 @@ function atLeast(version2, minimum) {
|
|
|
25258
25292
|
}
|
|
25259
25293
|
function readInstalledSpindleVersion(startDir) {
|
|
25260
25294
|
const target = join3("node_modules", "@rohal12", "spindle", "package.json");
|
|
25261
|
-
let dir =
|
|
25295
|
+
let dir = resolve3(startDir);
|
|
25262
25296
|
for (; ; ) {
|
|
25263
25297
|
const candidate = join3(dir, target);
|
|
25264
25298
|
if (existsSync3(candidate)) {
|
|
25265
25299
|
try {
|
|
25266
|
-
const version2 = JSON.parse(
|
|
25300
|
+
const version2 = JSON.parse(readFileSync5(candidate, "utf-8")).version;
|
|
25267
25301
|
return typeof version2 === "string" && parseSpindleVersion(version2) ? version2 : void 0;
|
|
25268
25302
|
} catch {
|
|
25269
25303
|
return void 0;
|
|
@@ -25294,7 +25328,7 @@ var init_spindle_version = __esm({
|
|
|
25294
25328
|
});
|
|
25295
25329
|
|
|
25296
25330
|
// src/core/workspace/story-format.ts
|
|
25297
|
-
import { readFileSync as
|
|
25331
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
25298
25332
|
function isSpindleFormatName(name) {
|
|
25299
25333
|
return name.trim().toLowerCase() === "spindle";
|
|
25300
25334
|
}
|
|
@@ -25374,7 +25408,7 @@ async function findStoryFormat(texts, dir) {
|
|
|
25374
25408
|
const projectTexts = [];
|
|
25375
25409
|
for (const file2 of await findProjectFiles(findProjectRoot(dir), "**/*.{tw,twee}")) {
|
|
25376
25410
|
try {
|
|
25377
|
-
projectTexts.push(stripBom(
|
|
25411
|
+
projectTexts.push(stripBom(readFileSync6(file2, "utf-8")));
|
|
25378
25412
|
} catch {
|
|
25379
25413
|
}
|
|
25380
25414
|
}
|
|
@@ -25401,7 +25435,7 @@ async function findSpindleTarget(texts, dir) {
|
|
|
25401
25435
|
const projectTexts = [];
|
|
25402
25436
|
for (const file2 of await findProjectFiles(findProjectRoot(dir), "**/*.{tw,twee}")) {
|
|
25403
25437
|
try {
|
|
25404
|
-
projectTexts.push(
|
|
25438
|
+
projectTexts.push(readFileSync6(file2, "utf-8"));
|
|
25405
25439
|
} catch {
|
|
25406
25440
|
}
|
|
25407
25441
|
}
|
|
@@ -25877,7 +25911,7 @@ var init_workspace_model = __esm({
|
|
|
25877
25911
|
text: (uri) => this.documents.getText(uri),
|
|
25878
25912
|
passages: (uri) => this.passages.getPassagesInDocument(uri),
|
|
25879
25913
|
context: () => ({
|
|
25880
|
-
macros: this.
|
|
25914
|
+
macros: this.toolingMacros(),
|
|
25881
25915
|
isBlock: (name) => this.isContainer(name)
|
|
25882
25916
|
})
|
|
25883
25917
|
});
|
|
@@ -26054,60 +26088,38 @@ var init_workspace_model = __esm({
|
|
|
26054
26088
|
this.markup.invalidate();
|
|
26055
26089
|
this.declaredVersion = storyDataFormatVersion(this.passages.getAllPassages(), (uri) => this.documents.getText(uri));
|
|
26056
26090
|
this.target = resolveSpindleTarget(this.installedVersion, this.declaredVersion);
|
|
26057
|
-
const
|
|
26058
|
-
|
|
26059
|
-
|
|
26060
|
-
|
|
26061
|
-
|
|
26062
|
-
|
|
26063
|
-
|
|
26064
|
-
|
|
26065
|
-
|
|
26066
|
-
|
|
26067
|
-
|
|
26068
|
-
}
|
|
26069
|
-
}
|
|
26070
|
-
const content = lines.slice(contentStart, contentEnd).join("\n");
|
|
26071
|
-
this.variables.parseStoryVariables(content, contentStart, storyVars.uri);
|
|
26072
|
-
}
|
|
26073
|
-
} else {
|
|
26074
|
-
this.variables.clearStoryVariables();
|
|
26075
|
-
}
|
|
26076
|
-
const storyTransients = this.passages.getStoryTransients();
|
|
26077
|
-
if (storyTransients) {
|
|
26078
|
-
const text2 = this.documents.getText(storyTransients.uri);
|
|
26079
|
-
if (text2) {
|
|
26080
|
-
const lines = text2.split("\n");
|
|
26081
|
-
const contentStart = storyTransients.headerEnd.end.line + 1;
|
|
26082
|
-
let contentEnd = lines.length;
|
|
26083
|
-
for (let i2 = contentStart; i2 < lines.length; i2++) {
|
|
26084
|
-
if (/^\uFEFF?::\s+/.test(lines[i2])) {
|
|
26085
|
-
contentEnd = i2;
|
|
26086
|
-
break;
|
|
26087
|
-
}
|
|
26088
|
-
}
|
|
26089
|
-
const content = lines.slice(contentStart, contentEnd).join("\n");
|
|
26090
|
-
this.variables.parseStoryTransients(content, contentStart, storyTransients.uri);
|
|
26091
|
-
}
|
|
26092
|
-
} else {
|
|
26093
|
-
this.variables.clearStoryTransients();
|
|
26094
|
-
}
|
|
26095
|
-
const documents = this.documents.getUris().flatMap((uri) => {
|
|
26091
|
+
const declarations = (name) => {
|
|
26092
|
+
const passage = this.passages.getPassage(name);
|
|
26093
|
+
return passage ? this.markup.get(passage.uri)?.passages.find((p) => p.passage === passage) : void 0;
|
|
26094
|
+
};
|
|
26095
|
+
const variables = declarations("StoryVariables");
|
|
26096
|
+
if (variables) this.variables.parseStoryVariables(variables.content, variables.passage.headerEnd.end.line + 1, variables.doc.uri);
|
|
26097
|
+
else this.variables.clearStoryVariables();
|
|
26098
|
+
const transients = declarations("StoryTransients");
|
|
26099
|
+
if (transients) this.variables.parseStoryTransients(transients.content, transients.passage.headerEnd.end.line + 1, transients.doc.uri);
|
|
26100
|
+
else this.variables.clearStoryTransients();
|
|
26101
|
+
const readDocuments = () => this.documents.getUris().flatMap((uri) => {
|
|
26096
26102
|
const markup = isMacroSource(uri) ? void 0 : this.markup.get(uri);
|
|
26097
26103
|
return markup ? [markup] : [];
|
|
26098
26104
|
});
|
|
26099
26105
|
const markups = /* @__PURE__ */ new Map();
|
|
26100
|
-
for (const doc of
|
|
26106
|
+
for (const doc of readDocuments()) for (const passage of doc.passages) markups.set(passage.passage, passage);
|
|
26101
26107
|
this.widgets.scan(
|
|
26102
26108
|
this.passages.getAllPassages().flatMap((passage) => markups.get(passage) ?? []),
|
|
26103
26109
|
this.macros.toolingMacros()
|
|
26104
26110
|
);
|
|
26111
|
+
this.markup.invalidate();
|
|
26105
26112
|
this.widgets.clearInvocations();
|
|
26106
|
-
for (const doc of
|
|
26113
|
+
for (const doc of readDocuments()) {
|
|
26107
26114
|
this.variables.scanDocument(doc.uri, doc.text, doc);
|
|
26108
26115
|
this.widgets.recordInvocations(doc.uri, doc.passages);
|
|
26109
26116
|
}
|
|
26110
26117
|
}
|
|
26118
|
+
/** All runtime metadata, with real macros taking precedence over widgets. */
|
|
26119
|
+
toolingMacros() {
|
|
26120
|
+
const macros = this.macros.toolingMacros();
|
|
26121
|
+
return [...macros, ...this.widgets.getAllWidgets().filter((widget) => !this.macros.getMacro(widget.name)).map((widget) => ({ name: widget.name, block: widget.block, subMacros: [], widget: widget.tooling }))];
|
|
26122
|
+
}
|
|
26111
26123
|
/** Debounce modelReady emission. */
|
|
26112
26124
|
scheduleModelReady() {
|
|
26113
26125
|
if (this.debounceTimer) {
|
|
@@ -27881,8 +27893,7 @@ var check_exports = {};
|
|
|
27881
27893
|
__export(check_exports, {
|
|
27882
27894
|
runCheck: () => runCheck
|
|
27883
27895
|
});
|
|
27884
|
-
import {
|
|
27885
|
-
import { resolve as resolve3 } from "node:path";
|
|
27896
|
+
import { resolve as resolve4 } from "node:path";
|
|
27886
27897
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
27887
27898
|
function parseArgs(args2) {
|
|
27888
27899
|
const options = {
|
|
@@ -27958,22 +27969,21 @@ async function runCheck(args2) {
|
|
|
27958
27969
|
let explicitConfig = null;
|
|
27959
27970
|
if (options.configPath) {
|
|
27960
27971
|
try {
|
|
27961
|
-
explicitConfig = loadConfigFile(
|
|
27972
|
+
explicitConfig = loadConfigFile(resolve4(cwd, options.configPath));
|
|
27962
27973
|
} catch (err) {
|
|
27963
27974
|
console.error(`spindle-lsp check: ${err instanceof Error ? err.message : String(err)}`);
|
|
27964
27975
|
return 2;
|
|
27965
27976
|
}
|
|
27966
27977
|
}
|
|
27967
|
-
|
|
27968
|
-
|
|
27969
|
-
|
|
27970
|
-
|
|
27971
|
-
|
|
27972
|
-
|
|
27973
|
-
});
|
|
27974
|
-
|
|
27978
|
+
let uniqueFiles;
|
|
27979
|
+
let contents;
|
|
27980
|
+
try {
|
|
27981
|
+
uniqueFiles = await resolveInputs(options.patterns, cwd);
|
|
27982
|
+
contents = readFileContents(uniqueFiles);
|
|
27983
|
+
} catch (error48) {
|
|
27984
|
+
console.error(`spindle-lsp check: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
27985
|
+
return 2;
|
|
27975
27986
|
}
|
|
27976
|
-
const uniqueFiles = [...new Set(files)];
|
|
27977
27987
|
if (uniqueFiles.length === 0) {
|
|
27978
27988
|
if (options.format === "pretty") {
|
|
27979
27989
|
console.log("No files found");
|
|
@@ -27997,15 +28007,7 @@ async function runCheck(args2) {
|
|
|
27997
28007
|
return 1;
|
|
27998
28008
|
}
|
|
27999
28009
|
}
|
|
28000
|
-
const fileContents =
|
|
28001
|
-
for (const filePath of uniqueFiles) {
|
|
28002
|
-
try {
|
|
28003
|
-
const text2 = readFileSync6(filePath, "utf-8");
|
|
28004
|
-
const uri = pathToFileURL3(filePath).toString();
|
|
28005
|
-
fileContents.set(uri, text2);
|
|
28006
|
-
} catch {
|
|
28007
|
-
}
|
|
28008
|
-
}
|
|
28010
|
+
const fileContents = new Map([...contents].map(([path, text2]) => [pathToFileURL3(path).toString(), text2]));
|
|
28009
28011
|
const storyFormat = await findStoryFormat(fileContents.values(), commonDir);
|
|
28010
28012
|
if (!storyFormat.isSpindle) {
|
|
28011
28013
|
console.error(skippedFormatNote(storyFormat));
|
|
@@ -28058,7 +28060,7 @@ var SEVERITY_ORDER;
|
|
|
28058
28060
|
var init_check = __esm({
|
|
28059
28061
|
"src/cli/check.ts"() {
|
|
28060
28062
|
"use strict";
|
|
28061
|
-
|
|
28063
|
+
init_file_inputs();
|
|
28062
28064
|
init_workspace_model();
|
|
28063
28065
|
init_diagnostics();
|
|
28064
28066
|
init_config_loader();
|
|
@@ -28126,7 +28128,7 @@ var init_segment = __esm({
|
|
|
28126
28128
|
});
|
|
28127
28129
|
|
|
28128
28130
|
// src/plugins/format/prettier-bridge.ts
|
|
28129
|
-
import { resolve as
|
|
28131
|
+
import { resolve as resolve5 } from "node:path";
|
|
28130
28132
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
28131
28133
|
async function loadPrettier(filePath) {
|
|
28132
28134
|
prettier ??= import("prettier").catch(() => null);
|
|
@@ -28134,7 +28136,7 @@ async function loadPrettier(filePath) {
|
|
|
28134
28136
|
if (!p) return void 0;
|
|
28135
28137
|
try {
|
|
28136
28138
|
const path = filePath?.startsWith("file:") ? fileURLToPath2(filePath) : filePath;
|
|
28137
|
-
const resolved = await p.resolveConfig(path ??
|
|
28139
|
+
const resolved = await p.resolveConfig(path ?? resolve5(process.cwd(), "story.tw"));
|
|
28138
28140
|
return { prettier: p, options: { tabWidth: 2, ...resolved ?? {} } };
|
|
28139
28141
|
} catch {
|
|
28140
28142
|
return { prettier: p, options: { tabWidth: 2 } };
|
|
@@ -28192,8 +28194,10 @@ async function formatLf2(text2, options) {
|
|
|
28192
28194
|
resultLines.push(header.replace(/\s+$/, ""));
|
|
28193
28195
|
}
|
|
28194
28196
|
if (passage.body === "") continue;
|
|
28195
|
-
const
|
|
28196
|
-
|
|
28197
|
+
const role = parsePassageHeader(passage.header, passage.startLine);
|
|
28198
|
+
const kind = classifyPassage(passage.header);
|
|
28199
|
+
const body = kind === "normal" && role && !isMarkupPassage(role) ? passage.body : await formatPassage(passage.body, {
|
|
28200
|
+
kind,
|
|
28197
28201
|
prettier: prettier2?.prettier,
|
|
28198
28202
|
prettierOptions: prettier2?.options,
|
|
28199
28203
|
isBlock,
|
|
@@ -28232,6 +28236,7 @@ var init_format = __esm({
|
|
|
28232
28236
|
"src/plugins/format.ts"() {
|
|
28233
28237
|
"use strict";
|
|
28234
28238
|
init_tooling();
|
|
28239
|
+
init_passage_parser();
|
|
28235
28240
|
init_segment();
|
|
28236
28241
|
init_prettier_bridge();
|
|
28237
28242
|
PASSAGE_HEADER_REGEX = /^(::)\s*/;
|
|
@@ -28291,7 +28296,7 @@ var format_exports = {};
|
|
|
28291
28296
|
__export(format_exports, {
|
|
28292
28297
|
runFormat: () => runFormat
|
|
28293
28298
|
});
|
|
28294
|
-
import {
|
|
28299
|
+
import { writeFileSync } from "node:fs";
|
|
28295
28300
|
function parseArgs2(args2) {
|
|
28296
28301
|
const options = {
|
|
28297
28302
|
check: false,
|
|
@@ -28327,27 +28332,19 @@ function parseArgs2(args2) {
|
|
|
28327
28332
|
async function runFormat(args2) {
|
|
28328
28333
|
const options = parseArgs2(args2);
|
|
28329
28334
|
const cwd = process.cwd();
|
|
28330
|
-
|
|
28331
|
-
|
|
28332
|
-
|
|
28333
|
-
|
|
28334
|
-
|
|
28335
|
-
|
|
28336
|
-
});
|
|
28337
|
-
|
|
28335
|
+
let uniqueFiles;
|
|
28336
|
+
let texts;
|
|
28337
|
+
try {
|
|
28338
|
+
uniqueFiles = await resolveInputs(options.patterns, cwd);
|
|
28339
|
+
texts = readFileContents(uniqueFiles);
|
|
28340
|
+
} catch (error48) {
|
|
28341
|
+
console.error(`spindle-lsp format: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
28342
|
+
return 2;
|
|
28338
28343
|
}
|
|
28339
|
-
const uniqueFiles = [...new Set(files)];
|
|
28340
28344
|
if (uniqueFiles.length === 0) {
|
|
28341
28345
|
console.log("No files found");
|
|
28342
28346
|
return 0;
|
|
28343
28347
|
}
|
|
28344
|
-
const texts = /* @__PURE__ */ new Map();
|
|
28345
|
-
for (const filePath of uniqueFiles) {
|
|
28346
|
-
try {
|
|
28347
|
-
texts.set(filePath, readFileSync7(filePath, "utf-8"));
|
|
28348
|
-
} catch {
|
|
28349
|
-
}
|
|
28350
|
-
}
|
|
28351
28348
|
const storyFormat = await findStoryFormat(texts.values(), commonDirectory(uniqueFiles));
|
|
28352
28349
|
if (!storyFormat.isSpindle) {
|
|
28353
28350
|
console.error(skippedFormatNote(storyFormat));
|
|
@@ -28360,6 +28357,7 @@ async function runFormat(args2) {
|
|
|
28360
28357
|
formatOpts.maxLineLength = options.maxLineLength;
|
|
28361
28358
|
}
|
|
28362
28359
|
const unformatted = [];
|
|
28360
|
+
let failed = false;
|
|
28363
28361
|
for (const [filePath, text2] of texts) {
|
|
28364
28362
|
try {
|
|
28365
28363
|
const formatted = await formatDocument(text2, { ...formatOpts, filePath });
|
|
@@ -28371,9 +28369,12 @@ async function runFormat(args2) {
|
|
|
28371
28369
|
writeFileSync(filePath, formatted, "utf-8");
|
|
28372
28370
|
}
|
|
28373
28371
|
}
|
|
28374
|
-
} catch {
|
|
28372
|
+
} catch (error48) {
|
|
28373
|
+
failed = true;
|
|
28374
|
+
console.error(`spindle-lsp format: ${filePath}: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
28375
28375
|
}
|
|
28376
28376
|
}
|
|
28377
|
+
if (failed) return 2;
|
|
28377
28378
|
if (options.check) {
|
|
28378
28379
|
if (unformatted.length > 0) {
|
|
28379
28380
|
for (const file2 of unformatted) {
|
|
@@ -28390,7 +28391,7 @@ ${unformatted.length} file${unformatted.length !== 1 ? "s" : ""} would be reform
|
|
|
28390
28391
|
var init_format2 = __esm({
|
|
28391
28392
|
"src/cli/format.ts"() {
|
|
28392
28393
|
"use strict";
|
|
28393
|
-
|
|
28394
|
+
init_file_inputs();
|
|
28394
28395
|
init_format();
|
|
28395
28396
|
init_macro_sources();
|
|
28396
28397
|
init_story_format();
|
|
@@ -59658,8 +59659,7 @@ __export(server_exports, {
|
|
|
59658
59659
|
formatFiles: () => formatFiles,
|
|
59659
59660
|
startMcpServer: () => startMcpServer
|
|
59660
59661
|
});
|
|
59661
|
-
import {
|
|
59662
|
-
import { resolve as resolve5 } from "node:path";
|
|
59662
|
+
import { writeFileSync as writeFileSync2 } from "node:fs";
|
|
59663
59663
|
import { pathToFileURL as pathToFileURL4 } from "node:url";
|
|
59664
59664
|
function filterBySeverity2(diagnostics, minSeverity) {
|
|
59665
59665
|
const minIdx = SEVERITY_ORDER2.indexOf(minSeverity);
|
|
@@ -59668,37 +59668,8 @@ function filterBySeverity2(diagnostics, minSeverity) {
|
|
|
59668
59668
|
return idx >= minIdx;
|
|
59669
59669
|
});
|
|
59670
59670
|
}
|
|
59671
|
-
async function resolveFiles(pattern, cwd) {
|
|
59672
|
-
let input = pattern;
|
|
59673
|
-
let directory = cwd;
|
|
59674
|
-
try {
|
|
59675
|
-
const literal3 = resolve5(cwd, pattern);
|
|
59676
|
-
const stat = statSync(literal3);
|
|
59677
|
-
if (stat.isFile()) return [literal3];
|
|
59678
|
-
if (stat.isDirectory()) {
|
|
59679
|
-
directory = literal3;
|
|
59680
|
-
input = "**/*.{tw,twee}";
|
|
59681
|
-
}
|
|
59682
|
-
} catch {
|
|
59683
|
-
}
|
|
59684
|
-
const matches = await Ze(input, {
|
|
59685
|
-
cwd: directory,
|
|
59686
|
-
absolute: true,
|
|
59687
|
-
nodir: true
|
|
59688
|
-
});
|
|
59689
|
-
return [...new Set(matches)];
|
|
59690
|
-
}
|
|
59691
59671
|
function readFiles(files) {
|
|
59692
|
-
|
|
59693
|
-
for (const filePath of files) {
|
|
59694
|
-
try {
|
|
59695
|
-
const text2 = readFileSync8(filePath, "utf-8");
|
|
59696
|
-
const uri = pathToFileURL4(filePath).toString();
|
|
59697
|
-
fileContents.set(uri, text2);
|
|
59698
|
-
} catch {
|
|
59699
|
-
}
|
|
59700
|
-
}
|
|
59701
|
-
return fileContents;
|
|
59672
|
+
return new Map([...readFileContents(files)].map(([path, text2]) => [pathToFileURL4(path).toString(), text2]));
|
|
59702
59673
|
}
|
|
59703
59674
|
async function skippedReason(fileContents, files) {
|
|
59704
59675
|
const format = await findStoryFormat(fileContents.values(), commonDirectory(files));
|
|
@@ -59735,7 +59706,6 @@ async function checkProject(pattern, severity, cwd = process.cwd()) {
|
|
|
59735
59706
|
const results = [];
|
|
59736
59707
|
for (const filePath of files) {
|
|
59737
59708
|
const uri = pathToFileURL4(filePath).toString();
|
|
59738
|
-
if (!workspace.documents.has(uri)) continue;
|
|
59739
59709
|
let diags = computeDiagnostics(uri, workspace);
|
|
59740
59710
|
if (severity) {
|
|
59741
59711
|
diags = filterBySeverity2(diags, severity);
|
|
@@ -59781,7 +59751,8 @@ async function formatFiles(pattern, cwd = process.cwd()) {
|
|
|
59781
59751
|
} else {
|
|
59782
59752
|
unchanged++;
|
|
59783
59753
|
}
|
|
59784
|
-
} catch {
|
|
59754
|
+
} catch (error48) {
|
|
59755
|
+
throw new Error(`${filePath}: ${error48 instanceof Error ? error48.message : String(error48)}`, { cause: error48 });
|
|
59785
59756
|
}
|
|
59786
59757
|
}
|
|
59787
59758
|
return { formatted, unchanged, files: changedFiles, ...warning && { warning } };
|
|
@@ -59800,7 +59771,8 @@ async function checkFormatting(pattern, cwd = process.cwd()) {
|
|
|
59800
59771
|
try {
|
|
59801
59772
|
const result = await formatDocument(text2, { filePath });
|
|
59802
59773
|
(result !== text2 ? needsFormatting : alreadyFormatted).push(relativeTo(cwd, filePath));
|
|
59803
|
-
} catch {
|
|
59774
|
+
} catch (error48) {
|
|
59775
|
+
throw new Error(`${filePath}: ${error48 instanceof Error ? error48.message : String(error48)}`, { cause: error48 });
|
|
59804
59776
|
}
|
|
59805
59777
|
}
|
|
59806
59778
|
return { needsFormatting, alreadyFormatted, ...warning && { warning } };
|
|
@@ -59860,7 +59832,7 @@ var SEVERITY_ORDER2;
|
|
|
59860
59832
|
var init_server3 = __esm({
|
|
59861
59833
|
"src/mcp/server.ts"() {
|
|
59862
59834
|
"use strict";
|
|
59863
|
-
|
|
59835
|
+
init_file_inputs();
|
|
59864
59836
|
init_mcp();
|
|
59865
59837
|
init_stdio2();
|
|
59866
59838
|
init_zod();
|
|
@@ -71635,7 +71607,7 @@ var init_semantic_tokens = __esm({
|
|
|
71635
71607
|
});
|
|
71636
71608
|
|
|
71637
71609
|
// src/plugins/code-actions.ts
|
|
71638
|
-
import { readFileSync as
|
|
71610
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
71639
71611
|
import { basename, dirname as dirname3, join as join4 } from "node:path";
|
|
71640
71612
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL5 } from "node:url";
|
|
71641
71613
|
function computeCodeActions(uri, diagnostics, workspace, options = {}) {
|
|
@@ -71709,7 +71681,7 @@ function addMacroToConfig(uri, macroName, workspace, options) {
|
|
|
71709
71681
|
let text2 = workspace.documents.getText(configUri);
|
|
71710
71682
|
if (text2 === void 0) {
|
|
71711
71683
|
try {
|
|
71712
|
-
text2 =
|
|
71684
|
+
text2 = readFileSync7(existingPath, "utf-8");
|
|
71713
71685
|
} catch {
|
|
71714
71686
|
return null;
|
|
71715
71687
|
}
|
|
@@ -71840,18 +71812,6 @@ function lineEndingFor(workspace, uri) {
|
|
|
71840
71812
|
}
|
|
71841
71813
|
return "\n";
|
|
71842
71814
|
}
|
|
71843
|
-
function declarationInsertEdit(text2, headerLine, declaration, eol) {
|
|
71844
|
-
const lines = text2.split("\n");
|
|
71845
|
-
let contentEnd = lines.length;
|
|
71846
|
-
for (let i2 = headerLine + 1; i2 < lines.length; i2++) {
|
|
71847
|
-
if (/^\uFEFF?::\s+/.test(lines[i2])) {
|
|
71848
|
-
contentEnd = i2;
|
|
71849
|
-
break;
|
|
71850
|
-
}
|
|
71851
|
-
}
|
|
71852
|
-
if (contentEnd === lines.length && text2.endsWith("\n")) contentEnd = lines.length;
|
|
71853
|
-
return insertLinesAt(text2, contentEnd, declaration, eol);
|
|
71854
|
-
}
|
|
71855
71815
|
function declareVariable(diag, workspace, sigil) {
|
|
71856
71816
|
if (diag.data?.kind !== "undeclared-variable" || diag.data.sigil !== sigil) return [];
|
|
71857
71817
|
const { name } = diag.data;
|
|
@@ -71859,7 +71819,10 @@ function declareVariable(diag, workspace, sigil) {
|
|
|
71859
71819
|
if (!passage) return [];
|
|
71860
71820
|
const text2 = workspace.documents.getText(passage.uri);
|
|
71861
71821
|
if (text2 === void 0) return [];
|
|
71862
|
-
const
|
|
71822
|
+
const markup = workspace.markup.get(passage.uri)?.passages.find((p) => p.passage === passage);
|
|
71823
|
+
if (!markup) return [];
|
|
71824
|
+
const boundary = markup.bodyEnd === text2.length ? text2.split("\n").length : markup.position(markup.content.length).line;
|
|
71825
|
+
const edit = insertLinesAt(text2, boundary, `${sigil}${name} = 0
|
|
71863
71826
|
`, lineEndingFor(workspace, passage.uri));
|
|
71864
71827
|
return [{
|
|
71865
71828
|
title: `Declare '${sigil}${name}' in ${sigil === "$" ? "StoryVariables" : "StoryTransients"}`,
|
|
@@ -72354,7 +72317,7 @@ __export(server_exports2, {
|
|
|
72354
72317
|
startServer: () => startServer
|
|
72355
72318
|
});
|
|
72356
72319
|
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL6 } from "node:url";
|
|
72357
|
-
import { readFileSync as
|
|
72320
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
72358
72321
|
import { basename as basename2 } from "node:path";
|
|
72359
72322
|
function uriToFsPath(uri) {
|
|
72360
72323
|
try {
|
|
@@ -72492,7 +72455,7 @@ function startServer(args2) {
|
|
|
72492
72455
|
if (workspace) {
|
|
72493
72456
|
try {
|
|
72494
72457
|
const fsPath = uriToFsPath(textDocument.uri);
|
|
72495
|
-
const text2 =
|
|
72458
|
+
const text2 = readFileSync8(fsPath, "utf-8");
|
|
72496
72459
|
workspace.documents.update(textDocument.uri, text2);
|
|
72497
72460
|
} catch {
|
|
72498
72461
|
workspace.documents.close(textDocument.uri);
|
|
@@ -72528,7 +72491,7 @@ function startServer(args2) {
|
|
|
72528
72491
|
} else {
|
|
72529
72492
|
try {
|
|
72530
72493
|
const fsPath = uriToFsPath(change.uri);
|
|
72531
|
-
const text2 =
|
|
72494
|
+
const text2 = readFileSync8(fsPath, "utf-8");
|
|
72532
72495
|
if (workspace.documents.has(change.uri)) {
|
|
72533
72496
|
workspace.documents.update(change.uri, text2);
|
|
72534
72497
|
} else {
|
|
@@ -72564,7 +72527,7 @@ async function scanWorkspaceFiles(root) {
|
|
|
72564
72527
|
];
|
|
72565
72528
|
for (const filePath of files) {
|
|
72566
72529
|
try {
|
|
72567
|
-
const text2 =
|
|
72530
|
+
const text2 = readFileSync8(filePath, "utf-8");
|
|
72568
72531
|
const uri = fsPathToUri(filePath);
|
|
72569
72532
|
contents.set(uri, text2);
|
|
72570
72533
|
} catch {
|
|
@@ -72594,7 +72557,7 @@ var init_server4 = __esm({
|
|
|
72594
72557
|
|
|
72595
72558
|
// src/bin.ts
|
|
72596
72559
|
var args = process.argv.slice(2);
|
|
72597
|
-
var VERSION = "0.14.
|
|
72560
|
+
var VERSION = "0.14.3";
|
|
72598
72561
|
var HELP = `spindle-lsp v${VERSION}
|
|
72599
72562
|
Language Server Protocol server for Spindle story format
|
|
72600
72563
|
|