@marko/language-server 0.12.9 → 0.12.12

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/index.mjs CHANGED
@@ -571,7 +571,7 @@ function loadCompilerInfo(dir) {
571
571
  const rootDir = lassoPackageRoot.getRootDir(dir);
572
572
  const pkgPath = rootDir && resolveFrom.silent(rootDir, "@marko/compiler/package.json");
573
573
  const pkg = pkgPath && __require(pkgPath);
574
- const cache2 = /* @__PURE__ */ new Map();
574
+ const cache3 = /* @__PURE__ */ new Map();
575
575
  let translator = builtinTranslator;
576
576
  let compiler = builtinCompiler;
577
577
  if (pkg && /^5\./.test(pkg.version)) {
@@ -588,16 +588,16 @@ function loadCompilerInfo(dir) {
588
588
  }
589
589
  }
590
590
  return {
591
- cache: cache2,
591
+ cache: cache3,
592
592
  get lookup() {
593
- let lookup = cache2.get(lookupKey);
593
+ let lookup = cache3.get(lookupKey);
594
594
  if (lookup === void 0) {
595
595
  try {
596
596
  lookup = compiler.taglib.buildLookup(dir, translator);
597
597
  } catch {
598
598
  lookup = builtinInfo.lookup;
599
599
  }
600
- cache2.set(lookupKey, lookup);
600
+ cache3.set(lookupKey, lookup);
601
601
  }
602
602
  return lookup;
603
603
  },
@@ -674,76 +674,113 @@ ${closingTagStr}`
674
674
  }
675
675
  }
676
676
 
677
- // src/service/marko/complete/OpenTagName.ts
677
+ // src/service/marko/util/get-tag-name-completion.ts
678
678
  import path2 from "path";
679
- import { URI as URI2 } from "vscode-uri";
680
679
  import {
681
680
  CompletionItemKind as CompletionItemKind2,
681
+ CompletionItemTag,
682
682
  InsertTextFormat as InsertTextFormat2,
683
683
  MarkupKind,
684
684
  TextEdit as TextEdit2
685
685
  } from "vscode-languageserver";
686
+ import { URI as URI2 } from "vscode-uri";
687
+ var deprecated = [CompletionItemTag.Deprecated];
688
+ function getTagNameCompletion({
689
+ tag,
690
+ range,
691
+ showAutoComplete,
692
+ importer
693
+ }) {
694
+ var _a;
695
+ let label = tag.isNestedTag ? `@${tag.name}` : tag.name;
696
+ const fileForTag = tag.template || tag.renderer || tag.filePath;
697
+ const fileURIForTag = URI2.file(fileForTag).toString();
698
+ const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(fileForTag);
699
+ const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
700
+ const isCoreTag = nodeModuleName === "marko";
701
+ const documentation = {
702
+ kind: MarkupKind.Markdown,
703
+ value: tag.html ? `Built in [<${tag.name}>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${tag.name}) HTML tag.` : nodeModuleName ? isCoreTag ? `Core Marko [<${tag.name}>](${fileURIForTag}) tag.` : `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
704
+
705
+ [${importer ? path2.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
706
+ };
707
+ if (tag.description) {
708
+ documentation.value += `
709
+
710
+ ${tag.description}`;
711
+ }
712
+ const autocomplete = showAutoComplete ? (_a = tag.autocomplete) == null ? void 0 : _a[0] : void 0;
713
+ if (autocomplete) {
714
+ if (autocomplete.displayText) {
715
+ label = autocomplete.displayText;
716
+ }
717
+ if (autocomplete.description) {
718
+ documentation.value += `
719
+
720
+ ${autocomplete.description}`;
721
+ }
722
+ if (autocomplete.descriptionMoreURL) {
723
+ documentation.value += `
724
+
725
+ [More Info](${autocomplete.descriptionMoreURL})`;
726
+ }
727
+ }
728
+ return {
729
+ label,
730
+ documentation,
731
+ tags: tag.deprecated ? deprecated : void 0,
732
+ insertTextFormat: autocomplete ? InsertTextFormat2.Snippet : void 0,
733
+ kind: tag.html ? CompletionItemKind2.Property : CompletionItemKind2.Class,
734
+ textEdit: range && TextEdit2.replace(range, (autocomplete == null ? void 0 : autocomplete.snippet) || label)
735
+ };
736
+ }
737
+
738
+ // src/service/marko/complete/OpenTagName.ts
686
739
  function OpenTagName({
687
740
  document,
688
741
  lookup,
689
742
  parsed,
690
743
  node
691
744
  }) {
692
- const currentTemplateFilePath = getDocFile(document);
745
+ var _a;
746
+ const importer = getDocFile(document);
693
747
  const tag = node.parent;
694
- const tagNameLocation = parsed.locationAt(node);
695
- let tags;
696
- if (tag.type === 14 /* AttrTag */) {
748
+ const range = parsed.locationAt(node);
749
+ const isAttrTag = tag.type === 14 /* AttrTag */;
750
+ const result = [];
751
+ if (isAttrTag) {
697
752
  let parentTag = tag.owner;
698
753
  while ((parentTag == null ? void 0 : parentTag.type) === 14 /* AttrTag */)
699
754
  parentTag = parentTag.owner;
700
755
  const parentTagDef = parentTag && parentTag.nameText && lookup.getTag(parentTag.nameText);
701
- tags = parentTagDef && parentTagDef.nestedTags && Object.values(parentTagDef.nestedTags) || [];
702
- } else {
703
- tags = lookup.getTagsSorted().filter((it) => !it.isNestedTag);
704
- }
705
- return tags.filter((it) => !it.deprecated).filter((it) => it.name !== "*").filter((it) => /^[^_]/.test(it.name) || !/\/node_modules\//.test(it.filePath)).map((it) => {
706
- let label = it.isNestedTag ? `@${it.name}` : it.name;
707
- const fileForTag = it.template || it.renderer || it.filePath;
708
- const fileURIForTag = URI2.file(fileForTag).toString();
709
- const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(fileForTag);
710
- const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
711
- const isCoreTag = nodeModuleName === "marko";
712
- const documentation = {
713
- kind: MarkupKind.Markdown,
714
- value: it.html ? `Built in [<${it.name}>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${it.name}) HTML tag.` : nodeModuleName ? isCoreTag ? `Core Marko [<${it.name}>](${fileURIForTag}) tag.` : `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
715
-
716
- [${currentTemplateFilePath ? path2.relative(currentTemplateFilePath, fileForTag) : currentTemplateFilePath}](${fileURIForTag})`
717
- };
718
- if (it.description) {
719
- documentation.value += `
720
-
721
- ${it.description}`;
722
- }
723
- const autocomplete = it.autocomplete && it.autocomplete[0];
724
- if (autocomplete) {
725
- if (autocomplete.displayText) {
726
- label = autocomplete.displayText;
727
- }
728
- if (autocomplete.description) {
729
- documentation.value += `
730
-
731
- ${autocomplete.description}`;
756
+ if (parentTagDef) {
757
+ const { nestedTags } = parentTagDef;
758
+ for (const key in nestedTags) {
759
+ if (key !== "*") {
760
+ const tag2 = nestedTags[key];
761
+ result.push(getTagNameCompletion({
762
+ tag: tag2,
763
+ range,
764
+ importer,
765
+ showAutoComplete: true
766
+ }));
767
+ }
732
768
  }
733
- if (autocomplete.descriptionMoreURL) {
734
- documentation.value += `
735
-
736
- [More Info](${autocomplete.descriptionMoreURL})`;
769
+ }
770
+ } else {
771
+ const skipStatements = !(tag.concise && tag.parent.type === 0 /* Program */);
772
+ for (const tag2 of lookup.getTagsSorted()) {
773
+ if (!(tag2.name === "*" || tag2.isNestedTag || skipStatements && ((_a = tag2.parseOptions) == null ? void 0 : _a.statement) || tag2.name[0] === "_" && /^@?marko[/-]|[\\/]node_modules[\\/]/.test(tag2.filePath))) {
774
+ result.push(getTagNameCompletion({
775
+ tag: tag2,
776
+ range,
777
+ importer,
778
+ showAutoComplete: true
779
+ }));
737
780
  }
738
781
  }
739
- return {
740
- label,
741
- documentation,
742
- kind: CompletionItemKind2.Class,
743
- insertTextFormat: InsertTextFormat2.Snippet,
744
- textEdit: TextEdit2.replace(tagNameLocation, autocomplete && autocomplete.snippet || label)
745
- };
746
- });
782
+ }
783
+ return result;
747
784
  }
748
785
 
749
786
  // src/service/marko/complete/AttrName.ts
@@ -856,11 +893,187 @@ function AttrName({
856
893
  return completions;
857
894
  }
858
895
 
896
+ // src/service/marko/complete/AttrValue.ts
897
+ import path3 from "path";
898
+ import {
899
+ CompletionItemKind as CompletionItemKind4,
900
+ Range as Range2,
901
+ TextEdit as TextEdit4
902
+ } from "vscode-languageserver";
903
+
904
+ // src/service/marko/util/is-document-link-attr.ts
905
+ var linkedAttrs = /* @__PURE__ */ new Map([
906
+ [
907
+ "src",
908
+ /* @__PURE__ */ new Set([
909
+ "audio",
910
+ "embed",
911
+ "iframe",
912
+ "img",
913
+ "input",
914
+ "script",
915
+ "source",
916
+ "track",
917
+ "video"
918
+ ])
919
+ ],
920
+ ["href", /* @__PURE__ */ new Set(["a", "area", "link"])],
921
+ ["data", /* @__PURE__ */ new Set(["object"])],
922
+ ["poster", /* @__PURE__ */ new Set(["video"])]
923
+ ]);
924
+ function isDocumentLinkAttr(doc, tag, attr) {
925
+ var _a, _b;
926
+ return tag.nameText && attr.type === 8 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 11 /* AttrValue */ && /^['"]$/.test(doc.getText()[attr.value.value.start]) && ((_b = linkedAttrs.get(doc.getText().slice(attr.name.start, attr.name.end))) == null ? void 0 : _b.has(tag.nameText)) || false;
927
+ }
928
+
929
+ // src/utils/file-system.ts
930
+ import fs from "fs/promises";
931
+ import { FileType } from "vscode-css-languageservice";
932
+ import { fileURLToPath } from "url";
933
+ var file_system_default = {
934
+ stat,
935
+ readDirectory
936
+ };
937
+ async function stat(uri) {
938
+ let type = FileType.Unknown;
939
+ let ctime = -1;
940
+ let mtime = -1;
941
+ let size = -1;
942
+ try {
943
+ const stat2 = await fs.stat(fileURLToPath(uri));
944
+ if (stat2.isDirectory())
945
+ type = FileType.Directory;
946
+ else if (stat2.isFile())
947
+ type = FileType.File;
948
+ ctime = stat2.ctimeMs;
949
+ mtime = stat2.mtimeMs;
950
+ size = stat2.size;
951
+ } catch {
952
+ }
953
+ return {
954
+ type,
955
+ ctime,
956
+ mtime,
957
+ size
958
+ };
959
+ }
960
+ async function readDirectory(uri) {
961
+ try {
962
+ const entries = await fs.readdir(fileURLToPath(uri));
963
+ const base = uri.at(-1) === "/" ? uri : `${uri}/`;
964
+ return (await Promise.all(entries.map(async (entry) => [entry, (await stat(new URL(entry, base).toString())).type]))).filter(([, type]) => type !== FileType.Unknown);
965
+ } catch {
966
+ return [];
967
+ }
968
+ }
969
+
970
+ // src/utils/resolve-url.ts
971
+ function resolveUrl(to, base) {
972
+ try {
973
+ const url = new URL(to, base);
974
+ if (url.protocol === "file:")
975
+ return url.toString();
976
+ } catch {
977
+ return void 0;
978
+ }
979
+ }
980
+
981
+ // src/service/marko/complete/AttrValue.ts
982
+ async function AttrValue({
983
+ document,
984
+ offset,
985
+ node,
986
+ parsed,
987
+ code
988
+ }) {
989
+ const attr = node.parent;
990
+ if (isDocumentLinkAttr(document, attr.parent, attr)) {
991
+ const start = node.value.start + 1;
992
+ if (code[start] !== ".")
993
+ return;
994
+ const end = node.value.end - 1;
995
+ const relativeOffset = offset - start;
996
+ const rawValue = parsed.read({
997
+ start,
998
+ end
999
+ });
1000
+ const segmentStart = rawValue.lastIndexOf("/", relativeOffset);
1001
+ if (segmentStart === -1)
1002
+ return;
1003
+ const req = rawValue.slice(0, segmentStart);
1004
+ const uri = resolveUrl(req, document.uri);
1005
+ if (uri) {
1006
+ const result = [];
1007
+ const curFile = req === "." ? path3.basename(document.uri) : void 0;
1008
+ const replaceRange = Range2.create(document.positionAt(start + segmentStart + 1), document.positionAt(start + rawValue.length));
1009
+ for (const [entry, type] of await file_system_default.readDirectory(uri)) {
1010
+ if (entry[0] !== "." && entry !== curFile) {
1011
+ result.push(type === FileType.Directory ? {
1012
+ label: `${entry}/`,
1013
+ kind: CompletionItemKind4.Folder,
1014
+ textEdit: TextEdit4.replace(replaceRange, `${entry}/`),
1015
+ command: {
1016
+ title: "Suggest",
1017
+ command: "editor.action.triggerSuggest"
1018
+ }
1019
+ } : {
1020
+ label: entry,
1021
+ kind: CompletionItemKind4.File,
1022
+ textEdit: TextEdit4.replace(replaceRange, entry)
1023
+ });
1024
+ }
1025
+ }
1026
+ return result;
1027
+ }
1028
+ }
1029
+ }
1030
+
1031
+ // src/service/marko/complete/Statement.ts
1032
+ import { TextEdit as TextEdit5 } from "vscode-languageserver";
1033
+ var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1034
+ function Statement({
1035
+ code,
1036
+ node,
1037
+ parsed,
1038
+ lookup,
1039
+ document
1040
+ }) {
1041
+ var _a;
1042
+ if (code[node.start] === "i") {
1043
+ importTagReg.lastIndex = 0;
1044
+ const value = parsed.read(node);
1045
+ const match = importTagReg.exec(value);
1046
+ if (match) {
1047
+ const importer = getDocFile(document);
1048
+ const [{ length }] = match;
1049
+ const range = parsed.locationAt({
1050
+ start: node.start + match.index + 1,
1051
+ end: node.start + match.index + length - 1
1052
+ });
1053
+ const result = [];
1054
+ for (const tag of lookup.getTagsSorted()) {
1055
+ if ((tag.template || tag.renderer) && !(tag.html || tag.parser || tag.translator || tag.isNestedTag || tag.name === "*" || ((_a = tag.parseOptions) == null ? void 0 : _a.statement) || /^@?marko[/-]/.test(tag.taglibId) || tag.name[0] === "_" && /[\\/]node_modules[\\/]/.test(tag.filePath))) {
1056
+ const completion = getTagNameCompletion({
1057
+ tag,
1058
+ importer
1059
+ });
1060
+ completion.label = `<${completion.label}>`;
1061
+ completion.textEdit = TextEdit5.replace(range, completion.label);
1062
+ result.push(completion);
1063
+ }
1064
+ }
1065
+ return result;
1066
+ }
1067
+ }
1068
+ }
1069
+
859
1070
  // src/service/marko/complete/index.ts
860
1071
  var handlers = {
861
1072
  Tag,
862
1073
  OpenTagName,
863
- AttrName
1074
+ AttrName,
1075
+ AttrValue,
1076
+ Statement
864
1077
  };
865
1078
  var doComplete = async (doc, params) => {
866
1079
  var _a;
@@ -879,15 +1092,15 @@ var doComplete = async (doc, params) => {
879
1092
  };
880
1093
 
881
1094
  // src/service/marko/validate.ts
882
- import { Diagnostic, DiagnosticSeverity, Range as Range2 } from "vscode-languageserver";
1095
+ import { Diagnostic, DiagnosticSeverity, Range as Range3 } from "vscode-languageserver";
883
1096
  var markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
884
1097
  var doValidate = (doc) => {
885
1098
  const fsPath = getDocFile(doc);
886
1099
  const diagnostics = [];
887
- const { compiler, translator, cache: cache2 } = getCompilerInfo(doc);
1100
+ const { compiler, translator, cache: cache3 } = getCompilerInfo(doc);
888
1101
  try {
889
1102
  compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
890
- cache: cache2,
1103
+ cache: cache3,
891
1104
  translator,
892
1105
  code: false,
893
1106
  output: "source",
@@ -899,16 +1112,16 @@ var doValidate = (doc) => {
899
1112
  const [, fileName, rawLine, rawCol, msg] = match;
900
1113
  const line = (parseInt(rawLine, 10) || 1) - 1;
901
1114
  const col = (parseInt(rawCol, 10) || 1) - 1;
902
- diagnostics.push(Diagnostic.create(Range2.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
1115
+ diagnostics.push(Diagnostic.create(Range3.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
903
1116
  }
904
1117
  }
905
1118
  return diagnostics;
906
1119
  };
907
1120
 
908
1121
  // src/service/marko/definition/OpenTagName.ts
909
- import path3 from "path";
1122
+ import path4 from "path";
910
1123
  import { URI as URI4 } from "vscode-uri";
911
- import { Range as Range4, LocationLink } from "vscode-languageserver";
1124
+ import { Range as Range5, LocationLink } from "vscode-languageserver";
912
1125
 
913
1126
  // src/utils/regexp-builder.ts
914
1127
  function RegExpBuilder(strings, ...expressions) {
@@ -935,14 +1148,14 @@ function escape(val) {
935
1148
  }
936
1149
 
937
1150
  // src/utils/utils.ts
938
- import fs from "fs";
1151
+ import fs2 from "fs";
939
1152
  import { URI as URI3 } from "vscode-uri";
940
- import { Position, Range as Range3 } from "vscode-languageserver";
1153
+ import { Position, Range as Range4 } from "vscode-languageserver";
941
1154
  import { TextDocument } from "vscode-languageserver-textdocument";
942
- var START_OF_FILE = Range3.create(Position.create(0, 0), Position.create(0, 0));
1155
+ var START_OF_FILE = Range4.create(Position.create(0, 0), Position.create(0, 0));
943
1156
  function createTextDocument(filename) {
944
1157
  const uri = URI3.file(filename).toString();
945
- const content = fs.readFileSync(filename, "utf-8");
1158
+ const content = fs2.readFileSync(filename, "utf-8");
946
1159
  return TextDocument.create(uri, "plaintext", 0, content);
947
1160
  }
948
1161
 
@@ -967,14 +1180,14 @@ function OpenTagName2({
967
1180
  return;
968
1181
  }
969
1182
  const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
970
- if (!path3.isAbsolute(tagEntryFile)) {
1183
+ if (!path4.isAbsolute(tagEntryFile)) {
971
1184
  return;
972
1185
  }
973
1186
  if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
974
1187
  const tagDefDoc = createTextDocument(tagEntryFile);
975
1188
  const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
976
1189
  if (match && match.index) {
977
- range = Range4.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1190
+ range = Range5.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
978
1191
  }
979
1192
  }
980
1193
  return [
@@ -984,7 +1197,7 @@ function OpenTagName2({
984
1197
 
985
1198
  // src/service/marko/definition/AttrName.ts
986
1199
  import { URI as URI5 } from "vscode-uri";
987
- import { Range as Range5, LocationLink as LocationLink2 } from "vscode-languageserver";
1200
+ import { Range as Range6, LocationLink as LocationLink2 } from "vscode-languageserver";
988
1201
  function AttrName2({
989
1202
  lookup,
990
1203
  parsed,
@@ -1008,7 +1221,7 @@ function AttrName2({
1008
1221
  const tagDefDoc = createTextDocument(attrEntryFile);
1009
1222
  const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
1010
1223
  if (match && match.index) {
1011
- range = Range5.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1224
+ range = Range6.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1012
1225
  }
1013
1226
  }
1014
1227
  return [
@@ -1037,14 +1250,83 @@ var findDefinition = async (doc, params) => {
1037
1250
  })) || [];
1038
1251
  };
1039
1252
 
1040
- // src/service/marko/format.ts
1041
- import { Range as Range6, TextEdit as TextEdit4 } from "vscode-languageserver";
1253
+ // src/service/marko/document-links/extract.ts
1254
+ import { DocumentLink } from "vscode-languageserver";
1042
1255
  import { URI as URI6 } from "vscode-uri";
1256
+ var importTagReg2 = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1257
+ function extractDocumentLinks(doc, parsed, lookup) {
1258
+ if (URI6.parse(doc.uri).scheme === "untitled") {
1259
+ return [];
1260
+ }
1261
+ const links = [];
1262
+ const { program } = parsed;
1263
+ const code = doc.getText();
1264
+ const read = (range) => code.slice(range.start, range.end);
1265
+ const visit = (node) => {
1266
+ switch (node.type) {
1267
+ case 1 /* Tag */:
1268
+ if (node.attrs && node.nameText) {
1269
+ for (const attr of node.attrs) {
1270
+ if (isDocumentLinkAttr(doc, node, attr)) {
1271
+ links.push(DocumentLink.create({
1272
+ start: parsed.positionAt(attr.value.value.start),
1273
+ end: parsed.positionAt(attr.value.value.end)
1274
+ }, resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)));
1275
+ }
1276
+ }
1277
+ }
1278
+ if (node.body) {
1279
+ for (const child of node.body) {
1280
+ visit(child);
1281
+ }
1282
+ }
1283
+ break;
1284
+ }
1285
+ };
1286
+ for (const item of program.static) {
1287
+ if (item.type === 20 /* Statement */ && code[item.start] === "i") {
1288
+ importTagReg2.lastIndex = 0;
1289
+ const value = parsed.read(item);
1290
+ const match = importTagReg2.exec(value);
1291
+ if (match) {
1292
+ const [{ length }, , tagName] = match;
1293
+ const tagDef = lookup.getTag(tagName);
1294
+ const fileForTag = tagDef && (tagDef.template || tagDef.renderer);
1295
+ if (fileForTag) {
1296
+ links.push(DocumentLink.create({
1297
+ start: parsed.positionAt(item.start + match.index),
1298
+ end: parsed.positionAt(item.start + match.index + length)
1299
+ }, fileForTag));
1300
+ }
1301
+ }
1302
+ }
1303
+ }
1304
+ for (const item of program.body) {
1305
+ visit(item);
1306
+ }
1307
+ return links;
1308
+ }
1309
+
1310
+ // src/service/marko/document-links/index.ts
1311
+ var cache = /* @__PURE__ */ new WeakMap();
1312
+ var findDocumentLinks = async (doc) => {
1313
+ const parsed = parse2(doc);
1314
+ let result = cache.get(parsed);
1315
+ if (!result) {
1316
+ result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1317
+ cache.set(parsed, result);
1318
+ }
1319
+ return result;
1320
+ };
1321
+
1322
+ // src/service/marko/format.ts
1323
+ import { Range as Range7, TextEdit as TextEdit6 } from "vscode-languageserver";
1324
+ import { URI as URI7 } from "vscode-uri";
1043
1325
  import * as prettier from "prettier";
1044
1326
  import * as markoPrettier from "prettier-plugin-marko";
1045
1327
  var format2 = async (doc, params, cancel) => {
1046
1328
  try {
1047
- const { fsPath, scheme } = URI6.parse(doc.uri);
1329
+ const { fsPath, scheme } = URI7.parse(doc.uri);
1048
1330
  const text = doc.getText();
1049
1331
  const options = {
1050
1332
  parser: "marko",
@@ -1059,7 +1341,7 @@ var format2 = async (doc, params, cancel) => {
1059
1341
  if (cancel.isCancellationRequested)
1060
1342
  return;
1061
1343
  return [
1062
- TextEdit4.replace(Range6.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1344
+ TextEdit6.replace(Range7.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1063
1345
  ];
1064
1346
  } catch (e) {
1065
1347
  displayError(e);
@@ -1071,13 +1353,14 @@ var marko_default = {
1071
1353
  doComplete,
1072
1354
  doValidate,
1073
1355
  findDefinition,
1356
+ findDocumentLinks,
1074
1357
  format: format2
1075
1358
  };
1076
1359
 
1077
1360
  // src/service/stylesheet/index.ts
1078
1361
  import {
1079
1362
  CompletionList as CompletionList2,
1080
- Range as Range8,
1363
+ Range as Range9,
1081
1364
  TextDocumentEdit
1082
1365
  } from "vscode-languageserver";
1083
1366
  import {
@@ -1223,7 +1506,7 @@ function extractStyleSheets(code, program, lookup) {
1223
1506
  for (const attr of node.attrs) {
1224
1507
  if (attr.type === 8 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 11 /* AttrValue */ && /^['"]$/.test(code[attr.value.value.start])) {
1225
1508
  const name = read(attr.name);
1226
- if (name === "#style" || name === "style" && lookup && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
1509
+ if (name === "#style" || name === "style" && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
1227
1510
  getExtractor("css").write`:root{${{
1228
1511
  start: attr.value.value.start + 1,
1229
1512
  end: attr.value.value.end - 1
@@ -1245,13 +1528,17 @@ function extractStyleSheets(code, program, lookup) {
1245
1528
  }
1246
1529
 
1247
1530
  // src/service/stylesheet/index.ts
1248
- var cache = /* @__PURE__ */ new WeakMap();
1531
+ var cache2 = /* @__PURE__ */ new WeakMap();
1249
1532
  var services = {
1250
1533
  css: getCSSLanguageService,
1251
1534
  less: getLESSLanguageService,
1252
1535
  scss: getSCSSLanguageService
1253
1536
  };
1537
+ var clientCapabilities;
1254
1538
  var StyleSheetService = {
1539
+ initialize(params) {
1540
+ clientCapabilities = params.capabilities;
1541
+ },
1255
1542
  async doComplete(doc, params) {
1256
1543
  const infoByExt = getStyleSheetInfo(doc);
1257
1544
  const sourceOffset = doc.offsetAt(params.position);
@@ -1261,28 +1548,31 @@ var StyleSheetService = {
1261
1548
  if (generatedOffset === void 0)
1262
1549
  continue;
1263
1550
  const { service: service2, virtualDoc } = info;
1264
- const result = service2.doComplete(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1265
- for (const item of result.items) {
1266
- if (item.additionalTextEdits) {
1267
- for (const textEdit2 of item.additionalTextEdits) {
1268
- updateTextEdit(doc, info, textEdit2);
1551
+ const result = await service2.doComplete2(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed, { resolveReference: resolveUrl });
1552
+ if (result.itemDefaults) {
1553
+ const { editRange } = result.itemDefaults;
1554
+ if (editRange) {
1555
+ if ("start" in editRange) {
1556
+ result.itemDefaults.editRange = getSourceRange(doc, info, editRange);
1557
+ } else {
1558
+ editRange.insert = getSourceRange(doc, info, editRange.insert);
1559
+ editRange.replace = getSourceRange(doc, info, editRange.replace);
1269
1560
  }
1270
1561
  }
1271
- const { textEdit } = item;
1272
- if (textEdit) {
1273
- if (textEdit.range) {
1274
- updateTextEdit(doc, info, textEdit);
1275
- }
1276
- if (textEdit.insert) {
1277
- updateInsertReplaceEdit(doc, info, textEdit);
1278
- }
1562
+ }
1563
+ for (const item of result.items) {
1564
+ if (item.textEdit) {
1565
+ item.textEdit = getSourceInsertReplaceEdit(doc, info, item.textEdit);
1566
+ }
1567
+ if (item.additionalTextEdits) {
1568
+ item.additionalTextEdits = getSourceEdits(doc, info, item.additionalTextEdits);
1279
1569
  }
1280
1570
  }
1281
1571
  return result;
1282
1572
  }
1283
1573
  return CompletionList2.create([], true);
1284
1574
  },
1285
- async findDefinition(doc, params) {
1575
+ findDefinition(doc, params) {
1286
1576
  const infoByExt = getStyleSheetInfo(doc);
1287
1577
  const sourceOffset = doc.offsetAt(params.position);
1288
1578
  for (const ext in infoByExt) {
@@ -1292,13 +1582,19 @@ var StyleSheetService = {
1292
1582
  continue;
1293
1583
  const { service: service2, virtualDoc } = info;
1294
1584
  const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1295
- if (result && updateRange(doc, info, result.range)) {
1296
- return result;
1585
+ if (result) {
1586
+ const range = getSourceRange(doc, info, result.range);
1587
+ if (range) {
1588
+ return {
1589
+ range,
1590
+ uri: doc.uri
1591
+ };
1592
+ }
1297
1593
  }
1298
1594
  break;
1299
1595
  }
1300
1596
  },
1301
- async findReferences(doc, params) {
1597
+ findReferences(doc, params) {
1302
1598
  const infoByExt = getStyleSheetInfo(doc);
1303
1599
  const sourceOffset = doc.offsetAt(params.position);
1304
1600
  for (const ext in infoByExt) {
@@ -1309,14 +1605,38 @@ var StyleSheetService = {
1309
1605
  const { service: service2, virtualDoc } = info;
1310
1606
  const result = [];
1311
1607
  for (const location of service2.findReferences(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1312
- if (updateRange(doc, info, location.range)) {
1313
- result.push(location);
1608
+ const range = getSourceRange(doc, info, location.range);
1609
+ if (range) {
1610
+ result.push({
1611
+ range,
1612
+ uri: location.uri
1613
+ });
1314
1614
  }
1315
1615
  }
1316
1616
  return result.length ? result : void 0;
1317
1617
  }
1318
1618
  },
1319
- async findDocumentHighlights(doc, params) {
1619
+ async findDocumentLinks(doc) {
1620
+ const infoByExt = getStyleSheetInfo(doc);
1621
+ const result = [];
1622
+ for (const ext in infoByExt) {
1623
+ const info = infoByExt[ext];
1624
+ const { service: service2, virtualDoc } = info;
1625
+ for (const link of await service2.findDocumentLinks2(virtualDoc, info.parsed, { resolveReference: resolveUrl })) {
1626
+ const range = getSourceRange(doc, info, link.range);
1627
+ if (range) {
1628
+ result.push({
1629
+ range,
1630
+ target: link.target,
1631
+ tooltip: link.tooltip,
1632
+ data: link.data
1633
+ });
1634
+ }
1635
+ }
1636
+ }
1637
+ return result.length ? result : void 0;
1638
+ },
1639
+ findDocumentHighlights(doc, params) {
1320
1640
  const infoByExt = getStyleSheetInfo(doc);
1321
1641
  const sourceOffset = doc.offsetAt(params.position);
1322
1642
  for (const ext in infoByExt) {
@@ -1327,30 +1647,36 @@ var StyleSheetService = {
1327
1647
  const { service: service2, virtualDoc } = info;
1328
1648
  const result = [];
1329
1649
  for (const highlight of service2.findDocumentHighlights(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1330
- if (updateRange(doc, info, highlight.range)) {
1331
- result.push(highlight);
1650
+ const range = getSourceRange(doc, info, highlight.range);
1651
+ if (range) {
1652
+ result.push({
1653
+ range,
1654
+ kind: highlight.kind
1655
+ });
1332
1656
  }
1333
1657
  }
1334
1658
  return result.length ? result : void 0;
1335
1659
  }
1336
1660
  },
1337
- async findDocumentColors(doc) {
1661
+ findDocumentColors(doc) {
1338
1662
  const infoByExt = getStyleSheetInfo(doc);
1339
1663
  const result = [];
1340
1664
  for (const ext in infoByExt) {
1341
1665
  const info = infoByExt[ext];
1342
1666
  const { service: service2, virtualDoc } = info;
1343
1667
  for (const colorInfo of service2.findDocumentColors(virtualDoc, info.parsed)) {
1344
- if (updateRange(doc, info, colorInfo.range)) {
1345
- result.push(colorInfo);
1668
+ const range = getSourceRange(doc, info, colorInfo.range);
1669
+ if (range) {
1670
+ result.push({
1671
+ range,
1672
+ color: colorInfo.color
1673
+ });
1346
1674
  }
1347
1675
  }
1348
1676
  }
1349
- if (result.length) {
1350
- return result;
1351
- }
1677
+ return result.length ? result : void 0;
1352
1678
  },
1353
- async getColorPresentations(doc, params) {
1679
+ getColorPresentations(doc, params) {
1354
1680
  const infoByExt = getStyleSheetInfo(doc);
1355
1681
  const sourceOffset = doc.offsetAt(params.range.start);
1356
1682
  for (const ext in infoByExt) {
@@ -1362,21 +1688,22 @@ var StyleSheetService = {
1362
1688
  if (generatedOffsetEnd === void 0)
1363
1689
  continue;
1364
1690
  const { service: service2, virtualDoc } = info;
1365
- const result = service2.getColorPresentations(virtualDoc, info.parsed, params.color, Range8.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)));
1366
- for (const colorPresentation of result) {
1367
- if (colorPresentation.textEdit) {
1368
- updateTextEdit(doc, info, colorPresentation.textEdit);
1369
- }
1370
- if (colorPresentation.additionalTextEdits) {
1371
- for (const textEdit of colorPresentation.additionalTextEdits) {
1372
- updateTextEdit(doc, info, textEdit);
1373
- }
1691
+ const result = [];
1692
+ for (const colorPresentation of service2.getColorPresentations(virtualDoc, info.parsed, params.color, Range9.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)))) {
1693
+ const textEdit = colorPresentation.textEdit && getSourceEdit(doc, info, colorPresentation.textEdit);
1694
+ const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(doc, info, colorPresentation.additionalTextEdits);
1695
+ if (textEdit || additionalTextEdits) {
1696
+ result.push({
1697
+ label: colorPresentation.label,
1698
+ textEdit,
1699
+ additionalTextEdits
1700
+ });
1374
1701
  }
1375
1702
  }
1376
- return result;
1703
+ return result.length ? result : void 0;
1377
1704
  }
1378
1705
  },
1379
- async doHover(doc, params) {
1706
+ doHover(doc, params) {
1380
1707
  const infoByExt = getStyleSheetInfo(doc);
1381
1708
  const sourceOffset = doc.offsetAt(params.position);
1382
1709
  for (const ext in infoByExt) {
@@ -1386,8 +1713,18 @@ var StyleSheetService = {
1386
1713
  continue;
1387
1714
  const { service: service2, virtualDoc } = info;
1388
1715
  const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1389
- if (result && (!result.range || updateRange(doc, info, result.range))) {
1390
- return result;
1716
+ if (result) {
1717
+ if (result.range) {
1718
+ const range = getSourceRange(doc, info, result.range);
1719
+ if (range) {
1720
+ return {
1721
+ range,
1722
+ contents: result.contents
1723
+ };
1724
+ }
1725
+ } else {
1726
+ return result;
1727
+ }
1391
1728
  }
1392
1729
  }
1393
1730
  },
@@ -1404,9 +1741,7 @@ var StyleSheetService = {
1404
1741
  if (result.changes) {
1405
1742
  for (const uri in result.changes) {
1406
1743
  if (uri === doc.uri) {
1407
- for (const textEdit of result.changes[uri]) {
1408
- updateTextEdit(doc, info, textEdit);
1409
- }
1744
+ result.changes[uri] = getSourceEdits(doc, info, result.changes[uri]) || [];
1410
1745
  }
1411
1746
  }
1412
1747
  }
@@ -1414,9 +1749,7 @@ var StyleSheetService = {
1414
1749
  for (const change of result.documentChanges) {
1415
1750
  if (TextDocumentEdit.is(change)) {
1416
1751
  if (change.textDocument.uri === doc.uri) {
1417
- for (const textEdit of change.edits) {
1418
- updateTextEdit(doc, info, textEdit);
1419
- }
1752
+ change.edits = getSourceEdits(doc, info, change.edits) || [];
1420
1753
  }
1421
1754
  }
1422
1755
  }
@@ -1424,7 +1757,7 @@ var StyleSheetService = {
1424
1757
  return result;
1425
1758
  }
1426
1759
  },
1427
- async doCodeActions(doc, params) {
1760
+ doCodeActions(doc, params) {
1428
1761
  var _a;
1429
1762
  const infoByExt = getStyleSheetInfo(doc);
1430
1763
  const sourceOffset = doc.offsetAt(params.range.start);
@@ -1437,65 +1770,100 @@ var StyleSheetService = {
1437
1770
  if (generatedOffsetEnd === void 0)
1438
1771
  continue;
1439
1772
  const { service: service2, virtualDoc } = info;
1440
- const result = service2.doCodeActions(virtualDoc, Range8.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
1441
- if (result) {
1442
- for (const command of result) {
1443
- const edits = (_a = command.arguments) == null ? void 0 : _a[2];
1444
- if (edits) {
1445
- for (const textEdit of edits) {
1446
- updateTextEdit(doc, info, textEdit);
1447
- }
1448
- }
1773
+ const result = service2.doCodeActions(virtualDoc, Range9.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
1774
+ for (const command of result) {
1775
+ const edits = (_a = command.arguments) == null ? void 0 : _a[2];
1776
+ if (edits && Array.isArray(edits) && isTextEdit(edits[0])) {
1777
+ command.arguments[2] = getSourceEdits(doc, info, edits);
1449
1778
  }
1450
- return result;
1451
1779
  }
1780
+ return result;
1452
1781
  }
1453
1782
  },
1454
- async doValidate(doc) {
1783
+ doValidate(doc) {
1455
1784
  const infoByExt = getStyleSheetInfo(doc);
1456
1785
  const result = [];
1457
1786
  for (const ext in infoByExt) {
1458
1787
  const info = infoByExt[ext];
1459
1788
  for (const diag of info.service.doValidation(info.virtualDoc, info.parsed)) {
1460
- if (updateRange(doc, info, diag.range)) {
1789
+ const range = getSourceRange(doc, info, diag.range);
1790
+ if (range) {
1791
+ diag.range = range;
1461
1792
  result.push(diag);
1462
1793
  }
1463
1794
  }
1464
1795
  }
1465
- return result;
1796
+ return result.length ? result : void 0;
1466
1797
  }
1467
1798
  };
1468
- function updateTextEdit(doc, info, textEdit) {
1469
- if (!updateRange(doc, info, textEdit.range)) {
1470
- textEdit.newText = "";
1471
- textEdit.range = START_OF_FILE;
1799
+ function getSourceEdits(doc, info, edits) {
1800
+ const result = [];
1801
+ for (const edit of edits) {
1802
+ const sourceEdit = getSourceEdit(doc, info, edit);
1803
+ if (sourceEdit) {
1804
+ result.push(sourceEdit);
1805
+ }
1472
1806
  }
1807
+ return result.length ? result : void 0;
1473
1808
  }
1474
- function updateInsertReplaceEdit(doc, info, insertReplaceEdit) {
1475
- if (!updateRange(doc, info, insertReplaceEdit.insert)) {
1476
- insertReplaceEdit.newText = "";
1477
- insertReplaceEdit.insert = START_OF_FILE;
1809
+ function getSourceEdit(doc, info, textEdit) {
1810
+ const range = getSourceRange(doc, info, textEdit.range);
1811
+ if (range) {
1812
+ return {
1813
+ newText: textEdit.newText,
1814
+ range
1815
+ };
1478
1816
  }
1479
1817
  }
1480
- function updateRange(doc, info, range) {
1818
+ function getSourceInsertReplaceEdit(doc, info, textEdit) {
1819
+ if (isTextEdit(textEdit)) {
1820
+ return getSourceEdit(doc, info, textEdit);
1821
+ } else if (textEdit.replace) {
1822
+ const range = getSourceRange(doc, info, textEdit.replace);
1823
+ if (range) {
1824
+ return {
1825
+ newText: textEdit.newText,
1826
+ replace: range
1827
+ };
1828
+ }
1829
+ } else {
1830
+ const range = getSourceRange(doc, info, textEdit.insert);
1831
+ if (range) {
1832
+ return {
1833
+ newText: textEdit.newText,
1834
+ insert: range
1835
+ };
1836
+ }
1837
+ }
1838
+ }
1839
+ function getSourceRange(doc, info, range) {
1481
1840
  const start = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.start));
1482
- const end = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.end));
1483
- if (start !== void 0 || end !== void 0) {
1484
- range.start = doc.positionAt(start ?? end);
1485
- range.end = doc.positionAt(end ?? start);
1486
- return true;
1841
+ if (start === void 0)
1842
+ return;
1843
+ let end = start;
1844
+ if (range.start.line !== range.end.line || range.start.character !== range.end.character) {
1845
+ end = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.end));
1846
+ if (end === void 0)
1847
+ return;
1487
1848
  }
1488
- return false;
1849
+ const pos = doc.positionAt(start);
1850
+ return {
1851
+ start: pos,
1852
+ end: start === end ? pos : doc.positionAt(end)
1853
+ };
1489
1854
  }
1490
1855
  function getStyleSheetInfo(doc) {
1491
1856
  var _a;
1492
1857
  const parsed = parse2(doc);
1493
- let cached = cache.get(parsed);
1858
+ let cached = cache2.get(parsed);
1494
1859
  if (!cached) {
1495
1860
  const results = extractStyleSheets(doc.getText(), parsed.program, getCompilerInfo(doc).lookup);
1496
1861
  cached = {};
1497
1862
  for (const ext in results) {
1498
- const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services);
1863
+ const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services, {
1864
+ fileSystemProvider: file_system_default,
1865
+ clientCapabilities
1866
+ });
1499
1867
  if (!service2)
1500
1868
  continue;
1501
1869
  const { generated, sourceOffsetAt, generatedOffsetAt } = results[ext];
@@ -1508,60 +1876,65 @@ function getStyleSheetInfo(doc) {
1508
1876
  parsed: service2.parseStylesheet(virtualDoc)
1509
1877
  };
1510
1878
  }
1511
- cache.set(parsed, cached);
1879
+ cache2.set(parsed, cached);
1512
1880
  }
1513
1881
  return cached;
1514
1882
  }
1883
+ function isTextEdit(edit) {
1884
+ return edit.range !== void 0;
1885
+ }
1515
1886
 
1516
1887
  // src/service/index.ts
1517
1888
  var plugins = [marko_default, StyleSheetService];
1518
1889
  var service = {
1890
+ async initialize(params) {
1891
+ await Promise.all(plugins.map((plugin) => {
1892
+ var _a;
1893
+ return (_a = plugin.initialize) == null ? void 0 : _a.call(plugin, params);
1894
+ }));
1895
+ },
1519
1896
  async doComplete(doc, params, cancel) {
1520
- const result = CompletionList3.create([], false);
1897
+ let items;
1898
+ let isIncomplete = false;
1521
1899
  try {
1522
- const requests = plugins.map((plugin) => {
1900
+ for (const pending of plugins.map((plugin) => {
1523
1901
  var _a;
1524
1902
  return (_a = plugin.doComplete) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1525
- });
1526
- for (const pending of requests) {
1903
+ })) {
1527
1904
  const cur = await pending;
1528
1905
  if (cancel.isCancellationRequested)
1529
1906
  return;
1530
1907
  if (cur) {
1531
- let items;
1908
+ let curItems;
1532
1909
  if (Array.isArray(cur)) {
1533
- items = cur;
1910
+ curItems = cur;
1534
1911
  } else {
1535
- items = cur.items;
1536
- result.isIncomplete || (result.isIncomplete = cur.isIncomplete);
1912
+ curItems = cur.items;
1913
+ isIncomplete || (isIncomplete = cur.isIncomplete);
1537
1914
  }
1538
- result.items.push(...items);
1915
+ items = items ? items.concat(curItems) : curItems;
1539
1916
  }
1540
1917
  }
1541
1918
  } catch (err) {
1542
- result.isIncomplete = true;
1919
+ isIncomplete = true;
1543
1920
  displayError(err);
1544
1921
  }
1545
- return result;
1922
+ if (items) {
1923
+ return CompletionList3.create(items, isIncomplete);
1924
+ }
1546
1925
  },
1547
1926
  async findDefinition(doc, params, cancel) {
1548
- const result = [];
1927
+ let result;
1549
1928
  try {
1550
- const requests = plugins.map((plugin) => {
1929
+ for (const pending of plugins.map((plugin) => {
1551
1930
  var _a;
1552
1931
  return (_a = plugin.findDefinition) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1553
- });
1554
- for (const pending of requests) {
1932
+ })) {
1555
1933
  const cur = await pending;
1556
1934
  if (cancel.isCancellationRequested)
1557
1935
  return;
1558
- if (cur) {
1559
- if (Array.isArray(cur)) {
1560
- result.push(...cur);
1561
- } else {
1562
- result.push(cur);
1563
- }
1564
- }
1936
+ if (cur)
1937
+ result = (result || []).concat(cur);
1565
1938
  }
1566
1939
  } catch (err) {
1567
1940
  displayError(err);
@@ -1571,21 +1944,33 @@ var service = {
1571
1944
  async findReferences(doc, params, cancel) {
1572
1945
  let result;
1573
1946
  try {
1574
- const requests = plugins.map((plugin) => {
1947
+ for (const pending of plugins.map((plugin) => {
1575
1948
  var _a;
1576
1949
  return (_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1577
- });
1578
- for (const pending of requests) {
1950
+ })) {
1579
1951
  const cur = await pending;
1580
1952
  if (cancel.isCancellationRequested)
1581
1953
  return;
1582
- if (cur) {
1583
- if (result) {
1584
- result.push(...cur);
1585
- } else {
1586
- result = cur;
1587
- }
1588
- }
1954
+ if (cur)
1955
+ result = result ? result.concat(cur) : cur;
1956
+ }
1957
+ } catch (err) {
1958
+ displayError(err);
1959
+ }
1960
+ return result;
1961
+ },
1962
+ async findDocumentLinks(doc, params, cancel) {
1963
+ let result;
1964
+ try {
1965
+ for (const pending of plugins.map((plugin) => {
1966
+ var _a;
1967
+ return (_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1968
+ })) {
1969
+ const cur = await pending;
1970
+ if (cancel.isCancellationRequested)
1971
+ return;
1972
+ if (cur)
1973
+ result = result ? result.concat(cur) : cur;
1589
1974
  }
1590
1975
  } catch (err) {
1591
1976
  displayError(err);
@@ -1595,21 +1980,15 @@ var service = {
1595
1980
  async findDocumentHighlights(doc, params, cancel) {
1596
1981
  let result;
1597
1982
  try {
1598
- const requests = plugins.map((plugin) => {
1983
+ for (const pending of plugins.map((plugin) => {
1599
1984
  var _a;
1600
1985
  return (_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1601
- });
1602
- for (const pending of requests) {
1986
+ })) {
1603
1987
  const cur = await pending;
1604
1988
  if (cancel.isCancellationRequested)
1605
1989
  return;
1606
- if (cur) {
1607
- if (result) {
1608
- result.push(...cur);
1609
- } else {
1610
- result = cur;
1611
- }
1612
- }
1990
+ if (cur)
1991
+ result = result ? result.concat(cur) : cur;
1613
1992
  }
1614
1993
  } catch (err) {
1615
1994
  displayError(err);
@@ -1619,21 +1998,15 @@ var service = {
1619
1998
  async findDocumentColors(doc, params, cancel) {
1620
1999
  let result;
1621
2000
  try {
1622
- const requests = plugins.map((plugin) => {
2001
+ for (const pending of plugins.map((plugin) => {
1623
2002
  var _a;
1624
2003
  return (_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1625
- });
1626
- for (const pending of requests) {
2004
+ })) {
1627
2005
  const cur = await pending;
1628
2006
  if (cancel.isCancellationRequested)
1629
2007
  return;
1630
- if (cur) {
1631
- if (result) {
1632
- result.push(...cur);
1633
- } else {
1634
- result = cur;
1635
- }
1636
- }
2008
+ if (cur)
2009
+ result = result ? result.concat(cur) : cur;
1637
2010
  }
1638
2011
  } catch (err) {
1639
2012
  displayError(err);
@@ -1643,21 +2016,15 @@ var service = {
1643
2016
  async getColorPresentations(doc, params, cancel) {
1644
2017
  let result;
1645
2018
  try {
1646
- const requests = plugins.map((plugin) => {
2019
+ for (const pending of plugins.map((plugin) => {
1647
2020
  var _a;
1648
2021
  return (_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1649
- });
1650
- for (const pending of requests) {
2022
+ })) {
1651
2023
  const cur = await pending;
1652
2024
  if (cancel.isCancellationRequested)
1653
2025
  return;
1654
- if (cur) {
1655
- if (result) {
1656
- result.push(...cur);
1657
- } else {
1658
- result = cur;
1659
- }
1660
- }
2026
+ if (cur)
2027
+ result = result ? result.concat(cur) : cur;
1661
2028
  }
1662
2029
  } catch (err) {
1663
2030
  displayError(err);
@@ -1683,41 +2050,32 @@ var service = {
1683
2050
  let changeAnnotations;
1684
2051
  let documentChanges;
1685
2052
  try {
1686
- const requests = plugins.map((plugin) => {
2053
+ for (const pending of plugins.map((plugin) => {
1687
2054
  var _a;
1688
2055
  return (_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1689
- });
1690
- for (const pending of requests) {
2056
+ })) {
1691
2057
  const cur = await pending;
1692
2058
  if (cancel.isCancellationRequested)
1693
2059
  return;
1694
2060
  if (cur) {
1695
2061
  if (cur.changes) {
1696
2062
  if (changes) {
2063
+ changes = { ...changes };
1697
2064
  for (const uri in cur.changes) {
1698
- if (changes[uri]) {
1699
- changes[uri].push(...cur.changes[uri]);
1700
- } else {
1701
- changes[uri] = cur.changes[uri];
1702
- }
2065
+ changes[uri] = changes[uri] ? changes[uri].concat(cur.changes[uri]) : cur.changes[uri];
1703
2066
  }
1704
2067
  } else {
1705
2068
  changes = cur.changes;
1706
2069
  }
1707
2070
  }
1708
2071
  if (cur.changeAnnotations) {
1709
- if (changeAnnotations) {
1710
- Object.assign(changeAnnotations, cur.changeAnnotations);
1711
- } else {
1712
- changeAnnotations = cur.changeAnnotations;
1713
- }
2072
+ changeAnnotations = changeAnnotations ? {
2073
+ ...changeAnnotations,
2074
+ ...cur.changeAnnotations
2075
+ } : cur.changeAnnotations;
1714
2076
  }
1715
2077
  if (cur.documentChanges) {
1716
- if (documentChanges) {
1717
- documentChanges.push(...cur.documentChanges);
1718
- } else {
1719
- documentChanges = cur.documentChanges;
1720
- }
2078
+ documentChanges = documentChanges ? documentChanges.concat(cur.documentChanges) : cur.documentChanges;
1721
2079
  }
1722
2080
  }
1723
2081
  }
@@ -1733,19 +2091,17 @@ var service = {
1733
2091
  }
1734
2092
  },
1735
2093
  async doCodeActions(doc, params, cancel) {
1736
- const result = [];
2094
+ let result;
1737
2095
  try {
1738
- const requests = plugins.map((plugin) => {
2096
+ for (const pending of plugins.map((plugin) => {
1739
2097
  var _a;
1740
2098
  return (_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1741
- });
1742
- for (const pending of requests) {
2099
+ })) {
1743
2100
  const cur = await pending;
1744
2101
  if (cancel.isCancellationRequested)
1745
2102
  return;
1746
- if (cur) {
1747
- result.push(...cur);
1748
- }
2103
+ if (cur)
2104
+ result = result ? result.concat(cur) : cur;
1749
2105
  }
1750
2106
  } catch (err) {
1751
2107
  displayError(err);
@@ -1753,16 +2109,15 @@ var service = {
1753
2109
  return result;
1754
2110
  },
1755
2111
  async doValidate(doc) {
1756
- const result = [];
2112
+ let result;
1757
2113
  try {
1758
- const requests = plugins.map((plugin) => {
2114
+ for (const pending of plugins.map((plugin) => {
1759
2115
  var _a;
1760
2116
  return (_a = plugin.doValidate) == null ? void 0 : _a.call(plugin, doc);
1761
- });
1762
- for (const pending of requests) {
2117
+ })) {
1763
2118
  const cur = await pending;
1764
2119
  if (cur)
1765
- result.push(...cur);
2120
+ result = result ? result.concat(cur) : cur;
1766
2121
  }
1767
2122
  } catch (err) {
1768
2123
  displayError(err);
@@ -1789,8 +2144,9 @@ console.error = (...args) => {
1789
2144
  };
1790
2145
  process.on("uncaughtException", console.error);
1791
2146
  process.on("unhandledRejection", console.error);
1792
- connection2.onInitialize(() => {
2147
+ connection2.onInitialize(async (params) => {
1793
2148
  setup(connection2);
2149
+ await service.initialize(params);
1794
2150
  return {
1795
2151
  capabilities: {
1796
2152
  textDocumentSync: TextDocumentSyncKind.Incremental,
@@ -1800,6 +2156,7 @@ connection2.onInitialize(() => {
1800
2156
  renameProvider: true,
1801
2157
  codeActionProvider: true,
1802
2158
  referencesProvider: true,
2159
+ documentLinkProvider: { resolveProvider: false },
1803
2160
  colorProvider: true,
1804
2161
  documentHighlightProvider: true,
1805
2162
  completionProvider: {
@@ -1844,6 +2201,9 @@ connection2.onDefinition(async (params, cancel) => {
1844
2201
  connection2.onReferences(async (params, cancel) => {
1845
2202
  return await service.findReferences(documents.get(params.textDocument.uri), params, cancel) || null;
1846
2203
  });
2204
+ connection2.onDocumentLinks(async (params, cancel) => {
2205
+ return await service.findDocumentLinks(documents.get(params.textDocument.uri), params, cancel) || null;
2206
+ });
1847
2207
  connection2.onDocumentHighlight(async (params, cancel) => {
1848
2208
  return await service.findDocumentHighlights(documents.get(params.textDocument.uri), params, cancel) || null;
1849
2209
  });