@marko/language-server 0.12.9 → 0.12.10

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 cache2 = /* @__PURE__ */ new Map();
578
+ const cache3 = /* @__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: cache2,
595
+ cache: cache3,
596
596
  get lookup() {
597
- let lookup = cache2.get(lookupKey);
597
+ let lookup = cache3.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
- cache2.set(lookupKey, lookup);
604
+ cache3.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_languageserver11 = require("vscode-languageserver");
628
+ var import_vscode_languageserver13 = require("vscode-languageserver");
629
629
 
630
630
  // src/service/marko/complete/index.ts
631
- var import_vscode_languageserver4 = require("vscode-languageserver");
631
+ var import_vscode_languageserver5 = require("vscode-languageserver");
632
632
 
633
633
  // src/service/marko/complete/Tag.ts
634
634
  var import_vscode_languageserver = require("vscode-languageserver");
@@ -842,18 +842,146 @@ function AttrName({
842
842
  return completions;
843
843
  }
844
844
 
845
+ // src/service/marko/complete/AttrValue.ts
846
+ var import_path4 = __toESM(require("path"));
847
+ var import_vscode_languageserver4 = require("vscode-languageserver");
848
+
849
+ // src/service/marko/util/is-document-link-attr.ts
850
+ var linkedAttrs = /* @__PURE__ */ new Map([
851
+ [
852
+ "src",
853
+ /* @__PURE__ */ new Set([
854
+ "audio",
855
+ "embed",
856
+ "iframe",
857
+ "img",
858
+ "input",
859
+ "script",
860
+ "source",
861
+ "track",
862
+ "video"
863
+ ])
864
+ ],
865
+ ["href", /* @__PURE__ */ new Set(["a", "area", "link"])],
866
+ ["data", /* @__PURE__ */ new Set(["object"])],
867
+ ["poster", /* @__PURE__ */ new Set(["video"])]
868
+ ]);
869
+ function isDocumentLinkAttr(doc, tag, attr) {
870
+ var _a, _b;
871
+ 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;
872
+ }
873
+
874
+ // src/utils/file-system.ts
875
+ var import_path3 = __toESM(require("path"));
876
+ var import_promises = __toESM(require("fs/promises"));
877
+ var import_vscode_css_languageservice = require("vscode-css-languageservice");
878
+ var file_system_default = {
879
+ stat,
880
+ readDirectory
881
+ };
882
+ async function stat(fileName) {
883
+ const stat2 = await import_promises.default.stat(fileName).catch(() => null);
884
+ let type = import_vscode_css_languageservice.FileType.Unknown;
885
+ let ctime = 0;
886
+ let mtime = 0;
887
+ let size = 0;
888
+ if (stat2) {
889
+ if (stat2.isDirectory())
890
+ type = import_vscode_css_languageservice.FileType.Directory;
891
+ else if (stat2.isFile())
892
+ type = import_vscode_css_languageservice.FileType.File;
893
+ ctime = stat2.ctimeMs;
894
+ mtime = stat2.mtimeMs;
895
+ size = stat2.size;
896
+ }
897
+ return {
898
+ type,
899
+ ctime,
900
+ mtime,
901
+ size
902
+ };
903
+ }
904
+ async function readDirectory(dir) {
905
+ return (await Promise.all((await import_promises.default.readdir(dir).catch(() => [])).map(async (entry) => [entry, (await stat(import_path3.default.join(dir, entry))).type]))).filter(([, type]) => type !== import_vscode_css_languageservice.FileType.Unknown);
906
+ }
907
+
908
+ // src/utils/resolve-url.ts
909
+ function resolveUrl(to, base) {
910
+ try {
911
+ const baseUrl = new URL(base, "file://");
912
+ const resolved = new URL(to, baseUrl);
913
+ const { origin, protocol } = baseUrl;
914
+ if (resolved.origin === origin && resolved.protocol === protocol) {
915
+ return resolved.pathname + resolved.search + resolved.hash;
916
+ }
917
+ return resolved.toString();
918
+ } catch {
919
+ return void 0;
920
+ }
921
+ }
922
+
923
+ // src/service/marko/complete/AttrValue.ts
924
+ async function AttrValue({
925
+ document,
926
+ offset,
927
+ node,
928
+ parsed,
929
+ code
930
+ }) {
931
+ const attr = node.parent;
932
+ if (isDocumentLinkAttr(document, attr.parent, attr)) {
933
+ const start = node.value.start + 1;
934
+ if (code[start] !== ".")
935
+ return;
936
+ const end = node.value.end - 1;
937
+ const relativeOffset = offset - start;
938
+ const rawValue = parsed.read({
939
+ start,
940
+ end
941
+ });
942
+ let segmentStart = rawValue.lastIndexOf("/", relativeOffset);
943
+ if (segmentStart === -1)
944
+ segmentStart = relativeOffset;
945
+ const resolveRequest = rawValue.slice(0, segmentStart) || ".";
946
+ const dir = resolveUrl(resolveRequest, document.uri);
947
+ if ((dir == null ? void 0 : dir[0]) === "/") {
948
+ const result = [];
949
+ const curDir = resolveRequest === "." ? dir : resolveUrl(".", document.uri);
950
+ const curFile = curDir === dir ? import_path4.default.basename(document.uri) : void 0;
951
+ const replaceRange = import_vscode_languageserver4.Range.create(document.positionAt(start + segmentStart + 1), document.positionAt(start + rawValue.length));
952
+ for (const [entry, type] of await file_system_default.readDirectory(dir)) {
953
+ if (entry[0] !== "." && entry !== curFile) {
954
+ const isDir = type === import_vscode_css_languageservice.FileType.Directory;
955
+ const label = isDir ? `${entry}/` : entry;
956
+ result.push({
957
+ label,
958
+ kind: isDir ? import_vscode_languageserver4.CompletionItemKind.Folder : import_vscode_languageserver4.CompletionItemKind.File,
959
+ textEdit: import_vscode_languageserver4.TextEdit.replace(replaceRange, label),
960
+ command: isDir ? {
961
+ title: "Suggest",
962
+ command: "editor.action.triggerSuggest"
963
+ } : void 0
964
+ });
965
+ }
966
+ }
967
+ return result;
968
+ }
969
+ }
970
+ }
971
+
845
972
  // src/service/marko/complete/index.ts
846
973
  var handlers = {
847
974
  Tag,
848
975
  OpenTagName,
849
- AttrName
976
+ AttrName,
977
+ AttrValue
850
978
  };
851
979
  var doComplete = async (doc, params) => {
852
980
  var _a;
853
981
  const parsed = parse2(doc);
854
982
  const offset = doc.offsetAt(params.position);
855
983
  const node = parsed.nodeAt(offset);
856
- return import_vscode_languageserver4.CompletionList.create(await ((_a = handlers[NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
984
+ return import_vscode_languageserver5.CompletionList.create(await ((_a = handlers[NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
857
985
  document: doc,
858
986
  params,
859
987
  parsed,
@@ -865,15 +993,15 @@ var doComplete = async (doc, params) => {
865
993
  };
866
994
 
867
995
  // src/service/marko/validate.ts
868
- var import_vscode_languageserver5 = require("vscode-languageserver");
996
+ var import_vscode_languageserver6 = require("vscode-languageserver");
869
997
  var markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
870
998
  var doValidate = (doc) => {
871
999
  const fsPath = getDocFile(doc);
872
1000
  const diagnostics = [];
873
- const { compiler, translator, cache: cache2 } = getCompilerInfo(doc);
1001
+ const { compiler, translator, cache: cache3 } = getCompilerInfo(doc);
874
1002
  try {
875
1003
  compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
876
- cache: cache2,
1004
+ cache: cache3,
877
1005
  translator,
878
1006
  code: false,
879
1007
  output: "source",
@@ -885,16 +1013,16 @@ var doValidate = (doc) => {
885
1013
  const [, fileName, rawLine, rawCol, msg] = match;
886
1014
  const line = (parseInt(rawLine, 10) || 1) - 1;
887
1015
  const col = (parseInt(rawCol, 10) || 1) - 1;
888
- diagnostics.push(import_vscode_languageserver5.Diagnostic.create(import_vscode_languageserver5.Range.create(line, col, line, col), msg, import_vscode_languageserver5.DiagnosticSeverity.Error, void 0, fileName));
1016
+ 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));
889
1017
  }
890
1018
  }
891
1019
  return diagnostics;
892
1020
  };
893
1021
 
894
1022
  // src/service/marko/definition/OpenTagName.ts
895
- var import_path3 = __toESM(require("path"));
1023
+ var import_path5 = __toESM(require("path"));
896
1024
  var import_vscode_uri4 = require("vscode-uri");
897
- var import_vscode_languageserver7 = require("vscode-languageserver");
1025
+ var import_vscode_languageserver8 = require("vscode-languageserver");
898
1026
 
899
1027
  // src/utils/regexp-builder.ts
900
1028
  function RegExpBuilder(strings, ...expressions) {
@@ -923,9 +1051,9 @@ function escape(val) {
923
1051
  // src/utils/utils.ts
924
1052
  var import_fs = __toESM(require("fs"));
925
1053
  var import_vscode_uri3 = require("vscode-uri");
926
- var import_vscode_languageserver6 = require("vscode-languageserver");
1054
+ var import_vscode_languageserver7 = require("vscode-languageserver");
927
1055
  var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
928
- var START_OF_FILE = import_vscode_languageserver6.Range.create(import_vscode_languageserver6.Position.create(0, 0), import_vscode_languageserver6.Position.create(0, 0));
1056
+ var START_OF_FILE = import_vscode_languageserver7.Range.create(import_vscode_languageserver7.Position.create(0, 0), import_vscode_languageserver7.Position.create(0, 0));
929
1057
  function createTextDocument(filename) {
930
1058
  const uri = import_vscode_uri3.URI.file(filename).toString();
931
1059
  const content = import_fs.default.readFileSync(filename, "utf-8");
@@ -953,24 +1081,24 @@ function OpenTagName2({
953
1081
  return;
954
1082
  }
955
1083
  const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
956
- if (!import_path3.default.isAbsolute(tagEntryFile)) {
1084
+ if (!import_path5.default.isAbsolute(tagEntryFile)) {
957
1085
  return;
958
1086
  }
959
1087
  if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
960
1088
  const tagDefDoc = createTextDocument(tagEntryFile);
961
1089
  const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
962
1090
  if (match && match.index) {
963
- range = import_vscode_languageserver7.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1091
+ range = import_vscode_languageserver8.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
964
1092
  }
965
1093
  }
966
1094
  return [
967
- import_vscode_languageserver7.LocationLink.create(import_vscode_uri4.URI.file(tagEntryFile).toString(), range, range, parsed.locationAt(node))
1095
+ import_vscode_languageserver8.LocationLink.create(import_vscode_uri4.URI.file(tagEntryFile).toString(), range, range, parsed.locationAt(node))
968
1096
  ];
969
1097
  }
970
1098
 
971
1099
  // src/service/marko/definition/AttrName.ts
972
1100
  var import_vscode_uri5 = require("vscode-uri");
973
- var import_vscode_languageserver8 = require("vscode-languageserver");
1101
+ var import_vscode_languageserver9 = require("vscode-languageserver");
974
1102
  function AttrName2({
975
1103
  lookup,
976
1104
  parsed,
@@ -994,11 +1122,11 @@ function AttrName2({
994
1122
  const tagDefDoc = createTextDocument(attrEntryFile);
995
1123
  const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
996
1124
  if (match && match.index) {
997
- range = import_vscode_languageserver8.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1125
+ range = import_vscode_languageserver9.Range.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
998
1126
  }
999
1127
  }
1000
1128
  return [
1001
- import_vscode_languageserver8.LocationLink.create(import_vscode_uri5.URI.file(attrEntryFile).toString(), range, range, parsed.locationAt(node))
1129
+ import_vscode_languageserver9.LocationLink.create(import_vscode_uri5.URI.file(attrEntryFile).toString(), range, range, parsed.locationAt(node))
1002
1130
  ];
1003
1131
  }
1004
1132
 
@@ -1023,14 +1151,83 @@ var findDefinition = async (doc, params) => {
1023
1151
  })) || [];
1024
1152
  };
1025
1153
 
1026
- // src/service/marko/format.ts
1027
- var import_vscode_languageserver9 = require("vscode-languageserver");
1154
+ // src/service/marko/document-links/extract.ts
1155
+ var import_vscode_languageserver10 = require("vscode-languageserver");
1028
1156
  var import_vscode_uri6 = require("vscode-uri");
1157
+ var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1158
+ function extractDocumentLinks(doc, parsed, lookup) {
1159
+ if (import_vscode_uri6.URI.parse(doc.uri).scheme === "untitled") {
1160
+ return [];
1161
+ }
1162
+ const links = [];
1163
+ const { program } = parsed;
1164
+ const code = doc.getText();
1165
+ const read = (range) => code.slice(range.start, range.end);
1166
+ const visit = (node) => {
1167
+ switch (node.type) {
1168
+ case 1 /* Tag */:
1169
+ if (node.attrs && node.nameText) {
1170
+ for (const attr of node.attrs) {
1171
+ if (isDocumentLinkAttr(doc, node, attr)) {
1172
+ links.push(import_vscode_languageserver10.DocumentLink.create({
1173
+ start: parsed.positionAt(attr.value.value.start),
1174
+ end: parsed.positionAt(attr.value.value.end)
1175
+ }, resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)));
1176
+ }
1177
+ }
1178
+ }
1179
+ if (node.body) {
1180
+ for (const child of node.body) {
1181
+ visit(child);
1182
+ }
1183
+ }
1184
+ break;
1185
+ }
1186
+ };
1187
+ for (const item of program.static) {
1188
+ if (item.type === 20 /* Statement */ && code[item.start] === "i") {
1189
+ importTagReg.lastIndex = 0;
1190
+ const value = parsed.read(item);
1191
+ const match = importTagReg.exec(value);
1192
+ if (match) {
1193
+ const [{ length }, , tagName] = match;
1194
+ const tagDef = lookup.getTag(tagName);
1195
+ const fileForTag = tagDef && (tagDef.template || tagDef.renderer);
1196
+ if (fileForTag) {
1197
+ links.push(import_vscode_languageserver10.DocumentLink.create({
1198
+ start: parsed.positionAt(item.start + match.index),
1199
+ end: parsed.positionAt(item.start + match.index + length)
1200
+ }, fileForTag));
1201
+ }
1202
+ }
1203
+ }
1204
+ }
1205
+ for (const item of program.body) {
1206
+ visit(item);
1207
+ }
1208
+ return links;
1209
+ }
1210
+
1211
+ // src/service/marko/document-links/index.ts
1212
+ var cache = /* @__PURE__ */ new WeakMap();
1213
+ var findDocumentLinks = async (doc) => {
1214
+ const parsed = parse2(doc);
1215
+ let result = cache.get(parsed);
1216
+ if (!result) {
1217
+ result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1218
+ cache.set(parsed, result);
1219
+ }
1220
+ return result;
1221
+ };
1222
+
1223
+ // src/service/marko/format.ts
1224
+ var import_vscode_languageserver11 = require("vscode-languageserver");
1225
+ var import_vscode_uri7 = require("vscode-uri");
1029
1226
  var prettier = __toESM(require("prettier"));
1030
1227
  var markoPrettier = __toESM(require("prettier-plugin-marko"));
1031
1228
  var format2 = async (doc, params, cancel) => {
1032
1229
  try {
1033
- const { fsPath, scheme } = import_vscode_uri6.URI.parse(doc.uri);
1230
+ const { fsPath, scheme } = import_vscode_uri7.URI.parse(doc.uri);
1034
1231
  const text = doc.getText();
1035
1232
  const options = {
1036
1233
  parser: "marko",
@@ -1045,7 +1242,7 @@ var format2 = async (doc, params, cancel) => {
1045
1242
  if (cancel.isCancellationRequested)
1046
1243
  return;
1047
1244
  return [
1048
- import_vscode_languageserver9.TextEdit.replace(import_vscode_languageserver9.Range.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1245
+ import_vscode_languageserver11.TextEdit.replace(import_vscode_languageserver11.Range.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1049
1246
  ];
1050
1247
  } catch (e) {
1051
1248
  displayError(e);
@@ -1057,12 +1254,13 @@ var marko_default = {
1057
1254
  doComplete,
1058
1255
  doValidate,
1059
1256
  findDefinition,
1257
+ findDocumentLinks,
1060
1258
  format: format2
1061
1259
  };
1062
1260
 
1063
1261
  // src/service/stylesheet/index.ts
1064
- var import_vscode_languageserver10 = require("vscode-languageserver");
1065
- var import_vscode_css_languageservice = require("vscode-css-languageservice");
1262
+ var import_vscode_languageserver12 = require("vscode-languageserver");
1263
+ var import_vscode_css_languageservice2 = require("vscode-css-languageservice");
1066
1264
  var import_vscode_languageserver_textdocument2 = require("vscode-languageserver-textdocument");
1067
1265
 
1068
1266
  // src/utils/extractor.ts
@@ -1201,7 +1399,7 @@ function extractStyleSheets(code, program, lookup) {
1201
1399
  for (const attr of node.attrs) {
1202
1400
  if (attr.type === 8 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 11 /* AttrValue */ && /^['"]$/.test(code[attr.value.value.start])) {
1203
1401
  const name = read(attr.name);
1204
- if (name === "#style" || name === "style" && lookup && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
1402
+ if (name === "#style" || name === "style" && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
1205
1403
  getExtractor("css").write`:root{${{
1206
1404
  start: attr.value.value.start + 1,
1207
1405
  end: attr.value.value.end - 1
@@ -1223,13 +1421,17 @@ function extractStyleSheets(code, program, lookup) {
1223
1421
  }
1224
1422
 
1225
1423
  // src/service/stylesheet/index.ts
1226
- var cache = /* @__PURE__ */ new WeakMap();
1424
+ var cache2 = /* @__PURE__ */ new WeakMap();
1227
1425
  var services = {
1228
- css: import_vscode_css_languageservice.getCSSLanguageService,
1229
- less: import_vscode_css_languageservice.getLESSLanguageService,
1230
- scss: import_vscode_css_languageservice.getSCSSLanguageService
1426
+ css: import_vscode_css_languageservice2.getCSSLanguageService,
1427
+ less: import_vscode_css_languageservice2.getLESSLanguageService,
1428
+ scss: import_vscode_css_languageservice2.getSCSSLanguageService
1231
1429
  };
1430
+ var clientCapabilities;
1232
1431
  var StyleSheetService = {
1432
+ initialize(params) {
1433
+ clientCapabilities = params.capabilities;
1434
+ },
1233
1435
  async doComplete(doc, params) {
1234
1436
  const infoByExt = getStyleSheetInfo(doc);
1235
1437
  const sourceOffset = doc.offsetAt(params.position);
@@ -1239,28 +1441,31 @@ var StyleSheetService = {
1239
1441
  if (generatedOffset === void 0)
1240
1442
  continue;
1241
1443
  const { service: service2, virtualDoc } = info;
1242
- const result = service2.doComplete(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1243
- for (const item of result.items) {
1244
- if (item.additionalTextEdits) {
1245
- for (const textEdit2 of item.additionalTextEdits) {
1246
- updateTextEdit(doc, info, textEdit2);
1444
+ const result = await service2.doComplete2(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed, { resolveReference: resolveUrl });
1445
+ if (result.itemDefaults) {
1446
+ const { editRange } = result.itemDefaults;
1447
+ if (editRange) {
1448
+ if ("start" in editRange) {
1449
+ result.itemDefaults.editRange = getSourceRange(doc, info, editRange);
1450
+ } else {
1451
+ editRange.insert = getSourceRange(doc, info, editRange.insert);
1452
+ editRange.replace = getSourceRange(doc, info, editRange.replace);
1247
1453
  }
1248
1454
  }
1249
- const { textEdit } = item;
1250
- if (textEdit) {
1251
- if (textEdit.range) {
1252
- updateTextEdit(doc, info, textEdit);
1253
- }
1254
- if (textEdit.insert) {
1255
- updateInsertReplaceEdit(doc, info, textEdit);
1256
- }
1455
+ }
1456
+ for (const item of result.items) {
1457
+ if (item.textEdit) {
1458
+ item.textEdit = getSourceInsertReplaceEdit(doc, info, item.textEdit);
1459
+ }
1460
+ if (item.additionalTextEdits) {
1461
+ item.additionalTextEdits = getSourceEdits(doc, info, item.additionalTextEdits);
1257
1462
  }
1258
1463
  }
1259
1464
  return result;
1260
1465
  }
1261
- return import_vscode_languageserver10.CompletionList.create([], true);
1466
+ return import_vscode_languageserver12.CompletionList.create([], true);
1262
1467
  },
1263
- async findDefinition(doc, params) {
1468
+ findDefinition(doc, params) {
1264
1469
  const infoByExt = getStyleSheetInfo(doc);
1265
1470
  const sourceOffset = doc.offsetAt(params.position);
1266
1471
  for (const ext in infoByExt) {
@@ -1270,13 +1475,19 @@ var StyleSheetService = {
1270
1475
  continue;
1271
1476
  const { service: service2, virtualDoc } = info;
1272
1477
  const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1273
- if (result && updateRange(doc, info, result.range)) {
1274
- return result;
1478
+ if (result) {
1479
+ const range = getSourceRange(doc, info, result.range);
1480
+ if (range) {
1481
+ return {
1482
+ range,
1483
+ uri: doc.uri
1484
+ };
1485
+ }
1275
1486
  }
1276
1487
  break;
1277
1488
  }
1278
1489
  },
1279
- async findReferences(doc, params) {
1490
+ findReferences(doc, params) {
1280
1491
  const infoByExt = getStyleSheetInfo(doc);
1281
1492
  const sourceOffset = doc.offsetAt(params.position);
1282
1493
  for (const ext in infoByExt) {
@@ -1287,14 +1498,40 @@ var StyleSheetService = {
1287
1498
  const { service: service2, virtualDoc } = info;
1288
1499
  const result = [];
1289
1500
  for (const location of service2.findReferences(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1290
- if (updateRange(doc, info, location.range)) {
1291
- result.push(location);
1501
+ const range = getSourceRange(doc, info, location.range);
1502
+ if (range) {
1503
+ result.push({
1504
+ range,
1505
+ uri: location.uri
1506
+ });
1292
1507
  }
1293
1508
  }
1294
1509
  return result.length ? result : void 0;
1295
1510
  }
1296
1511
  },
1297
- async findDocumentHighlights(doc, params) {
1512
+ findDocumentLinks(doc) {
1513
+ const infoByExt = getStyleSheetInfo(doc);
1514
+ const result = [];
1515
+ for (const ext in infoByExt) {
1516
+ const info = infoByExt[ext];
1517
+ const { service: service2, virtualDoc } = info;
1518
+ for (const link of service2.findDocumentLinks(virtualDoc, info.parsed, {
1519
+ resolveReference: resolveUrl
1520
+ })) {
1521
+ const range = getSourceRange(doc, info, link.range);
1522
+ if (range) {
1523
+ result.push({
1524
+ range,
1525
+ target: link.target,
1526
+ tooltip: link.tooltip,
1527
+ data: link.data
1528
+ });
1529
+ }
1530
+ }
1531
+ }
1532
+ return result.length ? result : void 0;
1533
+ },
1534
+ findDocumentHighlights(doc, params) {
1298
1535
  const infoByExt = getStyleSheetInfo(doc);
1299
1536
  const sourceOffset = doc.offsetAt(params.position);
1300
1537
  for (const ext in infoByExt) {
@@ -1305,30 +1542,36 @@ var StyleSheetService = {
1305
1542
  const { service: service2, virtualDoc } = info;
1306
1543
  const result = [];
1307
1544
  for (const highlight of service2.findDocumentHighlights(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1308
- if (updateRange(doc, info, highlight.range)) {
1309
- result.push(highlight);
1545
+ const range = getSourceRange(doc, info, highlight.range);
1546
+ if (range) {
1547
+ result.push({
1548
+ range,
1549
+ kind: highlight.kind
1550
+ });
1310
1551
  }
1311
1552
  }
1312
1553
  return result.length ? result : void 0;
1313
1554
  }
1314
1555
  },
1315
- async findDocumentColors(doc) {
1556
+ findDocumentColors(doc) {
1316
1557
  const infoByExt = getStyleSheetInfo(doc);
1317
1558
  const result = [];
1318
1559
  for (const ext in infoByExt) {
1319
1560
  const info = infoByExt[ext];
1320
1561
  const { service: service2, virtualDoc } = info;
1321
1562
  for (const colorInfo of service2.findDocumentColors(virtualDoc, info.parsed)) {
1322
- if (updateRange(doc, info, colorInfo.range)) {
1323
- result.push(colorInfo);
1563
+ const range = getSourceRange(doc, info, colorInfo.range);
1564
+ if (range) {
1565
+ result.push({
1566
+ range,
1567
+ color: colorInfo.color
1568
+ });
1324
1569
  }
1325
1570
  }
1326
1571
  }
1327
- if (result.length) {
1328
- return result;
1329
- }
1572
+ return result.length ? result : void 0;
1330
1573
  },
1331
- async getColorPresentations(doc, params) {
1574
+ getColorPresentations(doc, params) {
1332
1575
  const infoByExt = getStyleSheetInfo(doc);
1333
1576
  const sourceOffset = doc.offsetAt(params.range.start);
1334
1577
  for (const ext in infoByExt) {
@@ -1340,21 +1583,22 @@ var StyleSheetService = {
1340
1583
  if (generatedOffsetEnd === void 0)
1341
1584
  continue;
1342
1585
  const { service: service2, virtualDoc } = info;
1343
- const result = service2.getColorPresentations(virtualDoc, info.parsed, params.color, import_vscode_languageserver10.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)));
1344
- for (const colorPresentation of result) {
1345
- if (colorPresentation.textEdit) {
1346
- updateTextEdit(doc, info, colorPresentation.textEdit);
1347
- }
1348
- if (colorPresentation.additionalTextEdits) {
1349
- for (const textEdit of colorPresentation.additionalTextEdits) {
1350
- updateTextEdit(doc, info, textEdit);
1351
- }
1586
+ const result = [];
1587
+ for (const colorPresentation of service2.getColorPresentations(virtualDoc, info.parsed, params.color, import_vscode_languageserver12.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)))) {
1588
+ const textEdit = colorPresentation.textEdit && getSourceEdit(doc, info, colorPresentation.textEdit);
1589
+ const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(doc, info, colorPresentation.additionalTextEdits);
1590
+ if (textEdit || additionalTextEdits) {
1591
+ result.push({
1592
+ label: colorPresentation.label,
1593
+ textEdit,
1594
+ additionalTextEdits
1595
+ });
1352
1596
  }
1353
1597
  }
1354
- return result;
1598
+ return result.length ? result : void 0;
1355
1599
  }
1356
1600
  },
1357
- async doHover(doc, params) {
1601
+ doHover(doc, params) {
1358
1602
  const infoByExt = getStyleSheetInfo(doc);
1359
1603
  const sourceOffset = doc.offsetAt(params.position);
1360
1604
  for (const ext in infoByExt) {
@@ -1364,8 +1608,18 @@ var StyleSheetService = {
1364
1608
  continue;
1365
1609
  const { service: service2, virtualDoc } = info;
1366
1610
  const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1367
- if (result && (!result.range || updateRange(doc, info, result.range))) {
1368
- return result;
1611
+ if (result) {
1612
+ if (result.range) {
1613
+ const range = getSourceRange(doc, info, result.range);
1614
+ if (range) {
1615
+ return {
1616
+ range,
1617
+ contents: result.contents
1618
+ };
1619
+ }
1620
+ } else {
1621
+ return result;
1622
+ }
1369
1623
  }
1370
1624
  }
1371
1625
  },
@@ -1382,19 +1636,15 @@ var StyleSheetService = {
1382
1636
  if (result.changes) {
1383
1637
  for (const uri in result.changes) {
1384
1638
  if (uri === doc.uri) {
1385
- for (const textEdit of result.changes[uri]) {
1386
- updateTextEdit(doc, info, textEdit);
1387
- }
1639
+ result.changes[uri] = getSourceEdits(doc, info, result.changes[uri]) || [];
1388
1640
  }
1389
1641
  }
1390
1642
  }
1391
1643
  if (result.documentChanges) {
1392
1644
  for (const change of result.documentChanges) {
1393
- if (import_vscode_languageserver10.TextDocumentEdit.is(change)) {
1645
+ if (import_vscode_languageserver12.TextDocumentEdit.is(change)) {
1394
1646
  if (change.textDocument.uri === doc.uri) {
1395
- for (const textEdit of change.edits) {
1396
- updateTextEdit(doc, info, textEdit);
1397
- }
1647
+ change.edits = getSourceEdits(doc, info, change.edits) || [];
1398
1648
  }
1399
1649
  }
1400
1650
  }
@@ -1402,7 +1652,7 @@ var StyleSheetService = {
1402
1652
  return result;
1403
1653
  }
1404
1654
  },
1405
- async doCodeActions(doc, params) {
1655
+ doCodeActions(doc, params) {
1406
1656
  var _a;
1407
1657
  const infoByExt = getStyleSheetInfo(doc);
1408
1658
  const sourceOffset = doc.offsetAt(params.range.start);
@@ -1415,65 +1665,100 @@ var StyleSheetService = {
1415
1665
  if (generatedOffsetEnd === void 0)
1416
1666
  continue;
1417
1667
  const { service: service2, virtualDoc } = info;
1418
- const result = service2.doCodeActions(virtualDoc, import_vscode_languageserver10.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
1419
- if (result) {
1420
- for (const command of result) {
1421
- const edits = (_a = command.arguments) == null ? void 0 : _a[2];
1422
- if (edits) {
1423
- for (const textEdit of edits) {
1424
- updateTextEdit(doc, info, textEdit);
1425
- }
1426
- }
1668
+ const result = service2.doCodeActions(virtualDoc, import_vscode_languageserver12.Range.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
1669
+ for (const command of result) {
1670
+ const edits = (_a = command.arguments) == null ? void 0 : _a[2];
1671
+ if (edits && Array.isArray(edits) && isTextEdit(edits[0])) {
1672
+ command.arguments[2] = getSourceEdits(doc, info, edits);
1427
1673
  }
1428
- return result;
1429
1674
  }
1675
+ return result;
1430
1676
  }
1431
1677
  },
1432
- async doValidate(doc) {
1678
+ doValidate(doc) {
1433
1679
  const infoByExt = getStyleSheetInfo(doc);
1434
1680
  const result = [];
1435
1681
  for (const ext in infoByExt) {
1436
1682
  const info = infoByExt[ext];
1437
1683
  for (const diag of info.service.doValidation(info.virtualDoc, info.parsed)) {
1438
- if (updateRange(doc, info, diag.range)) {
1684
+ const range = getSourceRange(doc, info, diag.range);
1685
+ if (range) {
1686
+ diag.range = range;
1439
1687
  result.push(diag);
1440
1688
  }
1441
1689
  }
1442
1690
  }
1443
- return result;
1691
+ return result.length ? result : void 0;
1444
1692
  }
1445
1693
  };
1446
- function updateTextEdit(doc, info, textEdit) {
1447
- if (!updateRange(doc, info, textEdit.range)) {
1448
- textEdit.newText = "";
1449
- textEdit.range = START_OF_FILE;
1694
+ function getSourceEdits(doc, info, edits) {
1695
+ const result = [];
1696
+ for (const edit of edits) {
1697
+ const sourceEdit = getSourceEdit(doc, info, edit);
1698
+ if (sourceEdit) {
1699
+ result.push(sourceEdit);
1700
+ }
1701
+ }
1702
+ return result.length ? result : void 0;
1703
+ }
1704
+ function getSourceEdit(doc, info, textEdit) {
1705
+ const range = getSourceRange(doc, info, textEdit.range);
1706
+ if (range) {
1707
+ return {
1708
+ newText: textEdit.newText,
1709
+ range
1710
+ };
1450
1711
  }
1451
1712
  }
1452
- function updateInsertReplaceEdit(doc, info, insertReplaceEdit) {
1453
- if (!updateRange(doc, info, insertReplaceEdit.insert)) {
1454
- insertReplaceEdit.newText = "";
1455
- insertReplaceEdit.insert = START_OF_FILE;
1713
+ function getSourceInsertReplaceEdit(doc, info, textEdit) {
1714
+ if (isTextEdit(textEdit)) {
1715
+ return getSourceEdit(doc, info, textEdit);
1716
+ } else if (textEdit.replace) {
1717
+ const range = getSourceRange(doc, info, textEdit.replace);
1718
+ if (range) {
1719
+ return {
1720
+ newText: textEdit.newText,
1721
+ replace: range
1722
+ };
1723
+ }
1724
+ } else {
1725
+ const range = getSourceRange(doc, info, textEdit.insert);
1726
+ if (range) {
1727
+ return {
1728
+ newText: textEdit.newText,
1729
+ insert: range
1730
+ };
1731
+ }
1456
1732
  }
1457
1733
  }
1458
- function updateRange(doc, info, range) {
1734
+ function getSourceRange(doc, info, range) {
1459
1735
  const start = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.start));
1460
- const end = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.end));
1461
- if (start !== void 0 || end !== void 0) {
1462
- range.start = doc.positionAt(start ?? end);
1463
- range.end = doc.positionAt(end ?? start);
1464
- return true;
1736
+ if (start === void 0)
1737
+ return;
1738
+ let end = start;
1739
+ if (range.start.line !== range.end.line || range.start.character !== range.end.character) {
1740
+ end = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.end));
1741
+ if (end === void 0)
1742
+ return;
1465
1743
  }
1466
- return false;
1744
+ const pos = doc.positionAt(start);
1745
+ return {
1746
+ start: pos,
1747
+ end: start === end ? pos : doc.positionAt(end)
1748
+ };
1467
1749
  }
1468
1750
  function getStyleSheetInfo(doc) {
1469
1751
  var _a;
1470
1752
  const parsed = parse2(doc);
1471
- let cached = cache.get(parsed);
1753
+ let cached = cache2.get(parsed);
1472
1754
  if (!cached) {
1473
1755
  const results = extractStyleSheets(doc.getText(), parsed.program, getCompilerInfo(doc).lookup);
1474
1756
  cached = {};
1475
1757
  for (const ext in results) {
1476
- const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services);
1758
+ const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services, {
1759
+ fileSystemProvider: file_system_default,
1760
+ clientCapabilities
1761
+ });
1477
1762
  if (!service2)
1478
1763
  continue;
1479
1764
  const { generated, sourceOffsetAt, generatedOffsetAt } = results[ext];
@@ -1486,16 +1771,25 @@ function getStyleSheetInfo(doc) {
1486
1771
  parsed: service2.parseStylesheet(virtualDoc)
1487
1772
  };
1488
1773
  }
1489
- cache.set(parsed, cached);
1774
+ cache2.set(parsed, cached);
1490
1775
  }
1491
1776
  return cached;
1492
1777
  }
1778
+ function isTextEdit(edit) {
1779
+ return edit.range !== void 0;
1780
+ }
1493
1781
 
1494
1782
  // src/service/index.ts
1495
1783
  var plugins = [marko_default, StyleSheetService];
1496
1784
  var service = {
1785
+ async initialize(params) {
1786
+ await Promise.all(plugins.map((plugin) => {
1787
+ var _a;
1788
+ return (_a = plugin.initialize) == null ? void 0 : _a.call(plugin, params);
1789
+ }));
1790
+ },
1497
1791
  async doComplete(doc, params, cancel) {
1498
- const result = import_vscode_languageserver11.CompletionList.create([], false);
1792
+ const result = import_vscode_languageserver13.CompletionList.create([], false);
1499
1793
  try {
1500
1794
  const requests = plugins.map((plugin) => {
1501
1795
  var _a;
@@ -1570,6 +1864,30 @@ var service = {
1570
1864
  }
1571
1865
  return result;
1572
1866
  },
1867
+ async findDocumentLinks(doc, params, cancel) {
1868
+ let result;
1869
+ try {
1870
+ const requests = plugins.map((plugin) => {
1871
+ var _a;
1872
+ return (_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1873
+ });
1874
+ for (const pending of requests) {
1875
+ const cur = await pending;
1876
+ if (cancel.isCancellationRequested)
1877
+ return;
1878
+ if (cur) {
1879
+ if (result) {
1880
+ result.push(...cur);
1881
+ } else {
1882
+ result = cur;
1883
+ }
1884
+ }
1885
+ }
1886
+ } catch (err) {
1887
+ displayError(err);
1888
+ }
1889
+ return result;
1890
+ },
1573
1891
  async findDocumentHighlights(doc, params, cancel) {
1574
1892
  let result;
1575
1893
  try {
@@ -1767,8 +2085,9 @@ console.error = (...args) => {
1767
2085
  };
1768
2086
  process.on("uncaughtException", console.error);
1769
2087
  process.on("unhandledRejection", console.error);
1770
- connection2.onInitialize(() => {
2088
+ connection2.onInitialize(async (params) => {
1771
2089
  setup(connection2);
2090
+ await service.initialize(params);
1772
2091
  return {
1773
2092
  capabilities: {
1774
2093
  textDocumentSync: import_node.TextDocumentSyncKind.Incremental,
@@ -1778,6 +2097,7 @@ connection2.onInitialize(() => {
1778
2097
  renameProvider: true,
1779
2098
  codeActionProvider: true,
1780
2099
  referencesProvider: true,
2100
+ documentLinkProvider: { resolveProvider: false },
1781
2101
  colorProvider: true,
1782
2102
  documentHighlightProvider: true,
1783
2103
  completionProvider: {
@@ -1822,6 +2142,9 @@ connection2.onDefinition(async (params, cancel) => {
1822
2142
  connection2.onReferences(async (params, cancel) => {
1823
2143
  return await service.findReferences(documents.get(params.textDocument.uri), params, cancel) || null;
1824
2144
  });
2145
+ connection2.onDocumentLinks(async (params, cancel) => {
2146
+ return await service.findDocumentLinks(documents.get(params.textDocument.uri), params, cancel) || null;
2147
+ });
1825
2148
  connection2.onDocumentHighlight(async (params, cancel) => {
1826
2149
  return await service.findDocumentHighlights(documents.get(params.textDocument.uri), params, cancel) || null;
1827
2150
  });