@master/css-language-server 2.0.0-rc.6 → 2.0.0-rc.60

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/README.md ADDED
@@ -0,0 +1,63 @@
1
+ <br>
2
+ <div align="center">
3
+
4
+ <p align="center">
5
+ <a href="https://css.master.co">
6
+ <picture>
7
+ <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/33840671/201701649-3bb7d698-abec-4d5f-ac30-ccc4d7bafcd4.svg">
8
+ <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg">
9
+ <img alt="Master CSS" src="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg" width="100%">
10
+ </picture>
11
+ </a>
12
+ </p>
13
+ <p align="center">Language Server for Master CSS</p>
14
+
15
+ <p align="center">
16
+ <a aria-label="GitHub release (latest by date including pre-releases)" href="https://github.com/master-co/css/releases">
17
+ <picture>
18
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=212022&label=&style=for-the-badge&logo=github&logoColor=fff">
19
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github&logoColor=%23000">
20
+ <img alt="NPM Version" src="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github">
21
+ </picture>
22
+ </a>
23
+ <a aria-label="NPM Package" href="https://www.npmjs.com/package/@master/css-language-server">
24
+ <picture>
25
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/npm/dm/@master/css-language-server?color=212022&label=%20&logo=npm&style=for-the-badge">
26
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/npm/dm/@master/css-language-server?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
27
+ <img alt="NPM package ( download / month )" src="https://img.shields.io/npm/dm/@master/css-language-server?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
28
+ </picture>
29
+ </a>
30
+ <a aria-label="JSDelivr" href="https://www.jsdelivr.com/package/npm/@master/css-language-server">
31
+ <picture>
32
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-server?color=212022&label=%20&logo=jsdelivr&style=for-the-badge">
33
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-server?color=f6f7f8&label=%20&logo=jsdelivr&style=for-the-badge">
34
+ <img alt="JSDelivr hits (npm scoped)" src="https://img.shields.io/jsdelivr/npm/hm/@master/css-language-server?color=f6f7f8&label=%20&logo=jsdelivr&style=for-the-badge">
35
+ </picture>
36
+ </a>
37
+ <a aria-label="Discord Community" href="https://discord.gg/sZNKpAAAw6">
38
+ <picture>
39
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/discord/917780624314613760?color=212022&label=%20&logo=discord&style=for-the-badge">
40
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
41
+ <img alt="Discord online" src="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
42
+ </picture>
43
+ </a>
44
+ <a aria-label="Follow @mastercorg" href="https://twitter.com/mastercorg">
45
+ <picture>
46
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=212022&logo=twitter&style=for-the-badge">
47
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
48
+ <img alt="Follow @mastercorg" src="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
49
+ </picture>
50
+ </a>
51
+ <a aria-label="Github Actions" href="https://github.com/master-co/css/actions/workflows/release.yml">
52
+ <picture>
53
+ <source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=rc&label=%20&message=twitter&color=212022&logo=githubactions&style=for-the-badge">
54
+ <source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
55
+ <img alt="Github release actions" src="https://img.shields.io/github/actions/workflow/status/master-co/css/release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
56
+ </picture>
57
+ </a>
58
+ </p>
59
+
60
+ </div>
61
+
62
+ ## Documentation
63
+ Check out the official [documentation](https://rc.css.master.co/reference/language-server).
package/dist/core.cjs ADDED
@@ -0,0 +1,228 @@
1
+ 'use strict';
2
+
3
+ var node = require('vscode-languageserver/node');
4
+ var vscodeLanguageserverTextdocument = require('vscode-languageserver-textdocument');
5
+ var path = require('node:path');
6
+ var CSSLanguageService = require('@master/css-language-service');
7
+ var exploreConfig = require('@master/css-explore-config');
8
+ var extend = require('@techor/extend');
9
+ var settings = require('./settings.cjs');
10
+ var glob = require('fast-glob');
11
+ var vscodeUri = require('vscode-uri');
12
+
13
+ class CSSLanguageServer {
14
+ connection;
15
+ customSettings;
16
+ workspaceFolders;
17
+ workspaces;
18
+ documents;
19
+ initializing;
20
+ clientCapabilities;
21
+ settings;
22
+ console;
23
+ disposables;
24
+ constructor(connection = process.argv.includes('--stdio') ? node.createConnection(process.stdin, process.stdout) : node.createConnection(), customSettings){
25
+ this.connection = connection;
26
+ this.customSettings = customSettings;
27
+ this.workspaceFolders = [];
28
+ this.workspaces = [];
29
+ this.clientCapabilities = {};
30
+ this.disposables = [];
31
+ this.documents = new node.TextDocuments(vscodeLanguageserverTextdocument.TextDocument);
32
+ this.settings = extend(settings, this.customSettings);
33
+ this.console = new Proxy(this.connection.console, {
34
+ get: (target, prop)=>{
35
+ if (!this.settings?.verbose) return ()=>{};
36
+ return this.connection.console[prop];
37
+ }
38
+ });
39
+ }
40
+ start() {
41
+ this.disposables.push(this.documents.onDidSave(this.onDidSave.bind(this)), this.documents.onDidOpen(this.onDidOpen.bind(this)), this.documents.onDidClose(this.onDidClose.bind(this)), this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(this.onDidChangeConfiguration.bind(this)), this.connection.onHover(this.onHover.bind(this)), this.connection.onCompletion(this.onCompletion.bind(this)), this.connection.onDocumentColor(this.onDocumentColor.bind(this)), this.connection.onColorPresentation(this.onColorPresentation.bind(this)), this.connection.onInitialize(this.onInitialize.bind(this)), this.connection.onInitialized(()=>this.init()));
42
+ this.connection.listen();
43
+ }
44
+ init() {
45
+ if (this.initializing) return this.initializing;
46
+ return this.initializing = new Promise(async (resolve)=>{
47
+ await Promise.all(this.workspaceFolders.map((folder)=>this.initWorkspaceFolder(folder.uri)));
48
+ resolve();
49
+ });
50
+ }
51
+ onInitialize(params) {
52
+ this.clientCapabilities = params.capabilities;
53
+ if (params.workspaceFolders?.length) {
54
+ this.workspaceFolders = params.workspaceFolders;
55
+ } else {
56
+ /**
57
+ * @deprecated — in favour of workspaceFolders
58
+ */ if (params.rootUri) {
59
+ this.workspaceFolders.push({
60
+ name: '',
61
+ uri: params.rootUri
62
+ });
63
+ }
64
+ }
65
+ return {
66
+ capabilities: CSSLanguageService.SERVER_CAPABILITIES
67
+ };
68
+ }
69
+ async onHover(params) {
70
+ await this.init();
71
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
72
+ if (workspace.languageService) {
73
+ const document = this.documents.get(params.textDocument.uri);
74
+ if (document) return workspace.languageService.inspectSyntax(document, params.position);
75
+ }
76
+ }
77
+ async onCompletion(params) {
78
+ await this.init();
79
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
80
+ if (workspace.languageService) {
81
+ const document = this.documents.get(params.textDocument.uri);
82
+ if (document) return workspace.languageService.suggestSyntax(document, params.position, params.context);
83
+ }
84
+ }
85
+ async onDocumentColor(params) {
86
+ await this.init();
87
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
88
+ if (workspace.languageService) {
89
+ const document = this.documents.get(params.textDocument.uri);
90
+ if (document) return workspace.languageService.renderSyntaxColors(document);
91
+ }
92
+ }
93
+ async onColorPresentation(params) {
94
+ await this.init();
95
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
96
+ if (workspace.languageService) {
97
+ const document = this.documents.get(params.textDocument.uri);
98
+ if (document) return workspace.languageService.editSyntaxColors(document, params.color, params.range);
99
+ }
100
+ }
101
+ async onDidOpen(params) {
102
+ await this.init();
103
+ const workspace = this.findClosestWorkspace(params.document.uri);
104
+ if (!workspace || workspace.openedTextDocuments.includes(params.document)) return;
105
+ if (!workspace.openedTextDocuments.length) {
106
+ this.initLanguageService(workspace);
107
+ }
108
+ workspace.openedTextDocuments.push(params.document);
109
+ }
110
+ async onDidClose(params) {
111
+ await this.init();
112
+ const workspace = this.findClosestWorkspace(params.document.uri);
113
+ if (!workspace) return;
114
+ workspace.openedTextDocuments.splice(workspace.openedTextDocuments.indexOf(params.document), 1);
115
+ if (!workspace.openedTextDocuments.length) {
116
+ this.destroyLanguageService(workspace);
117
+ }
118
+ }
119
+ async onDidSave(params) {
120
+ await this.init();
121
+ const workspace = this.findClosestWorkspace(params.document.uri);
122
+ if (!workspace) return;
123
+ const name = path.parse(params.document.uri).name;
124
+ if (name === 'master.css' || name.endsWith('.css')) {
125
+ this.connection.sendRequest('masterCSS/restart', {
126
+ title: 'Updating Master CSS configuration'
127
+ });
128
+ }
129
+ }
130
+ async onDidChangeConfiguration({ settings }) {
131
+ await this.init();
132
+ if (settings?.masterCSS) {
133
+ this.connection.sendNotification('masterCSS/globalSettingsChanged', settings.masterCSS);
134
+ this.customSettings = settings.masterCSS;
135
+ this.connection.sendRequest('masterCSS/restart', {
136
+ title: 'Updating Master CSS settings'
137
+ });
138
+ }
139
+ }
140
+ async initWorkspaceFolder(workspaceFolderURI) {
141
+ const workspaceFolderCWD = vscodeUri.URI.parse(workspaceFolderURI).fsPath;
142
+ let customWorkspaceFolderSettings;
143
+ if (this.clientCapabilities.workspace?.configuration) {
144
+ customWorkspaceFolderSettings = await this.connection.workspace.getConfiguration({
145
+ scopeUri: workspaceFolderURI,
146
+ section: 'masterCSS'
147
+ });
148
+ }
149
+ const { workspaces, ...languageServiceSettings } = extend(settings, this.customSettings, customWorkspaceFolderSettings);
150
+ const resolvedWorkspaceDirectories = new Set([
151
+ workspaceFolderCWD
152
+ ]);
153
+ this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
154
+ if (workspaces === 'auto') {
155
+ (await glob('**/master.css.*', {
156
+ cwd: workspaceFolderCWD,
157
+ absolute: true,
158
+ onlyFiles: true,
159
+ ignore: [
160
+ '**/node_modules/**'
161
+ ]
162
+ })).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(path.resolve(workspaceFile))));
163
+ } else if (workspaces?.length) {
164
+ (await glob(workspaces, {
165
+ cwd: workspaceFolderCWD,
166
+ absolute: true,
167
+ onlyDirectories: true,
168
+ ignore: [
169
+ '**/node_modules/**'
170
+ ]
171
+ })).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(path.resolve(workspaceDir)));
172
+ }
173
+ resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
174
+ const workspaceURI = vscodeUri.URI.file(workspaceDir).toString();
175
+ this.console.info(`Added workspace ${workspaceURI}`);
176
+ this.workspaces.push({
177
+ uri: workspaceURI,
178
+ openedTextDocuments: [],
179
+ languageServiceSettings
180
+ });
181
+ });
182
+ }
183
+ initLanguageService(workspace) {
184
+ let workspaceConfig;
185
+ try {
186
+ workspaceConfig = exploreConfig({
187
+ cwd: vscodeUri.URI.parse(workspace.uri).fsPath,
188
+ found: undefined
189
+ });
190
+ } catch (e) {
191
+ this.console.info(`Failed to load config from ${workspace}`);
192
+ this.console.error(e);
193
+ }
194
+ this.console.info(`Initialized workspace ${workspaceConfig ? '(with config file)' : ''} ${workspace.uri}`);
195
+ workspace.languageService = new CSSLanguageService({
196
+ ...workspace.languageServiceSettings,
197
+ config: workspaceConfig
198
+ });
199
+ }
200
+ destroyLanguageService(workspace) {
201
+ this.console.info(`Destroyed workspace ${workspace.uri}`);
202
+ delete workspace.languageService;
203
+ }
204
+ findClosestWorkspace(textDocumentURI) {
205
+ let foundWorkspace;
206
+ for (const workspace of this.workspaces){
207
+ if (textDocumentURI.startsWith(workspace.uri) && (!foundWorkspace || workspace.uri.length > foundWorkspace.uri.length)) {
208
+ foundWorkspace = workspace;
209
+ }
210
+ }
211
+ if (process.env.DEBUG && !foundWorkspace) {
212
+ this.console.info(`This is an external document ${textDocumentURI} assigned to the first workspace`);
213
+ }
214
+ return foundWorkspace || this.workspaces[0];
215
+ }
216
+ getWorkspace(uri) {
217
+ return Array.from(this.workspaces).find((workspace)=>workspace.uri === uri);
218
+ }
219
+ stop() {
220
+ this.connection.sendNotification('masterCSS/dispose');
221
+ this.disposables.forEach((disposable)=>disposable.dispose());
222
+ this.disposables.length = 0;
223
+ this.connection.dispose();
224
+ this.initializing = undefined;
225
+ }
226
+ }
227
+
228
+ module.exports = CSSLanguageServer;
package/dist/core.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { TextDocuments, InitializeParams, WorkspaceFolder, Connection, ClientCapabilities, TextDocumentChangeEvent, DidChangeConfigurationParams, HoverParams, CompletionParams, DocumentColorParams, ColorPresentationParams, RemoteConsole } from 'vscode-languageserver/node';
2
+ import { TextDocument } from 'vscode-languageserver-textdocument';
3
+ import CSSLanguageService, { Settings as CSSLanguageServiceSettings } from '@master/css-language-service';
4
+ import { Settings } from './settings';
5
+ export declare interface Workspace {
6
+ uri: string;
7
+ openedTextDocuments: TextDocument[];
8
+ languageService?: CSSLanguageService;
9
+ languageServiceSettings: CSSLanguageServiceSettings;
10
+ }
11
+ export default class CSSLanguageServer {
12
+ connection: Connection;
13
+ customSettings?: Settings | undefined;
14
+ workspaceFolders: WorkspaceFolder[];
15
+ workspaces: Workspace[];
16
+ documents: TextDocuments<TextDocument>;
17
+ initializing?: Promise<void>;
18
+ clientCapabilities: ClientCapabilities;
19
+ settings?: Settings;
20
+ console: RemoteConsole;
21
+ private disposables;
22
+ constructor(connection?: Connection, customSettings?: Settings | undefined);
23
+ start(): void;
24
+ init(): Promise<void>;
25
+ onInitialize(params: InitializeParams): {
26
+ capabilities: import("vscode-languageserver").ServerCapabilities<any>;
27
+ };
28
+ onHover(params: HoverParams): Promise<import("vscode-languageserver").Hover | undefined>;
29
+ onCompletion(params: CompletionParams): Promise<import("vscode-languageserver").CompletionItem[] | undefined>;
30
+ onDocumentColor(params: DocumentColorParams): Promise<import("vscode-languageserver").ColorInformation[] | undefined>;
31
+ onColorPresentation(params: ColorPresentationParams): Promise<import("vscode-languageserver").ColorPresentation[] | undefined>;
32
+ onDidOpen(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
33
+ onDidClose(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
34
+ onDidSave(params: TextDocumentChangeEvent<TextDocument>): Promise<void>;
35
+ onDidChangeConfiguration({ settings }: DidChangeConfigurationParams): Promise<void>;
36
+ private initWorkspaceFolder;
37
+ initLanguageService(workspace: Workspace): void;
38
+ destroyLanguageService(workspace: Workspace): void;
39
+ findClosestWorkspace(textDocumentURI: string): Workspace;
40
+ getWorkspace(uri: string): Workspace | undefined;
41
+ stop(): void;
42
+ }
package/dist/core.mjs ADDED
@@ -0,0 +1,226 @@
1
+ import { createConnection, TextDocuments } from 'vscode-languageserver/node';
2
+ import { TextDocument } from 'vscode-languageserver-textdocument';
3
+ import path from 'node:path';
4
+ import CSSLanguageService, { SERVER_CAPABILITIES } from '@master/css-language-service';
5
+ import exploreConfig from '@master/css-explore-config';
6
+ import extend from '@techor/extend';
7
+ import settings from './settings.mjs';
8
+ import glob from 'fast-glob';
9
+ import { URI } from 'vscode-uri';
10
+
11
+ class CSSLanguageServer {
12
+ connection;
13
+ customSettings;
14
+ workspaceFolders;
15
+ workspaces;
16
+ documents;
17
+ initializing;
18
+ clientCapabilities;
19
+ settings;
20
+ console;
21
+ disposables;
22
+ constructor(connection = process.argv.includes('--stdio') ? createConnection(process.stdin, process.stdout) : createConnection(), customSettings){
23
+ this.connection = connection;
24
+ this.customSettings = customSettings;
25
+ this.workspaceFolders = [];
26
+ this.workspaces = [];
27
+ this.clientCapabilities = {};
28
+ this.disposables = [];
29
+ this.documents = new TextDocuments(TextDocument);
30
+ this.settings = extend(settings, this.customSettings);
31
+ this.console = new Proxy(this.connection.console, {
32
+ get: (target, prop)=>{
33
+ if (!this.settings?.verbose) return ()=>{};
34
+ return this.connection.console[prop];
35
+ }
36
+ });
37
+ }
38
+ start() {
39
+ this.disposables.push(this.documents.onDidSave(this.onDidSave.bind(this)), this.documents.onDidOpen(this.onDidOpen.bind(this)), this.documents.onDidClose(this.onDidClose.bind(this)), this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(this.onDidChangeConfiguration.bind(this)), this.connection.onHover(this.onHover.bind(this)), this.connection.onCompletion(this.onCompletion.bind(this)), this.connection.onDocumentColor(this.onDocumentColor.bind(this)), this.connection.onColorPresentation(this.onColorPresentation.bind(this)), this.connection.onInitialize(this.onInitialize.bind(this)), this.connection.onInitialized(()=>this.init()));
40
+ this.connection.listen();
41
+ }
42
+ init() {
43
+ if (this.initializing) return this.initializing;
44
+ return this.initializing = new Promise(async (resolve)=>{
45
+ await Promise.all(this.workspaceFolders.map((folder)=>this.initWorkspaceFolder(folder.uri)));
46
+ resolve();
47
+ });
48
+ }
49
+ onInitialize(params) {
50
+ this.clientCapabilities = params.capabilities;
51
+ if (params.workspaceFolders?.length) {
52
+ this.workspaceFolders = params.workspaceFolders;
53
+ } else {
54
+ /**
55
+ * @deprecated — in favour of workspaceFolders
56
+ */ if (params.rootUri) {
57
+ this.workspaceFolders.push({
58
+ name: '',
59
+ uri: params.rootUri
60
+ });
61
+ }
62
+ }
63
+ return {
64
+ capabilities: SERVER_CAPABILITIES
65
+ };
66
+ }
67
+ async onHover(params) {
68
+ await this.init();
69
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
70
+ if (workspace.languageService) {
71
+ const document = this.documents.get(params.textDocument.uri);
72
+ if (document) return workspace.languageService.inspectSyntax(document, params.position);
73
+ }
74
+ }
75
+ async onCompletion(params) {
76
+ await this.init();
77
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
78
+ if (workspace.languageService) {
79
+ const document = this.documents.get(params.textDocument.uri);
80
+ if (document) return workspace.languageService.suggestSyntax(document, params.position, params.context);
81
+ }
82
+ }
83
+ async onDocumentColor(params) {
84
+ await this.init();
85
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
86
+ if (workspace.languageService) {
87
+ const document = this.documents.get(params.textDocument.uri);
88
+ if (document) return workspace.languageService.renderSyntaxColors(document);
89
+ }
90
+ }
91
+ async onColorPresentation(params) {
92
+ await this.init();
93
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
94
+ if (workspace.languageService) {
95
+ const document = this.documents.get(params.textDocument.uri);
96
+ if (document) return workspace.languageService.editSyntaxColors(document, params.color, params.range);
97
+ }
98
+ }
99
+ async onDidOpen(params) {
100
+ await this.init();
101
+ const workspace = this.findClosestWorkspace(params.document.uri);
102
+ if (!workspace || workspace.openedTextDocuments.includes(params.document)) return;
103
+ if (!workspace.openedTextDocuments.length) {
104
+ this.initLanguageService(workspace);
105
+ }
106
+ workspace.openedTextDocuments.push(params.document);
107
+ }
108
+ async onDidClose(params) {
109
+ await this.init();
110
+ const workspace = this.findClosestWorkspace(params.document.uri);
111
+ if (!workspace) return;
112
+ workspace.openedTextDocuments.splice(workspace.openedTextDocuments.indexOf(params.document), 1);
113
+ if (!workspace.openedTextDocuments.length) {
114
+ this.destroyLanguageService(workspace);
115
+ }
116
+ }
117
+ async onDidSave(params) {
118
+ await this.init();
119
+ const workspace = this.findClosestWorkspace(params.document.uri);
120
+ if (!workspace) return;
121
+ const name = path.parse(params.document.uri).name;
122
+ if (name === 'master.css' || name.endsWith('.css')) {
123
+ this.connection.sendRequest('masterCSS/restart', {
124
+ title: 'Updating Master CSS configuration'
125
+ });
126
+ }
127
+ }
128
+ async onDidChangeConfiguration({ settings }) {
129
+ await this.init();
130
+ if (settings?.masterCSS) {
131
+ this.connection.sendNotification('masterCSS/globalSettingsChanged', settings.masterCSS);
132
+ this.customSettings = settings.masterCSS;
133
+ this.connection.sendRequest('masterCSS/restart', {
134
+ title: 'Updating Master CSS settings'
135
+ });
136
+ }
137
+ }
138
+ async initWorkspaceFolder(workspaceFolderURI) {
139
+ const workspaceFolderCWD = URI.parse(workspaceFolderURI).fsPath;
140
+ let customWorkspaceFolderSettings;
141
+ if (this.clientCapabilities.workspace?.configuration) {
142
+ customWorkspaceFolderSettings = await this.connection.workspace.getConfiguration({
143
+ scopeUri: workspaceFolderURI,
144
+ section: 'masterCSS'
145
+ });
146
+ }
147
+ const { workspaces, ...languageServiceSettings } = extend(settings, this.customSettings, customWorkspaceFolderSettings);
148
+ const resolvedWorkspaceDirectories = new Set([
149
+ workspaceFolderCWD
150
+ ]);
151
+ this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
152
+ if (workspaces === 'auto') {
153
+ (await glob('**/master.css.*', {
154
+ cwd: workspaceFolderCWD,
155
+ absolute: true,
156
+ onlyFiles: true,
157
+ ignore: [
158
+ '**/node_modules/**'
159
+ ]
160
+ })).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(path.resolve(workspaceFile))));
161
+ } else if (workspaces?.length) {
162
+ (await glob(workspaces, {
163
+ cwd: workspaceFolderCWD,
164
+ absolute: true,
165
+ onlyDirectories: true,
166
+ ignore: [
167
+ '**/node_modules/**'
168
+ ]
169
+ })).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(path.resolve(workspaceDir)));
170
+ }
171
+ resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
172
+ const workspaceURI = URI.file(workspaceDir).toString();
173
+ this.console.info(`Added workspace ${workspaceURI}`);
174
+ this.workspaces.push({
175
+ uri: workspaceURI,
176
+ openedTextDocuments: [],
177
+ languageServiceSettings
178
+ });
179
+ });
180
+ }
181
+ initLanguageService(workspace) {
182
+ let workspaceConfig;
183
+ try {
184
+ workspaceConfig = exploreConfig({
185
+ cwd: URI.parse(workspace.uri).fsPath,
186
+ found: undefined
187
+ });
188
+ } catch (e) {
189
+ this.console.info(`Failed to load config from ${workspace}`);
190
+ this.console.error(e);
191
+ }
192
+ this.console.info(`Initialized workspace ${workspaceConfig ? '(with config file)' : ''} ${workspace.uri}`);
193
+ workspace.languageService = new CSSLanguageService({
194
+ ...workspace.languageServiceSettings,
195
+ config: workspaceConfig
196
+ });
197
+ }
198
+ destroyLanguageService(workspace) {
199
+ this.console.info(`Destroyed workspace ${workspace.uri}`);
200
+ delete workspace.languageService;
201
+ }
202
+ findClosestWorkspace(textDocumentURI) {
203
+ let foundWorkspace;
204
+ for (const workspace of this.workspaces){
205
+ if (textDocumentURI.startsWith(workspace.uri) && (!foundWorkspace || workspace.uri.length > foundWorkspace.uri.length)) {
206
+ foundWorkspace = workspace;
207
+ }
208
+ }
209
+ if (process.env.DEBUG && !foundWorkspace) {
210
+ this.console.info(`This is an external document ${textDocumentURI} assigned to the first workspace`);
211
+ }
212
+ return foundWorkspace || this.workspaces[0];
213
+ }
214
+ getWorkspace(uri) {
215
+ return Array.from(this.workspaces).find((workspace)=>workspace.uri === uri);
216
+ }
217
+ stop() {
218
+ this.connection.sendNotification('masterCSS/dispose');
219
+ this.disposables.forEach((disposable)=>disposable.dispose());
220
+ this.disposables.length = 0;
221
+ this.connection.dispose();
222
+ this.initializing = undefined;
223
+ }
224
+ }
225
+
226
+ export { CSSLanguageServer as default };
package/dist/index.cjs ADDED
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var core = require('./core.cjs');
6
+ var settings = require('./settings.cjs');
7
+
8
+
9
+
10
+ exports.CSSLanguageServer = core;
11
+ exports.default = core;
12
+ exports.settings = settings;
@@ -0,0 +1,3 @@
1
+ export { default, default as CSSLanguageServer } from './core';
2
+ export { default as settings, type Settings } from './settings';
3
+ export type { Workspace } from './core';
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export { default as CSSLanguageServer, default } from './core.mjs';
2
+ export { default as settings } from './settings.mjs';
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ var CSSLanguageService = require('@master/css-language-service');
4
+
5
+ const settings = {
6
+ ...CSSLanguageService.settings,
7
+ workspaces: 'auto',
8
+ verbose: false
9
+ };
10
+
11
+ module.exports = settings;
@@ -0,0 +1,8 @@
1
+ import { type Settings as CSSLanguageServiceSettings } from '@master/css-language-service';
2
+ import type { Pattern } from 'fast-glob';
3
+ declare const settings: Settings;
4
+ export default settings;
5
+ export declare type Settings = CSSLanguageServiceSettings & {
6
+ workspaces?: Pattern[] | 'auto';
7
+ verbose?: boolean;
8
+ };
@@ -0,0 +1,9 @@
1
+ import { settings as settings$1 } from '@master/css-language-service';
2
+
3
+ const settings = {
4
+ ...settings$1,
5
+ workspaces: 'auto',
6
+ verbose: false
7
+ };
8
+
9
+ export { settings as default };
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ var vscodeLanguageserverTextdocument = require('vscode-languageserver-textdocument');
4
+ var nanoid = require('nanoid');
5
+ var path = require('path');
6
+ var vscodeUri = require('vscode-uri');
7
+
8
+ const extOfLang = {
9
+ typescript: 'ts',
10
+ typescriptreact: 'tsx',
11
+ javascript: 'js',
12
+ javascriptreact: 'jsx',
13
+ css: 'css',
14
+ scss: 'scss',
15
+ less: 'less',
16
+ html: 'html',
17
+ json: 'json',
18
+ vue: 'vue',
19
+ svelte: 'svelte',
20
+ astro: 'astro'
21
+ };
22
+ function createDocument(text, options) {
23
+ const lang = options?.lang || 'html';
24
+ const dir = options?.dir || './';
25
+ const filePath = path.join(dir, `${nanoid.nanoid()}.${extOfLang[lang]}`);
26
+ const fileURI = vscodeUri.URI.file(filePath).toString();
27
+ return vscodeLanguageserverTextdocument.TextDocument.create(fileURI, lang, 0, text);
28
+ }
29
+
30
+ module.exports = createDocument;
@@ -0,0 +1,5 @@
1
+ import { TextDocument } from 'vscode-languageserver-textdocument';
2
+ export default function createDocument(text: string, options?: {
3
+ lang?: string;
4
+ dir?: string;
5
+ }): TextDocument;
@@ -0,0 +1,28 @@
1
+ import { TextDocument } from 'vscode-languageserver-textdocument';
2
+ import { nanoid } from 'nanoid';
3
+ import path from 'path';
4
+ import { URI } from 'vscode-uri';
5
+
6
+ const extOfLang = {
7
+ typescript: 'ts',
8
+ typescriptreact: 'tsx',
9
+ javascript: 'js',
10
+ javascriptreact: 'jsx',
11
+ css: 'css',
12
+ scss: 'scss',
13
+ less: 'less',
14
+ html: 'html',
15
+ json: 'json',
16
+ vue: 'vue',
17
+ svelte: 'svelte',
18
+ astro: 'astro'
19
+ };
20
+ function createDocument(text, options) {
21
+ const lang = options?.lang || 'html';
22
+ const dir = options?.dir || './';
23
+ const filePath = path.join(dir, `${nanoid()}.${extOfLang[lang]}`);
24
+ const fileURI = URI.file(filePath).toString();
25
+ return TextDocument.create(fileURI, lang, 0, text);
26
+ }
27
+
28
+ export { createDocument as default };
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@master/css-language-server","scripts":{"build":"techor pack --platform node --declare","dev":"pnpm run build --watch","type-check":"tsc --noEmit","lint":"eslint src","test":"jest"},"description":"Master CSS Language Server","author":"Aoyue Design LLC.","license":"MIT","dependencies":{"@master/css":"^2.0.0-rc.6","@master/css-language-service":"^2.0.0-rc.6","explore-config":"^2.5.24","js-beautify":"^1.14.7","minimatch":"^9.0.1","vscode-languageserver":"^7.0.0","vscode-languageserver-textdocument":"^1.0.9"},"main":"./dist/server.bundle.js","types":"./dist/server.d.ts","files":["dist"],"publishConfig":{"access":"public"},"version":"2.0.0-rc.6"}
1
+ {"name":"@master/css-language-server","type":"module","scripts":{"build":"techor build \"src/**/*.ts\"","dev":"pnpm build --watch","type-check":"tsc --noEmit","lint":"eslint","test":"vitest"},"description":"Master CSS Language Server","author":"Aoyue Design LLC.","license":"MIT","repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/language-server"},"dependencies":{"@master/css":"^2.0.0-rc.60","@master/css-explore-config":"^2.0.0-rc.60","@master/css-language-service":"^2.0.0-rc.60","@techor/extend":"^3.2.0","fast-glob":"^3.3.2","js-beautify":"^1.15.1","nanoid":"^5.0.6","vscode-languageserver":"^9.0.1","vscode-languageserver-textdocument":"^1.0.11","vscode-uri":"^3.0.8"},"devDependencies":{"shared":"^2.0.0-rc.60"},"sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.mjs","jsnext:main":"./dist/index.mjs","esnext":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"}},"files":["dist"],"publishConfig":{"access":"public","provenance":true},"version":"2.0.0-rc.60"}
@@ -1 +0,0 @@
1
- "use strict";var W=Object.create;var S=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var E=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of H(e))!L.call(t,i)&&i!==n&&S(t,i,{get:()=>e[i],enumerable:!(s=U(e,i))||s.enumerable});return t};var h=(t,e,n)=>(n=t!=null?W(K(t)):{},E(e||!t||!t.__esModule?S(n,"default",{value:t,enumerable:!0}):n,t));var u=require("vscode-languageserver/node"),w=require("@master/css"),b=require("minimatch"),P=require("vscode-languageserver-textdocument"),k=h(require("path")),T=require("url"),o=require("@master/css-language-service"),v=h(require("explore-config")),a=(0,u.createConnection)(u.ProposedFeatures.all),f=new u.TextDocuments(P.TextDocument),C=!1,D=!1,O=!1,l,g,I;var M=o.settings,p=new Map;a.onDidChangeConfiguration(t=>{C?p.clear():M=t.settings.masterCSS||o.settings,f.all().forEach(y)});async function B(t){if(!C)return Promise.resolve(M);let e=p.get(t);return e||(e=a.workspace.getConfiguration({scopeUri:t,section:"masterCSS"}),p.set(t,e)),e}f.onDidClose(t=>{p.delete(t.document.uri)});f.onDidOpen(t=>{y(t.document)});f.onDidSave(async t=>{k.default.parse(t.document.uri).name==="master.css"&&await A(t.document.uri)});async function y(t){l=await B(t.uri),await A(t.uri)}async function A(t){let e=await a.workspace.getWorkspaceFolders(),n;if(e?.length===1?n=e[0]:n=e?.find(s=>t.includes(s.uri)),n?.uri){let s=(0,T.fileURLToPath)(n.uri.replace("%3A",":"));I=(0,v.default)(l.config||"master.css.*",{cwd:s}),g=new w.MasterCSS(I)}}a.onInitialize(t=>{let e=t.capabilities;C=!!(e.workspace&&e.workspace.configuration),D=!!(e.workspace&&e.workspace.workspaceFolders),O=!!(e.textDocument&&e.textDocument.publishDiagnostics&&e.textDocument.publishDiagnostics.relatedInformation);let n={capabilities:{textDocumentSync:u.TextDocumentSyncKind.Incremental,completionProvider:{resolveProvider:!0,workDoneProgress:!1,triggerCharacters:[":","@","'"]},colorProvider:{},hoverProvider:!0}};return D&&(n.capabilities.workspace={workspaceFolders:{supported:!0}}),n});a.onInitialized(()=>{C&&a.client.register(u.DidChangeConfigurationNotification.type,void 0)});a.onCompletion(t=>{if(l.suggestions==!0&&x(t.textDocument.uri)){let e=t.textDocument.uri,n=f.get(e),s=e.substring(e.lastIndexOf(".")+1),i=t.position;if(n){let c=n.getText(),d=n.offsetAt(i)??0,r=n.offsetAt({line:i.line-100,character:0})??0,F=n.offsetAt({line:i.line+100,character:0})??void 0,R=(0,o.positionCheck)(c.substring(r,F),d,r,l.classMatch).IsMatch,z=n.getText({start:{line:i.line,character:0},end:{line:i.line,character:i.character}}).trim(),m=(0,o.getLastInstance)(z,i,s);if(m.isInstance==!0&&R==!0)return(0,o.getCompletionItem)(m.lastKey,m.triggerKey,m.isStart,m.language,g);if(m.isInstance==!0&&(0,o.checkConfigColorsBlock)(n,t.position)==!0)return(0,o.getConfigColorsCompletionItem)(g)}}return[]});a.onCompletionResolve(t=>t);a.onDocumentColor(async t=>{if(l==null)return[];if(l.previewColors==!0&&x(t.textDocument.uri)){let e=t.textDocument.uri,n=f.get(e);if(n){let s=n.getText()??"";if(typeof n==null)return[];let i=await(0,o.getDocumentColors)(s,g),c=new Set;return i.filter(r=>c.has(r.index.start)?!1:(c.add(r.index.start),!0)).map(r=>({range:{start:n.positionAt(r.index.start),end:n.positionAt(r.index.end)},color:r.color}))}}return[]});a.onColorPresentation(t=>{if(l.previewColors==!0&&x(t.textDocument.uri)){let e=f.get(t.textDocument.uri);if(e){let n=e.getText(),s=["(?<=colors:\\s*{\\s*.*)([^}]*)}"],i=e.offsetAt(t.range.start)??0,c=e.offsetAt({line:t.range.start.line-100,character:0})??0,d=e.offsetAt({line:t.range.start.line+100,character:0})??void 0,r=(0,o.positionCheck)(n.substring(c,d),i,c,s);return(0,o.getColorPresentation)(t,r.IsMatch)}}return[]});a.onHover(t=>{if(l.inspect==!0&&x(t.textDocument.uri)){let e=f.get(t.textDocument.uri),n=t.position;if(e){let s=e.getText(),i=e.offsetAt(n)??0,c=e.offsetAt({line:n.line-100,character:0})??0,d=e.offsetAt({line:n.line+100,character:0})??void 0,r=(0,o.positionCheck)(s.substring(c,d),i,c,l.classMatch);if(r.IsMatch)return(0,o.doHover)(r.instance.instanceString,N(r.instance.index,e),I)}}return null});function x(t){for(let e of l.files.exclude)if((0,b.minimatch)(t,e))return!1;return!0}function N(t,e){return{start:e.positionAt(t.start),end:e.positionAt(t.end)}}f.listen(a);a.listen();
package/dist/server.d.ts DELETED
@@ -1 +0,0 @@
1
- export {};