@theia/plugin-ext 1.22.0-next.7 → 1.22.1

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.
Files changed (92) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +4 -3
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js.map +1 -1
  4. package/lib/common/plugin-protocol.d.ts +5 -0
  5. package/lib/common/plugin-protocol.d.ts.map +1 -1
  6. package/lib/common/plugin-protocol.js.map +1 -1
  7. package/lib/main/browser/comments/comments-context-key-service.js +1 -1
  8. package/lib/main/browser/comments/comments-context-key-service.js.map +1 -1
  9. package/lib/main/browser/comments/comments-contribution.js +1 -1
  10. package/lib/main/browser/comments/comments-contribution.js.map +1 -1
  11. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts +3 -3
  12. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts.map +1 -1
  13. package/lib/main/browser/custom-editors/custom-editor-opener.js +1 -1
  14. package/lib/main/browser/custom-editors/custom-editor-opener.js.map +1 -1
  15. package/lib/main/browser/custom-editors/custom-editors-main.d.ts +3 -3
  16. package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
  17. package/lib/main/browser/custom-editors/custom-editors-main.js +34 -6
  18. package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
  19. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts +3 -3
  20. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts.map +1 -1
  21. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js +3 -3
  22. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js.map +1 -1
  23. package/lib/main/browser/debug/debug-main.d.ts +1 -0
  24. package/lib/main/browser/debug/debug-main.d.ts.map +1 -1
  25. package/lib/main/browser/debug/debug-main.js +12 -2
  26. package/lib/main/browser/debug/debug-main.js.map +1 -1
  27. package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
  28. package/lib/main/browser/menus/menus-contribution-handler.js +4 -6
  29. package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
  30. package/lib/main/browser/view/plugin-view-registry.js +1 -1
  31. package/lib/main/browser/view/plugin-view-registry.js.map +1 -1
  32. package/lib/main/browser/view/plugin-view-widget.d.ts +5 -3
  33. package/lib/main/browser/view/plugin-view-widget.d.ts.map +1 -1
  34. package/lib/main/browser/view/plugin-view-widget.js +12 -4
  35. package/lib/main/browser/view/plugin-view-widget.js.map +1 -1
  36. package/lib/main/browser/view/tree-view-widget.d.ts +1 -2
  37. package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
  38. package/lib/main/browser/view/tree-view-widget.js +5 -6
  39. package/lib/main/browser/view/tree-view-widget.js.map +1 -1
  40. package/lib/main/browser/view/view-context-key-service.d.ts +0 -4
  41. package/lib/main/browser/view/view-context-key-service.d.ts.map +1 -1
  42. package/lib/main/browser/view/view-context-key-service.js +1 -14
  43. package/lib/main/browser/view/view-context-key-service.js.map +1 -1
  44. package/lib/main/electron-browser/webview/electron-webview-widget-factory.js +3 -3
  45. package/lib/main/electron-browser/webview/electron-webview-widget-factory.js.map +1 -1
  46. package/lib/main/node/plugin-deployer-impl.d.ts +6 -9
  47. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  48. package/lib/main/node/plugin-deployer-impl.js +32 -24
  49. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  50. package/lib/main/node/plugin-server-handler.d.ts +2 -2
  51. package/lib/main/node/plugin-server-handler.d.ts.map +1 -1
  52. package/lib/main/node/plugin-server-handler.js +6 -3
  53. package/lib/main/node/plugin-server-handler.js.map +1 -1
  54. package/lib/plugin/custom-editors.d.ts +2 -1
  55. package/lib/plugin/custom-editors.d.ts.map +1 -1
  56. package/lib/plugin/custom-editors.js +2 -4
  57. package/lib/plugin/custom-editors.js.map +1 -1
  58. package/lib/plugin/node/debug/debug.d.ts +1 -0
  59. package/lib/plugin/node/debug/debug.d.ts.map +1 -1
  60. package/lib/plugin/node/debug/debug.js +3 -0
  61. package/lib/plugin/node/debug/debug.js.map +1 -1
  62. package/lib/plugin/plugin-context.d.ts +50 -2
  63. package/lib/plugin/plugin-context.d.ts.map +1 -1
  64. package/lib/plugin/plugin-context.js +37 -6
  65. package/lib/plugin/plugin-context.js.map +1 -1
  66. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  67. package/lib/plugin/plugin-manager.js +4 -1
  68. package/lib/plugin/plugin-manager.js.map +1 -1
  69. package/lib/plugin/types-impl.js +1 -1
  70. package/lib/plugin/types-impl.js.map +1 -1
  71. package/lib/plugin/types-impl.spec.js +33 -0
  72. package/lib/plugin/types-impl.spec.js.map +1 -1
  73. package/package.json +24 -26
  74. package/src/common/plugin-api-rpc.ts +4 -3
  75. package/src/common/plugin-protocol.ts +7 -1
  76. package/src/main/browser/custom-editors/custom-editor-opener.tsx +4 -4
  77. package/src/main/browser/custom-editors/custom-editors-main.ts +41 -8
  78. package/src/main/browser/custom-editors/plugin-custom-editor-registry.ts +6 -6
  79. package/src/main/browser/debug/debug-main.ts +13 -3
  80. package/src/main/browser/menus/menus-contribution-handler.ts +3 -7
  81. package/src/main/browser/view/plugin-view-widget.ts +14 -4
  82. package/src/main/browser/view/tree-view-widget.tsx +4 -5
  83. package/src/main/browser/view/view-context-key-service.ts +0 -14
  84. package/src/main/electron-browser/webview/electron-webview-widget-factory.ts +3 -3
  85. package/src/main/node/plugin-deployer-impl.ts +38 -27
  86. package/src/main/node/plugin-server-handler.ts +8 -4
  87. package/src/plugin/custom-editors.ts +3 -4
  88. package/src/plugin/node/debug/debug.ts +4 -0
  89. package/src/plugin/plugin-context.ts +73 -8
  90. package/src/plugin/plugin-manager.ts +4 -1
  91. package/src/plugin/types-impl.spec.ts +37 -1
  92. package/src/plugin/types-impl.ts +1 -1
package/package.json CHANGED
@@ -1,32 +1,31 @@
1
1
  {
2
2
  "name": "@theia/plugin-ext",
3
- "version": "1.22.0-next.7+ff1121f7f2b",
3
+ "version": "1.22.1",
4
4
  "description": "Theia - Plugin Extension",
5
5
  "main": "lib/common/index.js",
6
6
  "typings": "lib/common/index.d.ts",
7
7
  "dependencies": {
8
- "@theia/bulk-edit": "1.22.0-next.7+ff1121f7f2b",
9
- "@theia/callhierarchy": "1.22.0-next.7+ff1121f7f2b",
10
- "@theia/console": "1.22.0-next.7+ff1121f7f2b",
11
- "@theia/core": "1.22.0-next.7+ff1121f7f2b",
12
- "@theia/debug": "1.22.0-next.7+ff1121f7f2b",
13
- "@theia/editor": "1.22.0-next.7+ff1121f7f2b",
14
- "@theia/file-search": "1.22.0-next.7+ff1121f7f2b",
15
- "@theia/filesystem": "1.22.0-next.7+ff1121f7f2b",
16
- "@theia/markers": "1.22.0-next.7+ff1121f7f2b",
17
- "@theia/messages": "1.22.0-next.7+ff1121f7f2b",
18
- "@theia/monaco": "1.22.0-next.7+ff1121f7f2b",
19
- "@theia/navigator": "1.22.0-next.7+ff1121f7f2b",
20
- "@theia/output": "1.22.0-next.7+ff1121f7f2b",
21
- "@theia/plugin": "1.22.0-next.7+ff1121f7f2b",
22
- "@theia/preferences": "1.22.0-next.7+ff1121f7f2b",
23
- "@theia/scm": "1.22.0-next.7+ff1121f7f2b",
24
- "@theia/search-in-workspace": "1.22.0-next.7+ff1121f7f2b",
25
- "@theia/task": "1.22.0-next.7+ff1121f7f2b",
26
- "@theia/terminal": "1.22.0-next.7+ff1121f7f2b",
27
- "@theia/timeline": "1.22.0-next.7+ff1121f7f2b",
28
- "@theia/workspace": "1.22.0-next.7+ff1121f7f2b",
29
- "@types/markdown-it": "*",
8
+ "@theia/bulk-edit": "1.22.1",
9
+ "@theia/callhierarchy": "1.22.1",
10
+ "@theia/console": "1.22.1",
11
+ "@theia/core": "1.22.1",
12
+ "@theia/debug": "1.22.1",
13
+ "@theia/editor": "1.22.1",
14
+ "@theia/file-search": "1.22.1",
15
+ "@theia/filesystem": "1.22.1",
16
+ "@theia/markers": "1.22.1",
17
+ "@theia/messages": "1.22.1",
18
+ "@theia/monaco": "1.22.1",
19
+ "@theia/navigator": "1.22.1",
20
+ "@theia/output": "1.22.1",
21
+ "@theia/plugin": "1.22.1",
22
+ "@theia/preferences": "1.22.1",
23
+ "@theia/scm": "1.22.1",
24
+ "@theia/search-in-workspace": "1.22.1",
25
+ "@theia/task": "1.22.1",
26
+ "@theia/terminal": "1.22.1",
27
+ "@theia/timeline": "1.22.1",
28
+ "@theia/workspace": "1.22.1",
30
29
  "@types/mime": "^2.0.1",
31
30
  "decompress": "^4.2.1",
32
31
  "escape-html": "^1.0.3",
@@ -35,7 +34,6 @@
35
34
  "jsonc-parser": "^2.2.0",
36
35
  "lodash.clonedeep": "^4.5.0",
37
36
  "macaddress": "^0.2.9",
38
- "markdown-it": "^8.4.0",
39
37
  "mime": "^2.4.4",
40
38
  "ps-tree": "^1.2.0",
41
39
  "request": "^2.82.0",
@@ -82,7 +80,7 @@
82
80
  "watch": "theiaext watch"
83
81
  },
84
82
  "devDependencies": {
85
- "@theia/ext-scripts": "1.21.0",
83
+ "@theia/ext-scripts": "1.22.1",
86
84
  "@types/decompress": "^4.2.2",
87
85
  "@types/escape-html": "^0.0.20",
88
86
  "@types/lodash.clonedeep": "^4.5.3",
@@ -92,5 +90,5 @@
92
90
  "nyc": {
93
91
  "extends": "../../configs/nyc.json"
94
92
  },
95
- "gitHead": "ff1121f7f2b42324ded29d8ef70838cb0941083d"
93
+ "gitHead": "49910aeaecf520a54b253db0215b28c2268bb2f3"
96
94
  }
@@ -93,7 +93,7 @@ import type {
93
93
  import { SerializableEnvironmentVariableCollection } from '@theia/terminal/lib/common/base-terminal-protocol';
94
94
  import { ThemeType } from '@theia/core/lib/common/theme';
95
95
  import { Disposable } from '@theia/core/lib/common/disposable';
96
- import { PickOptions, QuickInputButtonHandle, QuickPickItem } from '@theia/core/lib/browser';
96
+ import { PickOptions, QuickInputButtonHandle, QuickPickItem, WidgetOpenerOptions } from '@theia/core/lib/browser';
97
97
 
98
98
  export interface PreferenceData {
99
99
  [scope: number]: any;
@@ -1555,7 +1555,7 @@ export interface CustomEditorsExt {
1555
1555
  newWebviewHandle: string,
1556
1556
  viewType: string,
1557
1557
  title: string,
1558
- position: number,
1558
+ widgetOpenerOptions: WidgetOpenerOptions | undefined,
1559
1559
  options: theia.WebviewPanelOptions,
1560
1560
  cancellation: CancellationToken): Promise<void>;
1561
1561
  $createCustomDocument(resource: UriComponents, viewType: string, backupId: string | undefined, cancellation: CancellationToken): Promise<{ editable: boolean }>;
@@ -1578,7 +1578,7 @@ export interface CustomEditorsMain {
1578
1578
  $registerTextEditorProvider(viewType: string, options: theia.WebviewPanelOptions, capabilities: CustomTextEditorCapabilities): void;
1579
1579
  $registerCustomEditorProvider(viewType: string, options: theia.WebviewPanelOptions, supportsMultipleEditorsPerDocument: boolean): void;
1580
1580
  $unregisterEditorProvider(viewType: string): void;
1581
- $createCustomEditorPanel(handle: string, title: string, viewColumn: theia.ViewColumn | undefined, options: theia.WebviewPanelOptions & theia.WebviewOptions): Promise<void>;
1581
+ $createCustomEditorPanel(handle: string, title: string, widgetOpenerOptions: WidgetOpenerOptions | undefined, options: theia.WebviewPanelOptions & theia.WebviewOptions): Promise<void>;
1582
1582
  $onDidEdit(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void;
1583
1583
  $onContentChange(resource: UriComponents, viewType: string): void;
1584
1584
  }
@@ -1636,6 +1636,7 @@ export interface DebugMain {
1636
1636
  $addBreakpoints(breakpoints: Breakpoint[]): Promise<void>;
1637
1637
  $removeBreakpoints(breakpoints: string[]): Promise<void>;
1638
1638
  $startDebugging(folder: theia.WorkspaceFolder | undefined, nameOrConfiguration: string | theia.DebugConfiguration, options: theia.DebugSessionOptions): Promise<boolean>;
1639
+ $stopDebugging(sessionId?: string): Promise<void>;
1639
1640
  $customRequest(sessionId: string, command: string, args?: any): Promise<DebugProtocol.Response>;
1640
1641
  }
1641
1642
 
@@ -406,6 +406,11 @@ export enum PluginType {
406
406
  User
407
407
  };
408
408
 
409
+ export interface UnresolvedPluginEntry {
410
+ id: string;
411
+ type?: PluginType;
412
+ }
413
+
409
414
  export interface PluginDeployerEntry {
410
415
 
411
416
  /**
@@ -822,9 +827,10 @@ export interface PluginDeployerHandler {
822
827
  deployFrontendPlugins(frontendPlugins: PluginDeployerEntry[]): Promise<void>;
823
828
  deployBackendPlugins(backendPlugins: PluginDeployerEntry[]): Promise<void>;
824
829
 
830
+ getDeployedPlugin(pluginId: string): DeployedPlugin | undefined;
825
831
  undeployPlugin(pluginId: string): Promise<boolean>;
826
832
 
827
- getPluginDependencies(pluginToBeInstalled: PluginDeployerEntry): Promise<PluginDependencies | undefined>
833
+ getPluginDependencies(pluginToBeInstalled: PluginDeployerEntry): Promise<PluginDependencies | undefined>;
828
834
  }
829
835
 
830
836
  export interface GetDeployedPluginsParams {
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { inject } from '@theia/core/shared/inversify';
18
18
  import URI from '@theia/core/lib/common/uri';
19
- import { ApplicationShell, OpenerOptions, OpenHandler, Widget, WidgetManager } from '@theia/core/lib/browser';
19
+ import { ApplicationShell, OpenHandler, Widget, WidgetManager, WidgetOpenerOptions } from '@theia/core/lib/browser';
20
20
  import { CustomEditor, CustomEditorPriority, CustomEditorSelector } from '../../../common';
21
21
  import * as glob from './glob';
22
22
  import { CustomEditorWidget } from './custom-editor-widget';
@@ -28,7 +28,7 @@ export class CustomEditorOpener implements OpenHandler {
28
28
  readonly id: string;
29
29
  readonly label: string;
30
30
 
31
- private readonly onDidOpenCustomEditorEmitter = new Emitter<CustomEditorWidget>();
31
+ private readonly onDidOpenCustomEditorEmitter = new Emitter<[CustomEditorWidget, WidgetOpenerOptions?]>();
32
32
  readonly onDidOpenCustomEditor = this.onDidOpenCustomEditorEmitter.event;
33
33
 
34
34
  constructor(
@@ -62,7 +62,7 @@ export class CustomEditorOpener implements OpenHandler {
62
62
  }
63
63
 
64
64
  protected readonly pendingWidgetPromises = new Map<string, Promise<CustomEditorWidget>>();
65
- async open(uri: URI, options?: OpenerOptions): Promise<Widget | undefined> {
65
+ async open(uri: URI, options?: WidgetOpenerOptions): Promise<Widget | undefined> {
66
66
  let widget: CustomEditorWidget | undefined;
67
67
  const widgets = this.widgetManager.getWidgets(CustomEditorWidget.FACTORY_ID) as CustomEditorWidget[];
68
68
  widget = widgets.find(w => w.viewType === this.editor.viewType && w.resource.toString() === uri.toString());
@@ -84,7 +84,7 @@ export class CustomEditorOpener implements OpenHandler {
84
84
  this.pendingWidgetPromises.delete(uriString);
85
85
  widget.viewType = this.editor.viewType;
86
86
  widget.resource = uri;
87
- this.onDidOpenCustomEditorEmitter.fire(widget);
87
+ this.onDidOpenCustomEditorEmitter.fire([widget, options]);
88
88
  }
89
89
  }
90
90
  return widget;
@@ -20,7 +20,7 @@
20
20
  // some code copied and modified from https://github.com/microsoft/vscode/blob/53eac52308c4611000a171cc7bf1214293473c78/src/vs/workbench/api/browser/mainThreadCustomEditors.ts
21
21
 
22
22
  import { interfaces } from '@theia/core/shared/inversify';
23
- import { MAIN_RPC_CONTEXT, CustomEditorsMain, CustomEditorsExt, CustomTextEditorCapabilities, EditorPosition } from '../../../common/plugin-api-rpc';
23
+ import { MAIN_RPC_CONTEXT, CustomEditorsMain, CustomEditorsExt, CustomTextEditorCapabilities } from '../../../common/plugin-api-rpc';
24
24
  import { RPCProtocol } from '../../../common/rpc-protocol';
25
25
  import { HostedPluginSupport } from '../../../hosted/browser/hosted-plugin';
26
26
  import { PluginCustomEditorRegistry } from './plugin-custom-editor-registry';
@@ -39,10 +39,11 @@ import { FileService } from '@theia/filesystem/lib/browser/file-service';
39
39
  import { UndoRedoService } from './undo-redo-service';
40
40
  import { WebviewsMainImpl } from '../webviews-main';
41
41
  import { WidgetManager } from '@theia/core/lib/browser/widget-manager';
42
- import { ApplicationShell, DefaultUriLabelProviderContribution, Saveable, SaveOptions } from '@theia/core/lib/browser';
43
- import { WebviewOptions, WebviewPanelOptions, ViewColumn } from '@theia/plugin';
42
+ import { ApplicationShell, DefaultUriLabelProviderContribution, Saveable, SaveOptions, WidgetOpenerOptions } from '@theia/core/lib/browser';
43
+ import { WebviewOptions, WebviewPanelOptions, WebviewPanelShowOptions } from '@theia/plugin';
44
44
  import { WebviewWidgetIdentifier } from '../webview/webview';
45
45
  import { EditorPreferences } from '@theia/editor/lib/browser';
46
+ import { ViewColumn, WebviewPanelTargetArea } from '../../../plugin/types-impl';
46
47
 
47
48
  const enum CustomEditorModelType {
48
49
  Custom,
@@ -110,7 +111,7 @@ export class CustomEditorsMainImpl implements CustomEditorsMain, Disposable {
110
111
  const disposables = new DisposableCollection();
111
112
 
112
113
  disposables.push(
113
- this.customEditorRegistry.registerResolver(viewType, async widget => {
114
+ this.customEditorRegistry.registerResolver(viewType, async (widget, widgetOpenerOptions) => {
114
115
  const { resource, identifier } = widget;
115
116
  widget.options = options;
116
117
 
@@ -149,7 +150,7 @@ export class CustomEditorsMainImpl implements CustomEditorsMain, Disposable {
149
150
  identifier.id,
150
151
  viewType,
151
152
  this.labelProvider.getName(resource)!,
152
- EditorPosition.ONE, // TODO: fix this when Theia has support splitting editors,
153
+ widgetOpenerOptions,
153
154
  options,
154
155
  _cancellationSource.token
155
156
  );
@@ -216,14 +217,14 @@ export class CustomEditorsMainImpl implements CustomEditorsMain, Disposable {
216
217
  async $createCustomEditorPanel(
217
218
  panelId: string,
218
219
  title: string,
219
- viewColumn: ViewColumn,
220
+ widgetOpenerOptions: WidgetOpenerOptions | undefined,
220
221
  options: WebviewPanelOptions & WebviewOptions
221
222
  ): Promise<void> {
222
223
  const view = await this.widgetManager.getOrCreateWidget<CustomEditorWidget>(CustomEditorWidget.FACTORY_ID, <WebviewWidgetIdentifier>{ id: panelId });
223
224
  this.webviewsMain.hookWebview(view);
224
225
  view.title.label = title;
225
226
  const { enableFindWidget, retainContextWhenHidden, enableScripts, localResourceRoots, ...contentOptions } = options;
226
- view.viewColumn = viewColumn;
227
+ view.viewColumn = ViewColumn.One; // behaviour might be overridden later using widgetOpenerOptions (if available)
227
228
  view.options = { enableFindWidget, retainContextWhenHidden };
228
229
  view.setContentOptions({
229
230
  allowScripts: enableScripts,
@@ -237,7 +238,39 @@ export class CustomEditorsMainImpl implements CustomEditorsMain, Disposable {
237
238
  }
238
239
  return;
239
240
  }
240
- this.webviewsMain.addOrReattachWidget(view, { preserveFocus: true });
241
+ const showOptions: WebviewPanelShowOptions = {
242
+ preserveFocus: true
243
+ };
244
+
245
+ if (widgetOpenerOptions) {
246
+ if (widgetOpenerOptions.mode === 'reveal') {
247
+ showOptions.preserveFocus = false;
248
+ }
249
+
250
+ if (widgetOpenerOptions.widgetOptions) {
251
+ let area: WebviewPanelTargetArea;
252
+ switch (widgetOpenerOptions.widgetOptions.area) {
253
+ case 'main':
254
+ area = WebviewPanelTargetArea.Main;
255
+ case 'left':
256
+ area = WebviewPanelTargetArea.Left;
257
+ case 'right':
258
+ area = WebviewPanelTargetArea.Right;
259
+ case 'bottom':
260
+ area = WebviewPanelTargetArea.Bottom;
261
+ default: // includes 'top'
262
+ area = WebviewPanelTargetArea.Main;
263
+ }
264
+ showOptions.area = area;
265
+
266
+ if (widgetOpenerOptions.widgetOptions.mode === 'split-right' ||
267
+ widgetOpenerOptions.widgetOptions.mode === 'open-to-right') {
268
+ showOptions.viewColumn = ViewColumn.Beside;
269
+ }
270
+ }
271
+ }
272
+
273
+ this.webviewsMain.addOrReattachWidget(view, showOptions);
241
274
  }
242
275
  }
243
276
 
@@ -23,14 +23,14 @@ import { CommandRegistry, Emitter, MenuModelRegistry } from '@theia/core';
23
23
  import { SelectionService } from '@theia/core/lib/common';
24
24
  import { UriAwareCommandHandler } from '@theia/core/lib/common/uri-command-handler';
25
25
  import { NavigatorContextMenu } from '@theia/navigator/lib//browser/navigator-contribution';
26
- import { ApplicationShell, DefaultOpenerService, WidgetManager } from '@theia/core/lib/browser';
26
+ import { ApplicationShell, DefaultOpenerService, WidgetManager, WidgetOpenerOptions } from '@theia/core/lib/browser';
27
27
  import { CustomEditorWidget } from './custom-editor-widget';
28
28
 
29
29
  @injectable()
30
30
  export class PluginCustomEditorRegistry {
31
31
  private readonly editors = new Map<string, CustomEditor>();
32
32
  private readonly pendingEditors = new Set<CustomEditorWidget>();
33
- private readonly resolvers = new Map<string, (widget: CustomEditorWidget) => void>();
33
+ private readonly resolvers = new Map<string, (widget: CustomEditorWidget, options?: WidgetOpenerOptions) => void>();
34
34
 
35
35
  private readonly onWillOpenCustomEditorEmitter = new Emitter<string>();
36
36
  readonly onWillOpenCustomEditor = this.onWillOpenCustomEditorEmitter.event;
@@ -109,22 +109,22 @@ export class PluginCustomEditorRegistry {
109
109
  )
110
110
  );
111
111
  toDispose.push(
112
- editorOpenHandler.onDidOpenCustomEditor(widget => this.resolveWidget(widget))
112
+ editorOpenHandler.onDidOpenCustomEditor(event => this.resolveWidget(event[0], event[1]))
113
113
  );
114
114
  return toDispose;
115
115
  }
116
116
 
117
- resolveWidget = (widget: CustomEditorWidget) => {
117
+ resolveWidget = (widget: CustomEditorWidget, options?: WidgetOpenerOptions) => {
118
118
  const resolver = this.resolvers.get(widget.viewType);
119
119
  if (resolver) {
120
- resolver(widget);
120
+ resolver(widget, options);
121
121
  } else {
122
122
  this.pendingEditors.add(widget);
123
123
  this.onWillOpenCustomEditorEmitter.fire(widget.viewType);
124
124
  }
125
125
  };
126
126
 
127
- registerResolver(viewType: string, resolver: (widget: CustomEditorWidget) => void): Disposable {
127
+ registerResolver(viewType: string, resolver: (widget: CustomEditorWidget, options?: WidgetOpenerOptions) => void): Disposable {
128
128
  if (this.resolvers.has(viewType)) {
129
129
  throw new Error(`Resolver for ${viewType} already registered`);
130
130
  }
@@ -274,16 +274,26 @@ export class DebugMainImpl implements DebugMain, Disposable {
274
274
  return false;
275
275
  }
276
276
 
277
- Object.assign(configuration, options);
278
-
277
+ const debugConfiguration = { ...configuration, ...options };
279
278
  const session = await this.sessionManager.start({
280
- configuration,
279
+ configuration: debugConfiguration,
281
280
  workspaceFolderUri: folder && Uri.revive(folder.uri).toString()
282
281
  });
283
282
 
284
283
  return !!session;
285
284
  }
286
285
 
286
+ async $stopDebugging(sessionId?: string): Promise<void> {
287
+ if (sessionId) {
288
+ const session = this.sessionManager.getSession(sessionId);
289
+ return this.sessionManager.terminateSession(session);
290
+ }
291
+ // Terminate all sessions if no session is provided.
292
+ for (const session of this.sessionManager.sessions) {
293
+ this.sessionManager.terminateSession(session);
294
+ }
295
+ }
296
+
287
297
  private toTheiaPluginApiBreakpoints(breakpoints: (SourceBreakpoint | FunctionBreakpoint)[]): Breakpoint[] {
288
298
  return breakpoints.map(b => this.toTheiaPluginApiBreakpoint(b));
289
299
  }
@@ -242,14 +242,10 @@ export class MenusContributionPointHandler {
242
242
  }
243
243
 
244
244
  protected registerViewTitleAction(location: string, action: Menu): Disposable {
245
- return this.registerTitleAction(location, { ...action, when: undefined }, {
245
+ return this.registerTitleAction(location, action, {
246
246
  execute: widget => widget instanceof PluginViewWidget && this.commands.executeCommand(action.command!),
247
- isEnabled: widget => widget instanceof PluginViewWidget &&
248
- this.viewContextKeys.with({ view: widget.options.viewId }, () =>
249
- this.commands.isEnabled(action.command!) && this.viewContextKeys.match(action.when)),
250
- isVisible: widget => widget instanceof PluginViewWidget &&
251
- this.viewContextKeys.with({ view: widget.options.viewId }, () =>
252
- this.commands.isVisible(action.command!) && this.viewContextKeys.match(action.when))
247
+ isEnabled: widget => widget instanceof PluginViewWidget && this.commands.isEnabled(action.command!),
248
+ isVisible: widget => widget instanceof PluginViewWidget && this.commands.isVisible(action.command!),
253
249
  });
254
250
  }
255
251
 
@@ -18,12 +18,12 @@ import { injectable, inject, postConstruct } from '@theia/core/shared/inversify'
18
18
  import { Panel, Widget } from '@theia/core/shared/@phosphor/widgets';
19
19
  import { MenuModelRegistry } from '@theia/core/lib/common/menu';
20
20
  import { CommandRegistry } from '@theia/core/lib/common/command';
21
- import { ViewContextKeyService } from './view-context-key-service';
22
21
  import { StatefulWidget } from '@theia/core/lib/browser/shell/shell-layout-restorer';
23
22
  import { Message } from '@theia/core/shared/@phosphor/messaging';
24
23
  import { TreeViewWidget } from './tree-view-widget';
25
24
  import { DescriptionWidget } from '@theia/core/lib/browser/view-container';
26
- import { Emitter } from '@theia/core/lib/common';
25
+ import { DisposableCollection, Emitter } from '@theia/core/lib/common';
26
+ import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
27
27
 
28
28
  @injectable()
29
29
  export class PluginViewWidgetIdentifier {
@@ -34,14 +34,16 @@ export class PluginViewWidgetIdentifier {
34
34
  @injectable()
35
35
  export class PluginViewWidget extends Panel implements StatefulWidget, DescriptionWidget {
36
36
 
37
+ protected readonly toDispose = new DisposableCollection();
38
+
37
39
  @inject(MenuModelRegistry)
38
40
  protected readonly menus: MenuModelRegistry;
39
41
 
40
42
  @inject(CommandRegistry)
41
43
  protected readonly commands: CommandRegistry;
42
44
 
43
- @inject(ViewContextKeyService)
44
- protected readonly contextKeys: ViewContextKeyService;
45
+ @inject(ContextKeyService)
46
+ protected readonly contextKeyService: ContextKeyService;
45
47
 
46
48
  @inject(PluginViewWidgetIdentifier)
47
49
  readonly options: PluginViewWidgetIdentifier;
@@ -59,6 +61,9 @@ export class PluginViewWidget extends Panel implements StatefulWidget, Descripti
59
61
  @postConstruct()
60
62
  protected init(): void {
61
63
  this.id = this.options.id;
64
+ const localContext = this.contextKeyService.createScoped(this.node);
65
+ localContext.setContext('view', this.options.viewId);
66
+ this.toDispose.push(localContext);
62
67
  }
63
68
 
64
69
  protected onActivateRequest(msg: Message): void {
@@ -148,6 +153,11 @@ export class PluginViewWidget extends Panel implements StatefulWidget, Descripti
148
153
  super.insertWidget(index, widget);
149
154
  this.updateWidgetMessage();
150
155
  }
156
+
157
+ dispose(): void {
158
+ this.toDispose.dispose();
159
+ super.dispose();
160
+ }
151
161
  }
152
162
  export namespace PluginViewWidget {
153
163
  export interface State {
@@ -36,14 +36,13 @@ import {
36
36
  import { MenuPath, MenuModelRegistry, ActionMenuNode } from '@theia/core/lib/common/menu';
37
37
  import * as React from '@theia/core/shared/react';
38
38
  import { PluginSharedStyle } from '../plugin-shared-style';
39
- import { ViewContextKeyService } from './view-context-key-service';
40
39
  import { ACTION_ITEM, Widget } from '@theia/core/lib/browser/widgets/widget';
41
40
  import { Emitter, Event } from '@theia/core/lib/common/event';
42
41
  import { MessageService } from '@theia/core/lib/common/message-service';
43
42
  import { View } from '../../../common/plugin-protocol';
44
43
  import CoreURI from '@theia/core/lib/common/uri';
45
44
  import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
46
- import * as markdownit from 'markdown-it';
45
+ import * as markdownit from '@theia/core/shared/markdown-it';
47
46
  import { isMarkdownString } from '../../../plugin/markdown-string';
48
47
 
49
48
  export const TREE_NODE_HYPERLINK = 'theia-TreeNodeHyperlink';
@@ -236,8 +235,8 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
236
235
  @inject(MenuModelRegistry)
237
236
  protected readonly menus: MenuModelRegistry;
238
237
 
239
- @inject(ViewContextKeyService)
240
- protected readonly contextKeys: ViewContextKeyService;
238
+ @inject(ContextKeyService)
239
+ protected readonly contextKeys: ContextKeyService;
241
240
 
242
241
  @inject(TreeViewWidgetIdentifier)
243
242
  readonly identifier: TreeViewWidgetIdentifier;
@@ -343,7 +342,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
343
342
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
344
343
  protected renderInlineCommand(node: ActionMenuNode, index: number, arg: any): React.ReactNode {
345
344
  const { icon } = node;
346
- if (!icon || !this.commands.isVisible(node.action.commandId, arg) || !this.contextKeys.match(node.action.when)) {
345
+ if (!icon || !this.commands.isVisible(node.action.commandId, arg) || !node.action.when || !this.contextKeys.match(node.action.when)) {
347
346
  return false;
348
347
  }
349
348
  const className = [TREE_NODE_SEGMENT_CLASS, TREE_NODE_TAIL_CLASS, icon, ACTION_ITEM, 'theia-tree-view-inline-action'].join(' ');
@@ -74,18 +74,4 @@ export class ViewContextKeyService {
74
74
  match(expression: string | undefined): boolean {
75
75
  return !expression || this.contextKeyService.match(expression);
76
76
  }
77
-
78
- with<T>(input: { view?: string, viewItem?: string }, cb: () => T): T {
79
- const view = this.view.get();
80
- const viewItem = this.viewItem.get();
81
- this.view.set(input.view);
82
- this.viewItem.set(input.viewItem);
83
- try {
84
- return cb();
85
- } finally {
86
- this.view.set(view);
87
- this.viewItem.set(viewItem);
88
- }
89
- }
90
-
91
77
  }
@@ -14,7 +14,7 @@
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
16
 
17
- import { remote } from '@theia/core/shared/electron';
17
+ import * as electronRemote from '@theia/core/electron-shared/@electron/remote';
18
18
  import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token';
19
19
  import { WebviewWidgetFactory } from '../../browser/webview/webview-widget-factory';
20
20
  import { WebviewWidgetIdentifier, WebviewWidget } from '../../browser/webview/webview';
@@ -35,7 +35,7 @@ export class ElectronWebviewWidgetFactory extends WebviewWidgetFactory {
35
35
  * @param endpoint cookie's target url
36
36
  */
37
37
  protected async attachElectronSecurityCookie(endpoint: string): Promise<void> {
38
- await remote.session.defaultSession!.cookies.set({
38
+ await electronRemote.session.defaultSession!.cookies.set({
39
39
  url: endpoint,
40
40
  name: ElectronSecurityToken,
41
41
  value: JSON.stringify(this.container.get(ElectronSecurityToken)),
@@ -59,7 +59,7 @@ export class ElectronCustomEditorWidgetFactory extends CustomEditorWidgetFactory
59
59
  * @param endpoint cookie's target url
60
60
  */
61
61
  protected async attachElectronSecurityCookie(endpoint: string): Promise<void> {
62
- await remote.session.defaultSession!.cookies.set({
62
+ await electronRemote.session.defaultSession!.cookies.set({
63
63
  url: endpoint,
64
64
  name: ElectronSecurityToken,
65
65
  value: JSON.stringify(this.container.get(ElectronSecurityToken)),
@@ -21,7 +21,7 @@ import {
21
21
  PluginDeployerResolver, PluginDeployerFileHandler, PluginDeployerDirectoryHandler,
22
22
  PluginDeployerEntry, PluginDeployer, PluginDeployerParticipant, PluginDeployerStartContext,
23
23
  PluginDeployerResolverInit, PluginDeployerFileHandlerContext,
24
- PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType
24
+ PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry
25
25
  } from '../../common/plugin-protocol';
26
26
  import { PluginDeployerEntryImpl } from './plugin-deployer-entry-impl';
27
27
  import {
@@ -118,11 +118,16 @@ export class PluginDeployerImpl implements PluginDeployer {
118
118
  }
119
119
 
120
120
  const startDeployTime = performance.now();
121
- const [userPlugins, systemPlugins] = await Promise.all([
122
- this.resolvePlugins(context.userEntries, PluginType.User),
123
- this.resolvePlugins(context.systemEntries, PluginType.System)
124
- ]);
125
- await this.deployPlugins([...userPlugins, ...systemPlugins]);
121
+ const unresolvedUserEntries = context.userEntries.map(id => ({
122
+ id,
123
+ type: PluginType.User
124
+ }));
125
+ const unresolvedSystemEntries = context.systemEntries.map(id => ({
126
+ id,
127
+ type: PluginType.System
128
+ }));
129
+ const plugins = await this.resolvePlugins([...unresolvedUserEntries, ...unresolvedSystemEntries]);
130
+ await this.deployPlugins(plugins);
126
131
  this.logMeasurement('Deploy plugins list', startDeployTime);
127
132
  }
128
133
 
@@ -132,50 +137,53 @@ export class PluginDeployerImpl implements PluginDeployer {
132
137
  }
133
138
  }
134
139
 
135
- async deploy(pluginEntry: string, type: PluginType = PluginType.System): Promise<void> {
140
+ async deploy(plugin: UnresolvedPluginEntry): Promise<void> {
136
141
  const startDeployTime = performance.now();
137
- await this.deployMultipleEntries([pluginEntry], type);
142
+ await this.deployMultipleEntries([plugin]);
138
143
  this.logMeasurement('Deploy plugin entry', startDeployTime);
139
144
  }
140
145
 
141
- protected async deployMultipleEntries(pluginEntries: ReadonlyArray<string>, type: PluginType = PluginType.System): Promise<void> {
142
- const pluginsToDeploy = await this.resolvePlugins(pluginEntries, type);
146
+ protected async deployMultipleEntries(plugins: UnresolvedPluginEntry[]): Promise<void> {
147
+ const pluginsToDeploy = await this.resolvePlugins(plugins);
143
148
  await this.deployPlugins(pluginsToDeploy);
144
149
  }
145
150
 
146
151
  /**
147
152
  * Resolves plugins for the given type.
148
153
  *
149
- * One can call it multiple times for different types before triggering a single deploy, i.e.
154
+ * Only call it a single time before triggering a single deploy to prevent re-resolving of extension dependencies, i.e.
150
155
  * ```ts
151
156
  * const deployer: PluginDeployer;
152
- * deployer.deployPlugins([
153
- * ...await deployer.resolvePlugins(userEntries, PluginType.User),
154
- * ...await deployer.resolvePlugins(systemEntries, PluginType.System)
155
- * ]);
157
+ * deployer.deployPlugins(await deployer.resolvePlugins(allPluginEntries));
156
158
  * ```
157
159
  */
158
- async resolvePlugins(pluginEntries: ReadonlyArray<string>, type: PluginType): Promise<PluginDeployerEntry[]> {
160
+ async resolvePlugins(plugins: UnresolvedPluginEntry[]): Promise<PluginDeployerEntry[]> {
159
161
  const visited = new Set<string>();
160
162
  const pluginsToDeploy = new Map<string, PluginDeployerEntry>();
161
163
 
162
- let queue = [...pluginEntries];
164
+ let queue: UnresolvedPluginEntry[] = [...plugins];
163
165
  while (queue.length) {
164
- const dependenciesChunk: Array<Map<string, string>> = [];
165
- const workload: string[] = [];
166
+ const dependenciesChunk: Array<{
167
+ dependencies: Map<string, string>
168
+ type: PluginType
169
+ }> = [];
170
+ const workload: UnresolvedPluginEntry[] = [];
166
171
  while (queue.length) {
167
172
  const current = queue.shift()!;
168
- if (visited.has(current)) {
173
+ if (visited.has(current.id)) {
169
174
  continue;
170
175
  } else {
171
176
  workload.push(current);
172
177
  }
173
- visited.add(current);
178
+ visited.add(current.id);
174
179
  }
175
180
  queue = [];
176
- await Promise.all(workload.map(async current => {
181
+ await Promise.all(workload.map(async ({ id, type }) => {
182
+ if (type === undefined) {
183
+ type = PluginType.System;
184
+ }
177
185
  try {
178
- const pluginDeployerEntries = await this.resolvePlugin(current, type);
186
+ const pluginDeployerEntries = await this.resolvePlugin(id, type);
179
187
  await this.applyFileHandlers(pluginDeployerEntries);
180
188
  await this.applyDirectoryFileHandlers(pluginDeployerEntries);
181
189
  for (const deployerEntry of pluginDeployerEntries) {
@@ -183,18 +191,21 @@ export class PluginDeployerImpl implements PluginDeployer {
183
191
  if (dependencies && !pluginsToDeploy.has(dependencies.metadata.model.id)) {
184
192
  pluginsToDeploy.set(dependencies.metadata.model.id, deployerEntry);
185
193
  if (dependencies.mapping) {
186
- dependenciesChunk.push(dependencies.mapping);
194
+ dependenciesChunk.push({ dependencies: dependencies.mapping, type });
187
195
  }
188
196
  }
189
197
  }
190
198
  } catch (e) {
191
- console.error(`Failed to resolve plugins from '${current}'`, e);
199
+ console.error(`Failed to resolve plugins from '${id}'`, e);
192
200
  }
193
201
  }));
194
- for (const dependencies of dependenciesChunk) {
202
+ for (const { dependencies, type } of dependenciesChunk) {
195
203
  for (const [dependency, deployableDependency] of dependencies) {
196
204
  if (!pluginsToDeploy.has(dependency)) {
197
- queue.push(deployableDependency);
205
+ queue.push({
206
+ id: deployableDependency,
207
+ type
208
+ });
198
209
  }
199
210
  }
200
211
  }