@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 +440 -117
- package/dist/index.js.map +3 -3
- package/dist/index.mjs +434 -107
- package/dist/index.mjs.map +3 -3
- package/dist/service/marko/complete/AttrValue.d.ts +4 -0
- package/dist/service/marko/document-links/extract.d.ts +8 -0
- package/dist/service/marko/document-links/index.d.ts +2 -0
- package/dist/service/marko/util/is-document-link-attr.d.ts +5 -0
- package/dist/service/stylesheet/extract.d.ts +1 -1
- package/dist/service/types.d.ts +3 -1
- package/dist/utils/file-system.d.ts +9 -0
- package/dist/utils/resolve-url.d.ts +1 -0
- package/package.json +1 -1
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
|
|
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:
|
|
591
|
+
cache: cache3,
|
|
592
592
|
get lookup() {
|
|
593
|
-
let lookup =
|
|
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
|
-
|
|
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
|
|
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:
|
|
1019
|
+
const { compiler, translator, cache: cache3 } = getCompilerInfo(doc);
|
|
888
1020
|
try {
|
|
889
1021
|
compiler.compileSync(doc.getText(), fsPath || "untitled.marko", {
|
|
890
|
-
cache:
|
|
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(
|
|
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
|
|
1041
|
+
import path5 from "path";
|
|
910
1042
|
import { URI as URI4 } from "vscode-uri";
|
|
911
|
-
import { Range as
|
|
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
|
|
1070
|
+
import fs2 from "fs";
|
|
939
1071
|
import { URI as URI3 } from "vscode-uri";
|
|
940
|
-
import { Position, Range as
|
|
1072
|
+
import { Position, Range as Range4 } from "vscode-languageserver";
|
|
941
1073
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
942
|
-
var START_OF_FILE =
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
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
|
|
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 =
|
|
1143
|
+
range = Range6.create(tagDefDoc.positionAt(match.index), tagDefDoc.positionAt(match.index + match[0].length));
|
|
1012
1144
|
}
|
|
1013
1145
|
}
|
|
1014
1146
|
return [
|
|
@@ -1037,14 +1169,83 @@ var findDefinition = async (doc, params) => {
|
|
|
1037
1169
|
})) || [];
|
|
1038
1170
|
};
|
|
1039
1171
|
|
|
1040
|
-
// src/service/marko/
|
|
1041
|
-
import {
|
|
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
1246
|
var format2 = async (doc, params, cancel) => {
|
|
1046
1247
|
try {
|
|
1047
|
-
const { fsPath, scheme } =
|
|
1248
|
+
const { fsPath, scheme } = URI7.parse(doc.uri);
|
|
1048
1249
|
const text = doc.getText();
|
|
1049
1250
|
const options = {
|
|
1050
1251
|
parser: "marko",
|
|
@@ -1059,7 +1260,7 @@ var format2 = async (doc, params, cancel) => {
|
|
|
1059
1260
|
if (cancel.isCancellationRequested)
|
|
1060
1261
|
return;
|
|
1061
1262
|
return [
|
|
1062
|
-
|
|
1263
|
+
TextEdit5.replace(Range7.create(doc.positionAt(0), doc.positionAt(text.length)), prettier.format(text, options))
|
|
1063
1264
|
];
|
|
1064
1265
|
} catch (e) {
|
|
1065
1266
|
displayError(e);
|
|
@@ -1071,13 +1272,14 @@ var marko_default = {
|
|
|
1071
1272
|
doComplete,
|
|
1072
1273
|
doValidate,
|
|
1073
1274
|
findDefinition,
|
|
1275
|
+
findDocumentLinks,
|
|
1074
1276
|
format: format2
|
|
1075
1277
|
};
|
|
1076
1278
|
|
|
1077
1279
|
// src/service/stylesheet/index.ts
|
|
1078
1280
|
import {
|
|
1079
1281
|
CompletionList as CompletionList2,
|
|
1080
|
-
Range as
|
|
1282
|
+
Range as Range9,
|
|
1081
1283
|
TextDocumentEdit
|
|
1082
1284
|
} from "vscode-languageserver";
|
|
1083
1285
|
import {
|
|
@@ -1223,7 +1425,7 @@ function extractStyleSheets(code, program, lookup) {
|
|
|
1223
1425
|
for (const attr of node.attrs) {
|
|
1224
1426
|
if (attr.type === 8 /* AttrNamed */ && ((_a = attr.value) == null ? void 0 : _a.type) === 11 /* AttrValue */ && /^['"]$/.test(code[attr.value.value.start])) {
|
|
1225
1427
|
const name = read(attr.name);
|
|
1226
|
-
if (name === "#style" || name === "style" &&
|
|
1428
|
+
if (name === "#style" || name === "style" && node.nameText && name === "style" && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html)) {
|
|
1227
1429
|
getExtractor("css").write`:root{${{
|
|
1228
1430
|
start: attr.value.value.start + 1,
|
|
1229
1431
|
end: attr.value.value.end - 1
|
|
@@ -1245,13 +1447,17 @@ function extractStyleSheets(code, program, lookup) {
|
|
|
1245
1447
|
}
|
|
1246
1448
|
|
|
1247
1449
|
// src/service/stylesheet/index.ts
|
|
1248
|
-
var
|
|
1450
|
+
var cache2 = /* @__PURE__ */ new WeakMap();
|
|
1249
1451
|
var services = {
|
|
1250
1452
|
css: getCSSLanguageService,
|
|
1251
1453
|
less: getLESSLanguageService,
|
|
1252
1454
|
scss: getSCSSLanguageService
|
|
1253
1455
|
};
|
|
1456
|
+
var clientCapabilities;
|
|
1254
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,28 +1467,31 @@ var StyleSheetService = {
|
|
|
1261
1467
|
if (generatedOffset === void 0)
|
|
1262
1468
|
continue;
|
|
1263
1469
|
const { service: service2, virtualDoc } = info;
|
|
1264
|
-
const result = service2.
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
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);
|
|
1269
1479
|
}
|
|
1270
1480
|
}
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
}
|
|
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);
|
|
1279
1488
|
}
|
|
1280
1489
|
}
|
|
1281
1490
|
return result;
|
|
1282
1491
|
}
|
|
1283
1492
|
return CompletionList2.create([], true);
|
|
1284
1493
|
},
|
|
1285
|
-
|
|
1494
|
+
findDefinition(doc, params) {
|
|
1286
1495
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1287
1496
|
const sourceOffset = doc.offsetAt(params.position);
|
|
1288
1497
|
for (const ext in infoByExt) {
|
|
@@ -1292,13 +1501,19 @@ var StyleSheetService = {
|
|
|
1292
1501
|
continue;
|
|
1293
1502
|
const { service: service2, virtualDoc } = info;
|
|
1294
1503
|
const result = service2.findDefinition(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
|
|
1295
|
-
if (result
|
|
1296
|
-
|
|
1504
|
+
if (result) {
|
|
1505
|
+
const range = getSourceRange(doc, info, result.range);
|
|
1506
|
+
if (range) {
|
|
1507
|
+
return {
|
|
1508
|
+
range,
|
|
1509
|
+
uri: doc.uri
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1297
1512
|
}
|
|
1298
1513
|
break;
|
|
1299
1514
|
}
|
|
1300
1515
|
},
|
|
1301
|
-
|
|
1516
|
+
findReferences(doc, params) {
|
|
1302
1517
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1303
1518
|
const sourceOffset = doc.offsetAt(params.position);
|
|
1304
1519
|
for (const ext in infoByExt) {
|
|
@@ -1309,14 +1524,40 @@ var StyleSheetService = {
|
|
|
1309
1524
|
const { service: service2, virtualDoc } = info;
|
|
1310
1525
|
const result = [];
|
|
1311
1526
|
for (const location of service2.findReferences(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
|
|
1312
|
-
|
|
1313
|
-
|
|
1527
|
+
const range = getSourceRange(doc, info, location.range);
|
|
1528
|
+
if (range) {
|
|
1529
|
+
result.push({
|
|
1530
|
+
range,
|
|
1531
|
+
uri: location.uri
|
|
1532
|
+
});
|
|
1314
1533
|
}
|
|
1315
1534
|
}
|
|
1316
1535
|
return result.length ? result : void 0;
|
|
1317
1536
|
}
|
|
1318
1537
|
},
|
|
1319
|
-
|
|
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) {
|
|
1320
1561
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1321
1562
|
const sourceOffset = doc.offsetAt(params.position);
|
|
1322
1563
|
for (const ext in infoByExt) {
|
|
@@ -1327,30 +1568,36 @@ var StyleSheetService = {
|
|
|
1327
1568
|
const { service: service2, virtualDoc } = info;
|
|
1328
1569
|
const result = [];
|
|
1329
1570
|
for (const highlight of service2.findDocumentHighlights(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed)) {
|
|
1330
|
-
|
|
1331
|
-
|
|
1571
|
+
const range = getSourceRange(doc, info, highlight.range);
|
|
1572
|
+
if (range) {
|
|
1573
|
+
result.push({
|
|
1574
|
+
range,
|
|
1575
|
+
kind: highlight.kind
|
|
1576
|
+
});
|
|
1332
1577
|
}
|
|
1333
1578
|
}
|
|
1334
1579
|
return result.length ? result : void 0;
|
|
1335
1580
|
}
|
|
1336
1581
|
},
|
|
1337
|
-
|
|
1582
|
+
findDocumentColors(doc) {
|
|
1338
1583
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1339
1584
|
const result = [];
|
|
1340
1585
|
for (const ext in infoByExt) {
|
|
1341
1586
|
const info = infoByExt[ext];
|
|
1342
1587
|
const { service: service2, virtualDoc } = info;
|
|
1343
1588
|
for (const colorInfo of service2.findDocumentColors(virtualDoc, info.parsed)) {
|
|
1344
|
-
|
|
1345
|
-
|
|
1589
|
+
const range = getSourceRange(doc, info, colorInfo.range);
|
|
1590
|
+
if (range) {
|
|
1591
|
+
result.push({
|
|
1592
|
+
range,
|
|
1593
|
+
color: colorInfo.color
|
|
1594
|
+
});
|
|
1346
1595
|
}
|
|
1347
1596
|
}
|
|
1348
1597
|
}
|
|
1349
|
-
|
|
1350
|
-
return result;
|
|
1351
|
-
}
|
|
1598
|
+
return result.length ? result : void 0;
|
|
1352
1599
|
},
|
|
1353
|
-
|
|
1600
|
+
getColorPresentations(doc, params) {
|
|
1354
1601
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1355
1602
|
const sourceOffset = doc.offsetAt(params.range.start);
|
|
1356
1603
|
for (const ext in infoByExt) {
|
|
@@ -1362,21 +1609,22 @@ var StyleSheetService = {
|
|
|
1362
1609
|
if (generatedOffsetEnd === void 0)
|
|
1363
1610
|
continue;
|
|
1364
1611
|
const { service: service2, virtualDoc } = info;
|
|
1365
|
-
const result =
|
|
1366
|
-
for (const colorPresentation of
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
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
|
+
});
|
|
1374
1622
|
}
|
|
1375
1623
|
}
|
|
1376
|
-
return result;
|
|
1624
|
+
return result.length ? result : void 0;
|
|
1377
1625
|
}
|
|
1378
1626
|
},
|
|
1379
|
-
|
|
1627
|
+
doHover(doc, params) {
|
|
1380
1628
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1381
1629
|
const sourceOffset = doc.offsetAt(params.position);
|
|
1382
1630
|
for (const ext in infoByExt) {
|
|
@@ -1386,8 +1634,18 @@ var StyleSheetService = {
|
|
|
1386
1634
|
continue;
|
|
1387
1635
|
const { service: service2, virtualDoc } = info;
|
|
1388
1636
|
const result = service2.doHover(virtualDoc, virtualDoc.positionAt(generatedOffset), info.parsed);
|
|
1389
|
-
if (result
|
|
1390
|
-
|
|
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
|
+
}
|
|
1391
1649
|
}
|
|
1392
1650
|
}
|
|
1393
1651
|
},
|
|
@@ -1404,9 +1662,7 @@ var StyleSheetService = {
|
|
|
1404
1662
|
if (result.changes) {
|
|
1405
1663
|
for (const uri in result.changes) {
|
|
1406
1664
|
if (uri === doc.uri) {
|
|
1407
|
-
|
|
1408
|
-
updateTextEdit(doc, info, textEdit);
|
|
1409
|
-
}
|
|
1665
|
+
result.changes[uri] = getSourceEdits(doc, info, result.changes[uri]) || [];
|
|
1410
1666
|
}
|
|
1411
1667
|
}
|
|
1412
1668
|
}
|
|
@@ -1414,9 +1670,7 @@ var StyleSheetService = {
|
|
|
1414
1670
|
for (const change of result.documentChanges) {
|
|
1415
1671
|
if (TextDocumentEdit.is(change)) {
|
|
1416
1672
|
if (change.textDocument.uri === doc.uri) {
|
|
1417
|
-
|
|
1418
|
-
updateTextEdit(doc, info, textEdit);
|
|
1419
|
-
}
|
|
1673
|
+
change.edits = getSourceEdits(doc, info, change.edits) || [];
|
|
1420
1674
|
}
|
|
1421
1675
|
}
|
|
1422
1676
|
}
|
|
@@ -1424,7 +1678,7 @@ var StyleSheetService = {
|
|
|
1424
1678
|
return result;
|
|
1425
1679
|
}
|
|
1426
1680
|
},
|
|
1427
|
-
|
|
1681
|
+
doCodeActions(doc, params) {
|
|
1428
1682
|
var _a;
|
|
1429
1683
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1430
1684
|
const sourceOffset = doc.offsetAt(params.range.start);
|
|
@@ -1437,65 +1691,100 @@ var StyleSheetService = {
|
|
|
1437
1691
|
if (generatedOffsetEnd === void 0)
|
|
1438
1692
|
continue;
|
|
1439
1693
|
const { service: service2, virtualDoc } = info;
|
|
1440
|
-
const result = service2.doCodeActions(virtualDoc,
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
for (const textEdit of edits) {
|
|
1446
|
-
updateTextEdit(doc, info, textEdit);
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
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);
|
|
1449
1699
|
}
|
|
1450
|
-
return result;
|
|
1451
1700
|
}
|
|
1701
|
+
return result;
|
|
1452
1702
|
}
|
|
1453
1703
|
},
|
|
1454
|
-
|
|
1704
|
+
doValidate(doc) {
|
|
1455
1705
|
const infoByExt = getStyleSheetInfo(doc);
|
|
1456
1706
|
const result = [];
|
|
1457
1707
|
for (const ext in infoByExt) {
|
|
1458
1708
|
const info = infoByExt[ext];
|
|
1459
1709
|
for (const diag of info.service.doValidation(info.virtualDoc, info.parsed)) {
|
|
1460
|
-
|
|
1710
|
+
const range = getSourceRange(doc, info, diag.range);
|
|
1711
|
+
if (range) {
|
|
1712
|
+
diag.range = range;
|
|
1461
1713
|
result.push(diag);
|
|
1462
1714
|
}
|
|
1463
1715
|
}
|
|
1464
1716
|
}
|
|
1465
|
-
return result;
|
|
1717
|
+
return result.length ? result : void 0;
|
|
1466
1718
|
}
|
|
1467
1719
|
};
|
|
1468
|
-
function
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
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
|
+
};
|
|
1472
1737
|
}
|
|
1473
1738
|
}
|
|
1474
|
-
function
|
|
1475
|
-
if (
|
|
1476
|
-
|
|
1477
|
-
|
|
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
|
+
}
|
|
1478
1758
|
}
|
|
1479
1759
|
}
|
|
1480
|
-
function
|
|
1760
|
+
function getSourceRange(doc, info, range) {
|
|
1481
1761
|
const start = info.sourceOffsetAt(info.virtualDoc.offsetAt(range.start));
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
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;
|
|
1487
1769
|
}
|
|
1488
|
-
|
|
1770
|
+
const pos = doc.positionAt(start);
|
|
1771
|
+
return {
|
|
1772
|
+
start: pos,
|
|
1773
|
+
end: start === end ? pos : doc.positionAt(end)
|
|
1774
|
+
};
|
|
1489
1775
|
}
|
|
1490
1776
|
function getStyleSheetInfo(doc) {
|
|
1491
1777
|
var _a;
|
|
1492
1778
|
const parsed = parse2(doc);
|
|
1493
|
-
let cached =
|
|
1779
|
+
let cached = cache2.get(parsed);
|
|
1494
1780
|
if (!cached) {
|
|
1495
1781
|
const results = extractStyleSheets(doc.getText(), parsed.program, getCompilerInfo(doc).lookup);
|
|
1496
1782
|
cached = {};
|
|
1497
1783
|
for (const ext in results) {
|
|
1498
|
-
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
|
+
});
|
|
1499
1788
|
if (!service2)
|
|
1500
1789
|
continue;
|
|
1501
1790
|
const { generated, sourceOffsetAt, generatedOffsetAt } = results[ext];
|
|
@@ -1508,14 +1797,23 @@ function getStyleSheetInfo(doc) {
|
|
|
1508
1797
|
parsed: service2.parseStylesheet(virtualDoc)
|
|
1509
1798
|
};
|
|
1510
1799
|
}
|
|
1511
|
-
|
|
1800
|
+
cache2.set(parsed, cached);
|
|
1512
1801
|
}
|
|
1513
1802
|
return cached;
|
|
1514
1803
|
}
|
|
1804
|
+
function isTextEdit(edit) {
|
|
1805
|
+
return edit.range !== void 0;
|
|
1806
|
+
}
|
|
1515
1807
|
|
|
1516
1808
|
// src/service/index.ts
|
|
1517
1809
|
var plugins = [marko_default, StyleSheetService];
|
|
1518
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
|
+
},
|
|
1519
1817
|
async doComplete(doc, params, cancel) {
|
|
1520
1818
|
const result = CompletionList3.create([], false);
|
|
1521
1819
|
try {
|
|
@@ -1592,6 +1890,30 @@ var service = {
|
|
|
1592
1890
|
}
|
|
1593
1891
|
return result;
|
|
1594
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
|
+
},
|
|
1595
1917
|
async findDocumentHighlights(doc, params, cancel) {
|
|
1596
1918
|
let result;
|
|
1597
1919
|
try {
|
|
@@ -1789,8 +2111,9 @@ console.error = (...args) => {
|
|
|
1789
2111
|
};
|
|
1790
2112
|
process.on("uncaughtException", console.error);
|
|
1791
2113
|
process.on("unhandledRejection", console.error);
|
|
1792
|
-
connection2.onInitialize(() => {
|
|
2114
|
+
connection2.onInitialize(async (params) => {
|
|
1793
2115
|
setup(connection2);
|
|
2116
|
+
await service.initialize(params);
|
|
1794
2117
|
return {
|
|
1795
2118
|
capabilities: {
|
|
1796
2119
|
textDocumentSync: TextDocumentSyncKind.Incremental,
|
|
@@ -1800,6 +2123,7 @@ connection2.onInitialize(() => {
|
|
|
1800
2123
|
renameProvider: true,
|
|
1801
2124
|
codeActionProvider: true,
|
|
1802
2125
|
referencesProvider: true,
|
|
2126
|
+
documentLinkProvider: { resolveProvider: false },
|
|
1803
2127
|
colorProvider: true,
|
|
1804
2128
|
documentHighlightProvider: true,
|
|
1805
2129
|
completionProvider: {
|
|
@@ -1844,6 +2168,9 @@ connection2.onDefinition(async (params, cancel) => {
|
|
|
1844
2168
|
connection2.onReferences(async (params, cancel) => {
|
|
1845
2169
|
return await service.findReferences(documents.get(params.textDocument.uri), params, cancel) || null;
|
|
1846
2170
|
});
|
|
2171
|
+
connection2.onDocumentLinks(async (params, cancel) => {
|
|
2172
|
+
return await service.findDocumentLinks(documents.get(params.textDocument.uri), params, cancel) || null;
|
|
2173
|
+
});
|
|
1847
2174
|
connection2.onDocumentHighlight(async (params, cancel) => {
|
|
1848
2175
|
return await service.findDocumentHighlights(documents.get(params.textDocument.uri), params, cancel) || null;
|
|
1849
2176
|
});
|