-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcross-model-workspace-manager.ts
67 lines (61 loc) · 2.84 KB
/
cross-model-workspace-manager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/********************************************************************************
* Copyright (c) 2023 CrossBreeze.
********************************************************************************/
import { AstNode, DefaultWorkspaceManager, Deferred, FileSystemNode, LangiumDocument } from 'langium';
import { CancellationToken, Emitter, Event, WorkspaceFolder } from 'vscode-languageserver';
import { URI, Utils } from 'vscode-uri';
import { CrossModelSharedServices } from './cross-model-module.js';
/**
* A custom workspace manager that:
* - fires an event when the workspace is initialized (we use this for starting LSP-dependent servers)
* - sets up a package-system on top of the workspace folders (including the 'node_modules' folder)
* - validates all documents after workspace initialization
*/
export class CrossModelWorkspaceManager extends DefaultWorkspaceManager {
protected onWorkspaceInitializedEmitter = new Emitter<URI[]>();
protected workspaceInitializedDeferred = new Deferred<URI[]>();
workspaceInitialized = this.workspaceInitializedDeferred.promise;
constructor(
protected services: CrossModelSharedServices,
protected logger = services.logger.ClientLogger
) {
super(services);
this.initialBuildOptions = { validation: true };
}
override async initializeWorkspace(folders: WorkspaceFolder[], cancelToken?: CancellationToken | undefined): Promise<void> {
try {
await super.initializeWorkspace(folders, cancelToken);
this.logger.info('Workspace Initialized');
const uris = this.folders?.map(folder => this.getRootFolder(folder)) || [];
this.workspaceInitializedDeferred.resolve(uris);
this.onWorkspaceInitializedEmitter.fire(uris);
} catch (error) {
this.workspaceInitializedDeferred.reject(error);
}
}
get onWorkspaceInitialized(): Event<URI[]> {
return this.onWorkspaceInitializedEmitter.event;
}
protected override async loadAdditionalDocuments(
folders: WorkspaceFolder[],
_collector: (document: LangiumDocument<AstNode>) => void
): Promise<void> {
// build up package-system based on the workspace
return this.services.workspace.PackageManager.initialize(folders);
}
protected override includeEntry(_workspaceFolder: WorkspaceFolder, entry: FileSystemNode, fileExtensions: string[]): boolean {
// Note: same as super implementation but we also allow 'node_modules' directories to be scanned
const name = Utils.basename(entry.uri);
if (name.startsWith('.')) {
return false;
}
if (entry.isDirectory) {
// CHANGE: Also support 'node_modules' directory
return name !== 'out';
} else if (entry.isFile) {
const extname = Utils.extname(entry.uri);
return fileExtensions.includes(extname);
}
return false;
}
}