vscode-gem-languageservice 0.0.1 → 0.0.3

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 ADDED
@@ -0,0 +1,479 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // 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");
8
+
9
+ // src/color.ts
10
+ var import_color = require("duoyun-ui/lib/color");
11
+ var import_node = require("vscode-languageserver/node");
12
+
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;
18
+
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
+ };
70
+ return {
71
+ ...result,
72
+ items: result?.items.map((item) => ({
73
+ ...item,
74
+ textEdit: item.textEdit && {
75
+ ...item.textEdit,
76
+ range: getRange(item)
77
+ }
78
+ }))
79
+ };
80
+ }
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
146
+ });
147
+ }
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
164
+ });
165
+ }
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
182
+ });
183
+ }
184
+ };
185
+
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
+ };
299
+
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;
310
+ }
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;
322
+ }
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
+ };
353
+ }
354
+ }
355
+ }
356
+ ]);
357
+ const completions = this.#htmlLanguageService.doComplete(
358
+ virtualDocument,
359
+ virtualDocument.positionAt(virtualOffset),
360
+ vHtml
361
+ );
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
+ }
393
+ };
394
+
395
+ // 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;
405
+ return {
406
+ capabilities: {
407
+ completionProvider: {
408
+ resolveProvider: true,
409
+ triggerCharacters: ["!", ".", "}", ":", "*", "$", "]", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<"]
410
+ },
411
+ hoverProvider: true,
412
+ colorProvider: true,
413
+ textDocumentSync: import_node4.TextDocumentSyncKind.Incremental,
414
+ workspace: !hasWorkspaceFolderCapability ? void 0 : { workspaceFolders: { supported: true } }
415
+ }
416
+ };
417
+ });
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();
464
+ connection.onColorPresentation(({ color }) => {
465
+ return colorProvider.provideColorPresentations(color);
466
+ });
467
+ connection.onDocumentColor(({ textDocument }) => {
468
+ return colorProvider.provideDocumentColors(documents.get(textDocument.uri));
469
+ });
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
+ }
476
+ });
477
+ documents.listen(connection);
478
+ connection.listen();
479
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
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"]
7
+ }
package/package.json CHANGED
@@ -1,22 +1,28 @@
1
1
  {
2
2
  "name": "vscode-gem-languageservice",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Language service for Gem",
5
5
  "keywords": [
6
6
  "gem",
7
7
  "language-service"
8
8
  ],
9
- "type": "module",
10
9
  "module": "src/index.ts",
11
- "bin": "src/index.ts",
10
+ "main": "src/index.ts",
11
+ "bin": "src/index.js",
12
12
  "files": [
13
- "/src/"
13
+ "/dist/"
14
14
  ],
15
- "scripts": {},
15
+ "scripts": {
16
+ "prepublishOnly": "esbuild ./src/index.ts --outdir=./dist --platform=node --sourcemap --bundle --packages=external"
17
+ },
16
18
  "dependencies": {
19
+ "@vscode/emmet-helper": "^2.9.3",
20
+ "duoyun-ui": "^2.2.0",
17
21
  "gem-analyzer": "^2.2.0",
18
22
  "ts-morph": "^13.0.0",
19
23
  "typescript": "^5.6.2",
24
+ "vscode-css-languageservice": "^6.3.1",
25
+ "vscode-html-languageservice": "^5.3.1",
20
26
  "vscode-languageserver": "^9.0.1",
21
27
  "vscode-languageserver-textdocument": "^1.0.12"
22
28
  },
package/src/index.ts CHANGED
@@ -1,15 +1,22 @@
1
- #!/usr/bin/env -S node --experimental-transform-types
2
- import type { Diagnostic, InitializeParams } from 'vscode-languageserver/node';
1
+ #!/usr/bin/env node
2
+
3
+ import type { InitializeParams } from 'vscode-languageserver/node';
3
4
  import {
4
5
  createConnection,
5
6
  TextDocuments,
6
- DiagnosticSeverity,
7
7
  ProposedFeatures,
8
8
  DidChangeConfigurationNotification,
9
- CompletionItemKind,
10
9
  TextDocumentSyncKind,
11
10
  } from 'vscode-languageserver/node';
12
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';
13
20
 
14
21
  const connection = createConnection(ProposedFeatures.all);
15
22
  const documents = new TextDocuments(TextDocument);
@@ -24,8 +31,13 @@ connection.onInitialize(({ capabilities }: InitializeParams) => {
24
31
  hasDiagnosticRelatedInformationCapability = !!capabilities.textDocument?.publishDiagnostics?.relatedInformation;
25
32
  return {
26
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,
27
40
  textDocumentSync: TextDocumentSyncKind.Incremental,
28
- completionProvider: { resolveProvider: true },
29
41
  workspace: !hasWorkspaceFolderCapability ? undefined : { workspaceFolders: { supported: true } },
30
42
  },
31
43
  };
@@ -60,7 +72,7 @@ connection.onDidChangeConfiguration((change) => {
60
72
  documents.all().forEach(validateTextDocument);
61
73
  });
62
74
 
63
- async function getDocumentSettings(resource: string) {
75
+ function _getDocumentSettings(resource: string) {
64
76
  if (!hasConfigurationCapability) return globalSettings;
65
77
  if (!documentSettings.has(resource)) {
66
78
  const settings = connection.workspace.getConfiguration({ scopeUri: resource, section: 'languageServerGem' });
@@ -73,74 +85,47 @@ documents.onDidClose((e) => documentSettings.delete(e.document.uri));
73
85
 
74
86
  documents.onDidChangeContent((change) => validateTextDocument(change.document));
75
87
 
76
- async function validateTextDocument(textDocument: TextDocument) {
77
- const settings = await getDocumentSettings(textDocument.uri);
78
-
79
- const text = textDocument.getText();
80
- const pattern = /\b[A-Z]{20,}\b/g;
81
- let m: RegExpExecArray | null;
82
-
83
- let problems = 0;
84
- const diagnostics: Diagnostic[] = [];
85
- while ((m = pattern.exec(text)) && problems < settings.maxNumberOfProblems) {
86
- problems++;
87
- const diagnostic: Diagnostic = {
88
- severity: DiagnosticSeverity.Warning,
89
- range: { start: textDocument.positionAt(m.index), end: textDocument.positionAt(m.index + m[0].length) },
90
- message: `${m[0]} is all uppercase.`,
91
- source: 'vscode-gem',
92
- };
93
- if (hasDiagnosticRelatedInformationCapability) {
94
- diagnostic.relatedInformation = [
95
- {
96
- location: {
97
- uri: textDocument.uri,
98
- range: Object.assign({}, diagnostic.range),
99
- },
100
- message: 'Spelling matters',
101
- },
102
- {
103
- location: {
104
- uri: textDocument.uri,
105
- range: Object.assign({}, diagnostic.range),
106
- },
107
- message: 'Particularly for names',
108
- },
109
- ];
110
- }
111
- diagnostics.push(diagnostic);
112
- }
113
- connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
114
- }
88
+ const validateTextDocument = debounce((textDocument: TextDocument) => {
89
+ connection.sendDiagnostics({
90
+ uri: textDocument.uri,
91
+ diagnostics: getDiagnostics(textDocument, hasDiagnosticRelatedInformationCapability),
92
+ });
93
+ });
115
94
 
116
95
  connection.onDidChangeWatchedFiles((_change) => {
117
96
  connection.console.log('We received a file change event');
118
97
  });
119
98
 
120
- connection.onCompletion((_textDocumentPosition) => {
121
- return [
122
- {
123
- label: 'TypeScript',
124
- kind: CompletionItemKind.Text,
125
- data: 1,
126
- },
127
- {
128
- label: 'JavaScript',
129
- kind: CompletionItemKind.Text,
130
- data: 2,
131
- },
132
- ];
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)!);
133
121
  });
134
122
 
135
- connection.onCompletionResolve((item) => {
136
- if (item.data === 1) {
137
- item.detail = 'TypeScript details';
138
- item.documentation = 'TypeScript documentation';
139
- } else if (item.data === 2) {
140
- item.detail = 'JavaScript details';
141
- item.documentation = 'JavaScript documentation';
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;
142
128
  }
143
- return item;
144
129
  });
145
130
 
146
131
  documents.listen(connection);