|
2 | 2 | // Licensed under the MIT License.
|
3 | 3 |
|
4 | 4 | import { inject, injectable } from 'inversify';
|
5 |
| -import { Disposable, FileSystemWatcher, Uri, workspace } from 'vscode'; |
| 5 | +import { Disposable, Event, EventEmitter, FileSystemWatcher, Uri, workspace } from 'vscode'; |
6 | 6 | import { PythonSettings } from '../configSettings';
|
7 | 7 | import { NON_WINDOWS_PATH_VARIABLE_NAME, WINDOWS_PATH_VARIABLE_NAME } from '../platform/constants';
|
8 |
| -import { IDisposableRegistry, IsWindows } from '../types'; |
| 8 | +import { ICurrentProcess, IDisposableRegistry, IsWindows } from '../types'; |
9 | 9 | import { EnvironmentVariables, IEnvironmentVariablesProvider, IEnvironmentVariablesService } from './types';
|
10 | 10 |
|
11 | 11 | @injectable()
|
12 | 12 | export class EnvironmentVariablesProvider implements IEnvironmentVariablesProvider, Disposable {
|
13 |
| - private cache = new Map<string, { vars: EnvironmentVariables | undefined, mergedWithProc: EnvironmentVariables }>(); |
| 13 | + private cache = new Map<string, EnvironmentVariables>(); |
14 | 14 | private fileWatchers = new Map<string, FileSystemWatcher>();
|
15 | 15 | private disposables: Disposable[] = [];
|
16 |
| - |
| 16 | + private changeEventEmitter: EventEmitter<Uri | undefined>; |
17 | 17 | constructor( @inject(IEnvironmentVariablesService) private envVarsService: IEnvironmentVariablesService,
|
18 |
| - @inject(IDisposableRegistry) disposableRegistry: Disposable[], @inject(IsWindows) private isWidows: boolean) { |
| 18 | + @inject(IDisposableRegistry) disposableRegistry: Disposable[], @inject(IsWindows) private isWidows: boolean, |
| 19 | + @inject(ICurrentProcess) private process: ICurrentProcess) { |
19 | 20 | disposableRegistry.push(this);
|
| 21 | + this.changeEventEmitter = new EventEmitter(); |
| 22 | + } |
| 23 | + |
| 24 | + public get onDidEnvironmentVariablesChange(): Event<Uri | undefined> { |
| 25 | + return this.changeEventEmitter.event; |
20 | 26 | }
|
21 | 27 |
|
22 | 28 | public dispose() {
|
| 29 | + this.changeEventEmitter.dispose(); |
23 | 30 | this.fileWatchers.forEach(watcher => {
|
24 | 31 | watcher.dispose();
|
25 | 32 | });
|
26 | 33 | }
|
27 |
| - public async getEnvironmentVariables(mergeWithProcEnvVariables: boolean, resource?: Uri): Promise<EnvironmentVariables | undefined> { |
| 34 | + public async getEnvironmentVariables(resource?: Uri): Promise<EnvironmentVariables> { |
28 | 35 | const settings = PythonSettings.getInstance(resource);
|
29 | 36 | if (!this.cache.has(settings.envFile)) {
|
30 |
| - this.createFileWatcher(settings.envFile); |
31 |
| - const vars = await this.envVarsService.parseFile(settings.envFile); |
| 37 | + const workspaceFolderUri = this.getWorkspaceFolderUri(resource); |
| 38 | + this.createFileWatcher(settings.envFile, workspaceFolderUri); |
32 | 39 | let mergedVars = await this.envVarsService.parseFile(settings.envFile);
|
33 |
| - if (!mergedVars || Object.keys(mergedVars).length === 0) { |
34 |
| - mergedVars = { ...process.env }; |
| 40 | + if (!mergedVars) { |
| 41 | + mergedVars = {}; |
35 | 42 | }
|
36 |
| - this.envVarsService.mergeVariables(process.env, mergedVars!); |
| 43 | + this.envVarsService.mergeVariables(this.process.env, mergedVars!); |
37 | 44 | const pathVariable = this.isWidows ? WINDOWS_PATH_VARIABLE_NAME : NON_WINDOWS_PATH_VARIABLE_NAME;
|
38 |
| - this.envVarsService.appendPath(mergedVars!, process.env[pathVariable]); |
39 |
| - this.envVarsService.appendPythonPath(mergedVars!, process.env.PYTHONPATH); |
40 |
| - this.cache.set(settings.envFile, { vars, mergedWithProc: mergedVars! }); |
| 45 | + this.envVarsService.appendPath(mergedVars!, this.process.env[pathVariable]); |
| 46 | + this.envVarsService.appendPythonPath(mergedVars!, this.process.env.PYTHONPATH); |
| 47 | + this.cache.set(settings.envFile, mergedVars); |
41 | 48 | }
|
42 |
| - const data = this.cache.get(settings.envFile)!; |
43 |
| - return mergeWithProcEnvVariables ? data.mergedWithProc : data.vars; |
| 49 | + return this.cache.get(settings.envFile)!; |
44 | 50 | }
|
45 |
| - private createFileWatcher(envFile: string) { |
| 51 | + private getWorkspaceFolderUri(resource?: Uri): Uri | undefined { |
| 52 | + if (!resource) { |
| 53 | + return; |
| 54 | + } |
| 55 | + const workspaceFolder = workspace.getWorkspaceFolder(resource!); |
| 56 | + return workspaceFolder ? workspaceFolder.uri : undefined; |
| 57 | + } |
| 58 | + private createFileWatcher(envFile: string, workspaceFolderUri?: Uri) { |
46 | 59 | if (this.fileWatchers.has(envFile)) {
|
47 | 60 | return;
|
48 | 61 | }
|
49 | 62 | const envFileWatcher = workspace.createFileSystemWatcher(envFile);
|
50 | 63 | this.fileWatchers.set(envFile, envFileWatcher);
|
51 |
| - this.disposables.push(envFileWatcher.onDidChange(() => this.cache.delete(envFile))); |
52 |
| - this.disposables.push(envFileWatcher.onDidCreate(() => this.cache.delete(envFile))); |
53 |
| - this.disposables.push(envFileWatcher.onDidDelete(() => this.cache.delete(envFile))); |
| 64 | + this.disposables.push(envFileWatcher.onDidChange(() => this.onEnvironmentFileChanged(envFile, workspaceFolderUri))); |
| 65 | + this.disposables.push(envFileWatcher.onDidCreate(() => this.onEnvironmentFileChanged(envFile, workspaceFolderUri))); |
| 66 | + this.disposables.push(envFileWatcher.onDidDelete(() => this.onEnvironmentFileChanged(envFile, workspaceFolderUri))); |
| 67 | + } |
| 68 | + private onEnvironmentFileChanged(envFile, workspaceFolderUri?: Uri) { |
| 69 | + this.cache.delete(envFile); |
| 70 | + this.changeEventEmitter.fire(workspaceFolderUri); |
54 | 71 | }
|
55 | 72 | }
|
0 commit comments