@void2610/tyranoscript-lsp 0.3.0 → 0.5.0

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.
Files changed (3) hide show
  1. package/README.md +11 -0
  2. package/dist/server.js +300 -39
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,6 +8,17 @@
8
8
  - パラメータの補完(使用済みパラメータを自動除外)
9
9
  - 必須パラメータのスニペット自動挿入
10
10
  - ホバーによるタグ・パラメータのドキュメント表示
11
+ - ワークスペース内のアセット・ラベル・マクロのインデックス自動構築
12
+ - `storage=""` にアセットファイル名を補完
13
+ - `target=""` にラベル名(`*xxx`)を補完
14
+ - ユーザー定義マクロの補完・ホバードキュメント
15
+ - 定義へジャンプ(Go to Definition)
16
+ - `target="*xxx"` → ラベル定義行へジャンプ
17
+ - `storage="xxx.ks"` → 対象ファイル先頭へジャンプ
18
+ - `[mymacro]` / `@mymacro` → マクロ定義行へジャンプ
19
+ - 参照検索(Find References)
20
+ - ラベル定義行 / 参照箇所から全使用箇所を一覧表示
21
+ - マクロ定義行 / 使用箇所から全使用箇所を一覧表示
11
22
 
12
23
  ## 開発
13
24
 
package/dist/server.js CHANGED
@@ -3371,8 +3371,8 @@ var require_main2 = __commonJS({
3371
3371
  }
3372
3372
  uinteger2.is = is;
3373
3373
  })(uinteger || (exports3.uinteger = uinteger = {}));
3374
- var Position;
3375
- (function(Position2) {
3374
+ var Position2;
3375
+ (function(Position3) {
3376
3376
  function create(line, character) {
3377
3377
  if (line === Number.MAX_VALUE) {
3378
3378
  line = uinteger.MAX_VALUE;
@@ -3382,43 +3382,43 @@ var require_main2 = __commonJS({
3382
3382
  }
3383
3383
  return { line, character };
3384
3384
  }
3385
- Position2.create = create;
3385
+ Position3.create = create;
3386
3386
  function is(value) {
3387
3387
  var candidate = value;
3388
3388
  return Is.objectLiteral(candidate) && Is.uinteger(candidate.line) && Is.uinteger(candidate.character);
3389
3389
  }
3390
- Position2.is = is;
3391
- })(Position || (exports3.Position = Position = {}));
3392
- var Range;
3393
- (function(Range2) {
3390
+ Position3.is = is;
3391
+ })(Position2 || (exports3.Position = Position2 = {}));
3392
+ var Range2;
3393
+ (function(Range3) {
3394
3394
  function create(one, two, three, four) {
3395
3395
  if (Is.uinteger(one) && Is.uinteger(two) && Is.uinteger(three) && Is.uinteger(four)) {
3396
- return { start: Position.create(one, two), end: Position.create(three, four) };
3397
- } else if (Position.is(one) && Position.is(two)) {
3396
+ return { start: Position2.create(one, two), end: Position2.create(three, four) };
3397
+ } else if (Position2.is(one) && Position2.is(two)) {
3398
3398
  return { start: one, end: two };
3399
3399
  } else {
3400
3400
  throw new Error("Range#create called with invalid arguments[".concat(one, ", ").concat(two, ", ").concat(three, ", ").concat(four, "]"));
3401
3401
  }
3402
3402
  }
3403
- Range2.create = create;
3403
+ Range3.create = create;
3404
3404
  function is(value) {
3405
3405
  var candidate = value;
3406
- return Is.objectLiteral(candidate) && Position.is(candidate.start) && Position.is(candidate.end);
3406
+ return Is.objectLiteral(candidate) && Position2.is(candidate.start) && Position2.is(candidate.end);
3407
3407
  }
3408
- Range2.is = is;
3409
- })(Range || (exports3.Range = Range = {}));
3410
- var Location;
3411
- (function(Location2) {
3408
+ Range3.is = is;
3409
+ })(Range2 || (exports3.Range = Range2 = {}));
3410
+ var Location2;
3411
+ (function(Location3) {
3412
3412
  function create(uri, range) {
3413
3413
  return { uri, range };
3414
3414
  }
3415
- Location2.create = create;
3415
+ Location3.create = create;
3416
3416
  function is(value) {
3417
3417
  var candidate = value;
3418
- return Is.objectLiteral(candidate) && Range.is(candidate.range) && (Is.string(candidate.uri) || Is.undefined(candidate.uri));
3418
+ return Is.objectLiteral(candidate) && Range2.is(candidate.range) && (Is.string(candidate.uri) || Is.undefined(candidate.uri));
3419
3419
  }
3420
- Location2.is = is;
3421
- })(Location || (exports3.Location = Location = {}));
3420
+ Location3.is = is;
3421
+ })(Location2 || (exports3.Location = Location2 = {}));
3422
3422
  var LocationLink;
3423
3423
  (function(LocationLink2) {
3424
3424
  function create(targetUri, targetRange, targetSelectionRange, originSelectionRange) {
@@ -3427,7 +3427,7 @@ var require_main2 = __commonJS({
3427
3427
  LocationLink2.create = create;
3428
3428
  function is(value) {
3429
3429
  var candidate = value;
3430
- return Is.objectLiteral(candidate) && Range.is(candidate.targetRange) && Is.string(candidate.targetUri) && Range.is(candidate.targetSelectionRange) && (Range.is(candidate.originSelectionRange) || Is.undefined(candidate.originSelectionRange));
3430
+ return Is.objectLiteral(candidate) && Range2.is(candidate.targetRange) && Is.string(candidate.targetUri) && Range2.is(candidate.targetSelectionRange) && (Range2.is(candidate.originSelectionRange) || Is.undefined(candidate.originSelectionRange));
3431
3431
  }
3432
3432
  LocationLink2.is = is;
3433
3433
  })(LocationLink || (exports3.LocationLink = LocationLink = {}));
@@ -3459,7 +3459,7 @@ var require_main2 = __commonJS({
3459
3459
  ColorInformation2.create = create;
3460
3460
  function is(value) {
3461
3461
  var candidate = value;
3462
- return Is.objectLiteral(candidate) && Range.is(candidate.range) && Color.is(candidate.color);
3462
+ return Is.objectLiteral(candidate) && Range2.is(candidate.range) && Color.is(candidate.color);
3463
3463
  }
3464
3464
  ColorInformation2.is = is;
3465
3465
  })(ColorInformation || (exports3.ColorInformation = ColorInformation = {}));
@@ -3524,7 +3524,7 @@ var require_main2 = __commonJS({
3524
3524
  DiagnosticRelatedInformation2.create = create;
3525
3525
  function is(value) {
3526
3526
  var candidate = value;
3527
- return Is.defined(candidate) && Location.is(candidate.location) && Is.string(candidate.message);
3527
+ return Is.defined(candidate) && Location2.is(candidate.location) && Is.string(candidate.message);
3528
3528
  }
3529
3529
  DiagnosticRelatedInformation2.is = is;
3530
3530
  })(DiagnosticRelatedInformation || (exports3.DiagnosticRelatedInformation = DiagnosticRelatedInformation = {}));
@@ -3570,7 +3570,7 @@ var require_main2 = __commonJS({
3570
3570
  function is(value) {
3571
3571
  var _a;
3572
3572
  var candidate = value;
3573
- return Is.defined(candidate) && Range.is(candidate.range) && Is.string(candidate.message) && (Is.number(candidate.severity) || Is.undefined(candidate.severity)) && (Is.integer(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code)) && (Is.undefined(candidate.codeDescription) || Is.string((_a = candidate.codeDescription) === null || _a === void 0 ? void 0 : _a.href)) && (Is.string(candidate.source) || Is.undefined(candidate.source)) && (Is.undefined(candidate.relatedInformation) || Is.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation.is));
3573
+ return Is.defined(candidate) && Range2.is(candidate.range) && Is.string(candidate.message) && (Is.number(candidate.severity) || Is.undefined(candidate.severity)) && (Is.integer(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code)) && (Is.undefined(candidate.codeDescription) || Is.string((_a = candidate.codeDescription) === null || _a === void 0 ? void 0 : _a.href)) && (Is.string(candidate.source) || Is.undefined(candidate.source)) && (Is.undefined(candidate.relatedInformation) || Is.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation.is));
3574
3574
  }
3575
3575
  Diagnostic2.is = is;
3576
3576
  })(Diagnostic || (exports3.Diagnostic = Diagnostic = {}));
@@ -3610,7 +3610,7 @@ var require_main2 = __commonJS({
3610
3610
  TextEdit2.del = del;
3611
3611
  function is(value) {
3612
3612
  var candidate = value;
3613
- return Is.objectLiteral(candidate) && Is.string(candidate.newText) && Range.is(candidate.range);
3613
+ return Is.objectLiteral(candidate) && Is.string(candidate.newText) && Range2.is(candidate.range);
3614
3614
  }
3615
3615
  TextEdit2.is = is;
3616
3616
  })(TextEdit || (exports3.TextEdit = TextEdit = {}));
@@ -4154,7 +4154,7 @@ var require_main2 = __commonJS({
4154
4154
  InsertReplaceEdit2.create = create;
4155
4155
  function is(value) {
4156
4156
  var candidate = value;
4157
- return candidate && Is.string(candidate.newText) && Range.is(candidate.insert) && Range.is(candidate.replace);
4157
+ return candidate && Is.string(candidate.newText) && Range2.is(candidate.insert) && Range2.is(candidate.replace);
4158
4158
  }
4159
4159
  InsertReplaceEdit2.is = is;
4160
4160
  })(InsertReplaceEdit || (exports3.InsertReplaceEdit = InsertReplaceEdit = {}));
@@ -4201,7 +4201,7 @@ var require_main2 = __commonJS({
4201
4201
  (function(Hover3) {
4202
4202
  function is(value) {
4203
4203
  var candidate = value;
4204
- return !!candidate && Is.objectLiteral(candidate) && (MarkupContent.is(candidate.contents) || MarkedString.is(candidate.contents) || Is.typedArray(candidate.contents, MarkedString.is)) && (value.range === void 0 || Range.is(value.range));
4204
+ return !!candidate && Is.objectLiteral(candidate) && (MarkupContent.is(candidate.contents) || MarkedString.is(candidate.contents) || Is.typedArray(candidate.contents, MarkedString.is)) && (value.range === void 0 || Range2.is(value.range));
4205
4205
  }
4206
4206
  Hover3.is = is;
4207
4207
  })(Hover2 || (exports3.Hover = Hover2 = {}));
@@ -4322,7 +4322,7 @@ var require_main2 = __commonJS({
4322
4322
  DocumentSymbol2.create = create;
4323
4323
  function is(value) {
4324
4324
  var candidate = value;
4325
- return candidate && Is.string(candidate.name) && Is.number(candidate.kind) && Range.is(candidate.range) && Range.is(candidate.selectionRange) && (candidate.detail === void 0 || Is.string(candidate.detail)) && (candidate.deprecated === void 0 || Is.boolean(candidate.deprecated)) && (candidate.children === void 0 || Array.isArray(candidate.children)) && (candidate.tags === void 0 || Array.isArray(candidate.tags));
4325
+ return candidate && Is.string(candidate.name) && Is.number(candidate.kind) && Range2.is(candidate.range) && Range2.is(candidate.selectionRange) && (candidate.detail === void 0 || Is.string(candidate.detail)) && (candidate.deprecated === void 0 || Is.boolean(candidate.deprecated)) && (candidate.children === void 0 || Array.isArray(candidate.children)) && (candidate.tags === void 0 || Array.isArray(candidate.tags));
4326
4326
  }
4327
4327
  DocumentSymbol2.is = is;
4328
4328
  })(DocumentSymbol || (exports3.DocumentSymbol = DocumentSymbol = {}));
@@ -4399,7 +4399,7 @@ var require_main2 = __commonJS({
4399
4399
  CodeLens2.create = create;
4400
4400
  function is(value) {
4401
4401
  var candidate = value;
4402
- return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.command) || Command.is(candidate.command));
4402
+ return Is.defined(candidate) && Range2.is(candidate.range) && (Is.undefined(candidate.command) || Command.is(candidate.command));
4403
4403
  }
4404
4404
  CodeLens2.is = is;
4405
4405
  })(CodeLens || (exports3.CodeLens = CodeLens = {}));
@@ -4423,7 +4423,7 @@ var require_main2 = __commonJS({
4423
4423
  DocumentLink2.create = create;
4424
4424
  function is(value) {
4425
4425
  var candidate = value;
4426
- return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.target) || Is.string(candidate.target));
4426
+ return Is.defined(candidate) && Range2.is(candidate.range) && (Is.undefined(candidate.target) || Is.string(candidate.target));
4427
4427
  }
4428
4428
  DocumentLink2.is = is;
4429
4429
  })(DocumentLink || (exports3.DocumentLink = DocumentLink = {}));
@@ -4435,7 +4435,7 @@ var require_main2 = __commonJS({
4435
4435
  SelectionRange2.create = create;
4436
4436
  function is(value) {
4437
4437
  var candidate = value;
4438
- return Is.objectLiteral(candidate) && Range.is(candidate.range) && (candidate.parent === void 0 || SelectionRange2.is(candidate.parent));
4438
+ return Is.objectLiteral(candidate) && Range2.is(candidate.range) && (candidate.parent === void 0 || SelectionRange2.is(candidate.parent));
4439
4439
  }
4440
4440
  SelectionRange2.is = is;
4441
4441
  })(SelectionRange || (exports3.SelectionRange = SelectionRange = {}));
@@ -4494,7 +4494,7 @@ var require_main2 = __commonJS({
4494
4494
  InlineValueText2.create = create;
4495
4495
  function is(value) {
4496
4496
  var candidate = value;
4497
- return candidate !== void 0 && candidate !== null && Range.is(candidate.range) && Is.string(candidate.text);
4497
+ return candidate !== void 0 && candidate !== null && Range2.is(candidate.range) && Is.string(candidate.text);
4498
4498
  }
4499
4499
  InlineValueText2.is = is;
4500
4500
  })(InlineValueText || (exports3.InlineValueText = InlineValueText = {}));
@@ -4506,7 +4506,7 @@ var require_main2 = __commonJS({
4506
4506
  InlineValueVariableLookup2.create = create;
4507
4507
  function is(value) {
4508
4508
  var candidate = value;
4509
- return candidate !== void 0 && candidate !== null && Range.is(candidate.range) && Is.boolean(candidate.caseSensitiveLookup) && (Is.string(candidate.variableName) || candidate.variableName === void 0);
4509
+ return candidate !== void 0 && candidate !== null && Range2.is(candidate.range) && Is.boolean(candidate.caseSensitiveLookup) && (Is.string(candidate.variableName) || candidate.variableName === void 0);
4510
4510
  }
4511
4511
  InlineValueVariableLookup2.is = is;
4512
4512
  })(InlineValueVariableLookup || (exports3.InlineValueVariableLookup = InlineValueVariableLookup = {}));
@@ -4518,7 +4518,7 @@ var require_main2 = __commonJS({
4518
4518
  InlineValueEvaluatableExpression2.create = create;
4519
4519
  function is(value) {
4520
4520
  var candidate = value;
4521
- return candidate !== void 0 && candidate !== null && Range.is(candidate.range) && (Is.string(candidate.expression) || candidate.expression === void 0);
4521
+ return candidate !== void 0 && candidate !== null && Range2.is(candidate.range) && (Is.string(candidate.expression) || candidate.expression === void 0);
4522
4522
  }
4523
4523
  InlineValueEvaluatableExpression2.is = is;
4524
4524
  })(InlineValueEvaluatableExpression || (exports3.InlineValueEvaluatableExpression = InlineValueEvaluatableExpression = {}));
@@ -4530,7 +4530,7 @@ var require_main2 = __commonJS({
4530
4530
  InlineValueContext2.create = create;
4531
4531
  function is(value) {
4532
4532
  var candidate = value;
4533
- return Is.defined(candidate) && Range.is(value.stoppedLocation);
4533
+ return Is.defined(candidate) && Range2.is(value.stoppedLocation);
4534
4534
  }
4535
4535
  InlineValueContext2.is = is;
4536
4536
  })(InlineValueContext || (exports3.InlineValueContext = InlineValueContext = {}));
@@ -4551,7 +4551,7 @@ var require_main2 = __commonJS({
4551
4551
  InlayHintLabelPart2.create = create;
4552
4552
  function is(value) {
4553
4553
  var candidate = value;
4554
- return Is.objectLiteral(candidate) && (candidate.tooltip === void 0 || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip)) && (candidate.location === void 0 || Location.is(candidate.location)) && (candidate.command === void 0 || Command.is(candidate.command));
4554
+ return Is.objectLiteral(candidate) && (candidate.tooltip === void 0 || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip)) && (candidate.location === void 0 || Location2.is(candidate.location)) && (candidate.command === void 0 || Command.is(candidate.command));
4555
4555
  }
4556
4556
  InlayHintLabelPart2.is = is;
4557
4557
  })(InlayHintLabelPart || (exports3.InlayHintLabelPart = InlayHintLabelPart = {}));
@@ -4567,7 +4567,7 @@ var require_main2 = __commonJS({
4567
4567
  InlayHint2.create = create;
4568
4568
  function is(value) {
4569
4569
  var candidate = value;
4570
- return Is.objectLiteral(candidate) && Position.is(candidate.position) && (Is.string(candidate.label) || Is.typedArray(candidate.label, InlayHintLabelPart.is)) && (candidate.kind === void 0 || InlayHintKind.is(candidate.kind)) && candidate.textEdits === void 0 || Is.typedArray(candidate.textEdits, TextEdit.is) && (candidate.tooltip === void 0 || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip)) && (candidate.paddingLeft === void 0 || Is.boolean(candidate.paddingLeft)) && (candidate.paddingRight === void 0 || Is.boolean(candidate.paddingRight));
4570
+ return Is.objectLiteral(candidate) && Position2.is(candidate.position) && (Is.string(candidate.label) || Is.typedArray(candidate.label, InlayHintLabelPart.is)) && (candidate.kind === void 0 || InlayHintKind.is(candidate.kind)) && candidate.textEdits === void 0 || Is.typedArray(candidate.textEdits, TextEdit.is) && (candidate.tooltip === void 0 || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip)) && (candidate.paddingLeft === void 0 || Is.boolean(candidate.paddingLeft)) && (candidate.paddingRight === void 0 || Is.boolean(candidate.paddingRight));
4571
4571
  }
4572
4572
  InlayHint2.is = is;
4573
4573
  })(InlayHint || (exports3.InlayHint = InlayHint = {}));
@@ -4756,7 +4756,7 @@ var require_main2 = __commonJS({
4756
4756
  var lineOffsets = this.getLineOffsets();
4757
4757
  var low = 0, high = lineOffsets.length;
4758
4758
  if (high === 0) {
4759
- return Position.create(0, offset);
4759
+ return Position2.create(0, offset);
4760
4760
  }
4761
4761
  while (low < high) {
4762
4762
  var mid = Math.floor((low + high) / 2);
@@ -4767,7 +4767,7 @@ var require_main2 = __commonJS({
4767
4767
  }
4768
4768
  }
4769
4769
  var line = low - 1;
4770
- return Position.create(line, offset - lineOffsets[line]);
4770
+ return Position2.create(line, offset - lineOffsets[line]);
4771
4771
  };
4772
4772
  FullTextDocument3.prototype.offsetAt = function(position) {
4773
4773
  var lineOffsets = this.getLineOffsets();
@@ -12309,6 +12309,113 @@ var WorkspaceScanner = class {
12309
12309
  isInitialized() {
12310
12310
  return this.initialized;
12311
12311
  }
12312
+ /**
12313
+ * 全 .ks ファイルから target="*labelName" の参照箇所を検索する
12314
+ */
12315
+ findLabelReferences(labelName) {
12316
+ if (!this.initialized) return [];
12317
+ const results = [];
12318
+ const scenarioPath = path.join(this.dataPath, "scenario");
12319
+ if (!fs.existsSync(scenarioPath)) return results;
12320
+ const ksFiles = this.findKsFiles(scenarioPath);
12321
+ const regex = new RegExp(
12322
+ `target\\s*=\\s*"\\*${this.escapeRegExp(labelName)}"`,
12323
+ "g"
12324
+ );
12325
+ for (const filePath of ksFiles) {
12326
+ try {
12327
+ const content = fs.readFileSync(filePath, "utf-8");
12328
+ const lines = content.split("\n");
12329
+ const relativePath = path.relative(this.dataPath, filePath);
12330
+ for (let i = 0; i < lines.length; i++) {
12331
+ let match;
12332
+ regex.lastIndex = 0;
12333
+ while ((match = regex.exec(lines[i])) !== null) {
12334
+ const valueStart = lines[i].indexOf(`*${labelName}`, match.index);
12335
+ results.push({
12336
+ file: relativePath,
12337
+ line: i,
12338
+ startChar: valueStart,
12339
+ endChar: valueStart + labelName.length + 1
12340
+ // +1 は "*" の分
12341
+ });
12342
+ }
12343
+ }
12344
+ } catch {
12345
+ }
12346
+ }
12347
+ return results;
12348
+ }
12349
+ /**
12350
+ * 全 .ks ファイルからマクロの使用箇所を検索する
12351
+ * [macroName ...] または @macroName 形式にマッチし、定義行 [macro name="..."] は除外する
12352
+ */
12353
+ findMacroReferences(macroName) {
12354
+ if (!this.initialized) return [];
12355
+ const results = [];
12356
+ const scenarioPath = path.join(this.dataPath, "scenario");
12357
+ if (!fs.existsSync(scenarioPath)) return results;
12358
+ const ksFiles = this.findKsFiles(scenarioPath);
12359
+ const bracketRegex = new RegExp(
12360
+ `\\[${this.escapeRegExp(macroName)}(?=[\\s\\]]|$)`,
12361
+ "g"
12362
+ );
12363
+ const atRegex = new RegExp(
12364
+ `^@${this.escapeRegExp(macroName)}(?=[\\s]|$)`,
12365
+ "g"
12366
+ );
12367
+ const defRegex = new RegExp(
12368
+ `\\[macro\\s+name\\s*=\\s*"${this.escapeRegExp(macroName)}"\\s*\\]`,
12369
+ "i"
12370
+ );
12371
+ for (const filePath of ksFiles) {
12372
+ try {
12373
+ const content = fs.readFileSync(filePath, "utf-8");
12374
+ const lines = content.split("\n");
12375
+ const relativePath = path.relative(this.dataPath, filePath);
12376
+ for (let i = 0; i < lines.length; i++) {
12377
+ const line = lines[i];
12378
+ if (defRegex.test(line)) continue;
12379
+ bracketRegex.lastIndex = 0;
12380
+ let match;
12381
+ while ((match = bracketRegex.exec(line)) !== null) {
12382
+ const start = match.index + 1;
12383
+ results.push({
12384
+ file: relativePath,
12385
+ line: i,
12386
+ startChar: start,
12387
+ endChar: start + macroName.length
12388
+ });
12389
+ }
12390
+ atRegex.lastIndex = 0;
12391
+ while ((match = atRegex.exec(line)) !== null) {
12392
+ const start = match.index + 1;
12393
+ results.push({
12394
+ file: relativePath,
12395
+ line: i,
12396
+ startChar: start,
12397
+ endChar: start + macroName.length
12398
+ });
12399
+ }
12400
+ }
12401
+ } catch {
12402
+ }
12403
+ }
12404
+ return results;
12405
+ }
12406
+ /**
12407
+ * data/ からの相対パスを file:// URI に変換する
12408
+ */
12409
+ resolveFilePath(relativePath) {
12410
+ const absPath = path.join(this.dataPath, relativePath);
12411
+ return `file://${encodeURI(absPath)}`;
12412
+ }
12413
+ /**
12414
+ * 正規表現の特殊文字をエスケープする
12415
+ */
12416
+ escapeRegExp(str) {
12417
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12418
+ }
12312
12419
  };
12313
12420
 
12314
12421
  // src/server.ts
@@ -12329,7 +12436,9 @@ connection.onInitialize((params) => {
12329
12436
  triggerCharacters: ["[", "@", " ", '"'],
12330
12437
  resolveProvider: false
12331
12438
  },
12332
- hoverProvider: true
12439
+ hoverProvider: true,
12440
+ definitionProvider: true,
12441
+ referencesProvider: true
12333
12442
  }
12334
12443
  };
12335
12444
  });
@@ -12539,6 +12648,158 @@ connection.onCompletion(
12539
12648
  return [];
12540
12649
  }
12541
12650
  );
12651
+ function getDefinitionContext(lineText, character) {
12652
+ const valueCtx = getParamValueContext(lineText, character);
12653
+ if (valueCtx) {
12654
+ const afterCursor = lineText.substring(character);
12655
+ const closingQuoteIdx = afterCursor.indexOf('"');
12656
+ const fullValue = closingQuoteIdx >= 0 ? valueCtx.currentValue + afterCursor.substring(0, closingQuoteIdx) : valueCtx.currentValue;
12657
+ if (valueCtx.paramName === "target" && fullValue.startsWith("*")) {
12658
+ return { kind: "label", name: fullValue.substring(1) };
12659
+ }
12660
+ if (valueCtx.paramName === "storage" && fullValue.length > 0) {
12661
+ return { kind: "file", name: fullValue };
12662
+ }
12663
+ return null;
12664
+ }
12665
+ const tagCtx = getTagContext(lineText, character);
12666
+ if (tagCtx && !tagCtx.isInParams) {
12667
+ const afterCursor = lineText.substring(character);
12668
+ const remainingWord = afterCursor.match(/^(\w*)/)?.[1] ?? "";
12669
+ const fullTagName = tagCtx.tagName + remainingWord;
12670
+ if (!TAG_DATABASE.has(fullTagName)) {
12671
+ return { kind: "macro", name: fullTagName };
12672
+ }
12673
+ }
12674
+ return null;
12675
+ }
12676
+ function refToLocation(ref) {
12677
+ return {
12678
+ uri: scanner.resolveFilePath(ref.file),
12679
+ range: import_node.Range.create(
12680
+ import_node.Position.create(ref.line, ref.startChar),
12681
+ import_node.Position.create(ref.line, ref.endChar)
12682
+ )
12683
+ };
12684
+ }
12685
+ connection.onDefinition(
12686
+ (params) => {
12687
+ const document = documents.get(params.textDocument.uri);
12688
+ if (!document) return null;
12689
+ const lineText = document.getText({
12690
+ start: { line: params.position.line, character: 0 },
12691
+ end: { line: params.position.line + 1, character: 0 }
12692
+ }).replace(/\n$/, "");
12693
+ const ctx = getDefinitionContext(lineText, params.position.character);
12694
+ if (!ctx) return null;
12695
+ switch (ctx.kind) {
12696
+ case "label": {
12697
+ const label = scanner.getLabels().find((l) => l.name === ctx.name);
12698
+ if (!label) return null;
12699
+ return {
12700
+ uri: scanner.resolveFilePath(label.file),
12701
+ range: import_node.Range.create(
12702
+ import_node.Position.create(label.line, 0),
12703
+ import_node.Position.create(label.line, label.name.length + 1)
12704
+ // +1 は "*" の分
12705
+ )
12706
+ };
12707
+ }
12708
+ case "file": {
12709
+ const tagCtx = getTagContext(lineText, params.position.character);
12710
+ if (!tagCtx) return null;
12711
+ const category = TAG_STORAGE_MAPPING.get(tagCtx.tagName);
12712
+ if (!category) return null;
12713
+ const filePath = `${category}/${ctx.name}`;
12714
+ return {
12715
+ uri: scanner.resolveFilePath(filePath),
12716
+ range: import_node.Range.create(import_node.Position.create(0, 0), import_node.Position.create(0, 0))
12717
+ };
12718
+ }
12719
+ case "macro": {
12720
+ const macro = scanner.getMacros().find((m) => m.name === ctx.name);
12721
+ if (!macro) return null;
12722
+ return {
12723
+ uri: scanner.resolveFilePath(macro.file),
12724
+ range: import_node.Range.create(
12725
+ import_node.Position.create(macro.line, 0),
12726
+ import_node.Position.create(macro.line, 0)
12727
+ )
12728
+ };
12729
+ }
12730
+ }
12731
+ }
12732
+ );
12733
+ function getLabelDefinitionAtCursor(lineText, character) {
12734
+ const match = lineText.match(/^\*(\w+)/);
12735
+ if (match && character <= match[0].length) {
12736
+ return match[1];
12737
+ }
12738
+ return null;
12739
+ }
12740
+ function getMacroDefinitionAtCursor(lineText) {
12741
+ const match = lineText.match(/\[macro\s+name\s*=\s*"(\w+)"\s*\]/i);
12742
+ if (match) {
12743
+ return match[1];
12744
+ }
12745
+ return null;
12746
+ }
12747
+ connection.onReferences(
12748
+ (params) => {
12749
+ const document = documents.get(params.textDocument.uri);
12750
+ if (!document) return [];
12751
+ const lineText = document.getText({
12752
+ start: { line: params.position.line, character: 0 },
12753
+ end: { line: params.position.line + 1, character: 0 }
12754
+ }).replace(/\n$/, "");
12755
+ const character = params.position.character;
12756
+ const results = [];
12757
+ const labelDef = getLabelDefinitionAtCursor(lineText, character);
12758
+ if (labelDef) {
12759
+ const refs = scanner.findLabelReferences(labelDef);
12760
+ return refs.map(refToLocation);
12761
+ }
12762
+ const macroDef = getMacroDefinitionAtCursor(lineText);
12763
+ if (macroDef) {
12764
+ const refs = scanner.findMacroReferences(macroDef);
12765
+ return refs.map(refToLocation);
12766
+ }
12767
+ const defCtx = getDefinitionContext(lineText, character);
12768
+ if (defCtx) {
12769
+ if (defCtx.kind === "label") {
12770
+ const label = scanner.getLabels().find((l) => l.name === defCtx.name);
12771
+ if (label) {
12772
+ results.push({
12773
+ uri: scanner.resolveFilePath(label.file),
12774
+ range: import_node.Range.create(
12775
+ import_node.Position.create(label.line, 0),
12776
+ import_node.Position.create(label.line, label.name.length + 1)
12777
+ )
12778
+ });
12779
+ }
12780
+ const refs = scanner.findLabelReferences(defCtx.name);
12781
+ results.push(...refs.map(refToLocation));
12782
+ return results;
12783
+ }
12784
+ if (defCtx.kind === "macro") {
12785
+ const macro = scanner.getMacros().find((m) => m.name === defCtx.name);
12786
+ if (macro) {
12787
+ results.push({
12788
+ uri: scanner.resolveFilePath(macro.file),
12789
+ range: import_node.Range.create(
12790
+ import_node.Position.create(macro.line, 0),
12791
+ import_node.Position.create(macro.line, 0)
12792
+ )
12793
+ });
12794
+ }
12795
+ const refs = scanner.findMacroReferences(defCtx.name);
12796
+ results.push(...refs.map(refToLocation));
12797
+ return results;
12798
+ }
12799
+ }
12800
+ return results;
12801
+ }
12802
+ );
12542
12803
  connection.onHover(
12543
12804
  (params) => {
12544
12805
  const document = documents.get(params.textDocument.uri);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@void2610/tyranoscript-lsp",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "TyranoScript Language Server for Zed",
5
5
  "main": "dist/server.js",
6
6
  "files": [