@theia/plugin-ext 1.42.0 → 1.43.0
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/lib/common/arrays.d.ts +4 -0
- package/lib/common/arrays.d.ts.map +1 -1
- package/lib/common/arrays.js +15 -1
- package/lib/common/arrays.js.map +1 -1
- package/lib/common/commands.d.ts +4 -0
- package/lib/common/commands.d.ts.map +1 -0
- package/lib/common/commands.js +17 -0
- package/lib/common/commands.js.map +1 -0
- package/lib/common/plugin-api-rpc-model.d.ts +1 -0
- package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc-model.js.map +1 -1
- package/lib/common/plugin-api-rpc.d.ts +48 -6
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +3 -2
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +27 -3
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js +8 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/common/test-types.d.ts +83 -0
- package/lib/common/test-types.d.ts.map +1 -0
- package/lib/common/test-types.js +40 -0
- package/lib/common/test-types.js.map +1 -0
- package/lib/hosted/browser/hosted-plugin.d.ts +4 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +11 -0
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-localization-service.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin-localization-service.js +71 -33
- package/lib/hosted/node/hosted-plugin-localization-service.js.map +1 -1
- package/lib/hosted/node/plugin-reader.d.ts.map +1 -1
- package/lib/hosted/node/plugin-reader.js +4 -2
- package/lib/hosted/node/plugin-reader.js.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.d.ts +5 -4
- package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.js +79 -19
- package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
- package/lib/main/browser/command-registry-main.d.ts +3 -0
- package/lib/main/browser/command-registry-main.d.ts.map +1 -1
- package/lib/main/browser/command-registry-main.js +11 -1
- package/lib/main/browser/command-registry-main.js.map +1 -1
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +7 -5
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +3 -0
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +2 -2
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js +3 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
- package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js +2 -2
- package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js.map +1 -1
- package/lib/main/browser/notebooks/notebook-documents-main.js +1 -1
- package/lib/main/browser/notebooks/notebook-documents-main.js.map +1 -1
- package/lib/main/browser/notebooks/notebook-dto.js +2 -2
- package/lib/main/browser/notebooks/notebook-dto.js.map +1 -1
- package/lib/main/browser/notebooks/notebook-kernels-main.d.ts.map +1 -1
- package/lib/main/browser/notebooks/notebook-kernels-main.js +4 -10
- package/lib/main/browser/notebooks/notebook-kernels-main.js.map +1 -1
- package/lib/main/browser/notebooks/notebook-renderers-main.js +1 -1
- package/lib/main/browser/notebooks/notebook-renderers-main.js.map +1 -1
- package/lib/main/browser/notebooks/notebooks-main.d.ts +2 -2
- package/lib/main/browser/notebooks/notebooks-main.d.ts.map +1 -1
- package/lib/main/browser/notebooks/notebooks-main.js +5 -5
- package/lib/main/browser/notebooks/notebooks-main.js.map +1 -1
- package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts.map +1 -1
- package/lib/main/browser/notebooks/renderers/cell-output-webview.js +3 -0
- package/lib/main/browser/notebooks/renderers/cell-output-webview.js.map +1 -1
- package/lib/main/browser/notebooks/renderers/output-webview-internal.d.ts.map +1 -1
- package/lib/main/browser/notebooks/renderers/output-webview-internal.js +4 -2
- package/lib/main/browser/notebooks/renderers/output-webview-internal.js.map +1 -1
- package/lib/main/browser/plugin-contribution-handler.d.ts +2 -0
- package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
- package/lib/main/browser/plugin-contribution-handler.js +19 -1
- package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.js +3 -0
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/plugin-icon-service.d.ts +20 -0
- package/lib/main/browser/plugin-icon-service.d.ts.map +1 -0
- package/lib/main/browser/plugin-icon-service.js +156 -0
- package/lib/main/browser/plugin-icon-service.js.map +1 -0
- package/lib/main/browser/terminal-main.d.ts +2 -2
- package/lib/main/browser/terminal-main.d.ts.map +1 -1
- package/lib/main/browser/terminal-main.js +5 -9
- package/lib/main/browser/terminal-main.js.map +1 -1
- package/lib/main/browser/test-main.d.ts +141 -0
- package/lib/main/browser/test-main.d.ts.map +1 -0
- package/lib/main/browser/test-main.js +560 -0
- package/lib/main/browser/test-main.js.map +1 -0
- package/lib/main/browser/view/plugin-view-registry.d.ts +14 -3
- package/lib/main/browser/view/plugin-view-registry.d.ts.map +1 -1
- package/lib/main/browser/view/plugin-view-registry.js +108 -56
- package/lib/main/browser/view/plugin-view-registry.js.map +1 -1
- package/lib/main/browser/webview-views/webview-views-main.d.ts.map +1 -1
- package/lib/main/browser/webview-views/webview-views-main.js +5 -2
- package/lib/main/browser/webview-views/webview-views-main.js.map +1 -1
- package/lib/main/browser/webview-views/webview-views.d.ts +1 -0
- package/lib/main/browser/webview-views/webview-views.d.ts.map +1 -1
- package/lib/main/node/plugin-service.d.ts +2 -0
- package/lib/main/node/plugin-service.d.ts.map +1 -1
- package/lib/main/node/plugin-service.js +14 -1
- package/lib/main/node/plugin-service.js.map +1 -1
- package/lib/plugin/command-registry.d.ts +1 -3
- package/lib/plugin/command-registry.d.ts.map +1 -1
- package/lib/plugin/command-registry.js.map +1 -1
- package/lib/plugin/notebook/notebook-kernels.d.ts.map +1 -1
- package/lib/plugin/notebook/notebook-kernels.js +1 -0
- package/lib/plugin/notebook/notebook-kernels.js.map +1 -1
- package/lib/plugin/notebook/notebooks.d.ts.map +1 -1
- package/lib/plugin/notebook/notebooks.js +2 -2
- package/lib/plugin/notebook/notebooks.js.map +1 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +9 -18
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/telemetry-ext.js +1 -1
- package/lib/plugin/telemetry-ext.js.map +1 -1
- package/lib/plugin/terminal-ext.d.ts +11 -9
- package/lib/plugin/terminal-ext.d.ts.map +1 -1
- package/lib/plugin/terminal-ext.js +37 -25
- package/lib/plugin/terminal-ext.js.map +1 -1
- package/lib/plugin/test-item.d.ts +47 -0
- package/lib/plugin/test-item.d.ts.map +1 -0
- package/lib/plugin/test-item.js +196 -0
- package/lib/plugin/test-item.js.map +1 -0
- package/lib/plugin/tests.d.ts +117 -0
- package/lib/plugin/tests.d.ts.map +1 -0
- package/lib/plugin/tests.js +402 -0
- package/lib/plugin/tests.js.map +1 -0
- package/lib/plugin/tree/tree-views.d.ts.map +1 -1
- package/lib/plugin/tree/tree-views.js +2 -1
- package/lib/plugin/tree/tree-views.js.map +1 -1
- package/lib/plugin/type-converters.d.ts +10 -1
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +74 -2
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +29 -4
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +30 -8
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +30 -29
- package/src/common/arrays.ts +16 -0
- package/src/common/commands.ts +19 -0
- package/src/common/plugin-api-rpc-model.ts +1 -0
- package/src/common/plugin-api-rpc.ts +69 -7
- package/src/common/plugin-protocol.ts +31 -3
- package/src/common/test-types.ts +133 -0
- package/src/hosted/browser/hosted-plugin.ts +13 -1
- package/src/hosted/node/hosted-plugin-localization-service.ts +72 -37
- package/src/hosted/node/plugin-reader.ts +4 -2
- package/src/hosted/node/scanners/scanner-theia.ts +85 -20
- package/src/main/browser/command-registry-main.ts +14 -1
- package/src/main/browser/languages-main.ts +7 -5
- package/src/main/browser/main-context.ts +4 -0
- package/src/main/browser/menus/vscode-theia-menu-mappings.ts +3 -0
- package/src/main/browser/notebooks/notebook-documents-and-editors-main.ts +2 -2
- package/src/main/browser/notebooks/notebook-documents-main.ts +1 -1
- package/src/main/browser/notebooks/notebook-dto.ts +2 -2
- package/src/main/browser/notebooks/notebook-kernels-main.ts +6 -11
- package/src/main/browser/notebooks/notebook-renderers-main.ts +1 -1
- package/src/main/browser/notebooks/notebooks-main.ts +6 -6
- package/src/main/browser/notebooks/renderers/cell-output-webview.tsx +3 -0
- package/src/main/browser/notebooks/renderers/output-webview-internal.ts +3 -2
- package/src/main/browser/plugin-contribution-handler.ts +19 -2
- package/src/main/browser/plugin-ext-frontend-module.ts +4 -0
- package/src/main/browser/plugin-icon-service.ts +156 -0
- package/src/main/browser/terminal-main.ts +7 -11
- package/src/main/browser/test-main.ts +618 -0
- package/src/main/browser/view/plugin-view-registry.ts +114 -56
- package/src/main/browser/webview-views/webview-views-main.ts +5 -2
- package/src/main/browser/webview-views/webview-views.ts +1 -0
- package/src/main/node/plugin-service.ts +12 -1
- package/src/plugin/command-registry.ts +1 -5
- package/src/plugin/notebook/notebook-kernels.ts +3 -1
- package/src/plugin/notebook/notebooks.ts +1 -3
- package/src/plugin/plugin-context.ts +13 -32
- package/src/plugin/telemetry-ext.ts +1 -1
- package/src/plugin/terminal-ext.ts +40 -26
- package/src/plugin/test-item.ts +174 -0
- package/src/plugin/tests.ts +482 -0
- package/src/plugin/tree/tree-views.ts +2 -1
- package/src/plugin/type-converters.ts +87 -3
- package/src/plugin/types-impl.ts +36 -5
- package/lib/plugin/stubs/tests-api.d.ts +0 -25
- package/lib/plugin/stubs/tests-api.d.ts.map +0 -1
- package/lib/plugin/stubs/tests-api.js +0 -70
- package/lib/plugin/stubs/tests-api.js.map +0 -1
- package/src/plugin/stubs/tests-api.ts +0 -102
|
@@ -18,7 +18,7 @@ import { injectable, inject, postConstruct, optional } from '@theia/core/shared/
|
|
|
18
18
|
import {
|
|
19
19
|
ApplicationShell, ViewContainer as ViewContainerWidget, WidgetManager, QuickViewService,
|
|
20
20
|
ViewContainerIdentifier, ViewContainerTitleOptions, Widget, FrontendApplicationContribution,
|
|
21
|
-
StatefulWidget, CommonMenus, TreeViewWelcomeWidget,
|
|
21
|
+
StatefulWidget, CommonMenus, TreeViewWelcomeWidget, ViewContainerPart, BaseWidget
|
|
22
22
|
} from '@theia/core/lib/browser';
|
|
23
23
|
import { ViewContainer, View, ViewWelcome, PluginViewType } from '../../../common';
|
|
24
24
|
import { PluginSharedStyle } from '../plugin-shared-style';
|
|
@@ -39,6 +39,7 @@ import { OutputWidget } from '@theia/output/lib/browser/output-widget';
|
|
|
39
39
|
import { DebugConsoleContribution } from '@theia/debug/lib/browser/console/debug-console-contribution';
|
|
40
40
|
import { TreeViewWidget } from './tree-view-widget';
|
|
41
41
|
import { SEARCH_VIEW_CONTAINER_ID } from '@theia/search-in-workspace/lib/browser/search-in-workspace-factory';
|
|
42
|
+
import { TEST_VIEW_CONTAINER_ID } from '@theia/test/lib/browser/view/test-view-contribution';
|
|
42
43
|
import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService';
|
|
43
44
|
import { WebviewView, WebviewViewResolver } from '../webview-views/webview-views';
|
|
44
45
|
import { WebviewWidget, WebviewWidgetIdentifier } from '../webview/webview';
|
|
@@ -46,6 +47,7 @@ import { CancellationToken } from '@theia/core/lib/common/cancellation';
|
|
|
46
47
|
import { v4 } from 'uuid';
|
|
47
48
|
import { nls } from '@theia/core';
|
|
48
49
|
import { TheiaDockPanel } from '@theia/core/lib/browser/shell/theia-dock-panel';
|
|
50
|
+
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
49
51
|
|
|
50
52
|
export const PLUGIN_VIEW_FACTORY_ID = 'plugin-view';
|
|
51
53
|
export const PLUGIN_VIEW_CONTAINER_FACTORY_ID = 'plugin-view-container';
|
|
@@ -102,6 +104,10 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
102
104
|
private readonly viewDataState = new Map<string, object>();
|
|
103
105
|
|
|
104
106
|
private readonly webviewViewResolvers = new Map<string, WebviewViewResolver>();
|
|
107
|
+
protected readonly onNewResolverRegisteredEmitter = new Emitter<{ readonly viewType: string }>();
|
|
108
|
+
readonly onNewResolverRegistered = this.onNewResolverRegisteredEmitter.event;
|
|
109
|
+
|
|
110
|
+
private readonly webviewViewRevivals = new Map<string, { readonly webview: WebviewView; readonly revival: Deferred<void> }>();
|
|
105
111
|
|
|
106
112
|
private static readonly ID_MAPPINGS: Map<string, string> = new Map([
|
|
107
113
|
// VS Code Viewlets
|
|
@@ -111,6 +117,7 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
111
117
|
[DebugWidget.ID, 'workbench.view.debug'],
|
|
112
118
|
['vsx-extensions-view-container', 'workbench.view.extensions'], // cannot use the id from 'vsx-registry' package because of circular dependency
|
|
113
119
|
[PROBLEMS_WIDGET_ID, 'workbench.panel.markers'],
|
|
120
|
+
[TEST_VIEW_CONTAINER_ID, 'workbench.view.testing'],
|
|
114
121
|
[OutputWidget.ID, 'workbench.panel.output'],
|
|
115
122
|
[DebugConsoleContribution.options.id, 'workbench.panel.repl'],
|
|
116
123
|
// Theia does not have a single terminal widget, but instead each terminal gets its own widget. Therefore "the terminal widget is active" doesn't make sense in Theia
|
|
@@ -136,6 +143,9 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
136
143
|
if (factoryId === SEARCH_VIEW_CONTAINER_ID && widget instanceof ViewContainerWidget) {
|
|
137
144
|
waitUntil(this.prepareViewContainer('search', widget));
|
|
138
145
|
}
|
|
146
|
+
if (factoryId === TEST_VIEW_CONTAINER_ID && widget instanceof ViewContainerWidget) {
|
|
147
|
+
waitUntil(this.prepareViewContainer('test', widget));
|
|
148
|
+
}
|
|
139
149
|
if (factoryId === DebugWidget.ID && widget instanceof DebugWidget) {
|
|
140
150
|
const viewContainer = widget['sessionWidget']['viewContainer'];
|
|
141
151
|
waitUntil(this.prepareViewContainer('debug', viewContainer));
|
|
@@ -161,11 +171,6 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
161
171
|
disposable.push(event.widget.onDidDispose(() => disposable.dispose()));
|
|
162
172
|
}
|
|
163
173
|
});
|
|
164
|
-
this.doRegisterViewContainer('test', 'left', {
|
|
165
|
-
label: nls.localizeByDefault('Test'),
|
|
166
|
-
iconClass: codicon('beaker'),
|
|
167
|
-
closeable: true
|
|
168
|
-
});
|
|
169
174
|
this.contextKeyService.onDidChange(e => {
|
|
170
175
|
for (const [, view] of this.views.values()) {
|
|
171
176
|
const clauseContext = this.viewClauseContexts.get(view.id);
|
|
@@ -382,47 +387,51 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
382
387
|
return toDispose;
|
|
383
388
|
}
|
|
384
389
|
|
|
390
|
+
async resolveWebviewView(viewId: string, webview: WebviewView, cancellation: CancellationToken): Promise<void> {
|
|
391
|
+
const resolver = this.webviewViewResolvers.get(viewId);
|
|
392
|
+
if (resolver) {
|
|
393
|
+
return resolver.resolve(webview, cancellation);
|
|
394
|
+
}
|
|
395
|
+
const pendingRevival = this.webviewViewRevivals.get(viewId);
|
|
396
|
+
if (pendingRevival) {
|
|
397
|
+
return pendingRevival.revival.promise;
|
|
398
|
+
}
|
|
399
|
+
const pending = new Deferred<void>();
|
|
400
|
+
this.webviewViewRevivals.set(viewId, { webview, revival: pending });
|
|
401
|
+
return pending.promise;
|
|
402
|
+
}
|
|
403
|
+
|
|
385
404
|
async registerWebviewView(viewId: string, resolver: WebviewViewResolver): Promise<Disposable> {
|
|
386
405
|
if (this.webviewViewResolvers.has(viewId)) {
|
|
387
406
|
throw new Error(`View resolver already registered for ${viewId}`);
|
|
388
407
|
}
|
|
389
408
|
this.webviewViewResolvers.set(viewId, resolver);
|
|
409
|
+
this.onNewResolverRegisteredEmitter.fire({ viewType: viewId });
|
|
390
410
|
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
this.getView(viewId).then(async view => {
|
|
394
|
-
if (view) {
|
|
395
|
-
if (view.isVisible) {
|
|
396
|
-
await this.prepareView(view, webviewView.webview.identifier.id);
|
|
397
|
-
} else {
|
|
398
|
-
const toDisposeOnDidExpandView = new DisposableCollection(this.onDidExpandView(async id => {
|
|
399
|
-
if (id === viewId) {
|
|
400
|
-
dispose();
|
|
401
|
-
await this.prepareView(view, webviewView.webview.identifier.id);
|
|
402
|
-
}
|
|
403
|
-
}));
|
|
404
|
-
const dispose = () => toDisposeOnDidExpandView.dispose();
|
|
405
|
-
view.disposed.connect(dispose);
|
|
406
|
-
toDisposeOnDidExpandView.push(Disposable.create(() => view.disposed.disconnect(dispose)));
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
});
|
|
411
|
+
const toDispose = new DisposableCollection(Disposable.create(() => this.webviewViewResolvers.delete(viewId)));
|
|
412
|
+
this.initView(viewId, toDispose);
|
|
410
413
|
|
|
411
|
-
|
|
414
|
+
const pendingRevival = this.webviewViewRevivals.get(viewId);
|
|
415
|
+
if (pendingRevival) {
|
|
416
|
+
resolver.resolve(pendingRevival.webview, CancellationToken.None).then(() => {
|
|
417
|
+
this.webviewViewRevivals.delete(viewId);
|
|
418
|
+
pendingRevival.revival.resolve();
|
|
419
|
+
});
|
|
420
|
+
}
|
|
412
421
|
|
|
413
|
-
return
|
|
414
|
-
this.webviewViewResolvers.delete(viewId);
|
|
415
|
-
});
|
|
422
|
+
return toDispose;
|
|
416
423
|
}
|
|
417
424
|
|
|
418
|
-
async createNewWebviewView(): Promise<WebviewView> {
|
|
425
|
+
protected async createNewWebviewView(viewId: string): Promise<WebviewView> {
|
|
419
426
|
const webview = await this.widgetManager.getOrCreateWidget<WebviewWidget>(
|
|
420
427
|
WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: v4() });
|
|
421
428
|
webview.setContentOptions({ allowScripts: true });
|
|
422
429
|
|
|
423
430
|
let _description: string | undefined;
|
|
431
|
+
let _resolved = false;
|
|
432
|
+
let _pendingResolution: Promise<void> | undefined;
|
|
424
433
|
|
|
425
|
-
|
|
434
|
+
const webviewView: WebviewView = {
|
|
426
435
|
webview,
|
|
427
436
|
|
|
428
437
|
get onDidChangeVisibility(): Event<boolean> { return webview.onDidChangeVisibility; },
|
|
@@ -442,9 +451,36 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
442
451
|
onDidChangeBadge: webview.onDidChangeBadge,
|
|
443
452
|
onDidChangeBadgeTooltip: webview.onDidChangeBadgeTooltip,
|
|
444
453
|
|
|
445
|
-
dispose:
|
|
454
|
+
dispose: () => {
|
|
455
|
+
_resolved = false;
|
|
456
|
+
webview.dispose();
|
|
457
|
+
toDispose.dispose();
|
|
458
|
+
},
|
|
459
|
+
resolve: async () => {
|
|
460
|
+
if (_resolved) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
if (_pendingResolution) {
|
|
464
|
+
return _pendingResolution;
|
|
465
|
+
}
|
|
466
|
+
_pendingResolution = this.resolveWebviewView(viewId, webviewView, CancellationToken.None).then(() => {
|
|
467
|
+
_resolved = true;
|
|
468
|
+
_pendingResolution = undefined;
|
|
469
|
+
});
|
|
470
|
+
return _pendingResolution;
|
|
471
|
+
},
|
|
446
472
|
show: webview.show
|
|
447
473
|
};
|
|
474
|
+
|
|
475
|
+
const toDispose = this.onNewResolverRegistered(resolver => {
|
|
476
|
+
if (resolver.viewType === viewId) {
|
|
477
|
+
// Potentially re-activate if we have a new resolver
|
|
478
|
+
webviewView.resolve();
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
webviewView.resolve();
|
|
483
|
+
return webviewView;
|
|
448
484
|
}
|
|
449
485
|
|
|
450
486
|
registerViewWelcome(viewWelcome: ViewWelcome): Disposable {
|
|
@@ -526,7 +562,7 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
526
562
|
return this.getView(viewId);
|
|
527
563
|
}
|
|
528
564
|
|
|
529
|
-
protected async prepareView(widget: PluginViewWidget
|
|
565
|
+
protected async prepareView(widget: PluginViewWidget): Promise<void> {
|
|
530
566
|
const data = this.views.get(widget.options.viewId);
|
|
531
567
|
if (!data) {
|
|
532
568
|
return;
|
|
@@ -536,6 +572,7 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
536
572
|
widget.title.label = view.name;
|
|
537
573
|
}
|
|
538
574
|
const currentDataWidget = widget.widgets[0];
|
|
575
|
+
const webviewId = currentDataWidget instanceof WebviewWidget ? currentDataWidget.identifier?.id : undefined;
|
|
539
576
|
const viewDataWidget = await this.createViewDataWidget(view.id, webviewId);
|
|
540
577
|
if (widget.isDisposed) {
|
|
541
578
|
viewDataWidget?.dispose();
|
|
@@ -653,6 +690,7 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
653
690
|
case EXPLORER_VIEW_CONTAINER_ID: return 'explorer';
|
|
654
691
|
case SCM_VIEW_CONTAINER_ID: return 'scm';
|
|
655
692
|
case SEARCH_VIEW_CONTAINER_ID: return 'search';
|
|
693
|
+
case TEST_VIEW_CONTAINER_ID: return 'test';
|
|
656
694
|
case undefined: return container.parent?.parent instanceof DebugWidget ? 'debug' : container.id;
|
|
657
695
|
case PLUGIN_VIEW_CONTAINER_FACTORY_ID: return this.toViewContainerId(description.options);
|
|
658
696
|
default: return container.id;
|
|
@@ -669,6 +707,9 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
669
707
|
if (viewContainerId === 'search') {
|
|
670
708
|
return this.widgetManager.getWidget<ViewContainerWidget>(SEARCH_VIEW_CONTAINER_ID);
|
|
671
709
|
}
|
|
710
|
+
if (viewContainerId === 'test') {
|
|
711
|
+
return this.widgetManager.getWidget<ViewContainerWidget>(TEST_VIEW_CONTAINER_ID);
|
|
712
|
+
}
|
|
672
713
|
if (viewContainerId === 'debug') {
|
|
673
714
|
const debug = await this.widgetManager.getWidget(DebugWidget.ID);
|
|
674
715
|
if (debug instanceof DebugWidget) {
|
|
@@ -717,6 +758,12 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
717
758
|
await this.prepareViewContainer('search', search);
|
|
718
759
|
}
|
|
719
760
|
})().catch(console.error));
|
|
761
|
+
promises.push((async () => {
|
|
762
|
+
const test = await this.widgetManager.getWidget(TEST_VIEW_CONTAINER_ID);
|
|
763
|
+
if (test instanceof ViewContainerWidget) {
|
|
764
|
+
await this.prepareViewContainer('test', test);
|
|
765
|
+
}
|
|
766
|
+
})().catch(console.error));
|
|
720
767
|
promises.push((async () => {
|
|
721
768
|
const debug = await this.widgetManager.getWidget(DebugWidget.ID);
|
|
722
769
|
if (debug instanceof DebugWidget) {
|
|
@@ -793,35 +840,37 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
793
840
|
this.viewDataProviders.delete(viewId);
|
|
794
841
|
this.viewDataState.delete(viewId);
|
|
795
842
|
}));
|
|
796
|
-
this.
|
|
797
|
-
if (toDispose.disposed) {
|
|
798
|
-
return;
|
|
799
|
-
}
|
|
800
|
-
if (view) {
|
|
801
|
-
if (view.isVisible) {
|
|
802
|
-
await this.prepareView(view);
|
|
803
|
-
} else {
|
|
804
|
-
const toDisposeOnDidExpandView = new DisposableCollection(this.onDidExpandView(async id => {
|
|
805
|
-
if (id === viewId) {
|
|
806
|
-
unsubscribe();
|
|
807
|
-
await this.prepareView(view);
|
|
808
|
-
}
|
|
809
|
-
}));
|
|
810
|
-
const unsubscribe = () => toDisposeOnDidExpandView.dispose();
|
|
811
|
-
view.disposed.connect(unsubscribe);
|
|
812
|
-
toDisposeOnDidExpandView.push(Disposable.create(() => view.disposed.disconnect(unsubscribe)));
|
|
813
|
-
toDispose.push(toDisposeOnDidExpandView);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
});
|
|
843
|
+
this.initView(viewId, toDispose);
|
|
817
844
|
return toDispose;
|
|
818
845
|
}
|
|
819
846
|
|
|
847
|
+
protected async initView(viewId: string, toDispose: DisposableCollection): Promise<void> {
|
|
848
|
+
const view = await this.getView(viewId);
|
|
849
|
+
if (toDispose.disposed) {
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
if (view) {
|
|
853
|
+
if (view.isVisible) {
|
|
854
|
+
await this.prepareView(view);
|
|
855
|
+
} else {
|
|
856
|
+
const toDisposeOnDidExpandView = new DisposableCollection(this.onDidExpandView(async id => {
|
|
857
|
+
if (id === viewId) {
|
|
858
|
+
unsubscribe();
|
|
859
|
+
await this.prepareView(view);
|
|
860
|
+
}
|
|
861
|
+
}));
|
|
862
|
+
const unsubscribe = () => toDisposeOnDidExpandView.dispose();
|
|
863
|
+
view.disposed.connect(unsubscribe);
|
|
864
|
+
toDisposeOnDidExpandView.push(Disposable.create(() => view.disposed.disconnect(unsubscribe)));
|
|
865
|
+
toDispose.push(toDisposeOnDidExpandView);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
820
870
|
protected async createViewDataWidget(viewId: string, webviewId?: string): Promise<Widget | undefined> {
|
|
821
871
|
const view = this.views.get(viewId);
|
|
822
872
|
if (view?.[1]?.type === PluginViewType.Webview) {
|
|
823
|
-
|
|
824
|
-
return webviewWidget;
|
|
873
|
+
return this.createWebviewWidget(viewId, webviewId);
|
|
825
874
|
}
|
|
826
875
|
const provider = this.viewDataProviders.get(viewId);
|
|
827
876
|
if (!view || !provider) {
|
|
@@ -839,6 +888,15 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
|
|
|
839
888
|
return widget;
|
|
840
889
|
}
|
|
841
890
|
|
|
891
|
+
protected async createWebviewWidget(viewId: string, webviewId?: string): Promise<Widget | undefined> {
|
|
892
|
+
if (!webviewId) {
|
|
893
|
+
const webviewView = await this.createNewWebviewView(viewId);
|
|
894
|
+
webviewId = webviewView.webview.identifier.id;
|
|
895
|
+
}
|
|
896
|
+
const webviewWidget = this.widgetManager.getWidget(WebviewWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: webviewId });
|
|
897
|
+
return webviewWidget;
|
|
898
|
+
}
|
|
899
|
+
|
|
842
900
|
protected storeViewDataStateOnDispose(viewId: string, widget: Widget & StatefulWidget): void {
|
|
843
901
|
const dispose = widget.dispose.bind(widget);
|
|
844
902
|
widget.dispose = () => {
|
|
@@ -83,7 +83,10 @@ export class WebviewViewsMainImpl implements WebviewViewsMain, Disposable {
|
|
|
83
83
|
webviewView.webview.options = options;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
webviewView.onDidChangeVisibility(visible => {
|
|
86
|
+
webviewView.onDidChangeVisibility(async visible => {
|
|
87
|
+
if (visible) {
|
|
88
|
+
await webviewView.resolve();
|
|
89
|
+
}
|
|
87
90
|
this.proxy.$onDidChangeWebviewViewVisibility(handle, visible);
|
|
88
91
|
});
|
|
89
92
|
|
|
@@ -93,7 +96,7 @@ export class WebviewViewsMainImpl implements WebviewViewsMain, Disposable {
|
|
|
93
96
|
});
|
|
94
97
|
|
|
95
98
|
try {
|
|
96
|
-
this.proxy.$resolveWebviewView(handle, viewType, webviewView.title, state, cancellation);
|
|
99
|
+
await this.proxy.$resolveWebviewView(handle, viewType, webviewView.title, state, cancellation);
|
|
97
100
|
} catch (error) {
|
|
98
101
|
this.logger.error(`Error resolving webview view '${viewType}': ${error}`);
|
|
99
102
|
webviewView.webview.setHTML('failed to load plugin webview view');
|
|
@@ -26,6 +26,7 @@ import { environment } from '@theia/core/shared/@theia/application-package/lib/e
|
|
|
26
26
|
import { WsRequestValidatorContribution } from '@theia/core/lib/node/ws-request-validators';
|
|
27
27
|
import { MaybePromise } from '@theia/core/lib/common';
|
|
28
28
|
import { ApplicationPackage } from '@theia/core/shared/@theia/application-package';
|
|
29
|
+
import { BackendRemoteService } from '@theia/core/lib/node/backend-remote-service';
|
|
29
30
|
|
|
30
31
|
@injectable()
|
|
31
32
|
export class PluginApiContribution implements BackendApplicationContribution, WsRequestValidatorContribution {
|
|
@@ -37,6 +38,9 @@ export class PluginApiContribution implements BackendApplicationContribution, Ws
|
|
|
37
38
|
@inject(ApplicationPackage)
|
|
38
39
|
protected readonly applicationPackage: ApplicationPackage;
|
|
39
40
|
|
|
41
|
+
@inject(BackendRemoteService)
|
|
42
|
+
protected readonly remoteService: BackendRemoteService;
|
|
43
|
+
|
|
40
44
|
@postConstruct()
|
|
41
45
|
protected init(): void {
|
|
42
46
|
const webviewExternalEndpoint = this.webviewExternalEndpoint();
|
|
@@ -47,7 +51,14 @@ export class PluginApiContribution implements BackendApplicationContribution, Ws
|
|
|
47
51
|
configure(app: express.Application): void {
|
|
48
52
|
const webviewApp = express();
|
|
49
53
|
webviewApp.use('/webview', express.static(path.join(this.applicationPackage.projectPath, 'lib', 'webview', 'pre')));
|
|
50
|
-
|
|
54
|
+
if (this.remoteService.isRemoteServer()) {
|
|
55
|
+
// Any request to `subdomain.localhost:port/webview/...` will get redirected to the remote system.
|
|
56
|
+
// However, it will get redirected directly to the `localhost:remotePort` address, losing the subdomain info.
|
|
57
|
+
// In this case, we simply serve the webviews on a path.
|
|
58
|
+
app.use(webviewApp);
|
|
59
|
+
} else {
|
|
60
|
+
app.use(vhost(this.webviewExternalEndpointRegExp, webviewApp));
|
|
61
|
+
}
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
allowWsUpgrade(request: http.IncomingMessage): MaybePromise<boolean> {
|
|
@@ -25,15 +25,11 @@ import { RPCProtocol } from '../common/rpc-protocol';
|
|
|
25
25
|
import { Disposable } from './types-impl';
|
|
26
26
|
import { DisposableCollection } from '@theia/core';
|
|
27
27
|
import { KnownCommands } from './known-commands';
|
|
28
|
+
import { ArgumentProcessor } from '../common/commands';
|
|
28
29
|
|
|
29
30
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
31
|
export type Handler = <T>(...args: any[]) => T | PromiseLike<T | undefined>;
|
|
31
32
|
|
|
32
|
-
export interface ArgumentProcessor {
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
-
processArgument(arg: any): any;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
33
|
export class CommandRegistryImpl implements CommandRegistryExt {
|
|
38
34
|
|
|
39
35
|
private proxy: CommandRegistryMain;
|
|
@@ -483,11 +483,13 @@ class NotebookCellExecutionTask implements Disposable {
|
|
|
483
483
|
});
|
|
484
484
|
}
|
|
485
485
|
|
|
486
|
-
private async updateOutputItems(items: theia.NotebookCellOutputItem | theia.NotebookCellOutputItem[],
|
|
486
|
+
private async updateOutputItems(items: theia.NotebookCellOutputItem | theia.NotebookCellOutputItem[],
|
|
487
|
+
output: theia.NotebookCellOutput, append: boolean): Promise<void> {
|
|
487
488
|
items = NotebookCellOutputConverter.ensureUniqueMimeTypes(Array.isArray(items) ? items : [items], true);
|
|
488
489
|
return this.updateSoon({
|
|
489
490
|
editType: CellExecutionUpdateType.OutputItems,
|
|
490
491
|
items: items.map(NotebookCellOutputItem.from),
|
|
492
|
+
outputId: output instanceof NotebookCellOutput ? output.outputId : '',
|
|
491
493
|
append
|
|
492
494
|
});
|
|
493
495
|
}
|
|
@@ -137,7 +137,6 @@ export class NotebooksExtImpl implements NotebooksExt {
|
|
|
137
137
|
this.notebookSerializer.set(handle, serializer);
|
|
138
138
|
this.notebookProxy.$registerNotebookSerializer(
|
|
139
139
|
handle,
|
|
140
|
-
{ id: plugin.model.id, location: plugin.pluginUri },
|
|
141
140
|
viewType,
|
|
142
141
|
typeConverters.NotebookDocumentContentOptions.from(options),
|
|
143
142
|
);
|
|
@@ -347,8 +346,7 @@ export class NotebooksExtImpl implements NotebooksExt {
|
|
|
347
346
|
}
|
|
348
347
|
|
|
349
348
|
async showNotebookDocument(notebookOrUri: theia.NotebookDocument | TheiaURI, options?: theia.NotebookDocumentShowOptions): Promise<theia.NotebookEditor> {
|
|
350
|
-
|
|
351
|
-
if (URI.isUri(notebookOrUri)) {
|
|
349
|
+
if (TheiaURI.isUri(notebookOrUri)) {
|
|
352
350
|
notebookOrUri = await this.openNotebookDocument(notebookOrUri as TheiaURI);
|
|
353
351
|
}
|
|
354
352
|
|
|
@@ -161,7 +161,6 @@ import {
|
|
|
161
161
|
TerminalLocation,
|
|
162
162
|
TerminalExitReason,
|
|
163
163
|
TerminalProfile,
|
|
164
|
-
TerminalQuickFixType,
|
|
165
164
|
InlayHint,
|
|
166
165
|
InlayHintKind,
|
|
167
166
|
InlayHintLabelPart,
|
|
@@ -199,7 +198,10 @@ import {
|
|
|
199
198
|
DocumentPasteEdit,
|
|
200
199
|
ExternalUriOpenerPriority,
|
|
201
200
|
EditSessionIdentityMatch,
|
|
202
|
-
TerminalOutputAnchor
|
|
201
|
+
TerminalOutputAnchor,
|
|
202
|
+
TerminalQuickFixExecuteTerminalCommand,
|
|
203
|
+
TerminalQuickFixOpener,
|
|
204
|
+
TestResultState
|
|
203
205
|
} from './types-impl';
|
|
204
206
|
import { AuthenticationExtImpl } from './authentication-ext';
|
|
205
207
|
import { SymbolKind } from '../common/plugin-api-rpc-model';
|
|
@@ -228,13 +230,6 @@ import { ClipboardExt } from './clipboard-ext';
|
|
|
228
230
|
import { WebviewsExtImpl } from './webviews';
|
|
229
231
|
import { ExtHostFileSystemEventService } from './file-system-event-service-ext-impl';
|
|
230
232
|
import { LabelServiceExtImpl } from '../plugin/label-service';
|
|
231
|
-
import {
|
|
232
|
-
createRunProfile,
|
|
233
|
-
createTestRun,
|
|
234
|
-
testItemCollection,
|
|
235
|
-
createTestItem,
|
|
236
|
-
invalidateTestResults
|
|
237
|
-
} from './stubs/tests-api';
|
|
238
233
|
import { TimelineExtImpl } from './timeline';
|
|
239
234
|
import { ThemingExtImpl } from './theming';
|
|
240
235
|
import { CommentsExtImpl } from './comments';
|
|
@@ -252,6 +247,7 @@ import { NotebookRenderersExtImpl } from './notebook/notebook-renderers';
|
|
|
252
247
|
import { NotebookKernelsExtImpl } from './notebook/notebook-kernels';
|
|
253
248
|
import { NotebookDocumentsExtImpl } from './notebook/notebook-documents';
|
|
254
249
|
import { NotebookEditorsExtImpl } from './notebook/notebook-editors';
|
|
250
|
+
import { TestingExtImpl } from './tests';
|
|
255
251
|
|
|
256
252
|
export function createAPIFactory(
|
|
257
253
|
rpc: RPCProtocol,
|
|
@@ -299,6 +295,7 @@ export function createAPIFactory(
|
|
|
299
295
|
const customEditorExt = rpc.set(MAIN_RPC_CONTEXT.CUSTOM_EDITORS_EXT, new CustomEditorsExtImpl(rpc, documents, webviewExt, workspaceExt));
|
|
300
296
|
const webviewViewsExt = rpc.set(MAIN_RPC_CONTEXT.WEBVIEW_VIEWS_EXT, new WebviewViewsExtImpl(rpc, webviewExt));
|
|
301
297
|
const telemetryExt = rpc.set(MAIN_RPC_CONTEXT.TELEMETRY_EXT, new TelemetryExtImpl());
|
|
298
|
+
const testingExt = rpc.set(MAIN_RPC_CONTEXT.TESTING_EXT, new TestingExtImpl(rpc, commandRegistry));
|
|
302
299
|
rpc.set(MAIN_RPC_CONTEXT.DEBUG_EXT, debugExt);
|
|
303
300
|
|
|
304
301
|
return function (plugin: InternalPlugin): typeof theia {
|
|
@@ -993,28 +990,10 @@ export function createAPIFactory(
|
|
|
993
990
|
}
|
|
994
991
|
};
|
|
995
992
|
|
|
996
|
-
// Tests API (@stubbed)
|
|
997
|
-
// The following implementation is temporarily `@stubbed` and marked as such under `theia.d.ts`
|
|
998
993
|
const tests: typeof theia.tests = {
|
|
999
|
-
createTestController(
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
refreshHandler?: (
|
|
1003
|
-
token: theia.CancellationToken
|
|
1004
|
-
) => Thenable<void> | void
|
|
1005
|
-
) {
|
|
1006
|
-
return {
|
|
1007
|
-
id: provider,
|
|
1008
|
-
label: controllerLabel,
|
|
1009
|
-
items: testItemCollection,
|
|
1010
|
-
refreshHandler,
|
|
1011
|
-
createRunProfile,
|
|
1012
|
-
createTestRun,
|
|
1013
|
-
createTestItem,
|
|
1014
|
-
invalidateTestResults,
|
|
1015
|
-
dispose: () => undefined,
|
|
1016
|
-
};
|
|
1017
|
-
},
|
|
994
|
+
createTestController(id, label: string) {
|
|
995
|
+
return testingExt.createTestController(id, label);
|
|
996
|
+
}
|
|
1018
997
|
};
|
|
1019
998
|
/* End of Tests API */
|
|
1020
999
|
|
|
@@ -1391,8 +1370,10 @@ export function createAPIFactory(
|
|
|
1391
1370
|
TerminalExitReason,
|
|
1392
1371
|
DocumentPasteEdit,
|
|
1393
1372
|
ExternalUriOpenerPriority,
|
|
1394
|
-
|
|
1395
|
-
|
|
1373
|
+
TerminalQuickFixExecuteTerminalCommand,
|
|
1374
|
+
TerminalQuickFixOpener,
|
|
1375
|
+
EditSessionIdentityMatch,
|
|
1376
|
+
TestResultState
|
|
1396
1377
|
};
|
|
1397
1378
|
};
|
|
1398
1379
|
}
|
|
@@ -18,11 +18,12 @@ import { Terminal, TerminalOptions, PseudoTerminalOptions, ExtensionTerminalOpti
|
|
|
18
18
|
import { TerminalServiceExt, TerminalServiceMain, PLUGIN_RPC_CONTEXT } from '../common/plugin-api-rpc';
|
|
19
19
|
import { RPCProtocol } from '../common/rpc-protocol';
|
|
20
20
|
import { Event, Emitter } from '@theia/core/lib/common/event';
|
|
21
|
+
import { MultiKeyMap } from '@theia/core/lib/common/collections';
|
|
21
22
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
22
23
|
import * as theia from '@theia/plugin';
|
|
23
24
|
import * as Converter from './type-converters';
|
|
24
25
|
import { Disposable, EnvironmentVariableMutatorType, TerminalExitReason, ThemeIcon } from './types-impl';
|
|
25
|
-
import { SerializableEnvironmentVariableCollection } from '@theia/terminal/lib/common/
|
|
26
|
+
import { NO_ROOT_URI, SerializableEnvironmentVariableCollection } from '@theia/terminal/lib/common/shell-terminal-protocol';
|
|
26
27
|
import { ProvidedTerminalLink } from '../common/plugin-api-rpc-model';
|
|
27
28
|
import { ThemeIcon as MonacoThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService';
|
|
28
29
|
|
|
@@ -68,7 +69,7 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
68
69
|
private readonly onDidChangeTerminalStateEmitter = new Emitter<Terminal>();
|
|
69
70
|
readonly onDidChangeTerminalState: theia.Event<Terminal> = this.onDidChangeTerminalStateEmitter.event;
|
|
70
71
|
|
|
71
|
-
protected environmentVariableCollections:
|
|
72
|
+
protected environmentVariableCollections: MultiKeyMap<string, EnvironmentVariableCollectionImpl> = new MultiKeyMap(2);
|
|
72
73
|
|
|
73
74
|
constructor(rpc: RPCProtocol) {
|
|
74
75
|
this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.TERMINAL_MAIN);
|
|
@@ -303,46 +304,53 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
|
|
|
303
304
|
*--------------------------------------------------------------------------------------------*/
|
|
304
305
|
// some code copied and modified from https://github.com/microsoft/vscode/blob/1.49.0/src/vs/workbench/api/common/extHostTerminalService.ts
|
|
305
306
|
|
|
306
|
-
getEnvironmentVariableCollection(extensionIdentifier: string): theia.
|
|
307
|
-
|
|
307
|
+
getEnvironmentVariableCollection(extensionIdentifier: string, rootUri: string = NO_ROOT_URI): theia.GlobalEnvironmentVariableCollection {
|
|
308
|
+
const that = this;
|
|
309
|
+
let collection = this.environmentVariableCollections.get([extensionIdentifier, rootUri]);
|
|
308
310
|
if (!collection) {
|
|
309
|
-
collection = new
|
|
310
|
-
|
|
311
|
+
collection = new class extends EnvironmentVariableCollectionImpl {
|
|
312
|
+
override getScoped(scope: theia.EnvironmentVariableScope): theia.EnvironmentVariableCollection {
|
|
313
|
+
return that.getEnvironmentVariableCollection(extensionIdentifier, scope.workspaceFolder?.uri.toString());
|
|
314
|
+
}
|
|
315
|
+
}(true);
|
|
316
|
+
this.setEnvironmentVariableCollection(extensionIdentifier, rootUri, collection);
|
|
311
317
|
}
|
|
312
318
|
return collection;
|
|
313
319
|
}
|
|
314
320
|
|
|
315
|
-
private syncEnvironmentVariableCollection(extensionIdentifier: string, collection:
|
|
321
|
+
private syncEnvironmentVariableCollection(extensionIdentifier: string, rootUri: string, collection: EnvironmentVariableCollectionImpl): void {
|
|
316
322
|
const serialized = [...collection.map.entries()];
|
|
317
|
-
this.proxy.$setEnvironmentVariableCollection(collection.persistent,
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
323
|
+
this.proxy.$setEnvironmentVariableCollection(collection.persistent, extensionIdentifier,
|
|
324
|
+
rootUri,
|
|
325
|
+
{
|
|
326
|
+
mutators: serialized,
|
|
327
|
+
description: Converter.fromMarkdownOrString(collection.description)
|
|
328
|
+
});
|
|
322
329
|
}
|
|
323
330
|
|
|
324
|
-
private setEnvironmentVariableCollection(
|
|
325
|
-
this.environmentVariableCollections.set(
|
|
331
|
+
private setEnvironmentVariableCollection(pluginIdentifier: string, rootUri: string, collection: EnvironmentVariableCollectionImpl): void {
|
|
332
|
+
this.environmentVariableCollections.set([pluginIdentifier, rootUri], collection);
|
|
326
333
|
collection.onDidChangeCollection(() => {
|
|
327
334
|
// When any collection value changes send this immediately, this is done to ensure
|
|
328
335
|
// following calls to createTerminal will be created with the new environment. It will
|
|
329
336
|
// result in more noise by sending multiple updates when called but collections are
|
|
330
337
|
// expected to be small.
|
|
331
|
-
this.syncEnvironmentVariableCollection(
|
|
338
|
+
this.syncEnvironmentVariableCollection(pluginIdentifier, rootUri, collection);
|
|
332
339
|
});
|
|
333
340
|
}
|
|
334
341
|
|
|
335
|
-
$initEnvironmentVariableCollections(collections: [string, SerializableEnvironmentVariableCollection][]): void {
|
|
342
|
+
$initEnvironmentVariableCollections(collections: [string, string, boolean, SerializableEnvironmentVariableCollection][]): void {
|
|
336
343
|
collections.forEach(entry => {
|
|
337
344
|
const extensionIdentifier = entry[0];
|
|
338
|
-
const
|
|
339
|
-
|
|
345
|
+
const rootUri = entry[1];
|
|
346
|
+
const collection = new EnvironmentVariableCollectionImpl(entry[2], entry[3]);
|
|
347
|
+
this.setEnvironmentVariableCollection(extensionIdentifier, rootUri, collection);
|
|
340
348
|
});
|
|
341
349
|
}
|
|
342
350
|
|
|
343
351
|
}
|
|
344
352
|
|
|
345
|
-
export class
|
|
353
|
+
export class EnvironmentVariableCollectionImpl implements theia.GlobalEnvironmentVariableCollection {
|
|
346
354
|
readonly map: Map<string, theia.EnvironmentVariableMutator> = new Map();
|
|
347
355
|
private _description?: string | theia.MarkdownString;
|
|
348
356
|
private _persistent: boolean = true;
|
|
@@ -363,25 +371,31 @@ export class EnvironmentVariableCollection implements theia.EnvironmentVariableC
|
|
|
363
371
|
onDidChangeCollection: Event<void> = this.onDidChangeCollectionEmitter.event;
|
|
364
372
|
|
|
365
373
|
constructor(
|
|
374
|
+
persistent: boolean,
|
|
366
375
|
serialized?: SerializableEnvironmentVariableCollection
|
|
367
376
|
) {
|
|
368
|
-
this.
|
|
377
|
+
this._persistent = persistent;
|
|
378
|
+
this.map = new Map(serialized?.mutators);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
getScoped(scope: theia.EnvironmentVariableScope): theia.EnvironmentVariableCollection {
|
|
382
|
+
throw new Error('Cannot get scoped from a regular env var collection');
|
|
369
383
|
}
|
|
370
384
|
|
|
371
385
|
get size(): number {
|
|
372
386
|
return this.map.size;
|
|
373
387
|
}
|
|
374
388
|
|
|
375
|
-
replace(variable: string, value: string): void {
|
|
376
|
-
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace });
|
|
389
|
+
replace(variable: string, value: string, options?: theia.EnvironmentVariableMutatorOptions): void {
|
|
390
|
+
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace, options: options ?? { applyAtProcessCreation: true } });
|
|
377
391
|
}
|
|
378
392
|
|
|
379
|
-
append(variable: string, value: string): void {
|
|
380
|
-
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append });
|
|
393
|
+
append(variable: string, value: string, options?: theia.EnvironmentVariableMutatorOptions): void {
|
|
394
|
+
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append, options: options ?? { applyAtProcessCreation: true } });
|
|
381
395
|
}
|
|
382
396
|
|
|
383
|
-
prepend(variable: string, value: string): void {
|
|
384
|
-
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend });
|
|
397
|
+
prepend(variable: string, value: string, options?: theia.EnvironmentVariableMutatorOptions): void {
|
|
398
|
+
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend, options: options ?? { applyAtProcessCreation: true } });
|
|
385
399
|
}
|
|
386
400
|
|
|
387
401
|
private _setIfDiffers(variable: string, mutator: theia.EnvironmentVariableMutator): void {
|