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 CHANGED
@@ -1,479 +1,220 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
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 import_node4 = require("vscode-languageserver/node");
6
- var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
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/color.ts
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/constants.ts
14
- var COLOR_REG = /(?<start>'|")?(?<content>#([0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4}))($1|\s*;|\s*\))/g;
15
- var CSS_REG = /(?<start>\/\*\s*css\s*\*\/\s*`|(?<!`)(?:css|less|scss)\s*`)(?<content>.*?)(`(?=;|,?\s*\)))/gs;
16
- var STYLE_REG = /(?<start>\/\*\s*style\s*\*\/\s*`|(?<!`)styled?\s*`)(?<content>.*?)(`(?=,|\s*}\s*\)))/gs;
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/color.ts
20
- var ColorProvider = class {
21
- provideDocumentColors(document) {
22
- COLOR_REG.exec("null");
23
- const documentText = document.getText();
24
- const colors = [];
25
- let match;
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
- ...result,
72
- items: result?.items.map((item) => ({
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
- function matchOffset(regex, docText, offset) {
82
- regex.exec("null");
83
- let match;
84
- while ((match = regex.exec(docText)) !== null) {
85
- const [fullStr, startStr] = match;
86
- const start = match.index + startStr.length;
87
- const end = match.index + fullStr.length;
88
- if (offset > start && offset < end) {
89
- return match;
90
- }
91
- }
92
- return null;
93
- }
94
- function createVirtualDocument(languageId, content) {
95
- return import_vscode_html_languageservice.TextDocument.create(`embedded://document.${languageId}`, languageId, 1, content);
96
- }
97
-
98
- // src/diagnostic.ts
99
- var cssLanguageService = (0, import_vscode_css_languageservice.getCSSLanguageService)();
100
- function getDiagnostics(document, _relatedInformation) {
101
- const diagnostics = [];
102
- const text = document.getText();
103
- const matchFragments = (regexp, appendBefore, appendAfter) => {
104
- regexp.exec("null");
105
- let match;
106
- while (match = regexp.exec(text)) {
107
- const matchContent = match.groups.content;
108
- const offset = match.index + match.groups.start.length;
109
- const virtualDocument = createVirtualDocument("css", `${appendBefore}${removeSlot(matchContent)}${appendAfter}`);
110
- const vCss = cssLanguageService.parseStylesheet(virtualDocument);
111
- const oDiagnostics = cssLanguageService.doValidation(virtualDocument, vCss);
112
- for (const { message, range } of oDiagnostics) {
113
- const { start, end } = range;
114
- const startOffset = virtualDocument.offsetAt(start) - appendBefore.length + offset;
115
- const endOffset = virtualDocument.offsetAt(end) - appendBefore.length + offset;
116
- diagnostics.push({
117
- range: import_node3.Range.create(document.positionAt(startOffset), document.positionAt(endOffset)),
118
- message
119
- });
120
- }
121
- }
122
- };
123
- matchFragments(CSS_REG, "", "");
124
- matchFragments(STYLE_REG, ":host { ", " }");
125
- return diagnostics;
126
- }
127
-
128
- // src/hover.ts
129
- var import_vscode_html_languageservice2 = require("vscode-html-languageservice");
130
- var import_vscode_css_languageservice2 = require("vscode-css-languageservice");
131
- var HTMLHoverProvider = class {
132
- #htmlLanguageService = (0, import_vscode_html_languageservice2.getLanguageService)();
133
- provideHover(document, position) {
134
- const currentOffset = document.offsetAt(position);
135
- const documentText = removeHTMLSlot(document.getText(), currentOffset);
136
- const match = matchOffset(HTML_REG, documentText, currentOffset);
137
- if (!match) return null;
138
- const matchContent = match.groups.content;
139
- const matchStartOffset = match.index + match.groups.start.length;
140
- const virtualOffset = currentOffset - matchStartOffset;
141
- const virtualDocument = createVirtualDocument("html", matchContent);
142
- const html = this.#htmlLanguageService.parseHTMLDocument(virtualDocument);
143
- return this.#htmlLanguageService.doHover(virtualDocument, virtualDocument.positionAt(virtualOffset), html, {
144
- documentation: true,
145
- references: true
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
- var CSSHoverProvider = class {
150
- #cssLanguageService = (0, import_vscode_css_languageservice2.getCSSLanguageService)();
151
- provideHover(document, position) {
152
- const currentOffset = document.offsetAt(position);
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
- var StyleHoverProvider = class {
168
- #cssLanguageService = (0, import_vscode_css_languageservice2.getCSSLanguageService)();
169
- provideHover(document, position) {
170
- const currentOffset = document.offsetAt(position);
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/css.ts
187
- var import_vscode_html_languageservice3 = require("vscode-html-languageservice");
188
- var import_vscode_css_languageservice3 = require("vscode-css-languageservice");
189
-
190
- // src/cache.ts
191
- var CompletionsCache = class {
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/html.ts
301
- var import_vscode_html_languageservice4 = require("vscode-html-languageservice");
302
- var import_emmet_helper = require("@vscode/emmet-helper");
303
- var HTMLCompletionItemProvider = class {
304
- #htmlLanguageService = (0, import_vscode_html_languageservice4.getLanguageService)();
305
- #cache = new CompletionsCache();
306
- #connection;
307
- #emmetConfig;
308
- constructor(connection2) {
309
- this.#connection = connection2;
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
- async #getEmmetConfig() {
312
- if (!this.#emmetConfig) {
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
- async provideCompletionItems(document, position) {
324
- const emmetConfig = await this.#getEmmetConfig();
325
- const cached = this.#cache.getCached(document, position);
326
- if (cached) return cached;
327
- const currentOffset = document.offsetAt(position);
328
- const documentText = removeHTMLSlot(document.getText(), currentOffset);
329
- const match = matchOffset(HTML_REG, documentText, currentOffset);
330
- if (!match) return;
331
- const matchContent = match.groups.content;
332
- const matchStartOffset = match.index + match.groups.start.length;
333
- const virtualOffset = currentOffset - matchStartOffset;
334
- const virtualDocument = createVirtualDocument("html", matchContent);
335
- const vHtml = this.#htmlLanguageService.parseHTMLDocument(virtualDocument);
336
- let emmetResults = { isIncomplete: true, items: [] };
337
- this.#htmlLanguageService.setCompletionParticipants([
338
- {
339
- onHtmlContent: async () => {
340
- const pos = virtualDocument.positionAt(virtualOffset);
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, import_node4.createConnection)(import_node4.ProposedFeatures.all);
397
- var documents = new import_node4.TextDocuments(import_vscode_languageserver_textdocument.TextDocument);
398
- var hasConfigurationCapability = false;
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
- textDocumentSync: import_node4.TextDocumentSyncKind.Incremental,
414
- workspace: !hasWorkspaceFolderCapability ? void 0 : { workspaceFolders: { supported: true } }
204
+ documentSymbolProvider: true
415
205
  }
416
206
  };
417
207
  });
418
- connection.onInitialized(() => {
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 colorProvider.provideColorPresentations(color);
210
+ return provider.provideColorPresentations(color);
466
211
  });
467
212
  connection.onDocumentColor(({ textDocument }) => {
468
- return colorProvider.provideDocumentColors(documents.get(textDocument.uri));
213
+ return provider.provideDocumentColors(documents2.get(textDocument.uri));
469
214
  });
470
- var hoverProviders = [new CSSHoverProvider(), new StyleHoverProvider(), new HTMLHoverProvider()];
471
- connection.onHover(({ textDocument, position }) => {
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
- documents.listen(connection);
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/color.ts", "../src/constants.ts", "../src/diagnostic.ts", "../src/util.ts", "../src/hover.ts", "../src/css.ts", "../src/cache.ts", "../src/html.ts", "../src/style.ts"],
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": ["import_node", "import_node", "import_node", "import_vscode_html_languageservice", "import_vscode_css_languageservice", "getHtmlLanguageService", "import_vscode_html_languageservice", "import_vscode_css_languageservice", "HTMLTokenType", "getHTMLanguageService", "import_vscode_html_languageservice", "getHTMLanguageService", "connection", "doEmmetComplete", "import_vscode_css_languageservice"]
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",
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": "src/index.ts",
10
- "main": "src/index.ts",
11
- "bin": "src/index.js",
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
- "prepublishOnly": "esbuild ./src/index.ts --outdir=./dist --platform=node --sourcemap --bundle --packages=external"
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/emmet-helper": "^2.9.3",
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
- "gem-analyzer": "^2.2.0",
22
- "ts-morph": "^13.0.0",
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();