@marko/language-server 0.12.11 → 0.12.14

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.js CHANGED
@@ -575,7 +575,7 @@ function loadCompilerInfo(dir) {
575
575
  const rootDir = import_lasso_package_root.default.getRootDir(dir);
576
576
  const pkgPath = rootDir && import_resolve_from.default.silent(rootDir, "@marko/compiler/package.json");
577
577
  const pkg = pkgPath && require(pkgPath);
578
- const cache3 = /* @__PURE__ */ new Map();
578
+ const cache4 = /* @__PURE__ */ new Map();
579
579
  let translator = builtinTranslator;
580
580
  let compiler = builtinCompiler;
581
581
  if (pkg && /^5\./.test(pkg.version)) {
@@ -592,16 +592,16 @@ function loadCompilerInfo(dir) {
592
592
  }
593
593
  }
594
594
  return {
595
- cache: cache3,
595
+ cache: cache4,
596
596
  get lookup() {
597
- let lookup = cache3.get(lookupKey);
597
+ let lookup = cache4.get(lookupKey);
598
598
  if (lookup === void 0) {
599
599
  try {
600
600
  lookup = compiler.taglib.buildLookup(dir, translator);
601
601
  } catch {
602
602
  lookup = builtinInfo.lookup;
603
603
  }
604
- cache3.set(lookupKey, lookup);
604
+ cache4.set(lookupKey, lookup);
605
605
  }
606
606
  return lookup;
607
607
  },
@@ -625,10 +625,10 @@ function display(type, data) {
625
625
  }
626
626
 
627
627
  // src/service/index.ts
628
- var import_vscode_languageserver13 = require("vscode-languageserver");
628
+ var import_vscode_languageserver15 = require("vscode-languageserver");
629
629
 
630
630
  // src/service/marko/complete/index.ts
631
- var import_vscode_languageserver5 = require("vscode-languageserver");
631
+ var import_vscode_languageserver6 = require("vscode-languageserver");
632
632
 
633
633
  // src/service/marko/complete/Tag.ts
634
634
  var import_vscode_languageserver = require("vscode-languageserver");
@@ -670,71 +670,107 @@ ${closingTagStr}`
670
670
  }
671
671
  }
672
672
 
673
- // src/service/marko/complete/OpenTagName.ts
673
+ // src/service/marko/util/get-tag-name-completion.ts
674
674
  var import_path2 = __toESM(require("path"));
675
- var import_vscode_uri2 = require("vscode-uri");
676
675
  var import_vscode_languageserver2 = require("vscode-languageserver");
676
+ var import_vscode_uri2 = require("vscode-uri");
677
+ var deprecated = [import_vscode_languageserver2.CompletionItemTag.Deprecated];
678
+ function getTagNameCompletion({
679
+ tag,
680
+ range,
681
+ showAutoComplete,
682
+ importer
683
+ }) {
684
+ var _a;
685
+ let label = tag.isNestedTag ? `@${tag.name}` : tag.name;
686
+ const fileForTag = tag.template || tag.renderer || tag.filePath;
687
+ const fileURIForTag = import_vscode_uri2.URI.file(fileForTag).toString();
688
+ const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(fileForTag);
689
+ const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
690
+ const isCoreTag = /^@?marko[/-]/.test(tag.taglibId) || nodeModuleName === "marko";
691
+ const documentation = {
692
+ kind: import_vscode_languageserver2.MarkupKind.Markdown,
693
+ value: tag.html ? `Built in [<${tag.name}>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${tag.name}) HTML tag.` : isCoreTag ? `Core Marko <${tag.name}> tag.` : nodeModuleName ? `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
694
+
695
+ [${importer ? import_path2.default.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
696
+ };
697
+ if (tag.description) {
698
+ documentation.value += `
699
+
700
+ ${tag.description}`;
701
+ }
702
+ const autocomplete = showAutoComplete ? (_a = tag.autocomplete) == null ? void 0 : _a[0] : void 0;
703
+ if (autocomplete) {
704
+ if (autocomplete.displayText) {
705
+ label = autocomplete.displayText;
706
+ }
707
+ if (autocomplete.description) {
708
+ documentation.value += `
709
+
710
+ ${autocomplete.description}`;
711
+ }
712
+ if (autocomplete.descriptionMoreURL) {
713
+ documentation.value += `
714
+
715
+ [More Info](${autocomplete.descriptionMoreURL})`;
716
+ }
717
+ }
718
+ return {
719
+ label,
720
+ documentation,
721
+ tags: tag.deprecated ? deprecated : void 0,
722
+ insertTextFormat: autocomplete ? import_vscode_languageserver2.InsertTextFormat.Snippet : void 0,
723
+ kind: tag.html ? import_vscode_languageserver2.CompletionItemKind.Property : import_vscode_languageserver2.CompletionItemKind.Class,
724
+ textEdit: range && import_vscode_languageserver2.TextEdit.replace(range, (autocomplete == null ? void 0 : autocomplete.snippet) || label)
725
+ };
726
+ }
727
+
728
+ // src/service/marko/complete/OpenTagName.ts
677
729
  function OpenTagName({
678
730
  document,
679
731
  lookup,
680
732
  parsed,
681
733
  node
682
734
  }) {
683
- const currentTemplateFilePath = getDocFile(document);
735
+ var _a;
736
+ const importer = getDocFile(document);
684
737
  const tag = node.parent;
685
- const tagNameLocation = parsed.locationAt(node);
686
- let tags;
687
- if (tag.type === 14 /* AttrTag */) {
738
+ const range = parsed.locationAt(node);
739
+ const isAttrTag = tag.type === 14 /* AttrTag */;
740
+ const result = [];
741
+ if (isAttrTag) {
688
742
  let parentTag = tag.owner;
689
743
  while ((parentTag == null ? void 0 : parentTag.type) === 14 /* AttrTag */)
690
744
  parentTag = parentTag.owner;
691
745
  const parentTagDef = parentTag && parentTag.nameText && lookup.getTag(parentTag.nameText);
692
- tags = parentTagDef && parentTagDef.nestedTags && Object.values(parentTagDef.nestedTags) || [];
693
- } else {
694
- tags = lookup.getTagsSorted().filter((it) => !it.isNestedTag);
695
- }
696
- return tags.filter((it) => !it.deprecated).filter((it) => it.name !== "*").filter((it) => /^[^_]/.test(it.name) || !/\/node_modules\//.test(it.filePath)).map((it) => {
697
- let label = it.isNestedTag ? `@${it.name}` : it.name;
698
- const fileForTag = it.template || it.renderer || it.filePath;
699
- const fileURIForTag = import_vscode_uri2.URI.file(fileForTag).toString();
700
- const nodeModuleMatch = /\/node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(fileForTag);
701
- const nodeModuleName = nodeModuleMatch && nodeModuleMatch[1];
702
- const isCoreTag = nodeModuleName === "marko";
703
- const documentation = {
704
- kind: import_vscode_languageserver2.MarkupKind.Markdown,
705
- 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:
706
-
707
- [${currentTemplateFilePath ? import_path2.default.relative(currentTemplateFilePath, fileForTag) : currentTemplateFilePath}](${fileURIForTag})`
708
- };
709
- if (it.description) {
710
- documentation.value += `
711
-
712
- ${it.description}`;
713
- }
714
- const autocomplete = it.autocomplete && it.autocomplete[0];
715
- if (autocomplete) {
716
- if (autocomplete.displayText) {
717
- label = autocomplete.displayText;
718
- }
719
- if (autocomplete.description) {
720
- documentation.value += `
721
-
722
- ${autocomplete.description}`;
746
+ if (parentTagDef) {
747
+ const { nestedTags } = parentTagDef;
748
+ for (const key in nestedTags) {
749
+ if (key !== "*") {
750
+ const tag2 = nestedTags[key];
751
+ result.push(getTagNameCompletion({
752
+ tag: tag2,
753
+ range,
754
+ importer,
755
+ showAutoComplete: true
756
+ }));
757
+ }
723
758
  }
724
- if (autocomplete.descriptionMoreURL) {
725
- documentation.value += `
726
-
727
- [More Info](${autocomplete.descriptionMoreURL})`;
759
+ }
760
+ } else {
761
+ const skipStatements = !(tag.concise && tag.parent.type === 0 /* Program */);
762
+ for (const tag2 of lookup.getTagsSorted()) {
763
+ if (!(tag2.name === "*" || tag2.isNestedTag || skipStatements && ((_a = tag2.parseOptions) == null ? void 0 : _a.statement) || tag2.name[0] === "_" && /^@?marko[/-]|[\\/]node_modules[\\/]/.test(tag2.filePath))) {
764
+ result.push(getTagNameCompletion({
765
+ tag: tag2,
766
+ range,
767
+ importer,
768
+ showAutoComplete: true
769
+ }));
728
770
  }
729
771
  }
730
- return {
731
- label,
732
- documentation,
733
- kind: import_vscode_languageserver2.CompletionItemKind.Class,
734
- insertTextFormat: import_vscode_languageserver2.InsertTextFormat.Snippet,
735
- textEdit: import_vscode_languageserver2.TextEdit.replace(tagNameLocation, autocomplete && autocomplete.snippet || label)
736
- };
737
- });
772
+ }
773
+ return result;
738
774
  }
739
775
 
740
776
  // src/service/marko/complete/AttrName.ts
@@ -973,19 +1009,59 @@ async function AttrValue({
973
1009
  }
974
1010
  }
975
1011
 
1012
+ // src/service/marko/complete/Statement.ts
1013
+ var import_vscode_languageserver5 = require("vscode-languageserver");
1014
+ var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1015
+ function Statement({
1016
+ code,
1017
+ node,
1018
+ parsed,
1019
+ lookup,
1020
+ document
1021
+ }) {
1022
+ var _a;
1023
+ if (code[node.start] === "i") {
1024
+ importTagReg.lastIndex = 0;
1025
+ const value = parsed.read(node);
1026
+ const match = importTagReg.exec(value);
1027
+ if (match) {
1028
+ const importer = getDocFile(document);
1029
+ const [{ length }] = match;
1030
+ const range = parsed.locationAt({
1031
+ start: node.start + match.index + 1,
1032
+ end: node.start + match.index + length - 1
1033
+ });
1034
+ const result = [];
1035
+ for (const tag of lookup.getTagsSorted()) {
1036
+ 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))) {
1037
+ const completion = getTagNameCompletion({
1038
+ tag,
1039
+ importer
1040
+ });
1041
+ completion.label = `<${completion.label}>`;
1042
+ completion.textEdit = import_vscode_languageserver5.TextEdit.replace(range, completion.label);
1043
+ result.push(completion);
1044
+ }
1045
+ }
1046
+ return result;
1047
+ }
1048
+ }
1049
+ }
1050
+
976
1051
  // src/service/marko/complete/index.ts
977
1052
  var handlers = {
978
1053
  Tag,
979
1054
  OpenTagName,
980
1055
  AttrName,
981
- AttrValue
1056
+ AttrValue,
1057
+ Statement
982
1058
  };
983
1059
  var doComplete = async (doc, params) => {
984
1060
  var _a;
985
1061
  const parsed = parse2(doc);
986
1062
  const offset = doc.offsetAt(params.position);
987
1063
  const node = parsed.nodeAt(offset);
988
- return import_vscode_languageserver5.CompletionList.create(await ((_a = handlers[NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
1064
+ return import_vscode_languageserver6.CompletionList.create(await ((_a = handlers[NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
989
1065
  document: doc,
990
1066
  params,
991
1067
  parsed,
@@ -997,15 +1073,15 @@ var doComplete = async (doc, params) => {
997
1073
  };
998
1074
 
999
1075
  // src/service/marko/validate.ts
1000
- var import_vscode_languageserver6 = require("vscode-languageserver");
1076
+ var import_vscode_languageserver7 = require("vscode-languageserver");
1001
1077
  var markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
1002
1078
  var doValidate = (doc) => {
1003
1079
  const fsPath = getDocFile(doc);
1004
1080
  const diagnostics = [];
1005
- const { compiler, translator, cache: cache3 } = getCompilerInfo(doc);
1081
+ const { compiler, translator, cache: cache4 } = getCompilerInfo(doc);
1006
1082
  try {
1007
1083
  compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
1008
- cache: cache3,
1084
+ cache: cache4,
1009
1085
  translator,
1010
1086
  code: false,
1011
1087
  output: "source",
@@ -1017,16 +1093,72 @@ var doValidate = (doc) => {
1017
1093
  const [, fileName, rawLine, rawCol, msg] = match;
1018
1094
  const line = (parseInt(rawLine, 10) || 1) - 1;
1019
1095
  const col = (parseInt(rawCol, 10) || 1) - 1;
1020
- diagnostics.push(import_vscode_languageserver6.Diagnostic.create(import_vscode_languageserver6.Range.create(line, col, line, col), msg, import_vscode_languageserver6.DiagnosticSeverity.Error, void 0, fileName));
1096
+ diagnostics.push(import_vscode_languageserver7.Diagnostic.create(import_vscode_languageserver7.Range.create(line, col, line, col), msg, import_vscode_languageserver7.DiagnosticSeverity.Error, void 0, fileName));
1021
1097
  }
1022
1098
  }
1023
1099
  return diagnostics;
1024
1100
  };
1025
1101
 
1102
+ // src/utils/utils.ts
1103
+ var import_fs = __toESM(require("fs"));
1104
+ var import_vscode_uri3 = require("vscode-uri");
1105
+ var import_vscode_languageserver8 = require("vscode-languageserver");
1106
+ var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
1107
+ var START_OF_FILE = import_vscode_languageserver8.Range.create(import_vscode_languageserver8.Position.create(0, 0), import_vscode_languageserver8.Position.create(0, 0));
1108
+ function createTextDocument(filename) {
1109
+ const uri = import_vscode_uri3.URI.file(filename).toString();
1110
+ const content = import_fs.default.readFileSync(filename, "utf-8");
1111
+ return import_vscode_languageserver_textdocument.TextDocument.create(uri, "plaintext", 0, content);
1112
+ }
1113
+
1114
+ // src/service/marko/hover/OpenTagName.ts
1115
+ function OpenTagName2({
1116
+ document,
1117
+ lookup,
1118
+ parsed,
1119
+ node
1120
+ }) {
1121
+ const importer = getDocFile(document);
1122
+ const tag = node.parent;
1123
+ const range = parsed.locationAt(node);
1124
+ const tagDef = tag.nameText && lookup.getTag(tag.nameText);
1125
+ if (tagDef) {
1126
+ const completion = getTagNameCompletion({
1127
+ tag: tagDef,
1128
+ range: START_OF_FILE,
1129
+ importer
1130
+ });
1131
+ return {
1132
+ range,
1133
+ contents: completion.documentation
1134
+ };
1135
+ }
1136
+ }
1137
+
1138
+ // src/service/marko/hover/index.ts
1139
+ var handlers2 = {
1140
+ OpenTagName: OpenTagName2
1141
+ };
1142
+ var doHover = async (doc, params) => {
1143
+ var _a;
1144
+ const parsed = parse2(doc);
1145
+ const offset = doc.offsetAt(params.position);
1146
+ const node = parsed.nodeAt(offset);
1147
+ return await ((_a = handlers2[NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
1148
+ document: doc,
1149
+ params,
1150
+ parsed,
1151
+ offset,
1152
+ node,
1153
+ code: doc.getText(),
1154
+ ...getCompilerInfo(doc)
1155
+ }));
1156
+ };
1157
+
1026
1158
  // src/service/marko/definition/OpenTagName.ts
1027
1159
  var import_path4 = __toESM(require("path"));
1028
1160
  var import_vscode_uri4 = require("vscode-uri");
1029
- var import_vscode_languageserver8 = require("vscode-languageserver");
1161
+ var import_vscode_languageserver9 = require("vscode-languageserver");
1030
1162
 
1031
1163
  // src/utils/regexp-builder.ts
1032
1164
  function RegExpBuilder(strings, ...expressions) {
@@ -1052,20 +1184,8 @@ function escape(val) {
1052
1184
  return String(val).replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
1053
1185
  }
1054
1186
 
1055
- // src/utils/utils.ts
1056
- var import_fs = __toESM(require("fs"));
1057
- var import_vscode_uri3 = require("vscode-uri");
1058
- var import_vscode_languageserver7 = require("vscode-languageserver");
1059
- var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
1060
- var START_OF_FILE = import_vscode_languageserver7.Range.create(import_vscode_languageserver7.Position.create(0, 0), import_vscode_languageserver7.Position.create(0, 0));
1061
- function createTextDocument(filename) {
1062
- const uri = import_vscode_uri3.URI.file(filename).toString();
1063
- const content = import_fs.default.readFileSync(filename, "utf-8");
1064
- return import_vscode_languageserver_textdocument.TextDocument.create(uri, "plaintext", 0, content);
1065
- }
1066
-
1067
1187
  // src/service/marko/definition/OpenTagName.ts
1068
- function OpenTagName2({
1188
+ function OpenTagName3({
1069
1189
  lookup,
1070
1190
  parsed,
1071
1191
  node
@@ -1092,17 +1212,17 @@ function OpenTagName2({
1092
1212
  const tagDefDoc = createTextDocument(tagEntryFile);
1093
1213
  const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
1094
1214
  if (match && match.index) {
1095
- range = import_vscode_languageserver8.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1215
+ range = import_vscode_languageserver9.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1096
1216
  }
1097
1217
  }
1098
1218
  return [
1099
- import_vscode_languageserver8.LocationLink.create(import_vscode_uri4.URI.file(tagEntryFile).toString(), range, range, parsed.locationAt(node))
1219
+ import_vscode_languageserver9.LocationLink.create(import_vscode_uri4.URI.file(tagEntryFile).toString(), range, range, parsed.locationAt(node))
1100
1220
  ];
1101
1221
  }
1102
1222
 
1103
1223
  // src/service/marko/definition/AttrName.ts
1104
1224
  var import_vscode_uri5 = require("vscode-uri");
1105
- var import_vscode_languageserver9 = require("vscode-languageserver");
1225
+ var import_vscode_languageserver10 = require("vscode-languageserver");
1106
1226
  function AttrName2({
1107
1227
  lookup,
1108
1228
  parsed,
@@ -1126,17 +1246,17 @@ function AttrName2({
1126
1246
  const tagDefDoc = createTextDocument(attrEntryFile);
1127
1247
  const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
1128
1248
  if (match && match.index) {
1129
- range = import_vscode_languageserver9.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1249
+ range = import_vscode_languageserver10.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1130
1250
  }
1131
1251
  }
1132
1252
  return [
1133
- import_vscode_languageserver9.LocationLink.create(import_vscode_uri5.URI.file(attrEntryFile).toString(), range, range, parsed.locationAt(node))
1253
+ import_vscode_languageserver10.LocationLink.create(import_vscode_uri5.URI.file(attrEntryFile).toString(), range, range, parsed.locationAt(node))
1134
1254
  ];
1135
1255
  }
1136
1256
 
1137
1257
  // src/service/marko/definition/index.ts
1138
- var handlers2 = {
1139
- OpenTagName: OpenTagName2,
1258
+ var handlers3 = {
1259
+ OpenTagName: OpenTagName3,
1140
1260
  AttrName: AttrName2
1141
1261
  };
1142
1262
  var findDefinition = async (doc, params) => {
@@ -1144,7 +1264,7 @@ var findDefinition = async (doc, params) => {
1144
1264
  const parsed = parse2(doc);
1145
1265
  const offset = doc.offsetAt(params.position);
1146
1266
  const node = parsed.nodeAt(offset);
1147
- return await ((_a = handlers2[NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
1267
+ return await ((_a = handlers3[NodeType[node.type]]) == null ? void 0 : _a.call(handlers3, {
1148
1268
  document: doc,
1149
1269
  params,
1150
1270
  parsed,
@@ -1155,10 +1275,20 @@ var findDefinition = async (doc, params) => {
1155
1275
  })) || [];
1156
1276
  };
1157
1277
 
1158
- // src/service/marko/document-links/extract.ts
1159
- var import_vscode_languageserver10 = require("vscode-languageserver");
1278
+ // src/service/marko/document-links.ts
1279
+ var import_vscode_languageserver11 = require("vscode-languageserver");
1160
1280
  var import_vscode_uri6 = require("vscode-uri");
1161
- var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1281
+ var importTagReg2 = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1282
+ var cache = /* @__PURE__ */ new WeakMap();
1283
+ var findDocumentLinks = async (doc) => {
1284
+ const parsed = parse2(doc);
1285
+ let result = cache.get(parsed);
1286
+ if (!result) {
1287
+ result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1288
+ cache.set(parsed, result);
1289
+ }
1290
+ return result;
1291
+ };
1162
1292
  function extractDocumentLinks(doc, parsed, lookup) {
1163
1293
  if (import_vscode_uri6.URI.parse(doc.uri).scheme === "untitled") {
1164
1294
  return [];
@@ -1169,14 +1299,21 @@ function extractDocumentLinks(doc, parsed, lookup) {
1169
1299
  const read = (range) => code.slice(range.start, range.end);
1170
1300
  const visit = (node) => {
1171
1301
  switch (node.type) {
1302
+ case 14 /* AttrTag */:
1303
+ if (node.body) {
1304
+ for (const child of node.body) {
1305
+ visit(child);
1306
+ }
1307
+ }
1308
+ break;
1172
1309
  case 1 /* Tag */:
1173
1310
  if (node.attrs && node.nameText) {
1174
1311
  for (const attr of node.attrs) {
1175
1312
  if (isDocumentLinkAttr(doc, node, attr)) {
1176
- links.push(import_vscode_languageserver10.DocumentLink.create({
1177
- start: parsed.positionAt(attr.value.value.start),
1178
- end: parsed.positionAt(attr.value.value.end)
1179
- }, resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)));
1313
+ const resolved = resolveUrl(read(attr.value.value).slice(1, -1), doc.uri);
1314
+ if (resolved) {
1315
+ links.push(import_vscode_languageserver11.DocumentLink.create(parsed.locationAt(attr.value.value), resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)));
1316
+ }
1180
1317
  }
1181
1318
  }
1182
1319
  }
@@ -1190,18 +1327,18 @@ function extractDocumentLinks(doc, parsed, lookup) {
1190
1327
  };
1191
1328
  for (const item of program.static) {
1192
1329
  if (item.type === 20 /* Statement */ && code[item.start] === "i") {
1193
- importTagReg.lastIndex = 0;
1330
+ importTagReg2.lastIndex = 0;
1194
1331
  const value = parsed.read(item);
1195
- const match = importTagReg.exec(value);
1332
+ const match = importTagReg2.exec(value);
1196
1333
  if (match) {
1197
1334
  const [{ length }, , tagName] = match;
1198
1335
  const tagDef = lookup.getTag(tagName);
1199
1336
  const fileForTag = tagDef && (tagDef.template || tagDef.renderer);
1200
1337
  if (fileForTag) {
1201
- links.push(import_vscode_languageserver10.DocumentLink.create({
1202
- start: parsed.positionAt(item.start + match.index),
1203
- end: parsed.positionAt(item.start + match.index + length)
1204
- }, fileForTag));
1338
+ links.push(import_vscode_languageserver11.DocumentLink.create(parsed.locationAt({
1339
+ start: item.start + match.index,
1340
+ end: item.start + match.index + length
1341
+ }), fileForTag));
1205
1342
  }
1206
1343
  }
1207
1344
  }
@@ -1212,26 +1349,53 @@ function extractDocumentLinks(doc, parsed, lookup) {
1212
1349
  return links;
1213
1350
  }
1214
1351
 
1215
- // src/service/marko/document-links/index.ts
1216
- var cache = /* @__PURE__ */ new WeakMap();
1217
- var findDocumentLinks = async (doc) => {
1352
+ // src/service/marko/document-symbols.ts
1353
+ var import_vscode_uri7 = require("vscode-uri");
1354
+ var import_vscode_languageserver12 = require("vscode-languageserver");
1355
+ var cache2 = /* @__PURE__ */ new WeakMap();
1356
+ var findDocumentSymbols = async (doc) => {
1218
1357
  const parsed = parse2(doc);
1219
- let result = cache.get(parsed);
1358
+ let result = cache2.get(parsed);
1220
1359
  if (!result) {
1221
- result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1222
- cache.set(parsed, result);
1360
+ result = extractDocumentSymbols(doc, parsed, getCompilerInfo(doc).lookup);
1361
+ cache2.set(parsed, result);
1223
1362
  }
1224
1363
  return result;
1225
1364
  };
1365
+ function extractDocumentSymbols(doc, parsed, lookup) {
1366
+ if (import_vscode_uri7.URI.parse(doc.uri).scheme === "untitled") {
1367
+ return [];
1368
+ }
1369
+ const symbols = [];
1370
+ const { program } = parsed;
1371
+ const visit = (node) => {
1372
+ var _a, _b;
1373
+ switch (node.type) {
1374
+ case 1 /* Tag */:
1375
+ case 14 /* AttrTag */:
1376
+ symbols.push(import_vscode_languageserver12.SymbolInformation.create((node.type === 14 /* AttrTag */ ? (_a = node.nameText) == null ? void 0 : _a.slice(node.nameText.indexOf("@")) : node.nameText) || "<${...}>", node.nameText && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html) && import_vscode_languageserver12.SymbolKind.Property || import_vscode_languageserver12.SymbolKind.Class, parsed.locationAt(node), doc.uri));
1377
+ if (node.body) {
1378
+ for (const child of node.body) {
1379
+ visit(child);
1380
+ }
1381
+ }
1382
+ break;
1383
+ }
1384
+ };
1385
+ for (const item of program.body) {
1386
+ visit(item);
1387
+ }
1388
+ return symbols;
1389
+ }
1226
1390
 
1227
1391
  // src/service/marko/format.ts
1228
- var import_vscode_languageserver11 = require("vscode-languageserver");
1229
- var import_vscode_uri7 = require("vscode-uri");
1392
+ var import_vscode_languageserver13 = require("vscode-languageserver");
1393
+ var import_vscode_uri8 = require("vscode-uri");
1230
1394
  var prettier = __toESM(require("prettier"));
1231
1395
  var markoPrettier = __toESM(require("prettier-plugin-marko"));
1232
1396
  var format2 = async (doc, params, cancel) => {
1233
1397
  try {
1234
- const { fsPath, scheme } = import_vscode_uri7.URI.parse(doc.uri);
1398
+ const { fsPath, scheme } = import_vscode_uri8.URI.parse(doc.uri);
1235
1399
  const text = doc.getText();
1236
1400
  const options = {
1237
1401
  parser: "marko",
@@ -1246,7 +1410,7 @@ var format2 = async (doc, params, cancel) => {
1246
1410
  if (cancel.isCancellationRequested)
1247
1411
  return;
1248
1412
  return [
1249
- import_vscode_languageserver11.TextEdit.replace(import_vscode_languageserver11.Range.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1413
+ import_vscode_languageserver13.TextEdit.replace(import_vscode_languageserver13.Range.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1250
1414
  ];
1251
1415
  } catch (e) {
1252
1416
  displayError(e);
@@ -1257,13 +1421,15 @@ var format2 = async (doc, params, cancel) => {
1257
1421
  var marko_default = {
1258
1422
  doComplete,
1259
1423
  doValidate,
1424
+ doHover,
1260
1425
  findDefinition,
1261
1426
  findDocumentLinks,
1427
+ findDocumentSymbols,
1262
1428
  format: format2
1263
1429
  };
1264
1430
 
1265
1431
  // src/service/stylesheet/index.ts
1266
- var import_vscode_languageserver12 = require("vscode-languageserver");
1432
+ var import_vscode_languageserver14 = require("vscode-languageserver");
1267
1433
  var import_vscode_css_languageservice2 = require("vscode-css-languageservice");
1268
1434
  var import_vscode_languageserver_textdocument2 = require("vscode-languageserver-textdocument");
1269
1435
 
@@ -1369,6 +1535,13 @@ function extractStyleSheets(code, program, lookup) {
1369
1535
  const visit = (node) => {
1370
1536
  var _a, _b;
1371
1537
  switch (node.type) {
1538
+ case 14 /* AttrTag */:
1539
+ if (node.body) {
1540
+ for (const child of node.body) {
1541
+ visit(child);
1542
+ }
1543
+ }
1544
+ break;
1372
1545
  case 1 /* Tag */:
1373
1546
  if (node.nameText === "style" && node.concise && node.attrs) {
1374
1547
  const block = node.attrs.at(-1);
@@ -1425,7 +1598,7 @@ function extractStyleSheets(code, program, lookup) {
1425
1598
  }
1426
1599
 
1427
1600
  // src/service/stylesheet/index.ts
1428
- var cache2 = /* @__PURE__ */ new WeakMap();
1601
+ var cache3 = /* @__PURE__ */ new WeakMap();
1429
1602
  var services = {
1430
1603
  css: import_vscode_css_languageservice2.getCSSLanguageService,
1431
1604
  less: import_vscode_css_languageservice2.getLESSLanguageService,
@@ -1467,7 +1640,7 @@ var StyleSheetService = {
1467
1640
  }
1468
1641
  return result;
1469
1642
  }
1470
- return import_vscode_languageserver12.CompletionList.create([], true);
1643
+ return import_vscode_languageserver14.CompletionList.create([], true);
1471
1644
  },
1472
1645
  findDefinition(doc, params) {
1473
1646
  const infoByExt = getStyleSheetInfo(doc);
@@ -1513,6 +1686,32 @@ var StyleSheetService = {
1513
1686
  return result.length ? result : void 0;
1514
1687
  }
1515
1688
  },
1689
+ findDocumentSymbols(doc) {
1690
+ const infoByExt = getStyleSheetInfo(doc);
1691
+ const result = [];
1692
+ for (const ext in infoByExt) {
1693
+ const info = infoByExt[ext];
1694
+ const { service: service2, virtualDoc } = info;
1695
+ for (const symbol of service2.findDocumentSymbols(virtualDoc, info.parsed)) {
1696
+ if (symbol.location.uri === doc.uri) {
1697
+ const range = getSourceRange(doc, info, symbol.location.range);
1698
+ if (range) {
1699
+ result.push({
1700
+ kind: symbol.kind,
1701
+ name: symbol.name,
1702
+ tags: symbol.tags,
1703
+ deprecated: symbol.deprecated,
1704
+ containerName: symbol.containerName,
1705
+ location: { uri: doc.uri, range }
1706
+ });
1707
+ }
1708
+ } else {
1709
+ result.push(symbol);
1710
+ }
1711
+ }
1712
+ }
1713
+ return result.length ? result : void 0;
1714
+ },
1516
1715
  async findDocumentLinks(doc) {
1517
1716
  const infoByExt = getStyleSheetInfo(doc);
1518
1717
  const result = [];
@@ -1586,7 +1785,7 @@ var StyleSheetService = {
1586
1785
  continue;
1587
1786
  const { service: service2, virtualDoc } = info;
1588
1787
  const result = [];
1589
- for (const colorPresentation of service2.getColorPresentations(virtualDoc, info.parsed, params.color, import_vscode_languageserver12.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)))) {
1788
+ for (const colorPresentation of service2.getColorPresentations(virtualDoc, info.parsed, params.color, import_vscode_languageserver14.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)))) {
1590
1789
  const textEdit = colorPresentation.textEdit && getSourceEdit(doc, info, colorPresentation.textEdit);
1591
1790
  const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(doc, info, colorPresentation.additionalTextEdits);
1592
1791
  if (textEdit || additionalTextEdits) {
@@ -1644,7 +1843,7 @@ var StyleSheetService = {
1644
1843
  }
1645
1844
  if (result.documentChanges) {
1646
1845
  for (const change of result.documentChanges) {
1647
- if (import_vscode_languageserver12.TextDocumentEdit.is(change)) {
1846
+ if (import_vscode_languageserver14.TextDocumentEdit.is(change)) {
1648
1847
  if (change.textDocument.uri === doc.uri) {
1649
1848
  change.edits = getSourceEdits(doc, info, change.edits) || [];
1650
1849
  }
@@ -1667,7 +1866,7 @@ var StyleSheetService = {
1667
1866
  if (generatedOffsetEnd === void 0)
1668
1867
  continue;
1669
1868
  const { service: service2, virtualDoc } = info;
1670
- const result = service2.doCodeActions(virtualDoc, import_vscode_languageserver12.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
1869
+ const result = service2.doCodeActions(virtualDoc, import_vscode_languageserver14.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
1671
1870
  for (const command of result) {
1672
1871
  const edits = (_a = command.arguments) == null ? void 0 : _a[2];
1673
1872
  if (edits && Array.isArray(edits) && isTextEdit(edits[0])) {
@@ -1752,7 +1951,7 @@ function getSourceRange(doc, info, range) {
1752
1951
  function getStyleSheetInfo(doc) {
1753
1952
  var _a;
1754
1953
  const parsed = parse2(doc);
1755
- let cached = cache2.get(parsed);
1954
+ let cached = cache3.get(parsed);
1756
1955
  if (!cached) {
1757
1956
  const results = extractStyleSheets(doc.getText(), parsed.program, getCompilerInfo(doc).lookup);
1758
1957
  cached = {};
@@ -1773,7 +1972,7 @@ function getStyleSheetInfo(doc) {
1773
1972
  parsed: service2.parseStylesheet(virtualDoc)
1774
1973
  };
1775
1974
  }
1776
- cache2.set(parsed, cached);
1975
+ cache3.set(parsed, cached);
1777
1976
  }
1778
1977
  return cached;
1779
1978
  }
@@ -1791,51 +1990,47 @@ var service = {
1791
1990
  }));
1792
1991
  },
1793
1992
  async doComplete(doc, params, cancel) {
1794
- const result = import_vscode_languageserver13.CompletionList.create([], false);
1993
+ let items;
1994
+ let isIncomplete = false;
1795
1995
  try {
1796
- const requests = plugins.map((plugin) => {
1996
+ for (const pending of plugins.map((plugin) => {
1797
1997
  var _a;
1798
1998
  return (_a = plugin.doComplete) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1799
- });
1800
- for (const pending of requests) {
1999
+ })) {
1801
2000
  const cur = await pending;
1802
2001
  if (cancel.isCancellationRequested)
1803
2002
  return;
1804
2003
  if (cur) {
1805
- let items;
2004
+ let curItems;
1806
2005
  if (Array.isArray(cur)) {
1807
- items = cur;
2006
+ curItems = cur;
1808
2007
  } else {
1809
- items = cur.items;
1810
- result.isIncomplete || (result.isIncomplete = cur.isIncomplete);
2008
+ curItems = cur.items;
2009
+ isIncomplete || (isIncomplete = cur.isIncomplete);
1811
2010
  }
1812
- result.items.push(...items);
2011
+ items = items ? items.concat(curItems) : curItems;
1813
2012
  }
1814
2013
  }
1815
2014
  } catch (err) {
1816
- result.isIncomplete = true;
2015
+ isIncomplete = true;
1817
2016
  displayError(err);
1818
2017
  }
1819
- return result;
2018
+ if (items) {
2019
+ return import_vscode_languageserver15.CompletionList.create(items, isIncomplete);
2020
+ }
1820
2021
  },
1821
2022
  async findDefinition(doc, params, cancel) {
1822
- const result = [];
2023
+ let result;
1823
2024
  try {
1824
- const requests = plugins.map((plugin) => {
2025
+ for (const pending of plugins.map((plugin) => {
1825
2026
  var _a;
1826
2027
  return (_a = plugin.findDefinition) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1827
- });
1828
- for (const pending of requests) {
2028
+ })) {
1829
2029
  const cur = await pending;
1830
2030
  if (cancel.isCancellationRequested)
1831
2031
  return;
1832
- if (cur) {
1833
- if (Array.isArray(cur)) {
1834
- result.push(...cur);
1835
- } else {
1836
- result.push(cur);
1837
- }
1838
- }
2032
+ if (cur)
2033
+ result = (result || []).concat(cur);
1839
2034
  }
1840
2035
  } catch (err) {
1841
2036
  displayError(err);
@@ -1845,21 +2040,33 @@ var service = {
1845
2040
  async findReferences(doc, params, cancel) {
1846
2041
  let result;
1847
2042
  try {
1848
- const requests = plugins.map((plugin) => {
2043
+ for (const pending of plugins.map((plugin) => {
1849
2044
  var _a;
1850
2045
  return (_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1851
- });
1852
- for (const pending of requests) {
2046
+ })) {
1853
2047
  const cur = await pending;
1854
2048
  if (cancel.isCancellationRequested)
1855
2049
  return;
1856
- if (cur) {
1857
- if (result) {
1858
- result.push(...cur);
1859
- } else {
1860
- result = cur;
1861
- }
1862
- }
2050
+ if (cur)
2051
+ result = result ? result.concat(cur) : cur;
2052
+ }
2053
+ } catch (err) {
2054
+ displayError(err);
2055
+ }
2056
+ return result;
2057
+ },
2058
+ async findDocumentSymbols(doc, params, cancel) {
2059
+ let result;
2060
+ try {
2061
+ for (const pending of plugins.map((plugin) => {
2062
+ var _a;
2063
+ return (_a = plugin.findDocumentSymbols) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2064
+ })) {
2065
+ const cur = await pending;
2066
+ if (cancel.isCancellationRequested)
2067
+ return;
2068
+ if (cur)
2069
+ result = result ? result.concat(cur) : cur;
1863
2070
  }
1864
2071
  } catch (err) {
1865
2072
  displayError(err);
@@ -1869,21 +2076,15 @@ var service = {
1869
2076
  async findDocumentLinks(doc, params, cancel) {
1870
2077
  let result;
1871
2078
  try {
1872
- const requests = plugins.map((plugin) => {
2079
+ for (const pending of plugins.map((plugin) => {
1873
2080
  var _a;
1874
2081
  return (_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1875
- });
1876
- for (const pending of requests) {
2082
+ })) {
1877
2083
  const cur = await pending;
1878
2084
  if (cancel.isCancellationRequested)
1879
2085
  return;
1880
- if (cur) {
1881
- if (result) {
1882
- result.push(...cur);
1883
- } else {
1884
- result = cur;
1885
- }
1886
- }
2086
+ if (cur)
2087
+ result = result ? result.concat(cur) : cur;
1887
2088
  }
1888
2089
  } catch (err) {
1889
2090
  displayError(err);
@@ -1893,21 +2094,15 @@ var service = {
1893
2094
  async findDocumentHighlights(doc, params, cancel) {
1894
2095
  let result;
1895
2096
  try {
1896
- const requests = plugins.map((plugin) => {
2097
+ for (const pending of plugins.map((plugin) => {
1897
2098
  var _a;
1898
2099
  return (_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1899
- });
1900
- for (const pending of requests) {
2100
+ })) {
1901
2101
  const cur = await pending;
1902
2102
  if (cancel.isCancellationRequested)
1903
2103
  return;
1904
- if (cur) {
1905
- if (result) {
1906
- result.push(...cur);
1907
- } else {
1908
- result = cur;
1909
- }
1910
- }
2104
+ if (cur)
2105
+ result = result ? result.concat(cur) : cur;
1911
2106
  }
1912
2107
  } catch (err) {
1913
2108
  displayError(err);
@@ -1917,21 +2112,15 @@ var service = {
1917
2112
  async findDocumentColors(doc, params, cancel) {
1918
2113
  let result;
1919
2114
  try {
1920
- const requests = plugins.map((plugin) => {
2115
+ for (const pending of plugins.map((plugin) => {
1921
2116
  var _a;
1922
2117
  return (_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1923
- });
1924
- for (const pending of requests) {
2118
+ })) {
1925
2119
  const cur = await pending;
1926
2120
  if (cancel.isCancellationRequested)
1927
2121
  return;
1928
- if (cur) {
1929
- if (result) {
1930
- result.push(...cur);
1931
- } else {
1932
- result = cur;
1933
- }
1934
- }
2122
+ if (cur)
2123
+ result = result ? result.concat(cur) : cur;
1935
2124
  }
1936
2125
  } catch (err) {
1937
2126
  displayError(err);
@@ -1941,21 +2130,15 @@ var service = {
1941
2130
  async getColorPresentations(doc, params, cancel) {
1942
2131
  let result;
1943
2132
  try {
1944
- const requests = plugins.map((plugin) => {
2133
+ for (const pending of plugins.map((plugin) => {
1945
2134
  var _a;
1946
2135
  return (_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1947
- });
1948
- for (const pending of requests) {
2136
+ })) {
1949
2137
  const cur = await pending;
1950
2138
  if (cancel.isCancellationRequested)
1951
2139
  return;
1952
- if (cur) {
1953
- if (result) {
1954
- result.push(...cur);
1955
- } else {
1956
- result = cur;
1957
- }
1958
- }
2140
+ if (cur)
2141
+ result = result ? result.concat(cur) : cur;
1959
2142
  }
1960
2143
  } catch (err) {
1961
2144
  displayError(err);
@@ -1981,41 +2164,32 @@ var service = {
1981
2164
  let changeAnnotations;
1982
2165
  let documentChanges;
1983
2166
  try {
1984
- const requests = plugins.map((plugin) => {
2167
+ for (const pending of plugins.map((plugin) => {
1985
2168
  var _a;
1986
2169
  return (_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1987
- });
1988
- for (const pending of requests) {
2170
+ })) {
1989
2171
  const cur = await pending;
1990
2172
  if (cancel.isCancellationRequested)
1991
2173
  return;
1992
2174
  if (cur) {
1993
2175
  if (cur.changes) {
1994
2176
  if (changes) {
2177
+ changes = { ...changes };
1995
2178
  for (const uri in cur.changes) {
1996
- if (changes[uri]) {
1997
- changes[uri].push(...cur.changes[uri]);
1998
- } else {
1999
- changes[uri] = cur.changes[uri];
2000
- }
2179
+ changes[uri] = changes[uri] ? changes[uri].concat(cur.changes[uri]) : cur.changes[uri];
2001
2180
  }
2002
2181
  } else {
2003
2182
  changes = cur.changes;
2004
2183
  }
2005
2184
  }
2006
2185
  if (cur.changeAnnotations) {
2007
- if (changeAnnotations) {
2008
- Object.assign(changeAnnotations, cur.changeAnnotations);
2009
- } else {
2010
- changeAnnotations = cur.changeAnnotations;
2011
- }
2186
+ changeAnnotations = changeAnnotations ? {
2187
+ ...changeAnnotations,
2188
+ ...cur.changeAnnotations
2189
+ } : cur.changeAnnotations;
2012
2190
  }
2013
2191
  if (cur.documentChanges) {
2014
- if (documentChanges) {
2015
- documentChanges.push(...cur.documentChanges);
2016
- } else {
2017
- documentChanges = cur.documentChanges;
2018
- }
2192
+ documentChanges = documentChanges ? documentChanges.concat(cur.documentChanges) : cur.documentChanges;
2019
2193
  }
2020
2194
  }
2021
2195
  }
@@ -2031,19 +2205,17 @@ var service = {
2031
2205
  }
2032
2206
  },
2033
2207
  async doCodeActions(doc, params, cancel) {
2034
- const result = [];
2208
+ let result;
2035
2209
  try {
2036
- const requests = plugins.map((plugin) => {
2210
+ for (const pending of plugins.map((plugin) => {
2037
2211
  var _a;
2038
2212
  return (_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2039
- });
2040
- for (const pending of requests) {
2213
+ })) {
2041
2214
  const cur = await pending;
2042
2215
  if (cancel.isCancellationRequested)
2043
2216
  return;
2044
- if (cur) {
2045
- result.push(...cur);
2046
- }
2217
+ if (cur)
2218
+ result = result ? result.concat(cur) : cur;
2047
2219
  }
2048
2220
  } catch (err) {
2049
2221
  displayError(err);
@@ -2051,16 +2223,15 @@ var service = {
2051
2223
  return result;
2052
2224
  },
2053
2225
  async doValidate(doc) {
2054
- const result = [];
2226
+ let result;
2055
2227
  try {
2056
- const requests = plugins.map((plugin) => {
2228
+ for (const pending of plugins.map((plugin) => {
2057
2229
  var _a;
2058
2230
  return (_a = plugin.doValidate) == null ? void 0 : _a.call(plugin, doc);
2059
- });
2060
- for (const pending of requests) {
2231
+ })) {
2061
2232
  const cur = await pending;
2062
2233
  if (cur)
2063
- result.push(...cur);
2234
+ result = result ? result.concat(cur) : cur;
2064
2235
  }
2065
2236
  } catch (err) {
2066
2237
  displayError(err);
@@ -2102,6 +2273,7 @@ connection2.onInitialize(async (params) => {
2102
2273
  documentLinkProvider: { resolveProvider: false },
2103
2274
  colorProvider: true,
2104
2275
  documentHighlightProvider: true,
2276
+ documentSymbolProvider: true,
2105
2277
  completionProvider: {
2106
2278
  triggerCharacters: [
2107
2279
  ".",
@@ -2147,6 +2319,9 @@ connection2.onReferences(async (params, cancel) => {
2147
2319
  connection2.onDocumentLinks(async (params, cancel) => {
2148
2320
  return await service.findDocumentLinks(documents.get(params.textDocument.uri), params, cancel) || null;
2149
2321
  });
2322
+ connection2.onDocumentSymbol(async (params, cancel) => {
2323
+ return await service.findDocumentSymbols(documents.get(params.textDocument.uri), params, cancel) || null;
2324
+ });
2150
2325
  connection2.onDocumentHighlight(async (params, cancel) => {
2151
2326
  return await service.findDocumentHighlights(documents.get(params.textDocument.uri), params, cancel) || null;
2152
2327
  });