vscode-gem-languageservice 0.0.3 → 0.0.5
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 +178 -437
- package/dist/index.js.map +4 -4
- package/package.json +12 -11
- package/src/index.ts +0 -132
package/dist/index.js
CHANGED
|
@@ -1,479 +1,220 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
3
24
|
|
|
4
25
|
// src/index.ts
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var import_timer = require("duoyun-ui/lib/timer");
|
|
26
|
+
var import_vscode_languageserver_textdocument2 = require("vscode-languageserver-textdocument");
|
|
27
|
+
var import_node2 = require("vscode-languageserver/node");
|
|
8
28
|
|
|
9
|
-
// src/
|
|
29
|
+
// src/provider.ts
|
|
30
|
+
var import_css_color_keywords = __toESM(require("css-color-keywords"));
|
|
10
31
|
var import_color = require("duoyun-ui/lib/color");
|
|
32
|
+
var import_types = require("duoyun-ui/lib/types");
|
|
11
33
|
var import_node = require("vscode-languageserver/node");
|
|
12
34
|
|
|
13
|
-
// src/
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
var HTML_REG = /(?<start>\/\*\s*html\s*\*\/\s*`|(?<!`)(?:html|raw)\s*`)(?<content>[^`]*)(`)/g;
|
|
35
|
+
// src/global.ts
|
|
36
|
+
var import_vscode_css_languageservice = require("@mantou/vscode-css-languageservice");
|
|
37
|
+
var import_vscode_html_languageservice = require("@mantou/vscode-html-languageservice");
|
|
38
|
+
var import_cache2 = require("duoyun-ui/lib/cache");
|
|
18
39
|
|
|
19
|
-
// src/
|
|
20
|
-
var
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
while ((match = COLOR_REG.exec(documentText)) !== null) {
|
|
27
|
-
const hex = match.groups.content;
|
|
28
|
-
const [red, green, blue, alpha] = (0, import_color.parseHexColor)(hex);
|
|
29
|
-
const offset = match.index + (match.groups.start?.length || 0);
|
|
30
|
-
const range = import_node.Range.create(document.positionAt(offset), document.positionAt(offset + hex.length));
|
|
31
|
-
const color = import_node.Color.create(red / 255, green / 255, blue / 255, alpha);
|
|
32
|
-
colors.push({ range, color });
|
|
33
|
-
}
|
|
34
|
-
return colors;
|
|
35
|
-
}
|
|
36
|
-
provideColorPresentations({ red, green, blue, alpha }) {
|
|
37
|
-
return [{ label: (0, import_color.rgbToHexColor)([red * 255, green * 255, blue * 255, alpha]) }];
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// src/diagnostic.ts
|
|
42
|
-
var import_vscode_css_languageservice = require("vscode-css-languageservice");
|
|
43
|
-
var import_node3 = require("vscode-languageserver/node");
|
|
44
|
-
|
|
45
|
-
// src/util.ts
|
|
46
|
-
var import_vscode_html_languageservice = require("vscode-html-languageservice");
|
|
47
|
-
var import_node2 = require("vscode-languageserver/node");
|
|
48
|
-
function removeSlot(text) {
|
|
49
|
-
const v = text.replace(/\$\{[^${]*?\}/g, (str) => str.replaceAll(/[^\n]/g, "x"));
|
|
50
|
-
if (v === text) return v;
|
|
51
|
-
return removeSlot(v);
|
|
52
|
-
}
|
|
53
|
-
function removeHTMLSlot(text, position) {
|
|
54
|
-
const left = text.slice(0, position);
|
|
55
|
-
const right = text.slice(position);
|
|
56
|
-
const left1 = removeSlot(left);
|
|
57
|
-
const left2 = left1.replace(/(.*(?=html`))/s, (str) => str.replaceAll(/[^\n]/g, " "));
|
|
58
|
-
return left2 + removeSlot(right);
|
|
59
|
-
}
|
|
60
|
-
function translateCompletionList(result, position) {
|
|
61
|
-
const getRange = (item) => {
|
|
62
|
-
if (item.textEdit && "range" in item.textEdit) {
|
|
63
|
-
const { start, end } = item.textEdit.range;
|
|
64
|
-
return import_node2.Range.create(
|
|
65
|
-
import_node2.Position.create(position.line, start.character),
|
|
66
|
-
import_node2.Position.create(position.line, end.character)
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
40
|
+
// src/documents.ts
|
|
41
|
+
var import_cache = require("duoyun-ui/lib/cache");
|
|
42
|
+
var import_tree_sitter = __toESM(require("tree-sitter"));
|
|
43
|
+
var import_tree_sitter_typescript = __toESM(require("tree-sitter-typescript"));
|
|
44
|
+
var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
|
|
45
|
+
var language = import_tree_sitter_typescript.default.typescript;
|
|
46
|
+
function processTemplate({ children }) {
|
|
70
47
|
return {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
...item,
|
|
74
|
-
textEdit: item.textEdit && {
|
|
75
|
-
...item.textEdit,
|
|
76
|
-
range: getRange(item)
|
|
77
|
-
}
|
|
78
|
-
}))
|
|
48
|
+
startIndex: children[1].startIndex,
|
|
49
|
+
text: children.slice(1, -1).reduce((p, c) => p + (c.type === "template_substitution" ? c.text.replaceAll(/./g, "_") : c.text), "")
|
|
79
50
|
};
|
|
80
51
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
52
|
+
var CSTDocs = class extends WeakMap {
|
|
53
|
+
#cssCache = new import_cache.Cache({ max: 1e3 });
|
|
54
|
+
#htmlCache = new import_cache.Cache({ max: 1e3 });
|
|
55
|
+
getTypeScriptCST(textDocument) {
|
|
56
|
+
const parser = new import_tree_sitter.default();
|
|
57
|
+
parser.setLanguage(language);
|
|
58
|
+
const oldTree = this.get(textDocument);
|
|
59
|
+
if (oldTree?.getText(oldTree.rootNode) === textDocument.getText()) return oldTree;
|
|
60
|
+
const newTree = parser.parse(textDocument.getText());
|
|
61
|
+
this.set(textDocument, newTree);
|
|
62
|
+
return newTree;
|
|
63
|
+
}
|
|
64
|
+
getAllTemplate(textDocument, tag) {
|
|
65
|
+
const tree = this.getTypeScriptCST(textDocument);
|
|
66
|
+
const query = new import_tree_sitter.default.Query(
|
|
67
|
+
language,
|
|
68
|
+
`
|
|
69
|
+
(call_expression
|
|
70
|
+
function: (identifier) @tag (#eq? @tag "${tag}")
|
|
71
|
+
arguments: (template_string) @injection.content
|
|
72
|
+
)
|
|
73
|
+
`
|
|
74
|
+
);
|
|
75
|
+
const matches = query.matches(tree.rootNode);
|
|
76
|
+
const templateStrings = matches.map(({ captures }) => captures.pop().node);
|
|
77
|
+
return templateStrings.map(processTemplate);
|
|
78
|
+
}
|
|
79
|
+
getStyles(textDocument) {
|
|
80
|
+
const tree = this.getTypeScriptCST(textDocument);
|
|
81
|
+
const query = new import_tree_sitter.default.Query(
|
|
82
|
+
language,
|
|
83
|
+
`
|
|
84
|
+
(call_expression
|
|
85
|
+
function: (identifier) @_name (#eq? @_name "css")
|
|
86
|
+
arguments: (arguments (object (pair
|
|
87
|
+
value: (template_string) @injection.content
|
|
88
|
+
)))
|
|
89
|
+
)
|
|
90
|
+
`
|
|
91
|
+
);
|
|
92
|
+
const matches = query.matches(tree.rootNode);
|
|
93
|
+
const templateStrings = matches.map(({ captures }) => captures.pop().node);
|
|
94
|
+
return templateStrings.map(processTemplate);
|
|
95
|
+
}
|
|
96
|
+
getAllStyleValue(textDocument) {
|
|
97
|
+
const tree = this.getTypeScriptCST(textDocument);
|
|
98
|
+
const query = new import_tree_sitter.default.Query(
|
|
99
|
+
language,
|
|
100
|
+
`
|
|
101
|
+
(call_expression
|
|
102
|
+
function: (identifier) @_name (#eq? @_name "styleMap")
|
|
103
|
+
arguments: (arguments (object (pair
|
|
104
|
+
value: (string (string_fragment) @injection.content)
|
|
105
|
+
)))
|
|
106
|
+
)
|
|
107
|
+
`
|
|
108
|
+
);
|
|
109
|
+
const matches = query.matches(tree.rootNode);
|
|
110
|
+
return matches.map(({ captures }) => captures.pop().node);
|
|
111
|
+
}
|
|
112
|
+
getAllCSS(textDocument) {
|
|
113
|
+
return this.getAllTemplate(textDocument, "css").map((e) => {
|
|
114
|
+
const doc = import_vscode_languageserver_textdocument.TextDocument.create(``, "css", 1, e.text);
|
|
115
|
+
const cssDoc = this.#cssCache.get(e.text, () => cssLanguageService.parseStylesheet(doc));
|
|
116
|
+
return { ...e, doc, cssDoc };
|
|
146
117
|
});
|
|
147
118
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const documentText = document.getText();
|
|
154
|
-
const match = matchOffset(CSS_REG, documentText, currentOffset);
|
|
155
|
-
if (!match) return null;
|
|
156
|
-
const matchContent = match.groups.content;
|
|
157
|
-
const matchStartOffset = match.index + match.groups.start.length;
|
|
158
|
-
const virtualOffset = currentOffset - matchStartOffset;
|
|
159
|
-
const virtualDocument = createVirtualDocument("css", removeSlot(matchContent));
|
|
160
|
-
const stylesheet = this.#cssLanguageService.parseStylesheet(virtualDocument);
|
|
161
|
-
return this.#cssLanguageService.doHover(virtualDocument, virtualDocument.positionAt(virtualOffset), stylesheet, {
|
|
162
|
-
documentation: true,
|
|
163
|
-
references: true
|
|
119
|
+
getAllCSSFragment(textDocument) {
|
|
120
|
+
return [...this.getAllTemplate(textDocument, "styled"), ...this.getStyles(textDocument)].map((e) => {
|
|
121
|
+
const doc = import_vscode_languageserver_textdocument.TextDocument.create(``, "css", 1, `.parent {${e.text}}`);
|
|
122
|
+
const cssDoc = this.#cssCache.get(e.text, () => cssLanguageService.parseStylesheet(doc));
|
|
123
|
+
return { ...e, startIndex: e.startIndex - 9, doc, cssDoc };
|
|
164
124
|
});
|
|
165
125
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const documentText = document.getText();
|
|
172
|
-
const match = matchOffset(STYLE_REG, documentText, currentOffset);
|
|
173
|
-
if (!match) return null;
|
|
174
|
-
const matchContent = match.groups.content;
|
|
175
|
-
const matchStartOffset = match.index + match.groups.start.length;
|
|
176
|
-
const virtualOffset = currentOffset - matchStartOffset + 8;
|
|
177
|
-
const virtualDocument = createVirtualDocument("css", `:host { ${removeSlot(matchContent)} }`);
|
|
178
|
-
const stylesheet = this.#cssLanguageService.parseStylesheet(virtualDocument);
|
|
179
|
-
return this.#cssLanguageService.doHover(virtualDocument, virtualDocument.positionAt(virtualOffset), stylesheet, {
|
|
180
|
-
documentation: true,
|
|
181
|
-
references: true
|
|
126
|
+
getAllHTML(textDocument) {
|
|
127
|
+
return this.getAllTemplate(textDocument, "html").map((e) => {
|
|
128
|
+
const doc = import_vscode_languageserver_textdocument.TextDocument.create(``, "html", 1, e.text);
|
|
129
|
+
const htmlDoc = this.#htmlCache.get(e.text, () => htmlLanguageService.parseHTMLDocument(doc));
|
|
130
|
+
return { ...e, doc, htmlDoc };
|
|
182
131
|
});
|
|
183
132
|
}
|
|
184
133
|
};
|
|
185
134
|
|
|
186
|
-
// src/
|
|
187
|
-
var
|
|
188
|
-
var
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
var
|
|
192
|
-
#cachedCompletionsFile;
|
|
193
|
-
#cachedCompletionsPosition;
|
|
194
|
-
#cachedCompletionsContent;
|
|
195
|
-
#completions;
|
|
196
|
-
#equalPositions(left, right) {
|
|
197
|
-
return !!right && left.line === right.line && left.character === right.character;
|
|
198
|
-
}
|
|
199
|
-
getCached(doc, position) {
|
|
200
|
-
if (this.#completions && doc.uri === this.#cachedCompletionsFile && this.#equalPositions(position, this.#cachedCompletionsPosition) && doc.getText() === this.#cachedCompletionsContent) {
|
|
201
|
-
return this.#completions;
|
|
202
|
-
}
|
|
203
|
-
return void 0;
|
|
204
|
-
}
|
|
205
|
-
updateCached(context, position, completions) {
|
|
206
|
-
this.#cachedCompletionsFile = context.uri;
|
|
207
|
-
this.#cachedCompletionsPosition = position;
|
|
208
|
-
this.#cachedCompletionsContent = context.getText();
|
|
209
|
-
this.#completions = completions;
|
|
210
|
-
return completions;
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// src/css.ts
|
|
215
|
-
function getRegionAtOffset(regions, offset) {
|
|
216
|
-
for (const region of regions) {
|
|
217
|
-
if (region.start <= offset) {
|
|
218
|
-
if (offset <= region.end) {
|
|
219
|
-
return region;
|
|
220
|
-
}
|
|
221
|
-
} else {
|
|
222
|
-
break;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return null;
|
|
226
|
-
}
|
|
227
|
-
function getLanguageRegions(service, data) {
|
|
228
|
-
const scanner = service.createScanner(data);
|
|
229
|
-
const regions = [];
|
|
230
|
-
let tokenType;
|
|
231
|
-
while ((tokenType = scanner.scan()) !== import_vscode_html_languageservice3.TokenType.EOS) {
|
|
232
|
-
switch (tokenType) {
|
|
233
|
-
case import_vscode_html_languageservice3.TokenType.Styles:
|
|
234
|
-
regions.push({
|
|
235
|
-
languageId: "css",
|
|
236
|
-
start: scanner.getTokenOffset(),
|
|
237
|
-
end: scanner.getTokenEnd(),
|
|
238
|
-
length: scanner.getTokenLength(),
|
|
239
|
-
content: scanner.getTokenText()
|
|
240
|
-
});
|
|
241
|
-
break;
|
|
242
|
-
default:
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return regions;
|
|
247
|
-
}
|
|
248
|
-
var HTMLStyleCompletionItemProvider = class {
|
|
249
|
-
#cssLanguageService = (0, import_vscode_css_languageservice3.getCSSLanguageService)();
|
|
250
|
-
#htmlLanguageService = (0, import_vscode_html_languageservice3.getLanguageService)();
|
|
251
|
-
#cache = new CompletionsCache();
|
|
252
|
-
provideCompletionItems(document, position) {
|
|
253
|
-
const cached = this.#cache.getCached(document, position);
|
|
254
|
-
if (cached) return cached;
|
|
255
|
-
const currentOffset = document.offsetAt(position);
|
|
256
|
-
const documentText = document.getText();
|
|
257
|
-
const match = matchOffset(HTML_REG, documentText, currentOffset);
|
|
258
|
-
if (!match) return;
|
|
259
|
-
const matchContent = match.groups.content;
|
|
260
|
-
const matchStartOffset = match.index + match.groups.start.length;
|
|
261
|
-
const regions = getLanguageRegions(this.#htmlLanguageService, matchContent);
|
|
262
|
-
if (regions.length <= 0) return;
|
|
263
|
-
const region = getRegionAtOffset(regions, currentOffset - matchStartOffset);
|
|
264
|
-
if (!region) return;
|
|
265
|
-
const virtualOffset = currentOffset - (matchStartOffset + region.start);
|
|
266
|
-
const virtualDocument = createVirtualDocument("css", removeSlot(region.content));
|
|
267
|
-
const stylesheet = this.#cssLanguageService.parseStylesheet(virtualDocument);
|
|
268
|
-
const completions = this.#cssLanguageService.doComplete(
|
|
269
|
-
virtualDocument,
|
|
270
|
-
virtualDocument.positionAt(virtualOffset),
|
|
271
|
-
stylesheet
|
|
272
|
-
);
|
|
273
|
-
return this.#cache.updateCached(document, position, translateCompletionList(completions, position));
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
var CSSCompletionItemProvider = class {
|
|
277
|
-
#cssLanguageService = (0, import_vscode_css_languageservice3.getCSSLanguageService)();
|
|
278
|
-
#cache = new CompletionsCache();
|
|
279
|
-
provideCompletionItems(document, position) {
|
|
280
|
-
const cached = this.#cache.getCached(document, position);
|
|
281
|
-
if (cached) return cached;
|
|
282
|
-
const currentOffset = document.offsetAt(position);
|
|
283
|
-
const documentText = document.getText();
|
|
284
|
-
const match = matchOffset(CSS_REG, documentText, currentOffset);
|
|
285
|
-
if (!match) return;
|
|
286
|
-
const matchContent = match.groups.content;
|
|
287
|
-
const matchStartOffset = match.index + match.groups.start.length;
|
|
288
|
-
const virtualOffset = currentOffset - matchStartOffset;
|
|
289
|
-
const virtualDocument = createVirtualDocument("css", removeSlot(matchContent));
|
|
290
|
-
const vCss = this.#cssLanguageService.parseStylesheet(virtualDocument);
|
|
291
|
-
const completions = this.#cssLanguageService.doComplete(
|
|
292
|
-
virtualDocument,
|
|
293
|
-
virtualDocument.positionAt(virtualOffset),
|
|
294
|
-
vCss
|
|
295
|
-
);
|
|
296
|
-
return this.#cache.updateCached(document, position, translateCompletionList(completions, position));
|
|
297
|
-
}
|
|
298
|
-
};
|
|
135
|
+
// src/global.ts
|
|
136
|
+
var cssLanguageService = (0, import_vscode_css_languageservice.getCSSLanguageService)();
|
|
137
|
+
var htmlLanguageService = (0, import_vscode_html_languageservice.getLanguageService)();
|
|
138
|
+
var documents = new CSTDocs();
|
|
139
|
+
var cssCache = new import_cache2.Cache({ max: 1e3 });
|
|
140
|
+
var htmlCache = new import_cache2.Cache({ max: 1e3 });
|
|
299
141
|
|
|
300
|
-
// src/
|
|
301
|
-
var
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
142
|
+
// src/provider.ts
|
|
143
|
+
var Provider = class {
|
|
144
|
+
provideDocumentColors(document) {
|
|
145
|
+
return [
|
|
146
|
+
// NOTE: ignore `<style>`
|
|
147
|
+
...[...documents.getAllCSS(document), ...documents.getAllCSSFragment(document)].flatMap(
|
|
148
|
+
({ doc, startIndex, cssDoc }) => {
|
|
149
|
+
const colors = cssLanguageService.findDocumentColors(doc, cssDoc);
|
|
150
|
+
return colors.map((e) => ({
|
|
151
|
+
...e,
|
|
152
|
+
range: {
|
|
153
|
+
start: document.positionAt(startIndex + doc.offsetAt(e.range.start)),
|
|
154
|
+
end: document.positionAt(startIndex + doc.offsetAt(e.range.end))
|
|
155
|
+
}
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
...documents.getAllStyleValue(document).map(({ text, startIndex }) => {
|
|
160
|
+
const hex = import_css_color_keywords.default[text] || text;
|
|
161
|
+
if (!hex.startsWith("#")) return;
|
|
162
|
+
const [red, green, blue, alpha] = (0, import_color.parseHexColor)(hex);
|
|
163
|
+
const range = import_node.Range.create(document.positionAt(startIndex), document.positionAt(startIndex + hex.length));
|
|
164
|
+
const color = import_node.Color.create(red / 255, green / 255, blue / 255, alpha);
|
|
165
|
+
return { range, color };
|
|
166
|
+
}).filter(import_types.isNotNullish)
|
|
167
|
+
];
|
|
310
168
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const emmetConfig = await this.#connection.workspace.getConfiguration("emmet");
|
|
314
|
-
this.#emmetConfig = {
|
|
315
|
-
showExpandedAbbreviation: emmetConfig.showExpandedAbbreviation,
|
|
316
|
-
showAbbreviationSuggestions: emmetConfig.showAbbreviationSuggestions,
|
|
317
|
-
syntaxProfiles: emmetConfig.syntaxProfiles,
|
|
318
|
-
variables: emmetConfig.variables
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
return this.#emmetConfig;
|
|
169
|
+
provideColorPresentations({ red, green, blue, alpha }) {
|
|
170
|
+
return [{ label: (0, import_color.rgbToHexColor)([red * 255, green * 255, blue * 255, alpha]) }];
|
|
322
171
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const result = (0, import_emmet_helper.doComplete)(virtualDocument, pos, "html", emmetConfig);
|
|
342
|
-
if (result) {
|
|
343
|
-
emmetResults = {
|
|
344
|
-
...result,
|
|
345
|
-
items: result.items.map((item) => ({
|
|
346
|
-
...item,
|
|
347
|
-
command: {
|
|
348
|
-
title: "Emmet Expand Abbreviation",
|
|
349
|
-
command: "editor.emmet.action.expandAbbreviation"
|
|
350
|
-
}
|
|
351
|
-
}))
|
|
352
|
-
};
|
|
172
|
+
provideDocumentSymbols(document) {
|
|
173
|
+
return [
|
|
174
|
+
...documents.getAllCSS(document).map((e) => {
|
|
175
|
+
const symbols = cssLanguageService.findDocumentSymbols(e.doc, e.cssDoc);
|
|
176
|
+
return { ...e, symbols };
|
|
177
|
+
}),
|
|
178
|
+
...documents.getAllHTML(document).map((e) => {
|
|
179
|
+
const symbols = htmlLanguageService.findDocumentSymbols(e.doc, e.htmlDoc);
|
|
180
|
+
return { ...e, symbols };
|
|
181
|
+
})
|
|
182
|
+
].flatMap(
|
|
183
|
+
({ startIndex, symbols, doc }) => symbols.map((symbol) => ({
|
|
184
|
+
...symbol,
|
|
185
|
+
location: {
|
|
186
|
+
uri: document.uri,
|
|
187
|
+
range: {
|
|
188
|
+
start: document.positionAt(startIndex + doc.offsetAt(symbol.location.range.start)),
|
|
189
|
+
end: document.positionAt(startIndex + doc.offsetAt(symbol.location.range.end))
|
|
353
190
|
}
|
|
354
191
|
}
|
|
355
|
-
}
|
|
356
|
-
]);
|
|
357
|
-
const completions = this.#htmlLanguageService.doComplete(
|
|
358
|
-
virtualDocument,
|
|
359
|
-
virtualDocument.positionAt(virtualOffset),
|
|
360
|
-
vHtml
|
|
192
|
+
}))
|
|
361
193
|
);
|
|
362
|
-
if (emmetResults.items.length) {
|
|
363
|
-
completions.items.push(...emmetResults.items);
|
|
364
|
-
}
|
|
365
|
-
return this.#cache.updateCached(document, position, translateCompletionList(completions, position));
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
// src/style.ts
|
|
370
|
-
var import_vscode_css_languageservice4 = require("vscode-css-languageservice");
|
|
371
|
-
var StyleCompletionItemProvider = class {
|
|
372
|
-
#cssLanguageService = (0, import_vscode_css_languageservice4.getCSSLanguageService)();
|
|
373
|
-
#cache = new CompletionsCache();
|
|
374
|
-
provideCompletionItems(document, position) {
|
|
375
|
-
const cached = this.#cache.getCached(document, position);
|
|
376
|
-
if (cached) return cached;
|
|
377
|
-
const currentOffset = document.offsetAt(position);
|
|
378
|
-
const documentText = document.getText();
|
|
379
|
-
const match = matchOffset(STYLE_REG, documentText, currentOffset);
|
|
380
|
-
if (!match) return;
|
|
381
|
-
const matchContent = match.groups.content;
|
|
382
|
-
const matchStartOffset = match.index + match.groups.start.length;
|
|
383
|
-
const virtualOffset = currentOffset - matchStartOffset + 8;
|
|
384
|
-
const virtualDocument = createVirtualDocument("css", `:host { ${removeSlot(matchContent)} }`);
|
|
385
|
-
const vCss = this.#cssLanguageService.parseStylesheet(virtualDocument);
|
|
386
|
-
const completions = this.#cssLanguageService.doComplete(
|
|
387
|
-
virtualDocument,
|
|
388
|
-
virtualDocument.positionAt(virtualOffset),
|
|
389
|
-
vCss
|
|
390
|
-
);
|
|
391
|
-
return this.#cache.updateCached(document, position, translateCompletionList(completions, position));
|
|
392
194
|
}
|
|
393
195
|
};
|
|
394
196
|
|
|
395
197
|
// src/index.ts
|
|
396
|
-
var connection = (0,
|
|
397
|
-
var
|
|
398
|
-
|
|
399
|
-
var hasWorkspaceFolderCapability = false;
|
|
400
|
-
var hasDiagnosticRelatedInformationCapability = false;
|
|
401
|
-
connection.onInitialize(({ capabilities }) => {
|
|
402
|
-
hasConfigurationCapability = !!capabilities.workspace?.configuration;
|
|
403
|
-
hasWorkspaceFolderCapability = !!capabilities.workspace?.workspaceFolders;
|
|
404
|
-
hasDiagnosticRelatedInformationCapability = !!capabilities.textDocument?.publishDiagnostics?.relatedInformation;
|
|
198
|
+
var connection = (0, import_node2.createConnection)(import_node2.ProposedFeatures.all);
|
|
199
|
+
var documents2 = new import_node2.TextDocuments(import_vscode_languageserver_textdocument2.TextDocument);
|
|
200
|
+
connection.onInitialize(() => {
|
|
405
201
|
return {
|
|
406
202
|
capabilities: {
|
|
407
|
-
completionProvider: {
|
|
408
|
-
resolveProvider: true,
|
|
409
|
-
triggerCharacters: ["!", ".", "}", ":", "*", "$", "]", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<"]
|
|
410
|
-
},
|
|
411
|
-
hoverProvider: true,
|
|
412
203
|
colorProvider: true,
|
|
413
|
-
|
|
414
|
-
workspace: !hasWorkspaceFolderCapability ? void 0 : { workspaceFolders: { supported: true } }
|
|
204
|
+
documentSymbolProvider: true
|
|
415
205
|
}
|
|
416
206
|
};
|
|
417
207
|
});
|
|
418
|
-
|
|
419
|
-
if (hasConfigurationCapability) {
|
|
420
|
-
connection.client.register(import_node4.DidChangeConfigurationNotification.type, void 0);
|
|
421
|
-
}
|
|
422
|
-
if (hasWorkspaceFolderCapability) {
|
|
423
|
-
connection.workspace.onDidChangeWorkspaceFolders((_event) => {
|
|
424
|
-
connection.console.log("Workspace folder change event received.");
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
});
|
|
428
|
-
var defaultSettings = { maxNumberOfProblems: 1e3 };
|
|
429
|
-
var globalSettings = defaultSettings;
|
|
430
|
-
var documentSettings = /* @__PURE__ */ new Map();
|
|
431
|
-
connection.onDidChangeConfiguration((change) => {
|
|
432
|
-
if (hasConfigurationCapability) {
|
|
433
|
-
documentSettings.clear();
|
|
434
|
-
} else {
|
|
435
|
-
globalSettings = change.settings.languageServerGem || defaultSettings;
|
|
436
|
-
}
|
|
437
|
-
documents.all().forEach(validateTextDocument);
|
|
438
|
-
});
|
|
439
|
-
documents.onDidClose((e) => documentSettings.delete(e.document.uri));
|
|
440
|
-
documents.onDidChangeContent((change) => validateTextDocument(change.document));
|
|
441
|
-
var validateTextDocument = (0, import_timer.debounce)((textDocument) => {
|
|
442
|
-
connection.sendDiagnostics({
|
|
443
|
-
uri: textDocument.uri,
|
|
444
|
-
diagnostics: getDiagnostics(textDocument, hasDiagnosticRelatedInformationCapability)
|
|
445
|
-
});
|
|
446
|
-
});
|
|
447
|
-
connection.onDidChangeWatchedFiles((_change) => {
|
|
448
|
-
connection.console.log("We received a file change event");
|
|
449
|
-
});
|
|
450
|
-
var completionItemProviders = [
|
|
451
|
-
new CSSCompletionItemProvider(),
|
|
452
|
-
new HTMLStyleCompletionItemProvider(),
|
|
453
|
-
new HTMLCompletionItemProvider(connection),
|
|
454
|
-
new StyleCompletionItemProvider()
|
|
455
|
-
];
|
|
456
|
-
connection.onCompletion(async ({ textDocument, position }) => {
|
|
457
|
-
for (const provider of completionItemProviders) {
|
|
458
|
-
const result = await provider.provideCompletionItems(documents.get(textDocument.uri), position);
|
|
459
|
-
if (result) return { isIncomplete: true, items: result.items };
|
|
460
|
-
}
|
|
461
|
-
});
|
|
462
|
-
connection.onCompletionResolve((item) => item);
|
|
463
|
-
var colorProvider = new ColorProvider();
|
|
208
|
+
var provider = new Provider();
|
|
464
209
|
connection.onColorPresentation(({ color }) => {
|
|
465
|
-
return
|
|
210
|
+
return provider.provideColorPresentations(color);
|
|
466
211
|
});
|
|
467
212
|
connection.onDocumentColor(({ textDocument }) => {
|
|
468
|
-
return
|
|
213
|
+
return provider.provideDocumentColors(documents2.get(textDocument.uri));
|
|
469
214
|
});
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
for (const provider of hoverProviders) {
|
|
473
|
-
const result = provider.provideHover(documents.get(textDocument.uri), position);
|
|
474
|
-
if (result) return result;
|
|
475
|
-
}
|
|
215
|
+
connection.onDocumentSymbol(({ textDocument }) => {
|
|
216
|
+
return provider.provideDocumentSymbols(documents2.get(textDocument.uri));
|
|
476
217
|
});
|
|
477
|
-
|
|
218
|
+
documents2.listen(connection);
|
|
478
219
|
connection.listen();
|
|
479
220
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport type { InitializeParams } from 'vscode-languageserver/node';\nimport {\n createConnection,\n TextDocuments,\n ProposedFeatures,\n DidChangeConfigurationNotification,\n TextDocumentSyncKind,\n} from 'vscode-languageserver/node';\nimport { TextDocument } from 'vscode-languageserver-textdocument';\nimport { debounce } from 'duoyun-ui/lib/timer';\n\nimport { ColorProvider } from './color';\nimport { getDiagnostics } from './diagnostic';\nimport { CSSHoverProvider, HTMLHoverProvider, StyleHoverProvider } from './hover';\nimport { CSSCompletionItemProvider, HTMLStyleCompletionItemProvider } from './css';\nimport { HTMLCompletionItemProvider } from './html';\nimport { StyleCompletionItemProvider } from './style';\n\nconst connection = createConnection(ProposedFeatures.all);\nconst documents = new TextDocuments(TextDocument);\n\nlet hasConfigurationCapability = false;\nlet hasWorkspaceFolderCapability = false;\nlet hasDiagnosticRelatedInformationCapability = false;\n\nconnection.onInitialize(({ capabilities }: InitializeParams) => {\n hasConfigurationCapability = !!capabilities.workspace?.configuration;\n hasWorkspaceFolderCapability = !!capabilities.workspace?.workspaceFolders;\n hasDiagnosticRelatedInformationCapability = !!capabilities.textDocument?.publishDiagnostics?.relatedInformation;\n return {\n capabilities: {\n completionProvider: {\n resolveProvider: true,\n triggerCharacters: ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '<'],\n },\n hoverProvider: true,\n colorProvider: true,\n textDocumentSync: TextDocumentSyncKind.Incremental,\n workspace: !hasWorkspaceFolderCapability ? undefined : { workspaceFolders: { supported: true } },\n },\n };\n});\n\nconnection.onInitialized(() => {\n if (hasConfigurationCapability) {\n connection.client.register(DidChangeConfigurationNotification.type, undefined);\n }\n if (hasWorkspaceFolderCapability) {\n connection.workspace.onDidChangeWorkspaceFolders((_event) => {\n connection.console.log('Workspace folder change event received.');\n });\n }\n});\n\ninterface ExampleSettings {\n maxNumberOfProblems: number;\n}\n\nconst defaultSettings: ExampleSettings = { maxNumberOfProblems: 1000 };\n\nlet globalSettings: ExampleSettings = defaultSettings;\nconst documentSettings: Map<string, Thenable<ExampleSettings>> = new Map();\n\nconnection.onDidChangeConfiguration((change) => {\n if (hasConfigurationCapability) {\n documentSettings.clear();\n } else {\n globalSettings = <ExampleSettings>(change.settings.languageServerGem || defaultSettings);\n }\n documents.all().forEach(validateTextDocument);\n});\n\nfunction _getDocumentSettings(resource: string) {\n if (!hasConfigurationCapability) return globalSettings;\n if (!documentSettings.has(resource)) {\n const settings = connection.workspace.getConfiguration({ scopeUri: resource, section: 'languageServerGem' });\n documentSettings.set(resource, settings);\n }\n return documentSettings.get(resource)!;\n}\n\ndocuments.onDidClose((e) => documentSettings.delete(e.document.uri));\n\ndocuments.onDidChangeContent((change) => validateTextDocument(change.document));\n\nconst validateTextDocument = debounce((textDocument: TextDocument) => {\n connection.sendDiagnostics({\n uri: textDocument.uri,\n diagnostics: getDiagnostics(textDocument, hasDiagnosticRelatedInformationCapability),\n });\n});\n\nconnection.onDidChangeWatchedFiles((_change) => {\n connection.console.log('We received a file change event');\n});\n\nconst completionItemProviders = [\n new CSSCompletionItemProvider(),\n new HTMLStyleCompletionItemProvider(),\n new HTMLCompletionItemProvider(connection),\n new StyleCompletionItemProvider(),\n];\nconnection.onCompletion(async ({ textDocument, position }) => {\n for (const provider of completionItemProviders) {\n const result = await provider.provideCompletionItems(documents.get(textDocument.uri)!, position);\n if (result) return { isIncomplete: true, items: result.items };\n }\n});\n\nconnection.onCompletionResolve((item) => item);\n\nconst colorProvider = new ColorProvider();\nconnection.onColorPresentation(({ color }) => {\n return colorProvider.provideColorPresentations(color);\n});\n\nconnection.onDocumentColor(({ textDocument }) => {\n return colorProvider.provideDocumentColors(documents.get(textDocument.uri)!);\n});\n\nconst hoverProviders = [new CSSHoverProvider(), new StyleHoverProvider(), new HTMLHoverProvider()];\nconnection.onHover(({ textDocument, position }) => {\n for (const provider of hoverProviders) {\n const result = provider.provideHover(documents.get(textDocument.uri)!, position);\n if (result) return result;\n }\n});\n\ndocuments.listen(connection);\nconnection.listen();\n", "import { rgbToHexColor, parseHexColor } from 'duoyun-ui/lib/color';\nimport { Range, Color } from 'vscode-languageserver/node';\nimport type { ColorInformation, ColorPresentation } from 'vscode-languageserver/node';\nimport type { HexColor } from 'duoyun-ui/lib/color';\nimport type { TextDocument } from 'vscode-languageserver-textdocument';\n\nimport { COLOR_REG } from './constants';\n\nexport class ColorProvider {\n provideDocumentColors(document: TextDocument) {\n COLOR_REG.exec('null');\n\n const documentText = document.getText();\n const colors: ColorInformation[] = [];\n\n let match: RegExpExecArray | null;\n while ((match = COLOR_REG.exec(documentText)) !== null) {\n const hex = match.groups!.content as HexColor;\n const [red, green, blue, alpha] = parseHexColor(hex);\n const offset = match.index + (match.groups!.start?.length || 0);\n const range = Range.create(document.positionAt(offset), document.positionAt(offset + hex.length));\n const color = Color.create(red / 255, green / 255, blue / 255, alpha);\n colors.push({ range, color });\n }\n return colors;\n }\n\n provideColorPresentations({ red, green, blue, alpha }: Color): ColorPresentation[] {\n return [{ label: rgbToHexColor([red * 255, green * 255, blue * 255, alpha]) }];\n }\n}\n", "export const COLOR_REG = /(?<start>'|\")?(?<content>#([0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4}))($1|\\s*;|\\s*\\))/g;\n\n// \u76F4\u63A5\u901A\u8FC7\u6B63\u5219\u5339\u914D css \u7247\u6BB5\uFF0C\u901A\u8FC7\u6761\u4EF6\u7684\u7ED3\u675F ` \u53F7\u5339\u914D\nexport const CSS_REG = /(?<start>\\/\\*\\s*css\\s*\\*\\/\\s*`|(?<!`)(?:css|less|scss)\\s*`)(?<content>.*?)(`(?=;|,?\\s*\\)))/gs;\n// \u76F4\u63A5\u901A\u8FC7\u6B63\u5219\u5339\u914D style \u7247\u6BB5\uFF0C\u901A\u8FC7\u6761\u4EF6\u7684\u7ED3\u675F ` \u53F7\u5339\u914D\n// \u8BED\u8A00\u670D\u52A1\u548C\u9AD8\u4EAE\u90FD\u53EA\u652F\u6301 styled \u5199\u6CD5\nexport const STYLE_REG = /(?<start>\\/\\*\\s*style\\s*\\*\\/\\s*`|(?<!`)styled?\\s*`)(?<content>.*?)(`(?=,|\\s*}\\s*\\)))/gs;\n\n// \u5904\u7406\u540E\u8FDB\u884C\u6B63\u5219\u5339\u914D\uFF0C\u6240\u4EE5\u4E0D\u9700\u8981\u9A8C\u8BC1\u540E\u9762\u7684 ` \u53F7\nexport const HTML_REG = /(?<start>\\/\\*\\s*html\\s*\\*\\/\\s*`|(?<!`)(?:html|raw)\\s*`)(?<content>[^`]*)(`)/g;\n", "// \u53EA\u5BF9 CSS \u8BED\u6CD5\u548C\u5C5E\u6027\u505A\u4E86\u7B80\u5355\u7684\u68C0\u67E5\uFF0C\u4E0D\u505A\u503C\u68C0\u67E5\n// TODO: \u6FC0\u6D3B\u6269\u5C55\u3001\u6253\u5F00\u5DE5\u4F5C\u533A\u65F6\u9700\u8981\u81EA\u52A8\u8BCA\u65AD\u6240\u6709\u6587\u4EF6\n// TODO: \u4F7F\u7528 LRU \u7F13\u5B58\n\nimport { getCSSLanguageService } from 'vscode-css-languageservice';\nimport { Range } from 'vscode-languageserver/node';\nimport type { Diagnostic } from 'vscode-languageserver/node';\nimport type { TextDocument } from 'vscode-languageserver-textdocument';\n\nimport { CSS_REG, STYLE_REG } from './constants';\nimport { createVirtualDocument, removeSlot } from './util';\n\nconst cssLanguageService = getCSSLanguageService();\n\nexport function getDiagnostics(document: TextDocument, _relatedInformation: boolean) {\n const diagnostics: Diagnostic[] = [];\n const text = document.getText();\n\n const matchFragments = (regexp: RegExp, appendBefore: string, appendAfter: string) => {\n regexp.exec('null');\n\n let match;\n while ((match = regexp.exec(text))) {\n const matchContent = match.groups!.content;\n const offset = match.index + match.groups!.start.length;\n const virtualDocument = createVirtualDocument('css', `${appendBefore}${removeSlot(matchContent)}${appendAfter}`);\n const vCss = cssLanguageService.parseStylesheet(virtualDocument);\n const oDiagnostics = cssLanguageService.doValidation(virtualDocument, vCss) as Diagnostic[];\n for (const { message, range } of oDiagnostics) {\n const { start, end } = range;\n const startOffset = virtualDocument.offsetAt(start) - appendBefore.length + offset;\n const endOffset = virtualDocument.offsetAt(end) - appendBefore.length + offset;\n diagnostics.push({\n range: Range.create(document.positionAt(startOffset), document.positionAt(endOffset)),\n message,\n });\n }\n }\n };\n\n matchFragments(CSS_REG, '', '');\n matchFragments(STYLE_REG, ':host { ', ' }');\n\n return diagnostics;\n}\n", "import { TextDocument } from 'vscode-html-languageservice';\nimport { Position, Range } from 'vscode-languageserver/node';\nimport type { CompletionItem } from 'vscode-languageserver/node';\n\nexport function removeSlot(text: string) {\n const v = text.replace(/\\$\\{[^${]*?\\}/g, (str) => str.replaceAll(/[^\\n]/g, 'x'));\n if (v === text) return v;\n return removeSlot(v);\n}\n\nexport function removeHTMLSlot(text: string, position: number) {\n const left = text.slice(0, position);\n const right = text.slice(position);\n const left1 = removeSlot(left);\n // \u5904\u7406\u5728\u63D2\u69FD\u4E2D\u7684\u60C5\u51B5\uFF0C\u53EA\u4FDD\u7559\u5149\u6807\u9644\u4EF6\u7684 html \u6807\u7B7E\n const left2 = left1.replace(/(.*(?=html`))/s, (str) => str.replaceAll(/[^\\n]/g, ' '));\n return left2 + removeSlot(right);\n}\n\nexport function translateCompletionList(result: any, position: Position) {\n const getRange = (item: CompletionItem): Range | undefined => {\n if (item.textEdit && 'range' in item.textEdit) {\n const { start, end } = item.textEdit.range;\n return Range.create(\n Position.create(position.line, start.character),\n Position.create(position.line, end.character),\n );\n }\n };\n\n return {\n ...result,\n items: result?.items.map((item: CompletionItem) => ({\n ...item,\n textEdit: item.textEdit && {\n ...item.textEdit,\n range: getRange(item),\n },\n })),\n };\n}\nexport function matchOffset(regex: RegExp, docText: string, offset: number) {\n regex.exec('null');\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(docText)) !== null) {\n const [fullStr, startStr] = match;\n const start = match.index + startStr.length;\n const end = match.index + fullStr.length;\n if (offset > start && offset < end) {\n return match;\n }\n }\n return null;\n}\n\nexport function createVirtualDocument(languageId: string, content: string) {\n return TextDocument.create(`embedded://document.${languageId}`, languageId, 1, content);\n}\n", "import { getLanguageService as getHtmlLanguageService } from 'vscode-html-languageservice';\nimport { getCSSLanguageService } from 'vscode-css-languageservice';\nimport type { LanguageService as CssLanguageService } from 'vscode-css-languageservice';\nimport type { Position, TextDocument } from 'vscode-languageserver-textdocument';\n\nimport { createVirtualDocument, matchOffset, removeHTMLSlot, removeSlot } from './util';\nimport { CSS_REG, HTML_REG, STYLE_REG } from './constants';\n\nexport class HTMLHoverProvider {\n #htmlLanguageService = getHtmlLanguageService();\n\n provideHover(document: TextDocument, position: Position) {\n const currentOffset = document.offsetAt(position);\n const documentText = removeHTMLSlot(document.getText(), currentOffset);\n const match = matchOffset(HTML_REG, documentText, currentOffset);\n\n if (!match) return null;\n\n const matchContent = match.groups!.content;\n const matchStartOffset = match.index + match.groups!.start.length;\n const virtualOffset = currentOffset - matchStartOffset;\n const virtualDocument = createVirtualDocument('html', matchContent);\n const html = this.#htmlLanguageService.parseHTMLDocument(virtualDocument);\n return this.#htmlLanguageService.doHover(virtualDocument, virtualDocument.positionAt(virtualOffset), html, {\n documentation: true,\n references: true,\n });\n }\n}\n\nexport class CSSHoverProvider {\n #cssLanguageService: CssLanguageService = getCSSLanguageService();\n\n provideHover(document: TextDocument, position: Position) {\n const currentOffset = document.offsetAt(position);\n const documentText = document.getText();\n const match = matchOffset(CSS_REG, documentText, currentOffset);\n\n if (!match) return null;\n\n const matchContent = match.groups!.content;\n const matchStartOffset = match.index + match.groups!.start.length;\n const virtualOffset = currentOffset - matchStartOffset;\n const virtualDocument = createVirtualDocument('css', removeSlot(matchContent));\n const stylesheet = this.#cssLanguageService.parseStylesheet(virtualDocument);\n return this.#cssLanguageService.doHover(virtualDocument, virtualDocument.positionAt(virtualOffset), stylesheet, {\n documentation: true,\n references: true,\n });\n }\n}\n\nexport class StyleHoverProvider {\n #cssLanguageService: CssLanguageService = getCSSLanguageService();\n\n provideHover(document: TextDocument, position: Position) {\n const currentOffset = document.offsetAt(position);\n const documentText = document.getText();\n const match = matchOffset(STYLE_REG, documentText, currentOffset);\n\n if (!match) return null;\n\n const matchContent = match.groups!.content;\n const matchStartOffset = match.index + match.groups!.start.length;\n const virtualOffset = currentOffset - matchStartOffset + 8;\n const virtualDocument = createVirtualDocument('css', `:host { ${removeSlot(matchContent)} }`);\n const stylesheet = this.#cssLanguageService.parseStylesheet(virtualDocument);\n return this.#cssLanguageService.doHover(virtualDocument, virtualDocument.positionAt(virtualOffset), stylesheet, {\n documentation: true,\n references: true,\n });\n }\n}\n", "import type { LanguageService as HTMLanguageService } from 'vscode-html-languageservice';\nimport type { Position, TextDocument } from 'vscode-languageserver-textdocument';\nimport { getLanguageService as getHTMLanguageService, TokenType as HTMLTokenType } from 'vscode-html-languageservice';\nimport { getCSSLanguageService } from 'vscode-css-languageservice';\n\nimport { matchOffset, createVirtualDocument, removeSlot, translateCompletionList } from './util';\nimport { CSS_REG, HTML_REG } from './constants';\nimport { CompletionsCache } from './cache';\n\nfunction getRegionAtOffset(regions: IEmbeddedRegion[], offset: number) {\n for (const region of regions) {\n if (region.start <= offset) {\n if (offset <= region.end) {\n return region;\n }\n } else {\n break;\n }\n }\n return null;\n}\n\ninterface IEmbeddedRegion {\n languageId: string;\n start: number;\n end: number;\n length: number;\n content: string;\n}\n\nfunction getLanguageRegions(service: HTMLanguageService, data: string) {\n const scanner = service.createScanner(data);\n const regions: IEmbeddedRegion[] = [];\n let tokenType: HTMLTokenType;\n\n while ((tokenType = scanner.scan()) !== HTMLTokenType.EOS) {\n switch (tokenType) {\n case HTMLTokenType.Styles:\n regions.push({\n languageId: 'css',\n start: scanner.getTokenOffset(),\n end: scanner.getTokenEnd(),\n length: scanner.getTokenLength(),\n content: scanner.getTokenText(),\n });\n break;\n default:\n break;\n }\n }\n\n return regions;\n}\n\nexport class HTMLStyleCompletionItemProvider {\n #cssLanguageService = getCSSLanguageService();\n #htmlLanguageService = getHTMLanguageService();\n #cache = new CompletionsCache();\n\n provideCompletionItems(document: TextDocument, position: Position) {\n const cached = this.#cache.getCached(document, position);\n if (cached) return cached;\n\n const currentOffset = document.offsetAt(position);\n const documentText = document.getText();\n const match = matchOffset(HTML_REG, documentText, currentOffset);\n\n if (!match) return;\n\n const matchContent = match.groups!.content;\n const matchStartOffset = match.index + match.groups!.start.length;\n const regions = getLanguageRegions(this.#htmlLanguageService, matchContent);\n\n if (regions.length <= 0) return;\n\n const region = getRegionAtOffset(regions, currentOffset - matchStartOffset);\n\n if (!region) return;\n\n const virtualOffset = currentOffset - (matchStartOffset + region.start);\n const virtualDocument = createVirtualDocument('css', removeSlot(region.content));\n const stylesheet = this.#cssLanguageService.parseStylesheet(virtualDocument);\n\n const completions = this.#cssLanguageService.doComplete(\n virtualDocument,\n virtualDocument.positionAt(virtualOffset),\n stylesheet,\n );\n\n return this.#cache.updateCached(document, position, translateCompletionList(completions, position));\n }\n}\n\nexport class CSSCompletionItemProvider {\n #cssLanguageService = getCSSLanguageService();\n #cache = new CompletionsCache();\n\n provideCompletionItems(document: TextDocument, position: Position) {\n const cached = this.#cache.getCached(document, position);\n if (cached) return cached;\n\n const currentOffset = document.offsetAt(position);\n const documentText = document.getText();\n const match = matchOffset(CSS_REG, documentText, currentOffset);\n\n if (!match) return;\n\n const matchContent = match.groups!.content;\n const matchStartOffset = match.index + match.groups!.start.length;\n const virtualOffset = currentOffset - matchStartOffset;\n const virtualDocument = createVirtualDocument('css', removeSlot(matchContent));\n const vCss = this.#cssLanguageService.parseStylesheet(virtualDocument);\n\n const completions = this.#cssLanguageService.doComplete(\n virtualDocument,\n virtualDocument.positionAt(virtualOffset),\n vCss,\n );\n\n return this.#cache.updateCached(document, position, translateCompletionList(completions, position));\n }\n}\n", "import type { CompletionList } from 'vscode-languageserver';\nimport type { Position, TextDocument } from 'vscode-languageserver-textdocument';\n\nexport class CompletionsCache {\n #cachedCompletionsFile?: string;\n #cachedCompletionsPosition?: Position;\n #cachedCompletionsContent?: string;\n #completions?: CompletionList;\n\n #equalPositions(left: Position, right?: Position) {\n return !!right && left.line === right.line && left.character === right.character;\n }\n\n getCached(doc: TextDocument, position: Position) {\n if (\n this.#completions &&\n doc.uri === this.#cachedCompletionsFile &&\n this.#equalPositions(position, this.#cachedCompletionsPosition) &&\n doc.getText() === this.#cachedCompletionsContent\n ) {\n return this.#completions;\n }\n\n return undefined;\n }\n\n updateCached(context: TextDocument, position: Position, completions: CompletionList) {\n this.#cachedCompletionsFile = context.uri;\n this.#cachedCompletionsPosition = position;\n this.#cachedCompletionsContent = context.getText();\n this.#completions = completions;\n return completions;\n }\n}\n", "import type { CompletionList as HTMLCompletionList } from 'vscode-html-languageservice';\nimport { getLanguageService as getHTMLanguageService } from 'vscode-html-languageservice';\nimport { doComplete as doEmmetComplete, type VSCodeEmmetConfig } from '@vscode/emmet-helper';\nimport type { Position, TextDocument } from 'vscode-languageserver-textdocument';\nimport type { Connection } from 'vscode-languageserver';\n\nimport { matchOffset, createVirtualDocument, removeHTMLSlot, translateCompletionList } from './util';\nimport { HTML_REG } from './constants';\nimport { CompletionsCache } from './cache';\n\nexport class HTMLCompletionItemProvider {\n #htmlLanguageService = getHTMLanguageService();\n #cache = new CompletionsCache();\n #connection: Connection;\n #emmetConfig: VSCodeEmmetConfig;\n\n constructor(connection: Connection) {\n this.#connection = connection;\n }\n\n async #getEmmetConfig() {\n if (!this.#emmetConfig) {\n const emmetConfig = await this.#connection.workspace.getConfiguration('emmet');\n this.#emmetConfig = {\n showExpandedAbbreviation: emmetConfig.showExpandedAbbreviation,\n showAbbreviationSuggestions: emmetConfig.showAbbreviationSuggestions,\n syntaxProfiles: emmetConfig.syntaxProfiles,\n variables: emmetConfig.variables,\n };\n }\n return this.#emmetConfig;\n }\n\n async provideCompletionItems(document: TextDocument, position: Position) {\n const emmetConfig = await this.#getEmmetConfig();\n const cached = this.#cache.getCached(document, position);\n if (cached) return cached;\n\n const currentOffset = document.offsetAt(position);\n const documentText = removeHTMLSlot(document.getText(), currentOffset);\n const match = matchOffset(HTML_REG, documentText, currentOffset);\n\n if (!match) return;\n\n const matchContent = match.groups!.content;\n const matchStartOffset = match.index + match.groups!.start.length;\n const virtualOffset = currentOffset - matchStartOffset;\n const virtualDocument = createVirtualDocument('html', matchContent);\n const vHtml = this.#htmlLanguageService.parseHTMLDocument(virtualDocument);\n\n let emmetResults: HTMLCompletionList = { isIncomplete: true, items: [] };\n this.#htmlLanguageService.setCompletionParticipants([\n {\n onHtmlContent: async () => {\n const pos = virtualDocument.positionAt(virtualOffset);\n const result = doEmmetComplete(virtualDocument, pos, 'html', emmetConfig);\n if (result) {\n emmetResults = {\n ...result,\n items: result.items.map((item) => ({\n ...item,\n command: {\n title: 'Emmet Expand Abbreviation',\n command: 'editor.emmet.action.expandAbbreviation',\n },\n })),\n };\n }\n },\n },\n ]);\n\n const completions = this.#htmlLanguageService.doComplete(\n virtualDocument,\n virtualDocument.positionAt(virtualOffset),\n vHtml,\n );\n\n if (emmetResults.items.length) {\n completions.items.push(...emmetResults.items);\n }\n\n return this.#cache.updateCached(document, position, translateCompletionList(completions, position));\n }\n}\n", "import { getCSSLanguageService as getCSSLanguageService } from 'vscode-css-languageservice';\nimport type { Position, TextDocument } from 'vscode-languageserver-textdocument';\n\nimport { matchOffset, createVirtualDocument, removeSlot, translateCompletionList } from './util';\nimport { STYLE_REG } from './constants';\nimport { CompletionsCache } from './cache';\n\nexport class StyleCompletionItemProvider {\n #cssLanguageService = getCSSLanguageService();\n #cache = new CompletionsCache();\n\n provideCompletionItems(document: TextDocument, position: Position) {\n const cached = this.#cache.getCached(document, position);\n if (cached) return cached;\n\n const currentOffset = document.offsetAt(position);\n const documentText = document.getText();\n const match = matchOffset(STYLE_REG, documentText, currentOffset);\n\n if (!match) return;\n\n const matchContent = match.groups!.content;\n const matchStartOffset = match.index + match.groups!.start.length;\n const virtualOffset = currentOffset - matchStartOffset + 8; // accounting for :host { }\n const virtualDocument = createVirtualDocument('css', `:host { ${removeSlot(matchContent)} }`);\n const vCss = this.#cssLanguageService.parseStylesheet(virtualDocument);\n\n const completions = this.#cssLanguageService.doComplete(\n virtualDocument,\n virtualDocument.positionAt(virtualOffset),\n vCss,\n );\n\n return this.#cache.updateCached(document, position, translateCompletionList(completions, position));\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["
|
|
3
|
+
"sources": ["../src/index.ts", "../src/provider.ts", "../src/global.ts", "../src/documents.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\n// biome-ignore assist/source/organizeImports: export/path\nimport { TextDocument } from 'vscode-languageserver-textdocument';\nimport { createConnection, ProposedFeatures, TextDocuments } from 'vscode-languageserver/node';\n\nimport { Provider } from './provider';\n\nconst connection = createConnection(ProposedFeatures.all);\nconst documents = new TextDocuments(TextDocument);\n\nconnection.onInitialize(() => {\n return {\n capabilities: {\n colorProvider: true,\n documentSymbolProvider: true,\n },\n };\n});\n\nconst provider = new Provider();\n\nconnection.onColorPresentation(({ color }) => {\n return provider.provideColorPresentations(color);\n});\n\nconnection.onDocumentColor(({ textDocument }) => {\n return provider.provideDocumentColors(documents.get(textDocument.uri)!);\n});\n\nconnection.onDocumentSymbol(({ textDocument }) => {\n return provider.provideDocumentSymbols(documents.get(textDocument.uri)!);\n});\n\ndocuments.listen(connection);\nconnection.listen();\n", "// biome-ignore assist/source/organizeImports: export/path\nimport cssColors from 'css-color-keywords';\nimport type { HexColor } from 'duoyun-ui/lib/color';\nimport { parseHexColor, rgbToHexColor } from 'duoyun-ui/lib/color';\nimport { isNotNullish } from 'duoyun-ui/lib/types';\nimport type { TextDocument } from 'vscode-languageserver-textdocument';\nimport type { ColorInformation, ColorPresentation, SymbolInformation } from 'vscode-languageserver/node';\nimport { Color, Range } from 'vscode-languageserver/node';\nimport { cssLanguageService, documents, htmlLanguageService } from './global';\n\nexport class Provider {\n provideDocumentColors(document: TextDocument): ColorInformation[] {\n return [\n // NOTE: ignore `<style>`\n ...[...documents.getAllCSS(document), ...documents.getAllCSSFragment(document)].flatMap(\n ({ doc, startIndex, cssDoc }) => {\n const colors = cssLanguageService.findDocumentColors(doc, cssDoc);\n return colors.map((e) => ({\n ...e,\n range: {\n start: document.positionAt(startIndex + doc.offsetAt(e.range.start)),\n end: document.positionAt(startIndex + doc.offsetAt(e.range.end)),\n },\n }));\n },\n ),\n ...documents\n .getAllStyleValue(document)\n .map(({ text, startIndex }) => {\n const hex = (cssColors[text] || text) as HexColor;\n if (!hex.startsWith('#')) return;\n const [red, green, blue, alpha] = parseHexColor(hex);\n const range = Range.create(document.positionAt(startIndex), document.positionAt(startIndex + hex.length));\n const color = Color.create(red / 255, green / 255, blue / 255, alpha);\n return { range, color };\n })\n .filter(isNotNullish),\n ];\n }\n\n provideColorPresentations({ red, green, blue, alpha }: Color): ColorPresentation[] {\n return [{ label: rgbToHexColor([red * 255, green * 255, blue * 255, alpha]) }];\n }\n\n provideDocumentSymbols(document: TextDocument): SymbolInformation[] {\n return [\n ...documents.getAllCSS(document).map((e) => {\n const symbols = cssLanguageService.findDocumentSymbols(e.doc, e.cssDoc);\n return { ...e, symbols };\n }),\n ...documents.getAllHTML(document).map((e) => {\n const symbols = htmlLanguageService.findDocumentSymbols(e.doc, e.htmlDoc);\n return { ...e, symbols };\n }),\n ].flatMap(({ startIndex, symbols, doc }) =>\n symbols.map((symbol) => ({\n ...symbol,\n location: {\n uri: document.uri,\n range: {\n start: document.positionAt(startIndex + doc.offsetAt(symbol.location.range.start)),\n end: document.positionAt(startIndex + doc.offsetAt(symbol.location.range.end)),\n },\n },\n })),\n );\n }\n}\n", "import { getCSSLanguageService, type Stylesheet } from '@mantou/vscode-css-languageservice';\nimport { getLanguageService as getHTMLanguageService, type HTMLDocument } from '@mantou/vscode-html-languageservice';\nimport { Cache } from 'duoyun-ui/lib/cache';\n\nimport { CSTDocs } from './documents';\n\nexport const cssLanguageService = getCSSLanguageService();\nexport const htmlLanguageService = getHTMLanguageService();\nexport const documents = new CSTDocs();\nexport const cssCache = new Cache<Stylesheet>({ max: 1000 });\nexport const htmlCache = new Cache<HTMLDocument>({ max: 1000 });\n", "import type { Stylesheet } from '@mantou/vscode-css-languageservice';\nimport type { HTMLDocument } from '@mantou/vscode-html-languageservice';\nimport { Cache } from 'duoyun-ui/lib/cache';\nimport Parser from 'tree-sitter';\nimport tsTypescript from 'tree-sitter-typescript';\nimport { TextDocument } from 'vscode-languageserver-textdocument';\n\nimport { cssLanguageService, htmlLanguageService } from './global';\n\nconst language = tsTypescript.typescript as Parser.Language;\n\nfunction processTemplate({ children }: Parser.SyntaxNode) {\n return {\n startIndex: children[1].startIndex,\n text: children\n .slice(1, -1)\n .reduce((p, c) => p + (c.type === 'template_substitution' ? c.text.replaceAll(/./g, '_') : c.text), ''),\n };\n}\n\nexport class CSTDocs extends WeakMap<TextDocument, Parser.Tree> {\n #cssCache = new Cache<Stylesheet>({ max: 1000 });\n #htmlCache = new Cache<HTMLDocument>({ max: 1000 });\n\n getTypeScriptCST(textDocument: TextDocument) {\n const parser = new Parser();\n parser.setLanguage(language);\n\n const oldTree = this.get(textDocument);\n if (oldTree?.getText(oldTree.rootNode) === textDocument.getText()) return oldTree;\n\n const newTree = parser.parse(textDocument.getText());\n this.set(textDocument, newTree);\n\n return newTree;\n }\n\n getAllTemplate(textDocument: TextDocument, tag: string) {\n const tree = this.getTypeScriptCST(textDocument);\n const query = new Parser.Query(\n language,\n `\n (call_expression\n function: (identifier) @tag (#eq? @tag \"${tag}\")\n arguments: (template_string) @injection.content\n )\n `,\n );\n const matches = query.matches(tree.rootNode);\n const templateStrings = matches.map(({ captures }) => captures.pop()!.node);\n return templateStrings.map(processTemplate);\n }\n\n getStyles(textDocument: TextDocument) {\n const tree = this.getTypeScriptCST(textDocument);\n const query = new Parser.Query(\n language,\n `\n (call_expression\n function: (identifier) @_name (#eq? @_name \"css\")\n arguments: (arguments (object (pair\n value: (template_string) @injection.content\n )))\n )\n `,\n );\n const matches = query.matches(tree.rootNode);\n const templateStrings = matches.map(({ captures }) => captures.pop()!.node);\n return templateStrings.map(processTemplate);\n }\n\n getAllStyleValue(textDocument: TextDocument) {\n const tree = this.getTypeScriptCST(textDocument);\n const query = new Parser.Query(\n language,\n `\n (call_expression\n function: (identifier) @_name (#eq? @_name \"styleMap\")\n arguments: (arguments (object (pair\n value: (string (string_fragment) @injection.content)\n )))\n )\n `,\n );\n const matches = query.matches(tree.rootNode);\n return matches.map(({ captures }) => captures.pop()!.node);\n }\n\n getAllCSS(textDocument: TextDocument) {\n return this.getAllTemplate(textDocument, 'css').map((e) => {\n const doc = TextDocument.create(``, 'css', 1, e.text);\n const cssDoc = this.#cssCache.get(e.text, () => cssLanguageService.parseStylesheet(doc));\n return { ...e, doc, cssDoc };\n });\n }\n\n getAllCSSFragment(textDocument: TextDocument) {\n return [...this.getAllTemplate(textDocument, 'styled'), ...this.getStyles(textDocument)].map((e) => {\n const doc = TextDocument.create(``, 'css', 1, `.parent {${e.text}}`);\n const cssDoc = this.#cssCache.get(e.text, () => cssLanguageService.parseStylesheet(doc));\n return { ...e, startIndex: e.startIndex - 9, doc, cssDoc };\n });\n }\n\n getAllHTML(textDocument: TextDocument) {\n return this.getAllTemplate(textDocument, 'html').map((e) => {\n const doc = TextDocument.create(``, 'html', 1, e.text);\n const htmlDoc = this.#htmlCache.get(e.text, () => htmlLanguageService.parseHTMLDocument(doc));\n return { ...e, doc, htmlDoc };\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_vscode_languageserver_textdocument", "import_node", "import_cache", "tsTypescript", "Parser", "getHTMLanguageService", "cssColors", "documents"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vscode-gem-languageservice",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Language service for Gem",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gem",
|
|
7
7
|
"language-service"
|
|
8
8
|
],
|
|
9
|
-
"module": "
|
|
10
|
-
"main": "
|
|
11
|
-
"bin": "
|
|
9
|
+
"module": "dist/index.js",
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"bin": "dist/index.js",
|
|
12
12
|
"files": [
|
|
13
13
|
"/dist/"
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
|
-
"
|
|
16
|
+
"build": "esbuild ./src/index.ts --outdir=./dist --platform=node --sourcemap --bundle --packages=external --external:tree-sitter*",
|
|
17
|
+
"prepublishOnly": "pnpm run build",
|
|
18
|
+
"start": "pnpm run build --watch"
|
|
17
19
|
},
|
|
18
20
|
"dependencies": {
|
|
19
|
-
"@vscode
|
|
21
|
+
"@mantou/vscode-css-languageservice": "^6.3.6",
|
|
22
|
+
"@mantou/vscode-html-languageservice": "^5.3.6",
|
|
23
|
+
"css-color-keywords": "^1.0.0",
|
|
20
24
|
"duoyun-ui": "^2.2.0",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"typescript": "^5.6.2",
|
|
24
|
-
"vscode-css-languageservice": "^6.3.1",
|
|
25
|
-
"vscode-html-languageservice": "^5.3.1",
|
|
25
|
+
"tree-sitter": "^0.22.4",
|
|
26
|
+
"tree-sitter-typescript": "^0.23.2",
|
|
26
27
|
"vscode-languageserver": "^9.0.1",
|
|
27
28
|
"vscode-languageserver-textdocument": "^1.0.12"
|
|
28
29
|
},
|
package/src/index.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import type { InitializeParams } from 'vscode-languageserver/node';
|
|
4
|
-
import {
|
|
5
|
-
createConnection,
|
|
6
|
-
TextDocuments,
|
|
7
|
-
ProposedFeatures,
|
|
8
|
-
DidChangeConfigurationNotification,
|
|
9
|
-
TextDocumentSyncKind,
|
|
10
|
-
} from 'vscode-languageserver/node';
|
|
11
|
-
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
12
|
-
import { debounce } from 'duoyun-ui/lib/timer';
|
|
13
|
-
|
|
14
|
-
import { ColorProvider } from './color';
|
|
15
|
-
import { getDiagnostics } from './diagnostic';
|
|
16
|
-
import { CSSHoverProvider, HTMLHoverProvider, StyleHoverProvider } from './hover';
|
|
17
|
-
import { CSSCompletionItemProvider, HTMLStyleCompletionItemProvider } from './css';
|
|
18
|
-
import { HTMLCompletionItemProvider } from './html';
|
|
19
|
-
import { StyleCompletionItemProvider } from './style';
|
|
20
|
-
|
|
21
|
-
const connection = createConnection(ProposedFeatures.all);
|
|
22
|
-
const documents = new TextDocuments(TextDocument);
|
|
23
|
-
|
|
24
|
-
let hasConfigurationCapability = false;
|
|
25
|
-
let hasWorkspaceFolderCapability = false;
|
|
26
|
-
let hasDiagnosticRelatedInformationCapability = false;
|
|
27
|
-
|
|
28
|
-
connection.onInitialize(({ capabilities }: InitializeParams) => {
|
|
29
|
-
hasConfigurationCapability = !!capabilities.workspace?.configuration;
|
|
30
|
-
hasWorkspaceFolderCapability = !!capabilities.workspace?.workspaceFolders;
|
|
31
|
-
hasDiagnosticRelatedInformationCapability = !!capabilities.textDocument?.publishDiagnostics?.relatedInformation;
|
|
32
|
-
return {
|
|
33
|
-
capabilities: {
|
|
34
|
-
completionProvider: {
|
|
35
|
-
resolveProvider: true,
|
|
36
|
-
triggerCharacters: ['!', '.', '}', ':', '*', '$', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '<'],
|
|
37
|
-
},
|
|
38
|
-
hoverProvider: true,
|
|
39
|
-
colorProvider: true,
|
|
40
|
-
textDocumentSync: TextDocumentSyncKind.Incremental,
|
|
41
|
-
workspace: !hasWorkspaceFolderCapability ? undefined : { workspaceFolders: { supported: true } },
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
connection.onInitialized(() => {
|
|
47
|
-
if (hasConfigurationCapability) {
|
|
48
|
-
connection.client.register(DidChangeConfigurationNotification.type, undefined);
|
|
49
|
-
}
|
|
50
|
-
if (hasWorkspaceFolderCapability) {
|
|
51
|
-
connection.workspace.onDidChangeWorkspaceFolders((_event) => {
|
|
52
|
-
connection.console.log('Workspace folder change event received.');
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
interface ExampleSettings {
|
|
58
|
-
maxNumberOfProblems: number;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const defaultSettings: ExampleSettings = { maxNumberOfProblems: 1000 };
|
|
62
|
-
|
|
63
|
-
let globalSettings: ExampleSettings = defaultSettings;
|
|
64
|
-
const documentSettings: Map<string, Thenable<ExampleSettings>> = new Map();
|
|
65
|
-
|
|
66
|
-
connection.onDidChangeConfiguration((change) => {
|
|
67
|
-
if (hasConfigurationCapability) {
|
|
68
|
-
documentSettings.clear();
|
|
69
|
-
} else {
|
|
70
|
-
globalSettings = <ExampleSettings>(change.settings.languageServerGem || defaultSettings);
|
|
71
|
-
}
|
|
72
|
-
documents.all().forEach(validateTextDocument);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
function _getDocumentSettings(resource: string) {
|
|
76
|
-
if (!hasConfigurationCapability) return globalSettings;
|
|
77
|
-
if (!documentSettings.has(resource)) {
|
|
78
|
-
const settings = connection.workspace.getConfiguration({ scopeUri: resource, section: 'languageServerGem' });
|
|
79
|
-
documentSettings.set(resource, settings);
|
|
80
|
-
}
|
|
81
|
-
return documentSettings.get(resource)!;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
documents.onDidClose((e) => documentSettings.delete(e.document.uri));
|
|
85
|
-
|
|
86
|
-
documents.onDidChangeContent((change) => validateTextDocument(change.document));
|
|
87
|
-
|
|
88
|
-
const validateTextDocument = debounce((textDocument: TextDocument) => {
|
|
89
|
-
connection.sendDiagnostics({
|
|
90
|
-
uri: textDocument.uri,
|
|
91
|
-
diagnostics: getDiagnostics(textDocument, hasDiagnosticRelatedInformationCapability),
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
connection.onDidChangeWatchedFiles((_change) => {
|
|
96
|
-
connection.console.log('We received a file change event');
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
const completionItemProviders = [
|
|
100
|
-
new CSSCompletionItemProvider(),
|
|
101
|
-
new HTMLStyleCompletionItemProvider(),
|
|
102
|
-
new HTMLCompletionItemProvider(connection),
|
|
103
|
-
new StyleCompletionItemProvider(),
|
|
104
|
-
];
|
|
105
|
-
connection.onCompletion(async ({ textDocument, position }) => {
|
|
106
|
-
for (const provider of completionItemProviders) {
|
|
107
|
-
const result = await provider.provideCompletionItems(documents.get(textDocument.uri)!, position);
|
|
108
|
-
if (result) return { isIncomplete: true, items: result.items };
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
connection.onCompletionResolve((item) => item);
|
|
113
|
-
|
|
114
|
-
const colorProvider = new ColorProvider();
|
|
115
|
-
connection.onColorPresentation(({ color }) => {
|
|
116
|
-
return colorProvider.provideColorPresentations(color);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
connection.onDocumentColor(({ textDocument }) => {
|
|
120
|
-
return colorProvider.provideDocumentColors(documents.get(textDocument.uri)!);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
const hoverProviders = [new CSSHoverProvider(), new StyleHoverProvider(), new HTMLHoverProvider()];
|
|
124
|
-
connection.onHover(({ textDocument, position }) => {
|
|
125
|
-
for (const provider of hoverProviders) {
|
|
126
|
-
const result = provider.provideHover(documents.get(textDocument.uri)!, position);
|
|
127
|
-
if (result) return result;
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
documents.listen(connection);
|
|
132
|
-
connection.listen();
|