@master/css-language-server 2.0.0-rc.36 → 2.0.0-rc.38

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 CHANGED
@@ -3,58 +3,99 @@
3
3
  var node = require('vscode-languageserver/node');
4
4
  var vscodeLanguageserverTextdocument = require('vscode-languageserver-textdocument');
5
5
  var path = require('path');
6
- var url = require('url');
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');
10
+ var interceptLogs = require('./utils/intercept-logs.cjs');
11
+ var glob = require('fast-glob');
12
+ var vscodeUri = require('vscode-uri');
11
13
 
12
14
  class CSSLanguageServer {
13
15
  customSettings;
14
16
  workspaceFolders;
15
- workspaceCSSLanguageService;
16
- workspaceSettings;
17
- workspaceConfigs;
17
+ workspaces;
18
18
  connection;
19
19
  documents;
20
+ initializing;
20
21
  disposables;
21
22
  constructor(customSettings){
22
23
  this.customSettings = customSettings;
23
24
  this.workspaceFolders = [];
24
- this.workspaceCSSLanguageService = {};
25
- this.workspaceSettings = {};
26
- this.workspaceConfigs = {};
25
+ this.workspaces = new Set();
27
26
  this.disposables = [];
28
27
  if (process.argv.includes('--stdio')) {
29
- console.log = (...args)=>{
30
- console.warn(...args);
31
- };
32
28
  this.connection = node.createConnection(process.stdin, process.stdout);
33
29
  } else {
34
- this.connection = node.createConnection(new node.IPCMessageReader(process), new node.IPCMessageWriter(process));
30
+ this.connection = node.createConnection();
35
31
  }
32
+ interceptLogs(console, this.connection);
36
33
  this.documents = new node.TextDocuments(vscodeLanguageserverTextdocument.TextDocument);
34
+ }
35
+ start() {
37
36
  this.disposables.push(this.documents.onDidSave(async (change)=>{
38
37
  // if the saved file is the master.css file, we need to refresh the css instance
39
38
  const name = path.parse(change.document.uri).name;
40
39
  if (name === 'master.css' || name.endsWith('.css')) {
41
- // const cssLanguageService = this.findWorkspaceCSSLanguageService(change.document.uri)
42
- // const workspaceFolder = this.findWorkspaceFolder(change.document.uri)
43
- // if (cssLanguageService)
44
- // cssLanguageService.css.refresh(this.updateWorkspaceConfig(workspaceFolder.uri))
45
40
  this.connection.sendRequest('masterCSS/restart', {
46
- title: 'Updating configuration...'
41
+ title: 'Updating Master CSS configuration'
47
42
  });
48
43
  }
49
- }), // Make the text document manager listen on the connection
50
- // for open, change and close text document events
51
- this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(({ settings })=>{
44
+ }), this.documents.onDidOpen(async (params)=>{
45
+ await this.initializing;
46
+ const workspace = this.findClosestWorkspace(params.document.uri);
47
+ if (workspace.openedTextDocuments.has(params.document)) return;
48
+ if (!workspace.openedTextDocuments.size) {
49
+ this.initCSSLanguageService(workspace);
50
+ }
51
+ workspace.openedTextDocuments.add(params.document);
52
+ }), this.documents.onDidClose(async (params)=>{
53
+ await this.initializing;
54
+ const workspace = this.findClosestWorkspace(params.document.uri);
55
+ workspace.openedTextDocuments.delete(params.document);
56
+ if (!workspace.openedTextDocuments.size) {
57
+ this.destroyCSSLanguageService(workspace);
58
+ }
59
+ }), this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(async ({ settings })=>{
60
+ await this.initializing;
52
61
  if (settings?.masterCSS) {
53
62
  this.connection.sendNotification('masterCSS/globalSettingsChanged', settings.masterCSS);
54
63
  this.customSettings = settings.masterCSS;
55
- this.reload();
64
+ this.connection.sendRequest('masterCSS/restart', {
65
+ title: 'Updating Master CSS settings'
66
+ });
67
+ }
68
+ }), this.connection.onHover(async (params)=>{
69
+ await this.initializing;
70
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
71
+ if (workspace?.cssLanguageService) {
72
+ const document = this.documents.get(params.textDocument.uri);
73
+ if (document) return workspace.cssLanguageService.inspectSyntax(document, params.position);
74
+ }
75
+ }), this.connection.onCompletion(async (params)=>{
76
+ await this.initializing;
77
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
78
+ if (workspace?.cssLanguageService) {
79
+ const document = this.documents.get(params.textDocument.uri);
80
+ if (document) return workspace.cssLanguageService.suggestSyntax(document, params.position, params.context);
56
81
  }
57
- }), this.connection.onInitialize((params)=>{
82
+ }), this.connection.onDocumentColor(async (params)=>{
83
+ await this.initializing;
84
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
85
+ if (workspace?.cssLanguageService) {
86
+ const document = this.documents.get(params.textDocument.uri);
87
+ if (document) return workspace.cssLanguageService.renderSyntaxColors(document);
88
+ }
89
+ }), this.connection.onColorPresentation(async (params)=>{
90
+ await this.initializing;
91
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
92
+ if (workspace?.cssLanguageService) {
93
+ const document = this.documents.get(params.textDocument.uri);
94
+ if (document) return workspace.cssLanguageService.editSyntaxColors(document, params.color, params.range);
95
+ }
96
+ }), // Make the text document manager listen on the connection
97
+ // for open, change and close text document events
98
+ this.connection.onInitialize((params)=>{
58
99
  if (params.workspaceFolders?.length) {
59
100
  this.workspaceFolders = params.workspaceFolders;
60
101
  } else {
@@ -69,108 +110,92 @@ class CSSLanguageServer {
69
110
  capabilities: CSSLanguageService.SERVER_CAPABILITIES
70
111
  };
71
112
  }), this.connection.onInitialized(async ()=>{
72
- await this.workspaceFolders.map(async (folder)=>{
73
- this.workspaceCSSLanguageService[folder.uri] = await this.createLanguageService(folder.uri);
74
- });
75
- this.connection.client.register(node.DidChangeConfigurationNotification.type, undefined);
76
- }), this.connection.onHover((params)=>{
77
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
78
- if (cssLanguageService) {
79
- const document = this.documents.get(params.textDocument.uri);
80
- if (document) return cssLanguageService.inspectSyntax(document, params.position);
81
- }
82
- }), this.connection.onCompletion((params)=>{
83
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
84
- if (cssLanguageService) {
85
- const document = this.documents.get(params.textDocument.uri);
86
- if (document) return cssLanguageService.suggestSyntax(document, params.position, params.context);
87
- }
88
- }), this.connection.onDocumentColor((params)=>{
89
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
90
- if (cssLanguageService) {
91
- const document = this.documents.get(params.textDocument.uri);
92
- if (document) return cssLanguageService.renderSyntaxColors(document);
93
- }
94
- }), this.connection.onColorPresentation((params)=>{
95
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
96
- if (cssLanguageService) {
97
- const document = this.documents.get(params.textDocument.uri);
98
- if (document) return cssLanguageService.editSyntaxColors(document, params.color, params.range);
99
- }
100
- }), this.connection.onShutdown(()=>{
101
- this.dispose();
113
+ this.initializing = Promise.all([
114
+ ...this.workspaceFolders.map((folder)=>this.initWorkspaceFolder(folder.uri)),
115
+ this.connection.client.register(node.DidChangeConfigurationNotification.type, undefined)
116
+ ]);
102
117
  }));
118
+ this.connection.listen();
103
119
  }
104
- async createLanguageService(workspaceURI) {
105
- const { config, ...workspaceCSSLanguageServiceSettings } = await this.updateWorkspaceSettings(workspaceURI);
106
- const workspaceConfig = this.workspaceConfigs[workspaceURI];
107
- return new CSSLanguageService({
108
- ...workspaceCSSLanguageServiceSettings,
109
- config: workspaceConfig
110
- });
111
- }
112
- async updateWorkspaceSettings(workspaceURI) {
113
- const customWorkspaceSettings = await this.connection.workspace.getConfiguration({
114
- scopeUri: workspaceURI,
120
+ async initWorkspaceFolder(workspaceFolderURI) {
121
+ const workspaceFolderCWD = vscodeUri.URI.parse(workspaceFolderURI).fsPath;
122
+ const customWorkspaceFolderSettings = await this.connection.workspace.getConfiguration({
123
+ scopeUri: workspaceFolderURI,
115
124
  section: 'masterCSS'
116
125
  });
117
- const resolvedSettings = extend(settings, this.customSettings, customWorkspaceSettings);
118
- this.workspaceSettings[workspaceURI] = resolvedSettings;
119
- this.updateWorkspaceConfig(workspaceURI);
120
- return resolvedSettings;
126
+ const { workspaces, ...languageServiceSettings } = extend(settings, this.customSettings, customWorkspaceFolderSettings);
127
+ const resolvedWorkspaceDirectories = new Set([
128
+ workspaceFolderCWD
129
+ ]);
130
+ console.info('Registered workspace folder', workspaceFolderURI);
131
+ if (workspaces === 'auto') {
132
+ (await glob('**/master.css.*', {
133
+ cwd: workspaceFolderCWD,
134
+ absolute: true,
135
+ onlyFiles: true,
136
+ ignore: [
137
+ '**/node_modules/**'
138
+ ]
139
+ })).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(workspaceFile)));
140
+ } else if (workspaces?.length) {
141
+ (await glob(workspaces, {
142
+ cwd: workspaceFolderCWD,
143
+ absolute: true,
144
+ onlyDirectories: true,
145
+ ignore: [
146
+ '**/node_modules/**'
147
+ ]
148
+ })).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(workspaceDir));
149
+ }
150
+ resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
151
+ const workspaceURI = vscodeUri.URI.file(workspaceDir).toString();
152
+ console.info('Added workspace', workspaceURI);
153
+ this.workspaces.add({
154
+ path: workspaceDir,
155
+ uri: workspaceURI,
156
+ openedTextDocuments: new Set(),
157
+ languageServiceSettings
158
+ });
159
+ });
121
160
  }
122
- updateWorkspaceConfig(workspaceURI) {
123
- const workspaceSettings = this.workspaceSettings[workspaceURI];
124
- const workspaceCWD = url.fileURLToPath(workspaceURI.replace('%3A', ':'));
161
+ initCSSLanguageService(workspace) {
125
162
  let workspaceConfig;
126
- if (typeof workspaceSettings.config === 'string') {
127
- try {
128
- workspaceConfig = exploreConfig({
129
- name: workspaceSettings.config,
130
- cwd: workspaceCWD
131
- });
132
- } catch (e) {
133
- console.log('Config loading failed from', workspaceCWD);
134
- console.error(e);
135
- console.log('Fall back to default config');
136
- }
137
- } else {
138
- workspaceConfig = workspaceSettings.config;
163
+ try {
164
+ workspaceConfig = exploreConfig({
165
+ cwd: workspace.path,
166
+ found: undefined
167
+ });
168
+ } catch (e) {
169
+ console.info('Failed to load config from', workspace);
170
+ console.error(e);
139
171
  }
140
- return this.workspaceConfigs[workspaceURI] = workspaceConfig;
172
+ console.info('Initialized workspace', workspaceConfig ? '(with config file)' : '', workspace.uri);
173
+ workspace.cssLanguageService = new CSSLanguageService({
174
+ ...workspace.languageServiceSettings,
175
+ config: workspaceConfig
176
+ });
177
+ }
178
+ destroyCSSLanguageService(workspace) {
179
+ console.info('Destroyed workspace', workspace.uri);
180
+ delete workspace.cssLanguageService;
141
181
  }
142
- // find the workspace language service for the given uri
143
- findWorkspaceCSSLanguageService(uri) {
144
- for(const workspaceURI in this.workspaceCSSLanguageService){
145
- if (uri.startsWith(workspaceURI)) {
146
- return this.workspaceCSSLanguageService[workspaceURI];
182
+ findClosestWorkspace(textDocumentURI) {
183
+ let foundWorkspace;
184
+ for (const workspace of this.workspaces){
185
+ if (textDocumentURI.startsWith(workspace.uri) && (!foundWorkspace || workspace.uri.length > foundWorkspace.uri.length)) {
186
+ foundWorkspace = workspace;
147
187
  }
148
188
  }
149
- }
150
- findWorkspaceFolder(uri) {
151
- const workspaceFolder = this.workspaceFolders.find((workspace)=>uri.startsWith(workspace.uri));
152
- if (!workspaceFolder) {
153
- throw new Error(`Workspace folder not found for ${uri}`);
189
+ if (!foundWorkspace) {
190
+ throw new Error(`No workspace found for ${textDocumentURI}`);
154
191
  }
155
- return workspaceFolder;
156
- }
157
- // revalidate workspace language services by all documents
158
- async revalidate(documents = this.documents.all()) {
159
- this.connection.sendNotification('masterCSS/revalidate');
160
- return await Promise.all(documents.map(async (textDocument)=>{
161
- const workspaceFolder = this.findWorkspaceFolder(textDocument.uri);
162
- return this.workspaceCSSLanguageService[workspaceFolder.uri] = await this.createLanguageService(workspaceFolder.uri);
163
- }));
164
- }
165
- async reload() {
166
- await Promise.all(Object.keys(this.workspaceCSSLanguageService).map(async (workspaceURI)=>{
167
- this.workspaceCSSLanguageService[workspaceURI] = await this.createLanguageService(workspaceURI);
168
- }));
192
+ return foundWorkspace;
169
193
  }
170
- dispose() {
194
+ stop() {
171
195
  this.connection.sendNotification('masterCSS/dispose');
172
196
  this.disposables.forEach((disposable)=>disposable.dispose());
173
197
  this.disposables.length = 0;
198
+ this.connection.dispose();
174
199
  }
175
200
  }
176
201
 
package/dist/core.d.ts CHANGED
@@ -1,24 +1,28 @@
1
- import { TextDocuments, WorkspaceFolder } from 'vscode-languageserver/node';
1
+ import { TextDocuments, WorkspaceFolder, Connection } from 'vscode-languageserver/node';
2
2
  import { TextDocument } from 'vscode-languageserver-textdocument';
3
- import CSSLanguageService from '@master/css-language-service';
3
+ import CSSLanguageService, { Settings as CSSLanguageServiceSettings } from '@master/css-language-service';
4
4
  import { Settings } from './settings';
5
- import { Config } from '@master/css';
5
+ declare type Workspace = {
6
+ path: string;
7
+ uri: string;
8
+ openedTextDocuments: Set<TextDocument>;
9
+ cssLanguageService?: CSSLanguageService;
10
+ languageServiceSettings: CSSLanguageServiceSettings;
11
+ };
6
12
  export default class CSSLanguageServer {
7
13
  customSettings?: Settings | undefined;
8
14
  workspaceFolders: WorkspaceFolder[];
9
- workspaceCSSLanguageService: Record<string, CSSLanguageService>;
10
- workspaceSettings: Record<string, Settings>;
11
- workspaceConfigs: Record<string, Config | undefined>;
12
- connection: import("vscode-languageserver/node").Connection;
15
+ workspaces: Set<Workspace>;
16
+ connection: Connection;
13
17
  documents: TextDocuments<TextDocument>;
18
+ initializing?: Promise<any[]>;
14
19
  private disposables;
15
20
  constructor(customSettings?: Settings | undefined);
16
- createLanguageService(workspaceURI: string): Promise<CSSLanguageService>;
17
- updateWorkspaceSettings(workspaceURI: string): Promise<Settings>;
18
- updateWorkspaceConfig(workspaceURI: string): Config | undefined;
19
- findWorkspaceCSSLanguageService(uri: string): CSSLanguageService | undefined;
20
- findWorkspaceFolder(uri: string): WorkspaceFolder;
21
- revalidate(documents?: TextDocument[]): Promise<CSSLanguageService[]>;
22
- reload(): Promise<void>;
23
- dispose(): void;
21
+ start(): void;
22
+ private initWorkspaceFolder;
23
+ initCSSLanguageService(workspace: Workspace): void;
24
+ destroyCSSLanguageService(workspace: Workspace): void;
25
+ findClosestWorkspace(textDocumentURI: string): Workspace;
26
+ stop(): void;
24
27
  }
28
+ export {};
package/dist/core.mjs CHANGED
@@ -1,58 +1,99 @@
1
- import { createConnection, IPCMessageReader, IPCMessageWriter, TextDocuments, DidChangeConfigurationNotification } from 'vscode-languageserver/node';
1
+ import { createConnection, TextDocuments, DidChangeConfigurationNotification } from 'vscode-languageserver/node';
2
2
  import { TextDocument } from 'vscode-languageserver-textdocument';
3
3
  import path from 'path';
4
- import { fileURLToPath } from 'url';
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';
8
+ import interceptLogs from './utils/intercept-logs.mjs';
9
+ import glob from 'fast-glob';
10
+ import { URI } from 'vscode-uri';
9
11
 
10
12
  class CSSLanguageServer {
11
13
  customSettings;
12
14
  workspaceFolders;
13
- workspaceCSSLanguageService;
14
- workspaceSettings;
15
- workspaceConfigs;
15
+ workspaces;
16
16
  connection;
17
17
  documents;
18
+ initializing;
18
19
  disposables;
19
20
  constructor(customSettings){
20
21
  this.customSettings = customSettings;
21
22
  this.workspaceFolders = [];
22
- this.workspaceCSSLanguageService = {};
23
- this.workspaceSettings = {};
24
- this.workspaceConfigs = {};
23
+ this.workspaces = new Set();
25
24
  this.disposables = [];
26
25
  if (process.argv.includes('--stdio')) {
27
- console.log = (...args)=>{
28
- console.warn(...args);
29
- };
30
26
  this.connection = createConnection(process.stdin, process.stdout);
31
27
  } else {
32
- this.connection = createConnection(new IPCMessageReader(process), new IPCMessageWriter(process));
28
+ this.connection = createConnection();
33
29
  }
30
+ interceptLogs(console, this.connection);
34
31
  this.documents = new TextDocuments(TextDocument);
32
+ }
33
+ start() {
35
34
  this.disposables.push(this.documents.onDidSave(async (change)=>{
36
35
  // if the saved file is the master.css file, we need to refresh the css instance
37
36
  const name = path.parse(change.document.uri).name;
38
37
  if (name === 'master.css' || name.endsWith('.css')) {
39
- // const cssLanguageService = this.findWorkspaceCSSLanguageService(change.document.uri)
40
- // const workspaceFolder = this.findWorkspaceFolder(change.document.uri)
41
- // if (cssLanguageService)
42
- // cssLanguageService.css.refresh(this.updateWorkspaceConfig(workspaceFolder.uri))
43
38
  this.connection.sendRequest('masterCSS/restart', {
44
- title: 'Updating configuration...'
39
+ title: 'Updating Master CSS configuration'
45
40
  });
46
41
  }
47
- }), // Make the text document manager listen on the connection
48
- // for open, change and close text document events
49
- this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(({ settings })=>{
42
+ }), this.documents.onDidOpen(async (params)=>{
43
+ await this.initializing;
44
+ const workspace = this.findClosestWorkspace(params.document.uri);
45
+ if (workspace.openedTextDocuments.has(params.document)) return;
46
+ if (!workspace.openedTextDocuments.size) {
47
+ this.initCSSLanguageService(workspace);
48
+ }
49
+ workspace.openedTextDocuments.add(params.document);
50
+ }), this.documents.onDidClose(async (params)=>{
51
+ await this.initializing;
52
+ const workspace = this.findClosestWorkspace(params.document.uri);
53
+ workspace.openedTextDocuments.delete(params.document);
54
+ if (!workspace.openedTextDocuments.size) {
55
+ this.destroyCSSLanguageService(workspace);
56
+ }
57
+ }), this.documents.listen(this.connection), this.connection.onDidChangeConfiguration(async ({ settings })=>{
58
+ await this.initializing;
50
59
  if (settings?.masterCSS) {
51
60
  this.connection.sendNotification('masterCSS/globalSettingsChanged', settings.masterCSS);
52
61
  this.customSettings = settings.masterCSS;
53
- this.reload();
62
+ this.connection.sendRequest('masterCSS/restart', {
63
+ title: 'Updating Master CSS settings'
64
+ });
65
+ }
66
+ }), this.connection.onHover(async (params)=>{
67
+ await this.initializing;
68
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
69
+ if (workspace?.cssLanguageService) {
70
+ const document = this.documents.get(params.textDocument.uri);
71
+ if (document) return workspace.cssLanguageService.inspectSyntax(document, params.position);
72
+ }
73
+ }), this.connection.onCompletion(async (params)=>{
74
+ await this.initializing;
75
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
76
+ if (workspace?.cssLanguageService) {
77
+ const document = this.documents.get(params.textDocument.uri);
78
+ if (document) return workspace.cssLanguageService.suggestSyntax(document, params.position, params.context);
54
79
  }
55
- }), this.connection.onInitialize((params)=>{
80
+ }), this.connection.onDocumentColor(async (params)=>{
81
+ await this.initializing;
82
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
83
+ if (workspace?.cssLanguageService) {
84
+ const document = this.documents.get(params.textDocument.uri);
85
+ if (document) return workspace.cssLanguageService.renderSyntaxColors(document);
86
+ }
87
+ }), this.connection.onColorPresentation(async (params)=>{
88
+ await this.initializing;
89
+ const workspace = this.findClosestWorkspace(params.textDocument.uri);
90
+ if (workspace?.cssLanguageService) {
91
+ const document = this.documents.get(params.textDocument.uri);
92
+ if (document) return workspace.cssLanguageService.editSyntaxColors(document, params.color, params.range);
93
+ }
94
+ }), // Make the text document manager listen on the connection
95
+ // for open, change and close text document events
96
+ this.connection.onInitialize((params)=>{
56
97
  if (params.workspaceFolders?.length) {
57
98
  this.workspaceFolders = params.workspaceFolders;
58
99
  } else {
@@ -67,108 +108,92 @@ class CSSLanguageServer {
67
108
  capabilities: SERVER_CAPABILITIES
68
109
  };
69
110
  }), this.connection.onInitialized(async ()=>{
70
- await this.workspaceFolders.map(async (folder)=>{
71
- this.workspaceCSSLanguageService[folder.uri] = await this.createLanguageService(folder.uri);
72
- });
73
- this.connection.client.register(DidChangeConfigurationNotification.type, undefined);
74
- }), this.connection.onHover((params)=>{
75
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
76
- if (cssLanguageService) {
77
- const document = this.documents.get(params.textDocument.uri);
78
- if (document) return cssLanguageService.inspectSyntax(document, params.position);
79
- }
80
- }), this.connection.onCompletion((params)=>{
81
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
82
- if (cssLanguageService) {
83
- const document = this.documents.get(params.textDocument.uri);
84
- if (document) return cssLanguageService.suggestSyntax(document, params.position, params.context);
85
- }
86
- }), this.connection.onDocumentColor((params)=>{
87
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
88
- if (cssLanguageService) {
89
- const document = this.documents.get(params.textDocument.uri);
90
- if (document) return cssLanguageService.renderSyntaxColors(document);
91
- }
92
- }), this.connection.onColorPresentation((params)=>{
93
- const cssLanguageService = this.findWorkspaceCSSLanguageService(params.textDocument.uri);
94
- if (cssLanguageService) {
95
- const document = this.documents.get(params.textDocument.uri);
96
- if (document) return cssLanguageService.editSyntaxColors(document, params.color, params.range);
97
- }
98
- }), this.connection.onShutdown(()=>{
99
- this.dispose();
111
+ this.initializing = Promise.all([
112
+ ...this.workspaceFolders.map((folder)=>this.initWorkspaceFolder(folder.uri)),
113
+ this.connection.client.register(DidChangeConfigurationNotification.type, undefined)
114
+ ]);
100
115
  }));
116
+ this.connection.listen();
101
117
  }
102
- async createLanguageService(workspaceURI) {
103
- const { config, ...workspaceCSSLanguageServiceSettings } = await this.updateWorkspaceSettings(workspaceURI);
104
- const workspaceConfig = this.workspaceConfigs[workspaceURI];
105
- return new CSSLanguageService({
106
- ...workspaceCSSLanguageServiceSettings,
107
- config: workspaceConfig
108
- });
109
- }
110
- async updateWorkspaceSettings(workspaceURI) {
111
- const customWorkspaceSettings = await this.connection.workspace.getConfiguration({
112
- scopeUri: workspaceURI,
118
+ async initWorkspaceFolder(workspaceFolderURI) {
119
+ const workspaceFolderCWD = URI.parse(workspaceFolderURI).fsPath;
120
+ const customWorkspaceFolderSettings = await this.connection.workspace.getConfiguration({
121
+ scopeUri: workspaceFolderURI,
113
122
  section: 'masterCSS'
114
123
  });
115
- const resolvedSettings = extend(settings, this.customSettings, customWorkspaceSettings);
116
- this.workspaceSettings[workspaceURI] = resolvedSettings;
117
- this.updateWorkspaceConfig(workspaceURI);
118
- return resolvedSettings;
124
+ const { workspaces, ...languageServiceSettings } = extend(settings, this.customSettings, customWorkspaceFolderSettings);
125
+ const resolvedWorkspaceDirectories = new Set([
126
+ workspaceFolderCWD
127
+ ]);
128
+ console.info('Registered workspace folder', workspaceFolderURI);
129
+ if (workspaces === 'auto') {
130
+ (await glob('**/master.css.*', {
131
+ cwd: workspaceFolderCWD,
132
+ absolute: true,
133
+ onlyFiles: true,
134
+ ignore: [
135
+ '**/node_modules/**'
136
+ ]
137
+ })).forEach((workspaceFile)=>resolvedWorkspaceDirectories.add(path.dirname(workspaceFile)));
138
+ } else if (workspaces?.length) {
139
+ (await glob(workspaces, {
140
+ cwd: workspaceFolderCWD,
141
+ absolute: true,
142
+ onlyDirectories: true,
143
+ ignore: [
144
+ '**/node_modules/**'
145
+ ]
146
+ })).forEach((workspaceDir)=>resolvedWorkspaceDirectories.add(workspaceDir));
147
+ }
148
+ resolvedWorkspaceDirectories.forEach(async (workspaceDir)=>{
149
+ const workspaceURI = URI.file(workspaceDir).toString();
150
+ console.info('Added workspace', workspaceURI);
151
+ this.workspaces.add({
152
+ path: workspaceDir,
153
+ uri: workspaceURI,
154
+ openedTextDocuments: new Set(),
155
+ languageServiceSettings
156
+ });
157
+ });
119
158
  }
120
- updateWorkspaceConfig(workspaceURI) {
121
- const workspaceSettings = this.workspaceSettings[workspaceURI];
122
- const workspaceCWD = fileURLToPath(workspaceURI.replace('%3A', ':'));
159
+ initCSSLanguageService(workspace) {
123
160
  let workspaceConfig;
124
- if (typeof workspaceSettings.config === 'string') {
125
- try {
126
- workspaceConfig = exploreConfig({
127
- name: workspaceSettings.config,
128
- cwd: workspaceCWD
129
- });
130
- } catch (e) {
131
- console.log('Config loading failed from', workspaceCWD);
132
- console.error(e);
133
- console.log('Fall back to default config');
134
- }
135
- } else {
136
- workspaceConfig = workspaceSettings.config;
161
+ try {
162
+ workspaceConfig = exploreConfig({
163
+ cwd: workspace.path,
164
+ found: undefined
165
+ });
166
+ } catch (e) {
167
+ console.info('Failed to load config from', workspace);
168
+ console.error(e);
137
169
  }
138
- return this.workspaceConfigs[workspaceURI] = workspaceConfig;
170
+ console.info('Initialized workspace', workspaceConfig ? '(with config file)' : '', workspace.uri);
171
+ workspace.cssLanguageService = new CSSLanguageService({
172
+ ...workspace.languageServiceSettings,
173
+ config: workspaceConfig
174
+ });
175
+ }
176
+ destroyCSSLanguageService(workspace) {
177
+ console.info('Destroyed workspace', workspace.uri);
178
+ delete workspace.cssLanguageService;
139
179
  }
140
- // find the workspace language service for the given uri
141
- findWorkspaceCSSLanguageService(uri) {
142
- for(const workspaceURI in this.workspaceCSSLanguageService){
143
- if (uri.startsWith(workspaceURI)) {
144
- return this.workspaceCSSLanguageService[workspaceURI];
180
+ findClosestWorkspace(textDocumentURI) {
181
+ let foundWorkspace;
182
+ for (const workspace of this.workspaces){
183
+ if (textDocumentURI.startsWith(workspace.uri) && (!foundWorkspace || workspace.uri.length > foundWorkspace.uri.length)) {
184
+ foundWorkspace = workspace;
145
185
  }
146
186
  }
147
- }
148
- findWorkspaceFolder(uri) {
149
- const workspaceFolder = this.workspaceFolders.find((workspace)=>uri.startsWith(workspace.uri));
150
- if (!workspaceFolder) {
151
- throw new Error(`Workspace folder not found for ${uri}`);
187
+ if (!foundWorkspace) {
188
+ throw new Error(`No workspace found for ${textDocumentURI}`);
152
189
  }
153
- return workspaceFolder;
154
- }
155
- // revalidate workspace language services by all documents
156
- async revalidate(documents = this.documents.all()) {
157
- this.connection.sendNotification('masterCSS/revalidate');
158
- return await Promise.all(documents.map(async (textDocument)=>{
159
- const workspaceFolder = this.findWorkspaceFolder(textDocument.uri);
160
- return this.workspaceCSSLanguageService[workspaceFolder.uri] = await this.createLanguageService(workspaceFolder.uri);
161
- }));
162
- }
163
- async reload() {
164
- await Promise.all(Object.keys(this.workspaceCSSLanguageService).map(async (workspaceURI)=>{
165
- this.workspaceCSSLanguageService[workspaceURI] = await this.createLanguageService(workspaceURI);
166
- }));
190
+ return foundWorkspace;
167
191
  }
168
- dispose() {
192
+ stop() {
169
193
  this.connection.sendNotification('masterCSS/dispose');
170
194
  this.disposables.forEach((disposable)=>disposable.dispose());
171
195
  this.disposables.length = 0;
196
+ this.connection.dispose();
172
197
  }
173
198
  }
174
199
 
package/dist/settings.cjs CHANGED
@@ -4,7 +4,7 @@ var CSSLanguageService = require('@master/css-language-service');
4
4
 
5
5
  const settings = {
6
6
  ...CSSLanguageService.settings,
7
- config: 'master.css'
7
+ workspaces: 'auto'
8
8
  };
9
9
 
10
10
  module.exports = settings;
@@ -1,6 +1,6 @@
1
1
  import { type Settings as CSSLanguageServiceSettings } from '@master/css-language-service';
2
2
  declare const settings: Settings;
3
3
  export default settings;
4
- export declare type Settings = CSSLanguageServiceSettings | {
5
- config: string;
4
+ export declare type Settings = CSSLanguageServiceSettings & {
5
+ workspaces: string[] | 'auto';
6
6
  };
package/dist/settings.mjs CHANGED
@@ -2,7 +2,7 @@ import { settings as settings$1 } from '@master/css-language-service';
2
2
 
3
3
  const settings = {
4
4
  ...settings$1,
5
- config: 'master.css'
5
+ workspaces: 'auto'
6
6
  };
7
7
 
8
8
  export { settings as default };
@@ -0,0 +1,17 @@
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;
@@ -0,0 +1,2 @@
1
+ import type { Connection } from 'vscode-languageserver';
2
+ export default function interceptLogs(console: Console, connection: Connection): Console;
@@ -0,0 +1,15 @@
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 };
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":"jest"},"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.36","@master/css-explore-config":"^2.0.0-rc.36","@master/css-language-service":"^2.0.0-rc.36","@techor/extend":"^3.0.22","js-beautify":"^1.15.1","vscode-languageserver":"^9.0.1","vscode-languageserver-textdocument":"^1.0.11"},"devDependencies":{"@master/css-shared":"^2.0.0-rc.36"},"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.36"}
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":"jest"},"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.38","@master/css-explore-config":"^2.0.0-rc.38","@master/css-language-service":"^2.0.0-rc.38","@techor/extend":"^3.0.22","fast-glob":"^3.3.2","js-beautify":"^1.15.1","vscode-languageserver":"^9.0.1","vscode-languageserver-textdocument":"^1.0.11","vscode-uri":"^3.0.8"},"devDependencies":{"@master/css-shared":"^2.0.0-rc.38"},"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.38"}