@master/css-language-server 2.0.0-rc.37 → 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 +147 -125
- package/dist/core.d.ts +26 -13
- package/dist/core.mjs +148 -126
- 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,133 +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');
|
|
6
|
-
var url = require('url');
|
|
5
|
+
var path = require('node:path');
|
|
7
6
|
var CSSLanguageService = require('@master/css-language-service');
|
|
8
7
|
var exploreConfig = require('@master/css-explore-config');
|
|
9
8
|
var extend = require('@techor/extend');
|
|
10
9
|
var settings = require('./settings.cjs');
|
|
11
|
-
var interceptLogs = require('./utils/intercept-logs.cjs');
|
|
12
10
|
var glob = require('fast-glob');
|
|
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
|
-
const workspaceFolderCWD =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
143
|
+
const workspaceFolderCWD = vscodeUri.URI.parse(workspaceFolderURI).fsPath;
|
|
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(
|
|
131
|
-
console.log(workspaceFolderCWD);
|
|
155
|
+
this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
|
|
132
156
|
if (workspaces === 'auto') {
|
|
133
157
|
(await glob('**/master.css.*', {
|
|
134
158
|
cwd: workspaceFolderCWD,
|
|
@@ -137,7 +161,7 @@ class CSSLanguageServer {
|
|
|
137
161
|
ignore: [
|
|
138
162
|
'**/node_modules/**'
|
|
139
163
|
]
|
|
140
|
-
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(workspaceFile)));
|
|
164
|
+
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(path.resolve(workspaceFile))));
|
|
141
165
|
} else if (workspaces?.length) {
|
|
142
166
|
(await glob(workspaces, {
|
|
143
167
|
cwd: workspaceFolderCWD,
|
|
@@ -146,44 +170,38 @@ class CSSLanguageServer {
|
|
|
146
170
|
ignore: [
|
|
147
171
|
'**/node_modules/**'
|
|
148
172
|
]
|
|
149
|
-
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(workspaceDir));
|
|
173
|
+
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(path.resolve(workspaceDir)));
|
|
150
174
|
}
|
|
151
175
|
resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
|
|
152
|
-
|
|
153
|
-
console.
|
|
154
|
-
this.workspaces.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
openedTextDocuments: new Set(),
|
|
176
|
+
const workspaceURI = vscodeUri.URI.file(workspaceDir).toString();
|
|
177
|
+
this.console.info(`Added workspace ${workspaceURI}`);
|
|
178
|
+
this.workspaces.push({
|
|
179
|
+
uri: workspaceURI,
|
|
180
|
+
openedTextDocuments: [],
|
|
158
181
|
languageServiceSettings
|
|
159
182
|
});
|
|
160
183
|
});
|
|
161
184
|
}
|
|
162
|
-
|
|
185
|
+
initLanguageService(workspace) {
|
|
163
186
|
let workspaceConfig;
|
|
164
187
|
try {
|
|
165
188
|
workspaceConfig = exploreConfig({
|
|
166
|
-
cwd: workspace.
|
|
189
|
+
cwd: vscodeUri.URI.parse(workspace.uri).fsPath,
|
|
167
190
|
found: undefined
|
|
168
191
|
});
|
|
169
192
|
} catch (e) {
|
|
170
|
-
console.info(
|
|
171
|
-
console.error(e);
|
|
193
|
+
this.console.info(`Failed to load config from ${workspace}`);
|
|
194
|
+
this.console.error(e);
|
|
172
195
|
}
|
|
173
|
-
console.info(
|
|
174
|
-
|
|
175
|
-
workspace.cssLanguageService = new CSSLanguageService({
|
|
196
|
+
this.console.info(`Initialized workspace ${workspaceConfig ? '(with config file)' : ''} ${workspace.uri}`);
|
|
197
|
+
workspace.languageService = new CSSLanguageService({
|
|
176
198
|
...workspace.languageServiceSettings,
|
|
177
199
|
config: workspaceConfig
|
|
178
200
|
});
|
|
179
201
|
}
|
|
180
|
-
|
|
181
|
-
console.info(
|
|
182
|
-
|
|
183
|
-
delete workspace.cssLanguageService;
|
|
184
|
-
}
|
|
185
|
-
fileURLToPath(workspaceURI) {
|
|
186
|
-
return url.fileURLToPath(workspaceURI.replace('%3A', ':'));
|
|
202
|
+
destroyLanguageService(workspace) {
|
|
203
|
+
this.console.info(`Destroyed workspace ${workspace.uri}`);
|
|
204
|
+
delete workspace.languageService;
|
|
187
205
|
}
|
|
188
206
|
findClosestWorkspace(textDocumentURI) {
|
|
189
207
|
let foundWorkspace;
|
|
@@ -192,16 +210,20 @@ class CSSLanguageServer {
|
|
|
192
210
|
foundWorkspace = workspace;
|
|
193
211
|
}
|
|
194
212
|
}
|
|
195
|
-
if (!foundWorkspace) {
|
|
196
|
-
|
|
213
|
+
if (process.env.DEBUG && !foundWorkspace) {
|
|
214
|
+
this.console.info(`This is an external document ${textDocumentURI} assigned to the first workspace`);
|
|
197
215
|
}
|
|
198
|
-
return foundWorkspace;
|
|
216
|
+
return foundWorkspace || this.workspaces[0];
|
|
217
|
+
}
|
|
218
|
+
getWorkspace(uri) {
|
|
219
|
+
return Array.from(this.workspaces).find((workspace)=>workspace.uri === uri);
|
|
199
220
|
}
|
|
200
221
|
stop() {
|
|
201
222
|
this.connection.sendNotification('masterCSS/dispose');
|
|
202
223
|
this.disposables.forEach((disposable)=>disposable.dispose());
|
|
203
224
|
this.disposables.length = 0;
|
|
204
225
|
this.connection.dispose();
|
|
226
|
+
this.initializing = undefined;
|
|
205
227
|
}
|
|
206
228
|
}
|
|
207
229
|
|
package/dist/core.d.ts
CHANGED
|
@@ -1,29 +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
|
-
|
|
25
|
-
fileURLToPath(workspaceURI: string): string;
|
|
37
|
+
initLanguageService(workspace: Workspace): void;
|
|
38
|
+
destroyLanguageService(workspace: Workspace): void;
|
|
26
39
|
findClosestWorkspace(textDocumentURI: string): Workspace;
|
|
40
|
+
getWorkspace(uri: string): Workspace | undefined;
|
|
27
41
|
stop(): void;
|
|
28
42
|
}
|
|
29
|
-
export {};
|
package/dist/core.mjs
CHANGED
|
@@ -1,132 +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';
|
|
4
|
-
import { pathToFileURL, fileURLToPath } from 'url';
|
|
3
|
+
import path from 'node:path';
|
|
5
4
|
import CSSLanguageService, { SERVER_CAPABILITIES } from '@master/css-language-service';
|
|
6
5
|
import exploreConfig from '@master/css-explore-config';
|
|
7
6
|
import extend from '@techor/extend';
|
|
8
7
|
import settings from './settings.mjs';
|
|
9
|
-
import interceptLogs from './utils/intercept-logs.mjs';
|
|
10
8
|
import glob from 'fast-glob';
|
|
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
|
-
const workspaceFolderCWD =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
141
|
+
const workspaceFolderCWD = 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
|
+
}
|
|
124
149
|
const { workspaces, ...languageServiceSettings } = extend(settings, this.customSettings, customWorkspaceFolderSettings);
|
|
125
150
|
const resolvedWorkspaceDirectories = new Set([
|
|
126
151
|
workspaceFolderCWD
|
|
127
152
|
]);
|
|
128
|
-
console.info(
|
|
129
|
-
console.log(workspaceFolderCWD);
|
|
153
|
+
this.console.info(`Registered workspace folder ${workspaceFolderURI}`);
|
|
130
154
|
if (workspaces === 'auto') {
|
|
131
155
|
(await glob('**/master.css.*', {
|
|
132
156
|
cwd: workspaceFolderCWD,
|
|
@@ -135,7 +159,7 @@ class CSSLanguageServer {
|
|
|
135
159
|
ignore: [
|
|
136
160
|
'**/node_modules/**'
|
|
137
161
|
]
|
|
138
|
-
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(workspaceFile)));
|
|
162
|
+
})).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(path.resolve(workspaceFile))));
|
|
139
163
|
} else if (workspaces?.length) {
|
|
140
164
|
(await glob(workspaces, {
|
|
141
165
|
cwd: workspaceFolderCWD,
|
|
@@ -144,44 +168,38 @@ class CSSLanguageServer {
|
|
|
144
168
|
ignore: [
|
|
145
169
|
'**/node_modules/**'
|
|
146
170
|
]
|
|
147
|
-
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(workspaceDir));
|
|
171
|
+
})).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(path.resolve(workspaceDir)));
|
|
148
172
|
}
|
|
149
173
|
resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
|
|
150
|
-
|
|
151
|
-
console.
|
|
152
|
-
this.workspaces.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
openedTextDocuments: new Set(),
|
|
174
|
+
const workspaceURI = URI.file(workspaceDir).toString();
|
|
175
|
+
this.console.info(`Added workspace ${workspaceURI}`);
|
|
176
|
+
this.workspaces.push({
|
|
177
|
+
uri: workspaceURI,
|
|
178
|
+
openedTextDocuments: [],
|
|
156
179
|
languageServiceSettings
|
|
157
180
|
});
|
|
158
181
|
});
|
|
159
182
|
}
|
|
160
|
-
|
|
183
|
+
initLanguageService(workspace) {
|
|
161
184
|
let workspaceConfig;
|
|
162
185
|
try {
|
|
163
186
|
workspaceConfig = exploreConfig({
|
|
164
|
-
cwd: workspace.
|
|
187
|
+
cwd: URI.parse(workspace.uri).fsPath,
|
|
165
188
|
found: undefined
|
|
166
189
|
});
|
|
167
190
|
} catch (e) {
|
|
168
|
-
console.info(
|
|
169
|
-
console.error(e);
|
|
191
|
+
this.console.info(`Failed to load config from ${workspace}`);
|
|
192
|
+
this.console.error(e);
|
|
170
193
|
}
|
|
171
|
-
console.info(
|
|
172
|
-
|
|
173
|
-
workspace.cssLanguageService = new CSSLanguageService({
|
|
194
|
+
this.console.info(`Initialized workspace ${workspaceConfig ? '(with config file)' : ''} ${workspace.uri}`);
|
|
195
|
+
workspace.languageService = new CSSLanguageService({
|
|
174
196
|
...workspace.languageServiceSettings,
|
|
175
197
|
config: workspaceConfig
|
|
176
198
|
});
|
|
177
199
|
}
|
|
178
|
-
|
|
179
|
-
console.info(
|
|
180
|
-
|
|
181
|
-
delete workspace.cssLanguageService;
|
|
182
|
-
}
|
|
183
|
-
fileURLToPath(workspaceURI) {
|
|
184
|
-
return fileURLToPath(workspaceURI.replace('%3A', ':'));
|
|
200
|
+
destroyLanguageService(workspace) {
|
|
201
|
+
this.console.info(`Destroyed workspace ${workspace.uri}`);
|
|
202
|
+
delete workspace.languageService;
|
|
185
203
|
}
|
|
186
204
|
findClosestWorkspace(textDocumentURI) {
|
|
187
205
|
let foundWorkspace;
|
|
@@ -190,16 +208,20 @@ class CSSLanguageServer {
|
|
|
190
208
|
foundWorkspace = workspace;
|
|
191
209
|
}
|
|
192
210
|
}
|
|
193
|
-
if (!foundWorkspace) {
|
|
194
|
-
|
|
211
|
+
if (process.env.DEBUG && !foundWorkspace) {
|
|
212
|
+
this.console.info(`This is an external document ${textDocumentURI} assigned to the first workspace`);
|
|
195
213
|
}
|
|
196
|
-
return foundWorkspace;
|
|
214
|
+
return foundWorkspace || this.workspaces[0];
|
|
215
|
+
}
|
|
216
|
+
getWorkspace(uri) {
|
|
217
|
+
return Array.from(this.workspaces).find((workspace)=>workspace.uri === uri);
|
|
197
218
|
}
|
|
198
219
|
stop() {
|
|
199
220
|
this.connection.sendNotification('masterCSS/dispose');
|
|
200
221
|
this.disposables.forEach((disposable)=>disposable.dispose());
|
|
201
222
|
this.disposables.length = 0;
|
|
202
223
|
this.connection.dispose();
|
|
224
|
+
this.initializing = undefined;
|
|
203
225
|
}
|
|
204
226
|
}
|
|
205
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 };
|