@master/css-language-server 2.0.0-rc.38 → 2.0.0-rc.39
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/core.cjs +143 -115
- package/dist/core.d.ts +26 -12
- package/dist/core.mjs +144 -116
- package/dist/index.d.ts +1 -0
- package/dist/settings.cjs +2 -1
- package/dist/settings.d.ts +2 -1
- package/dist/settings.mjs +2 -1
- package/dist/utils/create-document.cjs +30 -0
- package/dist/utils/create-document.d.ts +5 -0
- package/dist/utils/create-document.mjs +28 -0
- package/package.json +1 -1
- package/dist/utils/intercept-logs.cjs +0 -17
- package/dist/utils/intercept-logs.d.ts +0 -2
- package/dist/utils/intercept-logs.mjs +0 -15
package/dist/core.cjs
CHANGED
|
@@ -2,132 +2,157 @@
|
|
|
2
2
|
|
|
3
3
|
var node = require('vscode-languageserver/node');
|
|
4
4
|
var vscodeLanguageserverTextdocument = require('vscode-languageserver-textdocument');
|
|
5
|
-
var path = require('path');
|
|
5
|
+
var path = require('node:path');
|
|
6
6
|
var CSSLanguageService = require('@master/css-language-service');
|
|
7
7
|
var exploreConfig = require('@master/css-explore-config');
|
|
8
8
|
var extend = require('@techor/extend');
|
|
9
9
|
var settings = require('./settings.cjs');
|
|
10
|
-
var interceptLogs = require('./utils/intercept-logs.cjs');
|
|
11
10
|
var glob = require('fast-glob');
|
|
12
11
|
var vscodeUri = require('vscode-uri');
|
|
13
12
|
|
|
14
13
|
class CSSLanguageServer {
|
|
14
|
+
connection;
|
|
15
15
|
customSettings;
|
|
16
16
|
workspaceFolders;
|
|
17
17
|
workspaces;
|
|
18
|
-
connection;
|
|
19
18
|
documents;
|
|
20
19
|
initializing;
|
|
20
|
+
clientCapabilities;
|
|
21
|
+
settings;
|
|
22
|
+
console;
|
|
21
23
|
disposables;
|
|
22
|
-
constructor(customSettings){
|
|
24
|
+
constructor(connection = process.argv.includes('--stdio') ? node.createConnection(process.stdin, process.stdout) : node.createConnection(), customSettings){
|
|
25
|
+
this.connection = connection;
|
|
23
26
|
this.customSettings = customSettings;
|
|
24
27
|
this.workspaceFolders = [];
|
|
25
|
-
this.workspaces =
|
|
28
|
+
this.workspaces = [];
|
|
29
|
+
this.clientCapabilities = {};
|
|
26
30
|
this.disposables = [];
|
|
27
|
-
if (process.argv.includes('--stdio')) {
|
|
28
|
-
this.connection = node.createConnection(process.stdin, process.stdout);
|
|
29
|
-
} else {
|
|
30
|
-
this.connection = node.createConnection();
|
|
31
|
-
}
|
|
32
|
-
interceptLogs(console, this.connection);
|
|
33
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
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
36
|
+
if (!this.settings?.verbose) return ()=>{};
|
|
37
|
+
return this.connection.console[prop];
|
|
38
|
+
}
|
|
39
|
+
});
|
|
34
40
|
}
|
|
35
41
|
start() {
|
|
36
|
-
this.disposables.push(this.documents.onDidSave(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
}), this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(async ({ settings })=>{
|
|
60
|
-
await this.initializing;
|
|
61
|
-
if (settings?.masterCSS) {
|
|
62
|
-
this.connection.sendNotification('masterCSS/globalSettingsChanged', settings.masterCSS);
|
|
63
|
-
this.customSettings = settings.masterCSS;
|
|
64
|
-
this.connection.sendRequest('masterCSS/restart', {
|
|
65
|
-
title: 'Updating Master CSS settings'
|
|
42
|
+
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()));
|
|
43
|
+
this.connection.listen();
|
|
44
|
+
}
|
|
45
|
+
init() {
|
|
46
|
+
if (this.initializing) return this.initializing;
|
|
47
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
48
|
+
return this.initializing = new Promise(async (resolve)=>{
|
|
49
|
+
await Promise.all(this.workspaceFolders.map((folder)=>this.initWorkspaceFolder(folder.uri)));
|
|
50
|
+
resolve();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
onInitialize(params) {
|
|
54
|
+
this.clientCapabilities = params.capabilities;
|
|
55
|
+
if (params.workspaceFolders?.length) {
|
|
56
|
+
this.workspaceFolders = params.workspaceFolders;
|
|
57
|
+
} else {
|
|
58
|
+
/**
|
|
59
|
+
* @deprecated — in favour of workspaceFolders
|
|
60
|
+
*/ if (params.rootUri) {
|
|
61
|
+
this.workspaceFolders.push({
|
|
62
|
+
name: '',
|
|
63
|
+
uri: params.rootUri
|
|
66
64
|
});
|
|
67
65
|
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
if (workspace
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
this.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
capabilities: CSSLanguageService.SERVER_CAPABILITIES
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async onHover(params) {
|
|
72
|
+
await this.init();
|
|
73
|
+
const workspace = this.findClosestWorkspace(params.textDocument.uri);
|
|
74
|
+
if (workspace.languageService) {
|
|
75
|
+
const document = this.documents.get(params.textDocument.uri);
|
|
76
|
+
if (document) return workspace.languageService.inspectSyntax(document, params.position);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async onCompletion(params) {
|
|
80
|
+
await this.init();
|
|
81
|
+
const workspace = this.findClosestWorkspace(params.textDocument.uri);
|
|
82
|
+
if (workspace.languageService) {
|
|
83
|
+
const document = this.documents.get(params.textDocument.uri);
|
|
84
|
+
if (document) return workspace.languageService.suggestSyntax(document, params.position, params.context);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async onDocumentColor(params) {
|
|
88
|
+
await this.init();
|
|
89
|
+
const workspace = this.findClosestWorkspace(params.textDocument.uri);
|
|
90
|
+
if (workspace.languageService) {
|
|
91
|
+
const document = this.documents.get(params.textDocument.uri);
|
|
92
|
+
if (document) return workspace.languageService.renderSyntaxColors(document);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async onColorPresentation(params) {
|
|
96
|
+
await this.init();
|
|
97
|
+
const workspace = this.findClosestWorkspace(params.textDocument.uri);
|
|
98
|
+
if (workspace.languageService) {
|
|
99
|
+
const document = this.documents.get(params.textDocument.uri);
|
|
100
|
+
if (document) return workspace.languageService.editSyntaxColors(document, params.color, params.range);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async onDidOpen(params) {
|
|
104
|
+
await this.init();
|
|
105
|
+
const workspace = this.findClosestWorkspace(params.document.uri);
|
|
106
|
+
if (!workspace || workspace.openedTextDocuments.includes(params.document)) return;
|
|
107
|
+
if (!workspace.openedTextDocuments.length) {
|
|
108
|
+
this.initLanguageService(workspace);
|
|
109
|
+
}
|
|
110
|
+
workspace.openedTextDocuments.push(params.document);
|
|
111
|
+
}
|
|
112
|
+
async onDidClose(params) {
|
|
113
|
+
await this.init();
|
|
114
|
+
const workspace = this.findClosestWorkspace(params.document.uri);
|
|
115
|
+
if (!workspace) return;
|
|
116
|
+
workspace.openedTextDocuments.splice(workspace.openedTextDocuments.indexOf(params.document), 1);
|
|
117
|
+
if (!workspace.openedTextDocuments.length) {
|
|
118
|
+
this.destroyLanguageService(workspace);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async onDidSave(params) {
|
|
122
|
+
await this.init();
|
|
123
|
+
const workspace = this.findClosestWorkspace(params.document.uri);
|
|
124
|
+
if (!workspace) return;
|
|
125
|
+
const name = path.parse(params.document.uri).name;
|
|
126
|
+
if (name === 'master.css' || name.endsWith('.css')) {
|
|
127
|
+
this.connection.sendRequest('masterCSS/restart', {
|
|
128
|
+
title: 'Updating Master CSS configuration'
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async onDidChangeConfiguration({ settings }) {
|
|
133
|
+
await this.init();
|
|
134
|
+
if (settings?.masterCSS) {
|
|
135
|
+
this.connection.sendNotification('masterCSS/globalSettingsChanged', settings.masterCSS);
|
|
136
|
+
this.customSettings = settings.masterCSS;
|
|
137
|
+
this.connection.sendRequest('masterCSS/restart', {
|
|
138
|
+
title: 'Updating Master CSS settings'
|
|
139
|
+
});
|
|
140
|
+
}
|
|
119
141
|
}
|
|
120
142
|
async initWorkspaceFolder(workspaceFolderURI) {
|
|
121
143
|
const workspaceFolderCWD = vscodeUri.URI.parse(workspaceFolderURI).fsPath;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
144
|
+
let customWorkspaceFolderSettings;
|
|
145
|
+
if (this.clientCapabilities.workspace?.configuration) {
|
|
146
|
+
customWorkspaceFolderSettings = await this.connection.workspace.getConfiguration({
|
|
147
|
+
scopeUri: workspaceFolderURI,
|
|
148
|
+
section: 'masterCSS'
|
|
149
|
+
});
|
|
150
|
+
}
|
|
126
151
|
const { workspaces, ...languageServiceSettings } = extend(settings, this.customSettings, customWorkspaceFolderSettings);
|
|
127
152
|
const resolvedWorkspaceDirectories = new Set([
|
|
128
153
|
workspaceFolderCWD
|
|
129
154
|
]);
|
|
130
|
-
console.info(
|
|
155
|
+
this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
|
|
131
156
|
if (workspaces === 'auto') {
|
|
132
157
|
(await glob('**/master.css.*', {
|
|
133
158
|
cwd: workspaceFolderCWD,
|
|
@@ -136,7 +161,7 @@ class CSSLanguageServer {
|
|
|
136
161
|
ignore: [
|
|
137
162
|
'**/node_modules/**'
|
|
138
163
|
]
|
|
139
|
-
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(workspaceFile)));
|
|
164
|
+
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(path.resolve(workspaceFile))));
|
|
140
165
|
} else if (workspaces?.length) {
|
|
141
166
|
(await glob(workspaces, {
|
|
142
167
|
cwd: workspaceFolderCWD,
|
|
@@ -145,39 +170,38 @@ class CSSLanguageServer {
|
|
|
145
170
|
ignore: [
|
|
146
171
|
'**/node_modules/**'
|
|
147
172
|
]
|
|
148
|
-
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(workspaceDir));
|
|
173
|
+
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(path.resolve(workspaceDir)));
|
|
149
174
|
}
|
|
150
175
|
resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
|
|
151
176
|
const workspaceURI = vscodeUri.URI.file(workspaceDir).toString();
|
|
152
|
-
console.info(
|
|
153
|
-
this.workspaces.
|
|
154
|
-
path: workspaceDir,
|
|
177
|
+
this.console.info(`Added workspace ${workspaceURI}`);
|
|
178
|
+
this.workspaces.push({
|
|
155
179
|
uri: workspaceURI,
|
|
156
|
-
openedTextDocuments:
|
|
180
|
+
openedTextDocuments: [],
|
|
157
181
|
languageServiceSettings
|
|
158
182
|
});
|
|
159
183
|
});
|
|
160
184
|
}
|
|
161
|
-
|
|
185
|
+
initLanguageService(workspace) {
|
|
162
186
|
let workspaceConfig;
|
|
163
187
|
try {
|
|
164
188
|
workspaceConfig = exploreConfig({
|
|
165
|
-
cwd: workspace.
|
|
189
|
+
cwd: vscodeUri.URI.parse(workspace.uri).fsPath,
|
|
166
190
|
found: undefined
|
|
167
191
|
});
|
|
168
192
|
} catch (e) {
|
|
169
|
-
console.info(
|
|
170
|
-
console.error(e);
|
|
193
|
+
this.console.info(`Failed to load config from ${workspace}`);
|
|
194
|
+
this.console.error(e);
|
|
171
195
|
}
|
|
172
|
-
console.info(
|
|
173
|
-
workspace.
|
|
196
|
+
this.console.info(`Initialized workspace ${workspaceConfig ? '(with config file)' : ''} ${workspace.uri}`);
|
|
197
|
+
workspace.languageService = new CSSLanguageService({
|
|
174
198
|
...workspace.languageServiceSettings,
|
|
175
199
|
config: workspaceConfig
|
|
176
200
|
});
|
|
177
201
|
}
|
|
178
|
-
|
|
179
|
-
console.info(
|
|
180
|
-
delete workspace.
|
|
202
|
+
destroyLanguageService(workspace) {
|
|
203
|
+
this.console.info(`Destroyed workspace ${workspace.uri}`);
|
|
204
|
+
delete workspace.languageService;
|
|
181
205
|
}
|
|
182
206
|
findClosestWorkspace(textDocumentURI) {
|
|
183
207
|
let foundWorkspace;
|
|
@@ -186,16 +210,20 @@ class CSSLanguageServer {
|
|
|
186
210
|
foundWorkspace = workspace;
|
|
187
211
|
}
|
|
188
212
|
}
|
|
189
|
-
if (!foundWorkspace) {
|
|
190
|
-
|
|
213
|
+
if (process.env.DEBUG && !foundWorkspace) {
|
|
214
|
+
this.console.info(`This is an external document ${textDocumentURI} assigned to the first workspace`);
|
|
191
215
|
}
|
|
192
|
-
return foundWorkspace;
|
|
216
|
+
return foundWorkspace || this.workspaces[0];
|
|
217
|
+
}
|
|
218
|
+
getWorkspace(uri) {
|
|
219
|
+
return Array.from(this.workspaces).find((workspace)=>workspace.uri === uri);
|
|
193
220
|
}
|
|
194
221
|
stop() {
|
|
195
222
|
this.connection.sendNotification('masterCSS/dispose');
|
|
196
223
|
this.disposables.forEach((disposable)=>disposable.dispose());
|
|
197
224
|
this.disposables.length = 0;
|
|
198
225
|
this.connection.dispose();
|
|
226
|
+
this.initializing = undefined;
|
|
199
227
|
}
|
|
200
228
|
}
|
|
201
229
|
|
package/dist/core.d.ts
CHANGED
|
@@ -1,28 +1,42 @@
|
|
|
1
|
-
import { TextDocuments, WorkspaceFolder, Connection } from 'vscode-languageserver/node';
|
|
1
|
+
import { TextDocuments, InitializeParams, WorkspaceFolder, Connection, ClientCapabilities, TextDocumentChangeEvent, DidChangeConfigurationParams, HoverParams, CompletionParams, DocumentColorParams, ColorPresentationParams, RemoteConsole } from 'vscode-languageserver/node';
|
|
2
2
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
3
3
|
import CSSLanguageService, { Settings as CSSLanguageServiceSettings } from '@master/css-language-service';
|
|
4
4
|
import { Settings } from './settings';
|
|
5
|
-
declare type Workspace = {
|
|
6
|
-
path: string;
|
|
5
|
+
export declare type Workspace = {
|
|
7
6
|
uri: string;
|
|
8
|
-
openedTextDocuments:
|
|
9
|
-
|
|
7
|
+
openedTextDocuments: TextDocument[];
|
|
8
|
+
languageService?: CSSLanguageService;
|
|
10
9
|
languageServiceSettings: CSSLanguageServiceSettings;
|
|
11
10
|
};
|
|
12
11
|
export default class CSSLanguageServer {
|
|
12
|
+
connection: Connection;
|
|
13
13
|
customSettings?: Settings | undefined;
|
|
14
14
|
workspaceFolders: WorkspaceFolder[];
|
|
15
|
-
workspaces:
|
|
16
|
-
connection: Connection;
|
|
15
|
+
workspaces: Workspace[];
|
|
17
16
|
documents: TextDocuments<TextDocument>;
|
|
18
|
-
initializing?: Promise<
|
|
17
|
+
initializing?: Promise<void>;
|
|
18
|
+
clientCapabilities: ClientCapabilities;
|
|
19
|
+
settings?: Settings;
|
|
20
|
+
console: RemoteConsole;
|
|
19
21
|
private disposables;
|
|
20
|
-
constructor(customSettings?: Settings | undefined);
|
|
22
|
+
constructor(connection?: Connection, customSettings?: Settings | undefined);
|
|
21
23
|
start(): void;
|
|
24
|
+
init(): Promise<void>;
|
|
25
|
+
onInitialize(params: InitializeParams): {
|
|
26
|
+
capabilities: import("vscode-languageserver/node").ServerCapabilities<any>;
|
|
27
|
+
};
|
|
28
|
+
onHover(params: HoverParams): Promise<import("vscode-languageserver/node").Hover | undefined>;
|
|
29
|
+
onCompletion(params: CompletionParams): Promise<import("vscode-languageserver/node").CompletionItem[] | undefined>;
|
|
30
|
+
onDocumentColor(params: DocumentColorParams): Promise<import("vscode-languageserver/node").ColorInformation[] | undefined>;
|
|
31
|
+
onColorPresentation(params: ColorPresentationParams): Promise<import("vscode-languageserver/node").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>;
|
|
22
36
|
private initWorkspaceFolder;
|
|
23
|
-
|
|
24
|
-
|
|
37
|
+
initLanguageService(workspace: Workspace): void;
|
|
38
|
+
destroyLanguageService(workspace: Workspace): void;
|
|
25
39
|
findClosestWorkspace(textDocumentURI: string): Workspace;
|
|
40
|
+
getWorkspace(uri: string): Workspace | undefined;
|
|
26
41
|
stop(): void;
|
|
27
42
|
}
|
|
28
|
-
export {};
|
package/dist/core.mjs
CHANGED
|
@@ -1,131 +1,156 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TextDocuments, createConnection } from 'vscode-languageserver/node';
|
|
2
2
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
3
|
-
import path from 'path';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import CSSLanguageService, { SERVER_CAPABILITIES } from '@master/css-language-service';
|
|
5
5
|
import exploreConfig from '@master/css-explore-config';
|
|
6
6
|
import extend from '@techor/extend';
|
|
7
7
|
import settings from './settings.mjs';
|
|
8
|
-
import interceptLogs from './utils/intercept-logs.mjs';
|
|
9
8
|
import glob from 'fast-glob';
|
|
10
9
|
import { URI } from 'vscode-uri';
|
|
11
10
|
|
|
12
11
|
class CSSLanguageServer {
|
|
12
|
+
connection;
|
|
13
13
|
customSettings;
|
|
14
14
|
workspaceFolders;
|
|
15
15
|
workspaces;
|
|
16
|
-
connection;
|
|
17
16
|
documents;
|
|
18
17
|
initializing;
|
|
18
|
+
clientCapabilities;
|
|
19
|
+
settings;
|
|
20
|
+
console;
|
|
19
21
|
disposables;
|
|
20
|
-
constructor(customSettings){
|
|
22
|
+
constructor(connection = process.argv.includes('--stdio') ? createConnection(process.stdin, process.stdout) : createConnection(), customSettings){
|
|
23
|
+
this.connection = connection;
|
|
21
24
|
this.customSettings = customSettings;
|
|
22
25
|
this.workspaceFolders = [];
|
|
23
|
-
this.workspaces =
|
|
26
|
+
this.workspaces = [];
|
|
27
|
+
this.clientCapabilities = {};
|
|
24
28
|
this.disposables = [];
|
|
25
|
-
if (process.argv.includes('--stdio')) {
|
|
26
|
-
this.connection = createConnection(process.stdin, process.stdout);
|
|
27
|
-
} else {
|
|
28
|
-
this.connection = createConnection();
|
|
29
|
-
}
|
|
30
|
-
interceptLogs(console, this.connection);
|
|
31
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
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
34
|
+
if (!this.settings?.verbose) return ()=>{};
|
|
35
|
+
return this.connection.console[prop];
|
|
36
|
+
}
|
|
37
|
+
});
|
|
32
38
|
}
|
|
33
39
|
start() {
|
|
34
|
-
this.disposables.push(this.documents.onDidSave(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
}), this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(async ({ settings })=>{
|
|
58
|
-
await this.initializing;
|
|
59
|
-
if (settings?.masterCSS) {
|
|
60
|
-
this.connection.sendNotification('masterCSS/globalSettingsChanged', settings.masterCSS);
|
|
61
|
-
this.customSettings = settings.masterCSS;
|
|
62
|
-
this.connection.sendRequest('masterCSS/restart', {
|
|
63
|
-
title: 'Updating Master CSS settings'
|
|
40
|
+
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()));
|
|
41
|
+
this.connection.listen();
|
|
42
|
+
}
|
|
43
|
+
init() {
|
|
44
|
+
if (this.initializing) return this.initializing;
|
|
45
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
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
|
|
64
62
|
});
|
|
65
63
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
if (workspace
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
this.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
capabilities: 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
|
+
}
|
|
117
139
|
}
|
|
118
140
|
async initWorkspaceFolder(workspaceFolderURI) {
|
|
119
141
|
const workspaceFolderCWD = URI.parse(workspaceFolderURI).fsPath;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
142
|
+
let customWorkspaceFolderSettings;
|
|
143
|
+
if (this.clientCapabilities.workspace?.configuration) {
|
|
144
|
+
customWorkspaceFolderSettings = await this.connection.workspace.getConfiguration({
|
|
145
|
+
scopeUri: workspaceFolderURI,
|
|
146
|
+
section: 'masterCSS'
|
|
147
|
+
});
|
|
148
|
+
}
|
|
124
149
|
const { workspaces, ...languageServiceSettings } = extend(settings, this.customSettings, customWorkspaceFolderSettings);
|
|
125
150
|
const resolvedWorkspaceDirectories = new Set([
|
|
126
151
|
workspaceFolderCWD
|
|
127
152
|
]);
|
|
128
|
-
console.info(
|
|
153
|
+
this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
|
|
129
154
|
if (workspaces === 'auto') {
|
|
130
155
|
(await glob('**/master.css.*', {
|
|
131
156
|
cwd: workspaceFolderCWD,
|
|
@@ -134,7 +159,7 @@ class CSSLanguageServer {
|
|
|
134
159
|
ignore: [
|
|
135
160
|
'**/node_modules/**'
|
|
136
161
|
]
|
|
137
|
-
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(workspaceFile)));
|
|
162
|
+
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(path.resolve(workspaceFile))));
|
|
138
163
|
} else if (workspaces?.length) {
|
|
139
164
|
(await glob(workspaces, {
|
|
140
165
|
cwd: workspaceFolderCWD,
|
|
@@ -143,39 +168,38 @@ class CSSLanguageServer {
|
|
|
143
168
|
ignore: [
|
|
144
169
|
'**/node_modules/**'
|
|
145
170
|
]
|
|
146
|
-
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(workspaceDir));
|
|
171
|
+
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(path.resolve(workspaceDir)));
|
|
147
172
|
}
|
|
148
173
|
resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
|
|
149
174
|
const workspaceURI = URI.file(workspaceDir).toString();
|
|
150
|
-
console.info(
|
|
151
|
-
this.workspaces.
|
|
152
|
-
path: workspaceDir,
|
|
175
|
+
this.console.info(`Added workspace ${workspaceURI}`);
|
|
176
|
+
this.workspaces.push({
|
|
153
177
|
uri: workspaceURI,
|
|
154
|
-
openedTextDocuments:
|
|
178
|
+
openedTextDocuments: [],
|
|
155
179
|
languageServiceSettings
|
|
156
180
|
});
|
|
157
181
|
});
|
|
158
182
|
}
|
|
159
|
-
|
|
183
|
+
initLanguageService(workspace) {
|
|
160
184
|
let workspaceConfig;
|
|
161
185
|
try {
|
|
162
186
|
workspaceConfig = exploreConfig({
|
|
163
|
-
cwd: workspace.
|
|
187
|
+
cwd: URI.parse(workspace.uri).fsPath,
|
|
164
188
|
found: undefined
|
|
165
189
|
});
|
|
166
190
|
} catch (e) {
|
|
167
|
-
console.info(
|
|
168
|
-
console.error(e);
|
|
191
|
+
this.console.info(`Failed to load config from ${workspace}`);
|
|
192
|
+
this.console.error(e);
|
|
169
193
|
}
|
|
170
|
-
console.info(
|
|
171
|
-
workspace.
|
|
194
|
+
this.console.info(`Initialized workspace ${workspaceConfig ? '(with config file)' : ''} ${workspace.uri}`);
|
|
195
|
+
workspace.languageService = new CSSLanguageService({
|
|
172
196
|
...workspace.languageServiceSettings,
|
|
173
197
|
config: workspaceConfig
|
|
174
198
|
});
|
|
175
199
|
}
|
|
176
|
-
|
|
177
|
-
console.info(
|
|
178
|
-
delete workspace.
|
|
200
|
+
destroyLanguageService(workspace) {
|
|
201
|
+
this.console.info(`Destroyed workspace ${workspace.uri}`);
|
|
202
|
+
delete workspace.languageService;
|
|
179
203
|
}
|
|
180
204
|
findClosestWorkspace(textDocumentURI) {
|
|
181
205
|
let foundWorkspace;
|
|
@@ -184,16 +208,20 @@ class CSSLanguageServer {
|
|
|
184
208
|
foundWorkspace = workspace;
|
|
185
209
|
}
|
|
186
210
|
}
|
|
187
|
-
if (!foundWorkspace) {
|
|
188
|
-
|
|
211
|
+
if (process.env.DEBUG && !foundWorkspace) {
|
|
212
|
+
this.console.info(`This is an external document ${textDocumentURI} assigned to the first workspace`);
|
|
189
213
|
}
|
|
190
|
-
return foundWorkspace;
|
|
214
|
+
return foundWorkspace || this.workspaces[0];
|
|
215
|
+
}
|
|
216
|
+
getWorkspace(uri) {
|
|
217
|
+
return Array.from(this.workspaces).find((workspace)=>workspace.uri === uri);
|
|
191
218
|
}
|
|
192
219
|
stop() {
|
|
193
220
|
this.connection.sendNotification('masterCSS/dispose');
|
|
194
221
|
this.disposables.forEach((disposable)=>disposable.dispose());
|
|
195
222
|
this.disposables.length = 0;
|
|
196
223
|
this.connection.dispose();
|
|
224
|
+
this.initializing = undefined;
|
|
197
225
|
}
|
|
198
226
|
}
|
|
199
227
|
|
package/dist/index.d.ts
CHANGED
package/dist/settings.cjs
CHANGED
package/dist/settings.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import { type Settings as CSSLanguageServiceSettings } from '@master/css-languag
|
|
|
2
2
|
declare const settings: Settings;
|
|
3
3
|
export default settings;
|
|
4
4
|
export declare type Settings = CSSLanguageServiceSettings & {
|
|
5
|
-
workspaces
|
|
5
|
+
workspaces?: string[] | 'auto';
|
|
6
|
+
verbose?: boolean;
|
|
6
7
|
};
|
package/dist/settings.mjs
CHANGED
|
@@ -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,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","type":"module","scripts":{"build":"techor build \"src/**/*.ts\"","dev":"pnpm build --watch","type-check":"tsc --noEmit","lint":"eslint src","test":"
|
|
1
|
+
{"name":"@master/css-language-server","type":"module","scripts":{"build":"techor build \"src/**/*.ts\"","dev":"pnpm build --watch","type-check":"tsc --noEmit","lint":"eslint src","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.39","@master/css-explore-config":"^2.0.0-rc.39","@master/css-language-service":"^2.0.0-rc.39","@techor/extend":"^3.0.22","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":{"@master/css-shared":"^2.0.0-rc.39"},"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":{".":{"import":"./dist/index.mjs","require":"./dist/index.cjs","types":"./dist/index.d.ts"}},"files":["dist"],"publishConfig":{"access":"public","provenance":true},"version":"2.0.0-rc.39"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var node_util = require('node:util');
|
|
4
|
-
|
|
5
|
-
function formatMessages(params) {
|
|
6
|
-
return params.map((item)=>node_util.format(item)).join(' ');
|
|
7
|
-
}
|
|
8
|
-
function interceptLogs(console, connection) {
|
|
9
|
-
console.debug = (...params)=>connection.console.info(formatMessages(params));
|
|
10
|
-
console.error = (...params)=>connection.console.error(formatMessages(params));
|
|
11
|
-
console.warn = (...params)=>connection.console.warn(formatMessages(params));
|
|
12
|
-
console.info = (...params)=>connection.console.info(formatMessages(params));
|
|
13
|
-
console.log = (...params)=>connection.console.log(formatMessages(params));
|
|
14
|
-
return console;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = interceptLogs;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { format } from 'node:util';
|
|
2
|
-
|
|
3
|
-
function formatMessages(params) {
|
|
4
|
-
return params.map((item)=>format(item)).join(' ');
|
|
5
|
-
}
|
|
6
|
-
function interceptLogs(console, connection) {
|
|
7
|
-
console.debug = (...params)=>connection.console.info(formatMessages(params));
|
|
8
|
-
console.error = (...params)=>connection.console.error(formatMessages(params));
|
|
9
|
-
console.warn = (...params)=>connection.console.warn(formatMessages(params));
|
|
10
|
-
console.info = (...params)=>connection.console.info(formatMessages(params));
|
|
11
|
-
console.log = (...params)=>connection.console.log(formatMessages(params));
|
|
12
|
-
return console;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export { interceptLogs as default };
|