@marko/language-server 0.12.7 → 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.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
  },
@@ -856,11 +856,143 @@ function AttrName({
856
856
  return completions;
857
857
  }
858
858
 
859
+ // src/service/marko/complete/AttrValue.ts
860
+ import path4 from "path";
861
+ import {
862
+ CompletionItemKind as CompletionItemKind4,
863
+ Range as Range2,
864
+ TextEdit as TextEdit4
865
+ } from "vscode-languageserver";
866
+
867
+ // src/service/marko/util/is-document-link-attr.ts
868
+ var linkedAttrs = /* @__PURE__ */ new Map([
869
+ [
870
+ "src",
871
+ /* @__PURE__ */ new Set([
872
+ "audio",
873
+ "embed",
874
+ "iframe",
875
+ "img",
876
+ "input",
877
+ "script",
878
+ "source",
879
+ "track",
880
+ "video"
881
+ ])
882
+ ],
883
+ ["href", /* @__PURE__ */ new Set(["a", "area", "link"])],
884
+ ["data", /* @__PURE__ */ new Set(["object"])],
885
+ ["poster", /* @__PURE__ */ new Set(["video"])]
886
+ ]);
887
+ function isDocumentLinkAttr(doc, tag, attr) {
888
+ var _a, _b;
889
+ 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;
890
+ }
891
+
892
+ // src/utils/file-system.ts
893
+ import path3 from "path";
894
+ import fs from "fs/promises";
895
+ import { FileType } from "vscode-css-languageservice";
896
+ var file_system_default = {
897
+ stat,
898
+ readDirectory
899
+ };
900
+ async function stat(fileName) {
901
+ const stat2 = await fs.stat(fileName).catch(() => null);
902
+ let type = FileType.Unknown;
903
+ let ctime = 0;
904
+ let mtime = 0;
905
+ let size = 0;
906
+ if (stat2) {
907
+ if (stat2.isDirectory())
908
+ type = FileType.Directory;
909
+ else if (stat2.isFile())
910
+ type = FileType.File;
911
+ ctime = stat2.ctimeMs;
912
+ mtime = stat2.mtimeMs;
913
+ size = stat2.size;
914
+ }
915
+ return {
916
+ type,
917
+ ctime,
918
+ mtime,
919
+ size
920
+ };
921
+ }
922
+ async function readDirectory(dir) {
923
+ return (await Promise.all((await fs.readdir(dir).catch(() => [])).map(async (entry) => [entry, (await stat(path3.join(dir, entry))).type]))).filter(([, type]) => type !== FileType.Unknown);
924
+ }
925
+
926
+ // src/utils/resolve-url.ts
927
+ function resolveUrl(to, base) {
928
+ try {
929
+ const baseUrl = new URL(base, "file://");
930
+ const resolved = new URL(to, baseUrl);
931
+ const { origin, protocol } = baseUrl;
932
+ if (resolved.origin === origin && resolved.protocol === protocol) {
933
+ return resolved.pathname + resolved.search + resolved.hash;
934
+ }
935
+ return resolved.toString();
936
+ } catch {
937
+ return void 0;
938
+ }
939
+ }
940
+
941
+ // src/service/marko/complete/AttrValue.ts
942
+ async function AttrValue({
943
+ document,
944
+ offset,
945
+ node,
946
+ parsed,
947
+ code
948
+ }) {
949
+ const attr = node.parent;
950
+ if (isDocumentLinkAttr(document, attr.parent, attr)) {
951
+ const start = node.value.start + 1;
952
+ if (code[start] !== ".")
953
+ return;
954
+ const end = node.value.end - 1;
955
+ const relativeOffset = offset - start;
956
+ const rawValue = parsed.read({
957
+ start,
958
+ end
959
+ });
960
+ let segmentStart = rawValue.lastIndexOf("/", relativeOffset);
961
+ if (segmentStart === -1)
962
+ segmentStart = relativeOffset;
963
+ const resolveRequest = rawValue.slice(0, segmentStart) || ".";
964
+ const dir = resolveUrl(resolveRequest, document.uri);
965
+ if ((dir == null ? void 0 : dir[0]) === "/") {
966
+ const result = [];
967
+ const curDir = resolveRequest === "." ? dir : resolveUrl(".", document.uri);
968
+ const curFile = curDir === dir ? path4.basename(document.uri) : void 0;
969
+ const replaceRange = Range2.create(document.positionAt(start + segmentStart + 1), document.positionAt(start + rawValue.length));
970
+ for (const [entry, type] of await file_system_default.readDirectory(dir)) {
971
+ if (entry[0] !== "." && entry !== curFile) {
972
+ const isDir = type === FileType.Directory;
973
+ const label = isDir ? `${entry}/` : entry;
974
+ result.push({
975
+ label,
976
+ kind: isDir ? CompletionItemKind4.Folder : CompletionItemKind4.File,
977
+ textEdit: TextEdit4.replace(replaceRange, label),
978
+ command: isDir ? {
979
+ title: "Suggest",
980
+ command: "editor.action.triggerSuggest"
981
+ } : void 0
982
+ });
983
+ }
984
+ }
985
+ return result;
986
+ }
987
+ }
988
+ }
989
+
859
990
  // src/service/marko/complete/index.ts
860
991
  var handlers = {
861
992
  Tag,
862
993
  OpenTagName,
863
- AttrName
994
+ AttrName,
995
+ AttrValue
864
996
  };
865
997
  var doComplete = async (doc, params) => {
866
998
  var _a;
@@ -879,15 +1011,15 @@ var doComplete = async (doc, params) => {
879
1011
  };
880
1012
 
881
1013
  // src/service/marko/validate.ts
882
- import { Diagnostic, DiagnosticSeverity, Range as Range2 } from "vscode-languageserver";
1014
+ import { Diagnostic, DiagnosticSeverity, Range as Range3 } from "vscode-languageserver";
883
1015
  var markoErrorRegExp = /^(.+?)(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
884
1016
  var doValidate = (doc) => {
885
1017
  const fsPath = getDocFile(doc);
886
1018
  const diagnostics = [];
887
- const { compiler, translator, cache: cache2 } = getCompilerInfo(doc);
1019
+ const { compiler, translator, cache: cache3 } = getCompilerInfo(doc);
888
1020
  try {
889
1021
  compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
890
- cache: cache2,
1022
+ cache: cache3,
891
1023
  translator,
892
1024
  code: false,
893
1025
  output: "source",
@@ -899,16 +1031,16 @@ var doValidate = (doc) => {
899
1031
  const [, fileName, rawLine, rawCol, msg] = match;
900
1032
  const line = (parseInt(rawLine, 10) || 1) - 1;
901
1033
  const col = (parseInt(rawCol, 10) || 1) - 1;
902
- diagnostics.push(Diagnostic.create(Range2.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
1034
+ diagnostics.push(Diagnostic.create(Range3.create(line, col, line, col), msg, DiagnosticSeverity.Error, void 0, fileName));
903
1035
  }
904
1036
  }
905
1037
  return diagnostics;
906
1038
  };
907
1039
 
908
1040
  // src/service/marko/definition/OpenTagName.ts
909
- import path3 from "path";
1041
+ import path5 from "path";
910
1042
  import { URI as URI4 } from "vscode-uri";
911
- import { Range as Range4, LocationLink } from "vscode-languageserver";
1043
+ import { Range as Range5, LocationLink } from "vscode-languageserver";
912
1044
 
913
1045
  // src/utils/regexp-builder.ts
914
1046
  function RegExpBuilder(strings, ...expressions) {
@@ -935,14 +1067,14 @@ function escape(val) {
935
1067
  }
936
1068
 
937
1069
  // src/utils/utils.ts
938
- import fs from "fs";
1070
+ import fs2 from "fs";
939
1071
  import { URI as URI3 } from "vscode-uri";
940
- import { Position, Range as Range3 } from "vscode-languageserver";
1072
+ import { Position, Range as Range4 } from "vscode-languageserver";
941
1073
  import { TextDocument } from "vscode-languageserver-textdocument";
942
- var START_OF_FILE = Range3.create(Position.create(0, 0), Position.create(0, 0));
1074
+ var START_OF_FILE = Range4.create(Position.create(0, 0), Position.create(0, 0));
943
1075
  function createTextDocument(filename) {
944
1076
  const uri = URI3.file(filename).toString();
945
- const content = fs.readFileSync(filename, "utf-8");
1077
+ const content = fs2.readFileSync(filename, "utf-8");
946
1078
  return TextDocument.create(uri, "plaintext", 0, content);
947
1079
  }
948
1080
 
@@ -967,14 +1099,14 @@ function OpenTagName2({
967
1099
  return;
968
1100
  }
969
1101
  const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
970
- if (!path3.isAbsolute(tagEntryFile)) {
1102
+ if (!path5.isAbsolute(tagEntryFile)) {
971
1103
  return;
972
1104
  }
973
1105
  if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
974
1106
  const tagDefDoc = createTextDocument(tagEntryFile);
975
1107
  const match = RegExpBuilder`/"(?:<${tag.nameText}>|${tag.nameText})"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
976
1108
  if (match && match.index) {
977
- range = Range4.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1109
+ range = Range5.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
978
1110
  }
979
1111
  }
980
1112
  return [
@@ -984,7 +1116,7 @@ function OpenTagName2({
984
1116
 
985
1117
  // src/service/marko/definition/AttrName.ts
986
1118
  import { URI as URI5 } from "vscode-uri";
987
- import { Range as Range5, LocationLink as LocationLink2 } from "vscode-languageserver";
1119
+ import { Range as Range6, LocationLink as LocationLink2 } from "vscode-languageserver";
988
1120
  function AttrName2({
989
1121
  lookup,
990
1122
  parsed,
@@ -1008,7 +1140,7 @@ function AttrName2({
1008
1140
  const tagDefDoc = createTextDocument(attrEntryFile);
1009
1141
  const match = RegExpBuilder`/"@${attrName}"\s*:\s*[^\r\n,]+/g`.exec(tagDefDoc.getText());
1010
1142
  if (match && match.index) {
1011
- range = Range5.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1143
+ range = Range6.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
1012
1144
  }
1013
1145
  }
1014
1146
  return [
@@ -1037,17 +1169,83 @@ var findDefinition = async (doc, params) => {
1037
1169
  })) || [];
1038
1170
  };
1039
1171
 
1040
- // src/service/marko/format.ts
1041
- import { Position as Position2, Range as Range6, TextEdit as TextEdit4 } from "vscode-languageserver";
1172
+ // src/service/marko/document-links/extract.ts
1173
+ import { DocumentLink } from "vscode-languageserver";
1042
1174
  import { URI as URI6 } from "vscode-uri";
1175
+ var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1176
+ function extractDocumentLinks(doc, parsed, lookup) {
1177
+ if (URI6.parse(doc.uri).scheme === "untitled") {
1178
+ return [];
1179
+ }
1180
+ const links = [];
1181
+ const { program } = parsed;
1182
+ const code = doc.getText();
1183
+ const read = (range) => code.slice(range.start, range.end);
1184
+ const visit = (node) => {
1185
+ switch (node.type) {
1186
+ case 1 /* Tag */:
1187
+ if (node.attrs && node.nameText) {
1188
+ for (const attr of node.attrs) {
1189
+ if (isDocumentLinkAttr(doc, node, attr)) {
1190
+ links.push(DocumentLink.create({
1191
+ start: parsed.positionAt(attr.value.value.start),
1192
+ end: parsed.positionAt(attr.value.value.end)
1193
+ }, resolveUrl(read(attr.value.value).slice(1, -1), doc.uri)));
1194
+ }
1195
+ }
1196
+ }
1197
+ if (node.body) {
1198
+ for (const child of node.body) {
1199
+ visit(child);
1200
+ }
1201
+ }
1202
+ break;
1203
+ }
1204
+ };
1205
+ for (const item of program.static) {
1206
+ if (item.type === 20 /* Statement */ && code[item.start] === "i") {
1207
+ importTagReg.lastIndex = 0;
1208
+ const value = parsed.read(item);
1209
+ const match = importTagReg.exec(value);
1210
+ if (match) {
1211
+ const [{ length }, , tagName] = match;
1212
+ const tagDef = lookup.getTag(tagName);
1213
+ const fileForTag = tagDef && (tagDef.template || tagDef.renderer);
1214
+ if (fileForTag) {
1215
+ links.push(DocumentLink.create({
1216
+ start: parsed.positionAt(item.start + match.index),
1217
+ end: parsed.positionAt(item.start + match.index + length)
1218
+ }, fileForTag));
1219
+ }
1220
+ }
1221
+ }
1222
+ }
1223
+ for (const item of program.body) {
1224
+ visit(item);
1225
+ }
1226
+ return links;
1227
+ }
1228
+
1229
+ // src/service/marko/document-links/index.ts
1230
+ var cache = /* @__PURE__ */ new WeakMap();
1231
+ var findDocumentLinks = async (doc) => {
1232
+ const parsed = parse2(doc);
1233
+ let result = cache.get(parsed);
1234
+ if (!result) {
1235
+ result = extractDocumentLinks(doc, parsed, getCompilerInfo(doc).lookup);
1236
+ cache.set(parsed, result);
1237
+ }
1238
+ return result;
1239
+ };
1240
+
1241
+ // src/service/marko/format.ts
1242
+ import { Range as Range7, TextEdit as TextEdit5 } from "vscode-languageserver";
1243
+ import { URI as URI7 } from "vscode-uri";
1043
1244
  import * as prettier from "prettier";
1044
1245
  import * as markoPrettier from "prettier-plugin-marko";
1045
- var NO_EDIT = [
1046
- TextEdit4.replace(Range6.create(Position2.create(0, 0), Position2.create(0, 0)), "")
1047
- ];
1048
- var format2 = async (doc, params, token) => {
1246
+ var format2 = async (doc, params, cancel) => {
1049
1247
  try {
1050
- const { fsPath, scheme } = URI6.parse(doc.uri);
1248
+ const { fsPath, scheme } = URI7.parse(doc.uri);
1051
1249
  const text = doc.getText();
1052
1250
  const options = {
1053
1251
  parser: "marko",
@@ -1059,15 +1257,14 @@ var format2 = async (doc, params, token) => {
1059
1257
  editorconfig: true
1060
1258
  }).catch(() => null) : null
1061
1259
  };
1062
- if (!token.isCancellationRequested) {
1063
- return [
1064
- TextEdit4.replace(Range6.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1065
- ];
1066
- }
1260
+ if (cancel.isCancellationRequested)
1261
+ return;
1262
+ return [
1263
+ TextEdit5.replace(Range7.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
1264
+ ];
1067
1265
  } catch (e) {
1068
1266
  displayError(e);
1069
1267
  }
1070
- return NO_EDIT;
1071
1268
  };
1072
1269
 
1073
1270
  // src/service/marko/index.ts
@@ -1075,12 +1272,15 @@ var marko_default = {
1075
1272
  doComplete,
1076
1273
  doValidate,
1077
1274
  findDefinition,
1275
+ findDocumentLinks,
1078
1276
  format: format2
1079
1277
  };
1080
1278
 
1081
1279
  // src/service/stylesheet/index.ts
1082
1280
  import {
1083
- CompletionList as CompletionList2
1281
+ CompletionList as CompletionList2,
1282
+ Range as Range9,
1283
+ TextDocumentEdit
1084
1284
  } from "vscode-languageserver";
1085
1285
  import {
1086
1286
  getCSSLanguageService,
@@ -1149,7 +1349,7 @@ function createExtractor(code) {
1149
1349
  const generatedStart = generatedMap[key];
1150
1350
  const sourceStart = generatedMap[key + 1];
1151
1351
  const sourceEnd = generatedMap[key + 2];
1152
- return sourceEnd - sourceStart <= generatedOffset - generatedStart ? void 0 : sourceStart + (generatedOffset - generatedStart);
1352
+ return sourceEnd - sourceStart < generatedOffset - generatedStart ? void 0 : sourceStart + (generatedOffset - generatedStart);
1153
1353
  },
1154
1354
  generatedOffsetAt(sourceOffset) {
1155
1355
  let max = sourceMap.length / 3;
@@ -1189,10 +1389,20 @@ function extractStyleSheets(code, program, lookup) {
1189
1389
  }).replace(/^.*\./, "") : "css";
1190
1390
  };
1191
1391
  const visit = (node) => {
1192
- var _a, _b, _c;
1392
+ var _a, _b;
1193
1393
  switch (node.type) {
1194
1394
  case 1 /* Tag */:
1195
- if ((_a = node.body) == null ? void 0 : _a.length) {
1395
+ if (node.nameText === "style" && node.concise && node.attrs) {
1396
+ const block = node.attrs.at(-1);
1397
+ if (block.type === 8 /* AttrNamed */ && code[block.start] === "{") {
1398
+ getExtractor(getFileExtFromTag(node)).write`${{
1399
+ start: block.start + 1,
1400
+ end: block.end - 1
1401
+ }}`;
1402
+ break;
1403
+ }
1404
+ }
1405
+ if (node.body) {
1196
1406
  if (node.nameText === "style") {
1197
1407
  const ext = getFileExtFromTag(node);
1198
1408
  for (const child of node.body) {
@@ -1206,30 +1416,22 @@ function extractStyleSheets(code, program, lookup) {
1206
1416
  }
1207
1417
  }
1208
1418
  } else {
1209
- if (node.attrs) {
1210
- for (const attr of node.attrs) {
1211
- if (attr.type === 8 /* AttrNamed */ && ((_b = attr.value) == null ? void 0 : _b.type) === 11 /* AttrValue */ && /^['"]$/.test(code[attr.value.value.start])) {
1212
- const name = read(attr.name);
1213
- if (name === "#style" || name === "style" && lookup && node.nameText && name === "style" && ((_c = lookup.getTag(node.nameText)) == null ? void 0 : _c.html)) {
1214
- getExtractor("css").write`:root{${{
1215
- start: attr.value.value.start + 1,
1216
- end: attr.value.value.end - 1
1217
- }}}`;
1218
- }
1219
- }
1220
- }
1221
- }
1222
1419
  for (const child of node.body) {
1223
1420
  visit(child);
1224
1421
  }
1225
1422
  }
1226
- } else if (node.nameText === "style" && node.concise && node.attrs) {
1227
- const block = node.attrs.at(-1);
1228
- if (block.type === 8 /* AttrNamed */ && code[block.start] === "{") {
1229
- getExtractor(getFileExtFromTag(node)).write`${{
1230
- start: block.start + 1,
1231
- end: block.end - 1
1232
- }}`;
1423
+ }
1424
+ if (node.attrs) {
1425
+ for (const attr of node.attrs) {
1426
+ if (attr.type === 8 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 11 /* AttrValue */ && /^['"]$/.test(code[attr.value.value.start])) {
1427
+ const name = read(attr.name);
1428
+ if (name === "#style" || name === "style" && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
1429
+ getExtractor("css").write`:root{${{
1430
+ start: attr.value.value.start + 1,
1431
+ end: attr.value.value.end - 1
1432
+ }}}`;
1433
+ }
1434
+ }
1233
1435
  }
1234
1436
  }
1235
1437
  break;
@@ -1245,13 +1447,17 @@ function extractStyleSheets(code, program, lookup) {
1245
1447
  }
1246
1448
 
1247
1449
  // src/service/stylesheet/index.ts
1248
- var cache = /* @__PURE__ */ new WeakMap();
1450
+ var cache2 = /* @__PURE__ */ new WeakMap();
1249
1451
  var services = {
1250
1452
  css: getCSSLanguageService,
1251
1453
  less: getLESSLanguageService,
1252
1454
  scss: getSCSSLanguageService
1253
1455
  };
1254
- var stylesheet_default = {
1456
+ var clientCapabilities;
1457
+ var StyleSheetService = {
1458
+ initialize(params) {
1459
+ clientCapabilities = params.capabilities;
1460
+ },
1255
1461
  async doComplete(doc, params) {
1256
1462
  const infoByExt = getStyleSheetInfo(doc);
1257
1463
  const sourceOffset = doc.offsetAt(params.position);
@@ -1261,37 +1467,31 @@ var stylesheet_default = {
1261
1467
  if (generatedOffset === void 0)
1262
1468
  continue;
1263
1469
  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 edit of item.additionalTextEdits) {
1268
- if (!updateRange(doc, info, edit.range)) {
1269
- edit.newText = "";
1270
- edit.range = START_OF_FILE;
1271
- }
1470
+ const result = await service2.doComplete2(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed, { resolveReference: resolveUrl });
1471
+ if (result.itemDefaults) {
1472
+ const { editRange } = result.itemDefaults;
1473
+ if (editRange) {
1474
+ if ("start" in editRange) {
1475
+ result.itemDefaults.editRange = getSourceRange(doc, info, editRange);
1476
+ } else {
1477
+ editRange.insert = getSourceRange(doc, info, editRange.insert);
1478
+ editRange.replace = getSourceRange(doc, info, editRange.replace);
1272
1479
  }
1273
1480
  }
1274
- const { textEdit } = item;
1275
- if (textEdit) {
1276
- if (textEdit.range) {
1277
- if (!updateRange(doc, info, textEdit.range)) {
1278
- textEdit.newText = "";
1279
- textEdit.range = START_OF_FILE;
1280
- }
1281
- }
1282
- if (textEdit.insert) {
1283
- if (!updateRange(doc, info, textEdit.insert)) {
1284
- textEdit.newText = "";
1285
- textEdit.insert = START_OF_FILE;
1286
- }
1287
- }
1481
+ }
1482
+ for (const item of result.items) {
1483
+ if (item.textEdit) {
1484
+ item.textEdit = getSourceInsertReplaceEdit(doc, info, item.textEdit);
1485
+ }
1486
+ if (item.additionalTextEdits) {
1487
+ item.additionalTextEdits = getSourceEdits(doc, info, item.additionalTextEdits);
1288
1488
  }
1289
1489
  }
1290
1490
  return result;
1291
1491
  }
1292
1492
  return CompletionList2.create([], true);
1293
1493
  },
1294
- async findDefinition(doc, params) {
1494
+ findDefinition(doc, params) {
1295
1495
  const infoByExt = getStyleSheetInfo(doc);
1296
1496
  const sourceOffset = doc.offsetAt(params.position);
1297
1497
  for (const ext in infoByExt) {
@@ -1301,13 +1501,19 @@ var stylesheet_default = {
1301
1501
  continue;
1302
1502
  const { service: service2, virtualDoc } = info;
1303
1503
  const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1304
- if (result && updateRange(doc, info, result.range)) {
1305
- return result;
1504
+ if (result) {
1505
+ const range = getSourceRange(doc, info, result.range);
1506
+ if (range) {
1507
+ return {
1508
+ range,
1509
+ uri: doc.uri
1510
+ };
1511
+ }
1306
1512
  }
1307
1513
  break;
1308
1514
  }
1309
1515
  },
1310
- async doHover(doc, params) {
1516
+ findReferences(doc, params) {
1311
1517
  const infoByExt = getStyleSheetInfo(doc);
1312
1518
  const sourceOffset = doc.offsetAt(params.position);
1313
1519
  for (const ext in infoByExt) {
@@ -1316,45 +1522,269 @@ var stylesheet_default = {
1316
1522
  if (generatedOffset === void 0)
1317
1523
  continue;
1318
1524
  const { service: service2, virtualDoc } = info;
1319
- const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), service2.parseStylesheet(virtualDoc));
1320
- if (result && (!result.range || updateRange(doc, info, result.range))) {
1321
- return result;
1525
+ const result = [];
1526
+ for (const location of service2.findReferences(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1527
+ const range = getSourceRange(doc, info, location.range);
1528
+ if (range) {
1529
+ result.push({
1530
+ range,
1531
+ uri: location.uri
1532
+ });
1533
+ }
1322
1534
  }
1535
+ return result.length ? result : void 0;
1323
1536
  }
1324
1537
  },
1325
- async doValidate(doc) {
1538
+ findDocumentLinks(doc) {
1539
+ const infoByExt = getStyleSheetInfo(doc);
1540
+ const result = [];
1541
+ for (const ext in infoByExt) {
1542
+ const info = infoByExt[ext];
1543
+ const { service: service2, virtualDoc } = info;
1544
+ for (const link of service2.findDocumentLinks(virtualDoc, info.parsed, {
1545
+ resolveReference: resolveUrl
1546
+ })) {
1547
+ const range = getSourceRange(doc, info, link.range);
1548
+ if (range) {
1549
+ result.push({
1550
+ range,
1551
+ target: link.target,
1552
+ tooltip: link.tooltip,
1553
+ data: link.data
1554
+ });
1555
+ }
1556
+ }
1557
+ }
1558
+ return result.length ? result : void 0;
1559
+ },
1560
+ findDocumentHighlights(doc, params) {
1561
+ const infoByExt = getStyleSheetInfo(doc);
1562
+ const sourceOffset = doc.offsetAt(params.position);
1563
+ for (const ext in infoByExt) {
1564
+ const info = infoByExt[ext];
1565
+ const generatedOffset = info.generatedOffsetAt(sourceOffset);
1566
+ if (generatedOffset === void 0)
1567
+ continue;
1568
+ const { service: service2, virtualDoc } = info;
1569
+ const result = [];
1570
+ for (const highlight of service2.findDocumentHighlights(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
1571
+ const range = getSourceRange(doc, info, highlight.range);
1572
+ if (range) {
1573
+ result.push({
1574
+ range,
1575
+ kind: highlight.kind
1576
+ });
1577
+ }
1578
+ }
1579
+ return result.length ? result : void 0;
1580
+ }
1581
+ },
1582
+ findDocumentColors(doc) {
1583
+ const infoByExt = getStyleSheetInfo(doc);
1584
+ const result = [];
1585
+ for (const ext in infoByExt) {
1586
+ const info = infoByExt[ext];
1587
+ const { service: service2, virtualDoc } = info;
1588
+ for (const colorInfo of service2.findDocumentColors(virtualDoc, info.parsed)) {
1589
+ const range = getSourceRange(doc, info, colorInfo.range);
1590
+ if (range) {
1591
+ result.push({
1592
+ range,
1593
+ color: colorInfo.color
1594
+ });
1595
+ }
1596
+ }
1597
+ }
1598
+ return result.length ? result : void 0;
1599
+ },
1600
+ getColorPresentations(doc, params) {
1601
+ const infoByExt = getStyleSheetInfo(doc);
1602
+ const sourceOffset = doc.offsetAt(params.range.start);
1603
+ for (const ext in infoByExt) {
1604
+ const info = infoByExt[ext];
1605
+ const generatedOffsetStart = info.generatedOffsetAt(sourceOffset);
1606
+ if (generatedOffsetStart === void 0)
1607
+ continue;
1608
+ const generatedOffsetEnd = info.generatedOffsetAt(doc.offsetAt(params.range.end));
1609
+ if (generatedOffsetEnd === void 0)
1610
+ continue;
1611
+ const { service: service2, virtualDoc } = info;
1612
+ const result = [];
1613
+ for (const colorPresentation of service2.getColorPresentations(virtualDoc, info.parsed, params.color, Range9.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)))) {
1614
+ const textEdit = colorPresentation.textEdit && getSourceEdit(doc, info, colorPresentation.textEdit);
1615
+ const additionalTextEdits = colorPresentation.additionalTextEdits && getSourceEdits(doc, info, colorPresentation.additionalTextEdits);
1616
+ if (textEdit || additionalTextEdits) {
1617
+ result.push({
1618
+ label: colorPresentation.label,
1619
+ textEdit,
1620
+ additionalTextEdits
1621
+ });
1622
+ }
1623
+ }
1624
+ return result.length ? result : void 0;
1625
+ }
1626
+ },
1627
+ doHover(doc, params) {
1628
+ const infoByExt = getStyleSheetInfo(doc);
1629
+ const sourceOffset = doc.offsetAt(params.position);
1630
+ for (const ext in infoByExt) {
1631
+ const info = infoByExt[ext];
1632
+ const generatedOffset = info.generatedOffsetAt(sourceOffset);
1633
+ if (generatedOffset === void 0)
1634
+ continue;
1635
+ const { service: service2, virtualDoc } = info;
1636
+ const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
1637
+ if (result) {
1638
+ if (result.range) {
1639
+ const range = getSourceRange(doc, info, result.range);
1640
+ if (range) {
1641
+ return {
1642
+ range,
1643
+ contents: result.contents
1644
+ };
1645
+ }
1646
+ } else {
1647
+ return result;
1648
+ }
1649
+ }
1650
+ }
1651
+ },
1652
+ async doRename(doc, params) {
1653
+ const infoByExt = getStyleSheetInfo(doc);
1654
+ const sourceOffset = doc.offsetAt(params.position);
1655
+ for (const ext in infoByExt) {
1656
+ const info = infoByExt[ext];
1657
+ const generatedOffset = info.generatedOffsetAt(sourceOffset);
1658
+ if (generatedOffset === void 0)
1659
+ continue;
1660
+ const { service: service2, virtualDoc } = info;
1661
+ const result = service2.doRename(virtualDoc, virtualDoc.positionAt(generatedOffset), params.newName, info.parsed);
1662
+ if (result.changes) {
1663
+ for (const uri in result.changes) {
1664
+ if (uri === doc.uri) {
1665
+ result.changes[uri] = getSourceEdits(doc, info, result.changes[uri]) || [];
1666
+ }
1667
+ }
1668
+ }
1669
+ if (result.documentChanges) {
1670
+ for (const change of result.documentChanges) {
1671
+ if (TextDocumentEdit.is(change)) {
1672
+ if (change.textDocument.uri === doc.uri) {
1673
+ change.edits = getSourceEdits(doc, info, change.edits) || [];
1674
+ }
1675
+ }
1676
+ }
1677
+ }
1678
+ return result;
1679
+ }
1680
+ },
1681
+ doCodeActions(doc, params) {
1682
+ var _a;
1683
+ const infoByExt = getStyleSheetInfo(doc);
1684
+ const sourceOffset = doc.offsetAt(params.range.start);
1685
+ for (const ext in infoByExt) {
1686
+ const info = infoByExt[ext];
1687
+ const generatedOffsetStart = info.generatedOffsetAt(sourceOffset);
1688
+ if (generatedOffsetStart === void 0)
1689
+ continue;
1690
+ const generatedOffsetEnd = info.generatedOffsetAt(doc.offsetAt(params.range.end));
1691
+ if (generatedOffsetEnd === void 0)
1692
+ continue;
1693
+ const { service: service2, virtualDoc } = info;
1694
+ const result = service2.doCodeActions(virtualDoc, Range9.create(virtualDoc.positionAt(generatedOffsetStart), virtualDoc.positionAt(generatedOffsetEnd)), params.context, info.parsed);
1695
+ for (const command of result) {
1696
+ const edits = (_a = command.arguments) == null ? void 0 : _a[2];
1697
+ if (edits && Array.isArray(edits) && isTextEdit(edits[0])) {
1698
+ command.arguments[2] = getSourceEdits(doc, info, edits);
1699
+ }
1700
+ }
1701
+ return result;
1702
+ }
1703
+ },
1704
+ doValidate(doc) {
1326
1705
  const infoByExt = getStyleSheetInfo(doc);
1327
1706
  const result = [];
1328
1707
  for (const ext in infoByExt) {
1329
1708
  const info = infoByExt[ext];
1330
1709
  for (const diag of info.service.doValidation(info.virtualDoc, info.parsed)) {
1331
- if (updateRange(doc, info, diag.range)) {
1710
+ const range = getSourceRange(doc, info, diag.range);
1711
+ if (range) {
1712
+ diag.range = range;
1332
1713
  result.push(diag);
1333
1714
  }
1334
1715
  }
1335
1716
  }
1336
- return result;
1717
+ return result.length ? result : void 0;
1337
1718
  }
1338
1719
  };
1339
- function updateRange(doc, info, range) {
1720
+ function getSourceEdits(doc, info, edits) {
1721
+ const result = [];
1722
+ for (const edit of edits) {
1723
+ const sourceEdit = getSourceEdit(doc, info, edit);
1724
+ if (sourceEdit) {
1725
+ result.push(sourceEdit);
1726
+ }
1727
+ }
1728
+ return result.length ? result : void 0;
1729
+ }
1730
+ function getSourceEdit(doc, info, textEdit) {
1731
+ const range = getSourceRange(doc, info, textEdit.range);
1732
+ if (range) {
1733
+ return {
1734
+ newText: textEdit.newText,
1735
+ range
1736
+ };
1737
+ }
1738
+ }
1739
+ function getSourceInsertReplaceEdit(doc, info, textEdit) {
1740
+ if (isTextEdit(textEdit)) {
1741
+ return getSourceEdit(doc, info, textEdit);
1742
+ } else if (textEdit.replace) {
1743
+ const range = getSourceRange(doc, info, textEdit.replace);
1744
+ if (range) {
1745
+ return {
1746
+ newText: textEdit.newText,
1747
+ replace: range
1748
+ };
1749
+ }
1750
+ } else {
1751
+ const range = getSourceRange(doc, info, textEdit.insert);
1752
+ if (range) {
1753
+ return {
1754
+ newText: textEdit.newText,
1755
+ insert: range
1756
+ };
1757
+ }
1758
+ }
1759
+ }
1760
+ function getSourceRange(doc, info, range) {
1340
1761
  const start = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.start));
1341
- const end = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.end));
1342
- if (start !== void 0 || end !== void 0) {
1343
- range.start = doc.positionAt(start ?? end);
1344
- range.end = doc.positionAt(end ?? start);
1345
- return true;
1762
+ if (start === void 0)
1763
+ return;
1764
+ let end = start;
1765
+ if (range.start.line !== range.end.line || range.start.character !== range.end.character) {
1766
+ end = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.end));
1767
+ if (end === void 0)
1768
+ return;
1346
1769
  }
1347
- return false;
1770
+ const pos = doc.positionAt(start);
1771
+ return {
1772
+ start: pos,
1773
+ end: start === end ? pos : doc.positionAt(end)
1774
+ };
1348
1775
  }
1349
1776
  function getStyleSheetInfo(doc) {
1350
1777
  var _a;
1351
1778
  const parsed = parse2(doc);
1352
- let cached = cache.get(parsed);
1779
+ let cached = cache2.get(parsed);
1353
1780
  if (!cached) {
1354
1781
  const results = extractStyleSheets(doc.getText(), parsed.program, getCompilerInfo(doc).lookup);
1355
1782
  cached = {};
1356
1783
  for (const ext in results) {
1357
- const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services);
1784
+ const service2 = (_a = services[ext]) == null ? void 0 : _a.call(services, {
1785
+ fileSystemProvider: file_system_default,
1786
+ clientCapabilities
1787
+ });
1358
1788
  if (!service2)
1359
1789
  continue;
1360
1790
  const { generated, sourceOffsetAt, generatedOffsetAt } = results[ext];
@@ -1367,14 +1797,23 @@ function getStyleSheetInfo(doc) {
1367
1797
  parsed: service2.parseStylesheet(virtualDoc)
1368
1798
  };
1369
1799
  }
1370
- cache.set(parsed, cached);
1800
+ cache2.set(parsed, cached);
1371
1801
  }
1372
1802
  return cached;
1373
1803
  }
1804
+ function isTextEdit(edit) {
1805
+ return edit.range !== void 0;
1806
+ }
1374
1807
 
1375
1808
  // src/service/index.ts
1376
- var plugins = [marko_default, stylesheet_default];
1809
+ var plugins = [marko_default, StyleSheetService];
1377
1810
  var service = {
1811
+ async initialize(params) {
1812
+ await Promise.all(plugins.map((plugin) => {
1813
+ var _a;
1814
+ return (_a = plugin.initialize) == null ? void 0 : _a.call(plugin, params);
1815
+ }));
1816
+ },
1378
1817
  async doComplete(doc, params, cancel) {
1379
1818
  const result = CompletionList3.create([], false);
1380
1819
  try {
@@ -1385,7 +1824,7 @@ var service = {
1385
1824
  for (const pending of requests) {
1386
1825
  const cur = await pending;
1387
1826
  if (cancel.isCancellationRequested)
1388
- break;
1827
+ return;
1389
1828
  if (cur) {
1390
1829
  let items;
1391
1830
  if (Array.isArray(cur)) {
@@ -1413,7 +1852,7 @@ var service = {
1413
1852
  for (const pending of requests) {
1414
1853
  const cur = await pending;
1415
1854
  if (cancel.isCancellationRequested)
1416
- break;
1855
+ return;
1417
1856
  if (cur) {
1418
1857
  if (Array.isArray(cur)) {
1419
1858
  result.push(...cur);
@@ -1427,6 +1866,126 @@ var service = {
1427
1866
  }
1428
1867
  return result;
1429
1868
  },
1869
+ async findReferences(doc, params, cancel) {
1870
+ let result;
1871
+ try {
1872
+ const requests = plugins.map((plugin) => {
1873
+ var _a;
1874
+ return (_a = plugin.findReferences) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1875
+ });
1876
+ for (const pending of requests) {
1877
+ const cur = await pending;
1878
+ if (cancel.isCancellationRequested)
1879
+ return;
1880
+ if (cur) {
1881
+ if (result) {
1882
+ result.push(...cur);
1883
+ } else {
1884
+ result = cur;
1885
+ }
1886
+ }
1887
+ }
1888
+ } catch (err) {
1889
+ displayError(err);
1890
+ }
1891
+ return result;
1892
+ },
1893
+ async findDocumentLinks(doc, params, cancel) {
1894
+ let result;
1895
+ try {
1896
+ const requests = plugins.map((plugin) => {
1897
+ var _a;
1898
+ return (_a = plugin.findDocumentLinks) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1899
+ });
1900
+ for (const pending of requests) {
1901
+ const cur = await pending;
1902
+ if (cancel.isCancellationRequested)
1903
+ return;
1904
+ if (cur) {
1905
+ if (result) {
1906
+ result.push(...cur);
1907
+ } else {
1908
+ result = cur;
1909
+ }
1910
+ }
1911
+ }
1912
+ } catch (err) {
1913
+ displayError(err);
1914
+ }
1915
+ return result;
1916
+ },
1917
+ async findDocumentHighlights(doc, params, cancel) {
1918
+ let result;
1919
+ try {
1920
+ const requests = plugins.map((plugin) => {
1921
+ var _a;
1922
+ return (_a = plugin.findDocumentHighlights) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1923
+ });
1924
+ for (const pending of requests) {
1925
+ const cur = await pending;
1926
+ if (cancel.isCancellationRequested)
1927
+ return;
1928
+ if (cur) {
1929
+ if (result) {
1930
+ result.push(...cur);
1931
+ } else {
1932
+ result = cur;
1933
+ }
1934
+ }
1935
+ }
1936
+ } catch (err) {
1937
+ displayError(err);
1938
+ }
1939
+ return result;
1940
+ },
1941
+ async findDocumentColors(doc, params, cancel) {
1942
+ let result;
1943
+ try {
1944
+ const requests = plugins.map((plugin) => {
1945
+ var _a;
1946
+ return (_a = plugin.findDocumentColors) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1947
+ });
1948
+ for (const pending of requests) {
1949
+ const cur = await pending;
1950
+ if (cancel.isCancellationRequested)
1951
+ return;
1952
+ if (cur) {
1953
+ if (result) {
1954
+ result.push(...cur);
1955
+ } else {
1956
+ result = cur;
1957
+ }
1958
+ }
1959
+ }
1960
+ } catch (err) {
1961
+ displayError(err);
1962
+ }
1963
+ return result;
1964
+ },
1965
+ async getColorPresentations(doc, params, cancel) {
1966
+ let result;
1967
+ try {
1968
+ const requests = plugins.map((plugin) => {
1969
+ var _a;
1970
+ return (_a = plugin.getColorPresentations) == null ? void 0 : _a.call(plugin, doc, params, cancel);
1971
+ });
1972
+ for (const pending of requests) {
1973
+ const cur = await pending;
1974
+ if (cancel.isCancellationRequested)
1975
+ return;
1976
+ if (cur) {
1977
+ if (result) {
1978
+ result.push(...cur);
1979
+ } else {
1980
+ result = cur;
1981
+ }
1982
+ }
1983
+ }
1984
+ } catch (err) {
1985
+ displayError(err);
1986
+ }
1987
+ return result;
1988
+ },
1430
1989
  async doHover(doc, params, cancel) {
1431
1990
  var _a;
1432
1991
  try {
@@ -1441,6 +2000,80 @@ var service = {
1441
2000
  displayError(err);
1442
2001
  }
1443
2002
  },
2003
+ async doRename(doc, params, cancel) {
2004
+ let changes;
2005
+ let changeAnnotations;
2006
+ let documentChanges;
2007
+ try {
2008
+ const requests = plugins.map((plugin) => {
2009
+ var _a;
2010
+ return (_a = plugin.doRename) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2011
+ });
2012
+ for (const pending of requests) {
2013
+ const cur = await pending;
2014
+ if (cancel.isCancellationRequested)
2015
+ return;
2016
+ if (cur) {
2017
+ if (cur.changes) {
2018
+ if (changes) {
2019
+ for (const uri in cur.changes) {
2020
+ if (changes[uri]) {
2021
+ changes[uri].push(...cur.changes[uri]);
2022
+ } else {
2023
+ changes[uri] = cur.changes[uri];
2024
+ }
2025
+ }
2026
+ } else {
2027
+ changes = cur.changes;
2028
+ }
2029
+ }
2030
+ if (cur.changeAnnotations) {
2031
+ if (changeAnnotations) {
2032
+ Object.assign(changeAnnotations, cur.changeAnnotations);
2033
+ } else {
2034
+ changeAnnotations = cur.changeAnnotations;
2035
+ }
2036
+ }
2037
+ if (cur.documentChanges) {
2038
+ if (documentChanges) {
2039
+ documentChanges.push(...cur.documentChanges);
2040
+ } else {
2041
+ documentChanges = cur.documentChanges;
2042
+ }
2043
+ }
2044
+ }
2045
+ }
2046
+ } catch (err) {
2047
+ displayError(err);
2048
+ }
2049
+ if (changes || changeAnnotations || documentChanges) {
2050
+ return {
2051
+ changes,
2052
+ changeAnnotations,
2053
+ documentChanges
2054
+ };
2055
+ }
2056
+ },
2057
+ async doCodeActions(doc, params, cancel) {
2058
+ const result = [];
2059
+ try {
2060
+ const requests = plugins.map((plugin) => {
2061
+ var _a;
2062
+ return (_a = plugin.doCodeActions) == null ? void 0 : _a.call(plugin, doc, params, cancel);
2063
+ });
2064
+ for (const pending of requests) {
2065
+ const cur = await pending;
2066
+ if (cancel.isCancellationRequested)
2067
+ return;
2068
+ if (cur) {
2069
+ result.push(...cur);
2070
+ }
2071
+ }
2072
+ } catch (err) {
2073
+ displayError(err);
2074
+ }
2075
+ return result;
2076
+ },
1444
2077
  async doValidate(doc) {
1445
2078
  const result = [];
1446
2079
  try {
@@ -1478,14 +2111,21 @@ console.error = (...args) => {
1478
2111
  };
1479
2112
  process.on("uncaughtException", console.error);
1480
2113
  process.on("unhandledRejection", console.error);
1481
- connection2.onInitialize(() => {
2114
+ connection2.onInitialize(async (params) => {
1482
2115
  setup(connection2);
2116
+ await service.initialize(params);
1483
2117
  return {
1484
2118
  capabilities: {
1485
2119
  textDocumentSync: TextDocumentSyncKind.Incremental,
1486
2120
  documentFormattingProvider: true,
1487
2121
  definitionProvider: true,
1488
2122
  hoverProvider: true,
2123
+ renameProvider: true,
2124
+ codeActionProvider: true,
2125
+ referencesProvider: true,
2126
+ documentLinkProvider: { resolveProvider: false },
2127
+ colorProvider: true,
2128
+ documentHighlightProvider: true,
1489
2129
  completionProvider: {
1490
2130
  triggerCharacters: [
1491
2131
  ".",
@@ -1525,9 +2165,30 @@ connection2.onCompletion(async (params, cancel) => {
1525
2165
  connection2.onDefinition(async (params, cancel) => {
1526
2166
  return await service.findDefinition(documents.get(params.textDocument.uri), params, cancel) || null;
1527
2167
  });
2168
+ connection2.onReferences(async (params, cancel) => {
2169
+ return await service.findReferences(documents.get(params.textDocument.uri), params, cancel) || null;
2170
+ });
2171
+ connection2.onDocumentLinks(async (params, cancel) => {
2172
+ return await service.findDocumentLinks(documents.get(params.textDocument.uri), params, cancel) || null;
2173
+ });
2174
+ connection2.onDocumentHighlight(async (params, cancel) => {
2175
+ return await service.findDocumentHighlights(documents.get(params.textDocument.uri), params, cancel) || null;
2176
+ });
2177
+ connection2.onDocumentColor(async (params, cancel) => {
2178
+ return await service.findDocumentColors(documents.get(params.textDocument.uri), params, cancel) || null;
2179
+ });
2180
+ connection2.onColorPresentation(async (params, cancel) => {
2181
+ return await service.getColorPresentations(documents.get(params.textDocument.uri), params, cancel) || null;
2182
+ });
1528
2183
  connection2.onHover(async (params, cancel) => {
1529
2184
  return await service.doHover(documents.get(params.textDocument.uri), params, cancel) || null;
1530
2185
  });
2186
+ connection2.onRenameRequest(async (params, cancel) => {
2187
+ return await service.doRename(documents.get(params.textDocument.uri), params, cancel) || null;
2188
+ });
2189
+ connection2.onCodeAction(async (params, cancel) => {
2190
+ return await service.doCodeActions(documents.get(params.textDocument.uri), params, cancel) || null;
2191
+ });
1531
2192
  connection2.onDocumentFormatting(async (params, cancel) => {
1532
2193
  return await service.format(documents.get(params.textDocument.uri), params, cancel) || null;
1533
2194
  });