@theia/plugin-ext 1.43.1 → 1.45.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.
Files changed (197) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +11 -1
  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 +9 -2
  5. package/lib/common/plugin-protocol.d.ts.map +1 -1
  6. package/lib/common/plugin-protocol.js.map +1 -1
  7. package/lib/common/proxy-handler.d.ts.map +1 -1
  8. package/lib/common/proxy-handler.js +3 -1
  9. package/lib/common/proxy-handler.js.map +1 -1
  10. package/lib/common/test-types.d.ts +9 -0
  11. package/lib/common/test-types.d.ts.map +1 -1
  12. package/lib/common/test-types.js +36 -1
  13. package/lib/common/test-types.js.map +1 -1
  14. package/lib/hosted/browser/hosted-plugin.d.ts +2 -0
  15. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  16. package/lib/hosted/browser/hosted-plugin.js +54 -6
  17. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  18. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts +1 -0
  19. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts.map +1 -1
  20. package/lib/hosted/node/hosted-plugin-deployer-handler.js +6 -0
  21. package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
  22. package/lib/hosted/node/plugin-activation-events.d.ts.map +1 -1
  23. package/lib/hosted/node/plugin-activation-events.js +1 -1
  24. package/lib/hosted/node/plugin-activation-events.js.map +1 -1
  25. package/lib/hosted/node/scanners/scanner-theia.d.ts +0 -3
  26. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  27. package/lib/hosted/node/scanners/scanner-theia.js +11 -94
  28. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  29. package/lib/main/browser/debug/plugin-debug-service.d.ts +3 -0
  30. package/lib/main/browser/debug/plugin-debug-service.d.ts.map +1 -1
  31. package/lib/main/browser/debug/plugin-debug-service.js +85 -1
  32. package/lib/main/browser/debug/plugin-debug-service.js.map +1 -1
  33. package/lib/main/browser/languages-main.d.ts.map +1 -1
  34. package/lib/main/browser/languages-main.js +1 -0
  35. package/lib/main/browser/languages-main.js.map +1 -1
  36. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts +1 -0
  37. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
  38. package/lib/main/browser/menus/plugin-menu-command-adapter.js +30 -0
  39. package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
  40. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +2 -2
  41. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
  42. package/lib/main/browser/menus/vscode-theia-menu-mappings.js +6 -1
  43. package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
  44. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts +4 -2
  45. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts.map +1 -1
  46. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js +34 -21
  47. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js.map +1 -1
  48. package/lib/main/browser/notebooks/notebook-documents-main.d.ts.map +1 -1
  49. package/lib/main/browser/notebooks/notebook-documents-main.js +8 -9
  50. package/lib/main/browser/notebooks/notebook-documents-main.js.map +1 -1
  51. package/lib/main/browser/notebooks/notebook-dto.d.ts +3 -0
  52. package/lib/main/browser/notebooks/notebook-dto.d.ts.map +1 -1
  53. package/lib/main/browser/notebooks/notebook-dto.js +27 -34
  54. package/lib/main/browser/notebooks/notebook-dto.js.map +1 -1
  55. package/lib/main/browser/notebooks/notebook-kernels-main.js +3 -3
  56. package/lib/main/browser/notebooks/notebook-kernels-main.js.map +1 -1
  57. package/lib/main/browser/notebooks/notebooks-main.d.ts +12 -1
  58. package/lib/main/browser/notebooks/notebooks-main.d.ts.map +1 -1
  59. package/lib/main/browser/notebooks/notebooks-main.js.map +1 -1
  60. package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts +1 -2
  61. package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts.map +1 -1
  62. package/lib/main/browser/notebooks/renderers/cell-output-webview.js +1 -1
  63. package/lib/main/browser/notebooks/renderers/cell-output-webview.js.map +1 -1
  64. package/lib/main/browser/plugin-contribution-handler.d.ts +2 -0
  65. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  66. package/lib/main/browser/plugin-contribution-handler.js +10 -0
  67. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  68. package/lib/main/browser/plugin-icon-theme-service.d.ts +12 -1
  69. package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
  70. package/lib/main/browser/plugin-icon-theme-service.js +44 -8
  71. package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
  72. package/lib/main/browser/plugin-shared-style.d.ts +5 -1
  73. package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
  74. package/lib/main/browser/plugin-shared-style.js +33 -16
  75. package/lib/main/browser/plugin-shared-style.js.map +1 -1
  76. package/lib/main/browser/terminal-main.d.ts +1 -0
  77. package/lib/main/browser/terminal-main.d.ts.map +1 -1
  78. package/lib/main/browser/terminal-main.js +5 -0
  79. package/lib/main/browser/terminal-main.js.map +1 -1
  80. package/lib/main/browser/text-editor-main.d.ts.map +1 -1
  81. package/lib/main/browser/text-editor-main.js +10 -0
  82. package/lib/main/browser/text-editor-main.js.map +1 -1
  83. package/lib/main/browser/webview/webview.d.ts +20 -1
  84. package/lib/main/browser/webview/webview.d.ts.map +1 -1
  85. package/lib/main/browser/webview/webview.js +38 -1
  86. package/lib/main/browser/webview/webview.js.map +1 -1
  87. package/lib/main/node/plugin-deployer-contribution.d.ts +1 -1
  88. package/lib/main/node/plugin-deployer-contribution.d.ts.map +1 -1
  89. package/lib/main/node/plugin-deployer-contribution.js +2 -1
  90. package/lib/main/node/plugin-deployer-contribution.js.map +1 -1
  91. package/lib/main/node/plugin-deployer-impl.d.ts +1 -1
  92. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  93. package/lib/main/node/plugin-deployer-impl.js +3 -2
  94. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  95. package/lib/main/node/plugin-ext-backend-module.d.ts.map +1 -1
  96. package/lib/main/node/plugin-ext-backend-module.js +3 -0
  97. package/lib/main/node/plugin-ext-backend-module.js.map +1 -1
  98. package/lib/main/node/plugin-mgmt-cli-contribution.d.ts +13 -0
  99. package/lib/main/node/plugin-mgmt-cli-contribution.d.ts.map +1 -0
  100. package/lib/main/node/plugin-mgmt-cli-contribution.js +71 -0
  101. package/lib/main/node/plugin-mgmt-cli-contribution.js.map +1 -0
  102. package/lib/plugin/command-registry.d.ts.map +1 -1
  103. package/lib/plugin/command-registry.js +9 -3
  104. package/lib/plugin/command-registry.js.map +1 -1
  105. package/lib/plugin/env.d.ts +0 -3
  106. package/lib/plugin/env.d.ts.map +1 -1
  107. package/lib/plugin/env.js +0 -6
  108. package/lib/plugin/env.js.map +1 -1
  109. package/lib/plugin/languages-utils.d.ts +2 -1
  110. package/lib/plugin/languages-utils.d.ts.map +1 -1
  111. package/lib/plugin/languages-utils.js +14 -1
  112. package/lib/plugin/languages-utils.js.map +1 -1
  113. package/lib/plugin/languages.d.ts.map +1 -1
  114. package/lib/plugin/languages.js +2 -1
  115. package/lib/plugin/languages.js.map +1 -1
  116. package/lib/plugin/notebook/notebook-document.js +3 -3
  117. package/lib/plugin/notebook/notebook-document.js.map +1 -1
  118. package/lib/plugin/notebook/notebooks.d.ts.map +1 -1
  119. package/lib/plugin/notebook/notebooks.js +7 -4
  120. package/lib/plugin/notebook/notebooks.js.map +1 -1
  121. package/lib/plugin/plugin-context.d.ts.map +1 -1
  122. package/lib/plugin/plugin-context.js +5 -1
  123. package/lib/plugin/plugin-context.js.map +1 -1
  124. package/lib/plugin/plugin-manager.d.ts +1 -1
  125. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  126. package/lib/plugin/plugin-manager.js +4 -24
  127. package/lib/plugin/plugin-manager.js.map +1 -1
  128. package/lib/plugin/status-bar/status-bar-item.d.ts.map +1 -1
  129. package/lib/plugin/terminal-ext.d.ts +5 -0
  130. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  131. package/lib/plugin/terminal-ext.js +11 -0
  132. package/lib/plugin/terminal-ext.js.map +1 -1
  133. package/lib/plugin/tests.d.ts +6 -1
  134. package/lib/plugin/tests.d.ts.map +1 -1
  135. package/lib/plugin/tests.js +22 -0
  136. package/lib/plugin/tests.js.map +1 -1
  137. package/lib/plugin/text-editor.d.ts +6 -2
  138. package/lib/plugin/text-editor.d.ts.map +1 -1
  139. package/lib/plugin/text-editor.js +57 -2
  140. package/lib/plugin/text-editor.js.map +1 -1
  141. package/lib/plugin/type-converters.d.ts +1 -12
  142. package/lib/plugin/type-converters.d.ts.map +1 -1
  143. package/lib/plugin/type-converters.js +3 -121
  144. package/lib/plugin/type-converters.js.map +1 -1
  145. package/lib/plugin/types-impl.d.ts +23 -0
  146. package/lib/plugin/types-impl.d.ts.map +1 -1
  147. package/lib/plugin/types-impl.js +36 -4
  148. package/lib/plugin/types-impl.js.map +1 -1
  149. package/lib/plugin/window-state.d.ts.map +1 -1
  150. package/lib/plugin/window-state.js +3 -4
  151. package/lib/plugin/window-state.js.map +1 -1
  152. package/package.json +29 -29
  153. package/src/common/plugin-api-rpc.ts +12 -1
  154. package/src/common/plugin-protocol.ts +9 -2
  155. package/src/common/proxy-handler.ts +3 -1
  156. package/src/common/test-types.ts +20 -0
  157. package/src/hosted/browser/hosted-plugin.ts +51 -6
  158. package/src/hosted/node/hosted-plugin-deployer-handler.ts +7 -0
  159. package/src/hosted/node/plugin-activation-events.ts +10 -9
  160. package/src/hosted/node/scanners/scanner-theia.ts +10 -101
  161. package/src/main/browser/debug/plugin-debug-service.ts +91 -2
  162. package/src/main/browser/languages-main.ts +1 -0
  163. package/src/main/browser/menus/plugin-menu-command-adapter.ts +30 -0
  164. package/src/main/browser/menus/vscode-theia-menu-mappings.ts +7 -2
  165. package/src/main/browser/notebooks/notebook-documents-and-editors-main.ts +36 -22
  166. package/src/main/browser/notebooks/notebook-documents-main.ts +11 -12
  167. package/src/main/browser/notebooks/notebook-dto.ts +24 -34
  168. package/src/main/browser/notebooks/notebook-kernels-main.ts +1 -1
  169. package/src/main/browser/notebooks/notebooks-main.ts +13 -2
  170. package/src/main/browser/notebooks/renderers/cell-output-webview.tsx +3 -3
  171. package/src/main/browser/plugin-contribution-handler.ts +9 -0
  172. package/src/main/browser/plugin-icon-theme-service.ts +46 -12
  173. package/src/main/browser/plugin-shared-style.ts +37 -17
  174. package/src/main/browser/terminal-main.ts +7 -0
  175. package/src/main/browser/text-editor-main.ts +9 -0
  176. package/src/main/browser/webview/pre/host.js +1 -1
  177. package/src/main/browser/webview/pre/main.js +84 -34
  178. package/src/main/browser/webview/webview.ts +49 -1
  179. package/src/main/node/plugin-deployer-contribution.ts +3 -2
  180. package/src/main/node/plugin-deployer-impl.ts +4 -3
  181. package/src/main/node/plugin-ext-backend-module.ts +4 -0
  182. package/src/main/node/plugin-mgmt-cli-contribution.ts +64 -0
  183. package/src/plugin/command-registry.ts +8 -3
  184. package/src/plugin/env.ts +0 -8
  185. package/src/plugin/languages-utils.ts +13 -1
  186. package/src/plugin/languages.ts +3 -2
  187. package/src/plugin/notebook/notebook-document.ts +8 -8
  188. package/src/plugin/notebook/notebooks.ts +6 -4
  189. package/src/plugin/plugin-context.ts +6 -1
  190. package/src/plugin/plugin-manager.ts +5 -25
  191. package/src/plugin/status-bar/status-bar-item.ts +1 -1
  192. package/src/plugin/terminal-ext.ts +15 -0
  193. package/src/plugin/tests.ts +25 -1
  194. package/src/plugin/text-editor.ts +64 -4
  195. package/src/plugin/type-converters.ts +3 -123
  196. package/src/plugin/types-impl.ts +33 -0
  197. package/src/plugin/window-state.ts +4 -4
@@ -84,6 +84,7 @@ export interface TestMessageDTO {
84
84
  readonly actual?: string;
85
85
  readonly location?: Location;
86
86
  readonly message: string | MarkdownString;
87
+ readonly contextValue?: string;
87
88
  }
88
89
 
89
90
  export interface TestItemDTO {
@@ -131,3 +132,22 @@ export namespace TestItemReference {
131
132
  }
132
133
  }
133
134
 
135
+ export interface TestMessageArg {
136
+ testItemReference: TestItemReference | undefined,
137
+ testMessage: TestMessageDTO
138
+ }
139
+
140
+ export namespace TestMessageArg {
141
+ export function is(arg: unknown): arg is TestMessageArg {
142
+ return isObject<TestMessageArg>(arg)
143
+ && isObject<TestMessageDTO>(arg.testMessage)
144
+ && (MarkdownString.is(arg.testMessage.message) || typeof arg.testMessage.message === 'string');
145
+ }
146
+
147
+ export function create(testItemReference: TestItemReference | undefined, testMessageDTO: TestMessageDTO): TestMessageArg {
148
+ return {
149
+ testItemReference: testItemReference,
150
+ testMessage: testMessageDTO
151
+ };
152
+ }
153
+ }
@@ -80,6 +80,30 @@ export const ALL_ACTIVATION_EVENT = '*';
80
80
  @injectable()
81
81
  export class HostedPluginSupport {
82
82
 
83
+ protected static ADDITIONAL_ACTIVATION_EVENTS_ENV = 'ADDITIONAL_ACTIVATION_EVENTS';
84
+ protected static BUILTIN_ACTIVATION_EVENTS = [
85
+ '*',
86
+ 'onLanguage',
87
+ 'onCommand',
88
+ 'onDebug',
89
+ 'onDebugInitialConfigurations',
90
+ 'onDebugResolve',
91
+ 'onDebugAdapterProtocolTracker',
92
+ 'onDebugDynamicConfigurations',
93
+ 'onTaskType',
94
+ 'workspaceContains',
95
+ 'onView',
96
+ 'onUri',
97
+ 'onTerminalProfile',
98
+ 'onWebviewPanel',
99
+ 'onFileSystem',
100
+ 'onCustomEditor',
101
+ 'onStartupFinished',
102
+ 'onAuthenticationRequest',
103
+ 'onNotebook',
104
+ 'onNotebookSerializer'
105
+ ];
106
+
83
107
  protected readonly clientId = UUID.uuid4();
84
108
 
85
109
  protected container: interfaces.Container;
@@ -377,8 +401,12 @@ export class HostedPluginSupport {
377
401
  waitPluginsMeasurement.error('Backend deployment failed.');
378
402
  }
379
403
  }
380
-
381
- syncPluginsMeasurement?.log(`Sync of ${this.getPluginCount(initialized)}`);
404
+ if (initialized > 0) {
405
+ // Only log sync measurement if there are were plugins to sync.
406
+ syncPluginsMeasurement?.log(`Sync of ${this.getPluginCount(initialized)}`);
407
+ } else {
408
+ syncPluginsMeasurement.stop();
409
+ }
382
410
  }
383
411
 
384
412
  /**
@@ -416,8 +444,12 @@ export class HostedPluginSupport {
416
444
  }));
417
445
  }
418
446
  }
419
-
420
- loadPluginsMeasurement.log(`Load contributions of ${this.getPluginCount(loaded)}`);
447
+ if (loaded > 0) {
448
+ // Only log load measurement if there are were plugins to load.
449
+ loadPluginsMeasurement?.log(`Load contributions of ${this.getPluginCount(loaded)}`);
450
+ } else {
451
+ loadPluginsMeasurement.stop();
452
+ }
421
453
 
422
454
  return hostContributions;
423
455
  }
@@ -488,7 +520,11 @@ export class HostedPluginSupport {
488
520
  return;
489
521
  }
490
522
 
491
- startPluginsMeasurement.log(`Start of ${this.getPluginCount(started)}`);
523
+ if (started > 0) {
524
+ startPluginsMeasurement.log(`Start of ${this.getPluginCount(started)}`);
525
+ } else {
526
+ startPluginsMeasurement.stop();
527
+ }
492
528
  }
493
529
 
494
530
  protected async obtainManager(host: string, hostContributions: PluginContributions[], toDisconnect: DisposableCollection): Promise<PluginManagerExt | undefined> {
@@ -519,6 +555,13 @@ export class HostedPluginSupport {
519
555
  }
520
556
 
521
557
  const isElectron = environment.electron.is();
558
+
559
+ const supportedActivationEvents = [...HostedPluginSupport.BUILTIN_ACTIVATION_EVENTS];
560
+ const additionalActivationEvents = await this.envServer.getValue(HostedPluginSupport.ADDITIONAL_ACTIVATION_EVENTS_ENV);
561
+ if (additionalActivationEvents && additionalActivationEvents.value) {
562
+ additionalActivationEvents.value.split(',').forEach(event => supportedActivationEvents.push(event));
563
+ }
564
+
522
565
  await manager.$init({
523
566
  preferences: getPreferences(this.preferenceProviderProvider, this.workspaceService.tryGetRoots()),
524
567
  globalState,
@@ -536,11 +579,13 @@ export class HostedPluginSupport {
536
579
  webviewResourceRoot,
537
580
  webviewCspSource
538
581
  },
539
- jsonValidation
582
+ jsonValidation,
583
+ supportedActivationEvents
540
584
  });
541
585
  if (toDisconnect.disposed) {
542
586
  return undefined;
543
587
  }
588
+ this.activationEvents.forEach(event => manager!.$activateByEvent(event));
544
589
  }
545
590
  return manager;
546
591
  }
@@ -76,6 +76,13 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
76
76
  return Array.from(this.deployedBackendPlugins.keys());
77
77
  }
78
78
 
79
+ async getDeployedBackendPlugins(): Promise<DeployedPlugin[]> {
80
+ // await first deploy
81
+ await this.backendPluginsMetadataDeferred.promise;
82
+ // fetch the last deployed state
83
+ return Array.from(this.deployedBackendPlugins.values());
84
+ }
85
+
79
86
  getDeployedPluginsById(pluginId: string): DeployedPlugin[] {
80
87
  const matches: DeployedPlugin[] = [];
81
88
  const handle = (plugins: Iterable<DeployedPlugin>): void => {
@@ -20,6 +20,7 @@ import {
20
20
  PluginPackage,
21
21
  PluginPackageAuthenticationProvider,
22
22
  PluginPackageCommand,
23
+ PluginPackageContribution,
23
24
  PluginPackageCustomEditor,
24
25
  PluginPackageLanguageContribution,
25
26
  PluginPackageNotebook,
@@ -31,7 +32,7 @@ import {
31
32
  * This function will update the manifest based on the plugin contributions.
32
33
  */
33
34
  export function updateActivationEvents(manifest: PluginPackage): void {
34
- if (!isObject(manifest) || !isObject(manifest.contributes) || !manifest.contributes) {
35
+ if (!isObject<PluginPackage>(manifest) || !isObject<PluginPackageContribution>(manifest.contributes) || !manifest.contributes) {
35
36
  return;
36
37
  }
37
38
 
@@ -42,8 +43,8 @@ export function updateActivationEvents(manifest: PluginPackage): void {
42
43
  const commands = Array.isArray(value) ? value : [value];
43
44
  updateCommandsContributions(commands, activationEvents);
44
45
  }
45
- if (Array.isArray(manifest.contributes.views)) {
46
- const views = flatten(Object.values(manifest.contributes.views)) as PluginPackageView[];
46
+ if (isObject(manifest.contributes.views)) {
47
+ const views = flatten(Object.values(manifest.contributes.views));
47
48
  updateViewsContribution(views, activationEvents);
48
49
  }
49
50
  if (Array.isArray(manifest.contributes.customEditors)) {
@@ -64,7 +65,7 @@ export function updateActivationEvents(manifest: PluginPackage): void {
64
65
 
65
66
  function updateViewsContribution(views: PluginPackageView[], activationEvents: Set<string>): void {
66
67
  for (const view of views) {
67
- if (isObject(view) && typeof view.id === 'string') {
68
+ if (isObject<PluginPackageView>(view) && typeof view.id === 'string') {
68
69
  activationEvents.add(`onView:${view.id}`);
69
70
  }
70
71
  }
@@ -72,7 +73,7 @@ function updateViewsContribution(views: PluginPackageView[], activationEvents: S
72
73
 
73
74
  function updateCustomEditorsContribution(customEditors: PluginPackageCustomEditor[], activationEvents: Set<string>): void {
74
75
  for (const customEditor of customEditors) {
75
- if (isObject(customEditor) && typeof customEditor.viewType === 'string') {
76
+ if (isObject<PluginPackageCustomEditor>(customEditor) && typeof customEditor.viewType === 'string') {
76
77
  activationEvents.add(`onCustomEditor:${customEditor.viewType}`);
77
78
  }
78
79
  }
@@ -80,7 +81,7 @@ function updateCustomEditorsContribution(customEditors: PluginPackageCustomEdito
80
81
 
81
82
  function updateCommandsContributions(commands: PluginPackageCommand[], activationEvents: Set<string>): void {
82
83
  for (const command of commands) {
83
- if (isObject(command) && typeof command.command === 'string') {
84
+ if (isObject<PluginPackageCommand>(command) && typeof command.command === 'string') {
84
85
  activationEvents.add(`onCommand:${command.command}`);
85
86
  }
86
87
  }
@@ -88,7 +89,7 @@ function updateCommandsContributions(commands: PluginPackageCommand[], activatio
88
89
 
89
90
  function updateAuthenticationProviderContributions(authProviders: PluginPackageAuthenticationProvider[], activationEvents: Set<string>): void {
90
91
  for (const authProvider of authProviders) {
91
- if (isObject(authProvider) && typeof authProvider.id === 'string') {
92
+ if (isObject<PluginPackageAuthenticationProvider>(authProvider) && typeof authProvider.id === 'string') {
92
93
  activationEvents.add(`onAuthenticationRequest:${authProvider.id}`);
93
94
  }
94
95
  }
@@ -96,7 +97,7 @@ function updateAuthenticationProviderContributions(authProviders: PluginPackageA
96
97
 
97
98
  function updateLanguageContributions(languages: PluginPackageLanguageContribution[], activationEvents: Set<string>): void {
98
99
  for (const language of languages) {
99
- if (isObject(language) && typeof language.id === 'string') {
100
+ if (isObject<PluginPackageLanguageContribution>(language) && typeof language.id === 'string') {
100
101
  activationEvents.add(`onLanguage:${language.id}`);
101
102
  }
102
103
  }
@@ -104,7 +105,7 @@ function updateLanguageContributions(languages: PluginPackageLanguageContributio
104
105
 
105
106
  function updateNotebookContributions(notebooks: PluginPackageNotebook[], activationEvents: Set<string>): void {
106
107
  for (const notebook of notebooks) {
107
- if (isObject(notebook) && typeof notebook.type === 'string') {
108
+ if (isObject<PluginPackageNotebook>(notebook) && typeof notebook.type === 'string') {
108
109
  activationEvents.add(`onNotebookSerializer:${notebook.type}`);
109
110
  }
110
111
  }
@@ -79,18 +79,6 @@ import { ColorDefinition } from '@theia/core/lib/common/color';
79
79
  import { CSSIcon } from '@theia/core/lib/common/markdown-rendering/icon-utilities';
80
80
  import { PluginUriFactory } from './plugin-uri-factory';
81
81
 
82
- namespace nls {
83
- export function localize(key: string, _default: string): string {
84
- return _default;
85
- }
86
- }
87
-
88
- const INTERNAL_CONSOLE_OPTIONS_SCHEMA = {
89
- enum: ['neverOpen', 'openOnSessionStart', 'openOnFirstSessionStart'],
90
- default: 'openOnFirstSessionStart',
91
- description: nls.localize('internalConsoleOptions', 'Controls when the internal debug console should open.')
92
- };
93
-
94
82
  const colorIdPattern = '^\\w+[.\\w+]*$';
95
83
  const iconIdPattern = `^${CSSIcon.iconNameSegment}(-${CSSIcon.iconNameSegment})+$`;
96
84
 
@@ -371,7 +359,7 @@ export class TheiaPluginScanner implements PluginScanner {
371
359
  }
372
360
 
373
361
  const [languagesResult, grammarsResult] = await Promise.allSettled([
374
- rawPlugin.contributes.languages ? this.readLanguages(rawPlugin.contributes.languages, rawPlugin.packagePath) : undefined,
362
+ rawPlugin.contributes.languages ? this.readLanguages(rawPlugin.contributes.languages, rawPlugin) : undefined,
375
363
  rawPlugin.contributes.grammars ? this.grammarsReader.readGrammars(rawPlugin.contributes.grammars, rawPlugin.packagePath) : undefined
376
364
  ]);
377
365
 
@@ -723,8 +711,8 @@ export class TheiaPluginScanner implements PluginScanner {
723
711
  return result;
724
712
  }
725
713
 
726
- private async readLanguages(rawLanguages: PluginPackageLanguageContribution[], pluginPath: string): Promise<LanguageContribution[]> {
727
- return Promise.all(rawLanguages.map(language => this.readLanguage(language, pluginPath)));
714
+ private async readLanguages(rawLanguages: PluginPackageLanguageContribution[], plugin: PluginPackage): Promise<LanguageContribution[]> {
715
+ return Promise.all(rawLanguages.map(language => this.readLanguage(language, plugin)));
728
716
  }
729
717
 
730
718
  private readSubmenus(rawSubmenus: PluginPackageSubmenu[], plugin: PluginPackage): Submenu[] {
@@ -741,8 +729,9 @@ export class TheiaPluginScanner implements PluginScanner {
741
729
 
742
730
  }
743
731
 
744
- private async readLanguage(rawLang: PluginPackageLanguageContribution, pluginPath: string): Promise<LanguageContribution> {
732
+ private async readLanguage(rawLang: PluginPackageLanguageContribution, plugin: PluginPackage): Promise<LanguageContribution> {
745
733
  // TODO: add validation to all parameters
734
+ const icon = this.transformIconUrl(plugin, rawLang.icon);
746
735
  const result: LanguageContribution = {
747
736
  id: rawLang.id,
748
737
  aliases: rawLang.aliases,
@@ -750,10 +739,11 @@ export class TheiaPluginScanner implements PluginScanner {
750
739
  filenamePatterns: rawLang.filenamePatterns,
751
740
  filenames: rawLang.filenames,
752
741
  firstLine: rawLang.firstLine,
753
- mimetypes: rawLang.mimetypes
742
+ mimetypes: rawLang.mimetypes,
743
+ icon: icon?.iconUrl ?? icon?.themeIcon
754
744
  };
755
745
  if (rawLang.configuration) {
756
- const rawConfiguration = await this.readJson<PluginPackageLanguageContributionConfiguration>(path.resolve(pluginPath, rawLang.configuration));
746
+ const rawConfiguration = await this.readJson<PluginPackageLanguageContributionConfiguration>(path.resolve(plugin.packagePath, rawLang.configuration));
757
747
  if (rawConfiguration) {
758
748
  const configuration: LanguageConfiguration = {
759
749
  brackets: rawConfiguration.brackets,
@@ -793,12 +783,10 @@ export class TheiaPluginScanner implements PluginScanner {
793
783
  program: rawDebugger.program,
794
784
  args: rawDebugger.args,
795
785
  runtime: rawDebugger.runtime,
796
- runtimeArgs: rawDebugger.runtimeArgs
786
+ runtimeArgs: rawDebugger.runtimeArgs,
787
+ configurationAttributes: rawDebugger.configurationAttributes
797
788
  };
798
789
 
799
- result.configurationAttributes = rawDebugger.configurationAttributes
800
- && this.resolveSchemaAttributes(rawDebugger.type, rawDebugger.configurationAttributes);
801
-
802
790
  return result;
803
791
  }
804
792
 
@@ -827,85 +815,6 @@ export class TheiaPluginScanner implements PluginScanner {
827
815
  return schema;
828
816
  }
829
817
 
830
- protected resolveSchemaAttributes(type: string, configurationAttributes: { [request: string]: IJSONSchema }): IJSONSchema[] {
831
- const taskSchema = {};
832
- return Object.keys(configurationAttributes).map(request => {
833
- const attributes: IJSONSchema = deepClone(configurationAttributes[request]);
834
- const defaultRequired = ['name', 'type', 'request'];
835
- attributes.required = attributes.required && attributes.required.length ? defaultRequired.concat(attributes.required) : defaultRequired;
836
- attributes.additionalProperties = false;
837
- attributes.type = 'object';
838
- if (!attributes.properties) {
839
- attributes.properties = {};
840
- }
841
- const properties = attributes.properties;
842
- properties['type'] = {
843
- enum: [type],
844
- description: nls.localize('debugType', 'Type of configuration.'),
845
- pattern: '^(?!node2)',
846
- errorMessage: nls.localize('debugTypeNotRecognised',
847
- 'The debug type is not recognized. Make sure that you have a corresponding debug extension installed and that it is enabled.'),
848
- patternErrorMessage: nls.localize('node2NotSupported',
849
- '"node2" is no longer supported, use "node" instead and set the "protocol" attribute to "inspector".')
850
- };
851
- properties['name'] = {
852
- type: 'string',
853
- description: nls.localize('debugName', 'Name of configuration; appears in the launch configuration drop down menu.'),
854
- default: 'Launch'
855
- };
856
- properties['request'] = {
857
- enum: [request],
858
- description: nls.localize('debugRequest', 'Request type of configuration. Can be "launch" or "attach".'),
859
- };
860
- properties['debugServer'] = {
861
- type: 'number',
862
- description: nls.localize('debugServer',
863
- 'For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode'),
864
- default: 4711
865
- };
866
- properties['preLaunchTask'] = {
867
- anyOf: [taskSchema, {
868
- type: ['string'],
869
- }],
870
- default: '',
871
- description: nls.localize('debugPrelaunchTask', 'Task to run before debug session starts.')
872
- };
873
- properties['postDebugTask'] = {
874
- anyOf: [taskSchema, {
875
- type: ['string'],
876
- }],
877
- default: '',
878
- description: nls.localize('debugPostDebugTask', 'Task to run after debug session ends.')
879
- };
880
- properties['internalConsoleOptions'] = INTERNAL_CONSOLE_OPTIONS_SCHEMA;
881
-
882
- const osProperties = Object.assign({}, properties);
883
- properties['windows'] = {
884
- type: 'object',
885
- description: nls.localize('debugWindowsConfiguration', 'Windows specific launch configuration attributes.'),
886
- properties: osProperties
887
- };
888
- properties['osx'] = {
889
- type: 'object',
890
- description: nls.localize('debugOSXConfiguration', 'OS X specific launch configuration attributes.'),
891
- properties: osProperties
892
- };
893
- properties['linux'] = {
894
- type: 'object',
895
- description: nls.localize('debugLinuxConfiguration', 'Linux specific launch configuration attributes.'),
896
- properties: osProperties
897
- };
898
- Object.keys(attributes.properties).forEach(name => {
899
- // Use schema allOf property to get independent error reporting #21113
900
- attributes!.properties![name].pattern = attributes!.properties![name].pattern || '^(?!.*\\$\\{(env|config|command)\\.)';
901
- attributes!.properties![name].patternErrorMessage = attributes!.properties![name].patternErrorMessage ||
902
- nls.localize('deprecatedVariables', "'env.', 'config.' and 'command.' are deprecated, use 'env:', 'config:' and 'command:' instead.");
903
- });
904
-
905
- return attributes;
906
- });
907
- }
908
-
909
818
  private extractValidAutoClosingPairs(langId: string, configuration: PluginPackageLanguageContributionConfiguration): AutoClosingPairConditional[] | undefined {
910
819
  const source = configuration.autoClosingPairs;
911
820
  if (typeof source === 'undefined') {
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { DebuggerDescription, DebugPath, DebugService } from '@theia/debug/lib/common/debug-service';
18
18
  import debounce = require('@theia/core/shared/lodash.debounce');
19
- import { Emitter, Event } from '@theia/core';
19
+ import { deepClone, Emitter, Event, nls } from '@theia/core';
20
20
  import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
21
21
  import { DebugConfiguration } from '@theia/debug/lib/common/debug-configuration';
22
22
  import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema';
@@ -97,6 +97,13 @@ export class PluginDebugService implements DebugService {
97
97
  }, 100);
98
98
 
99
99
  registerDebugConfigurationProvider(provider: PluginDebugConfigurationProvider): Disposable {
100
+ if (this.configurationProviders.has(provider.handle)) {
101
+ const configuration = this.configurationProviders.get(provider.handle);
102
+ if (configuration && configuration.type !== provider.type) {
103
+ console.warn(`Different debug configuration provider with type '${configuration.type}' already registered.`);
104
+ provider.handle = this.configurationProviders.size;
105
+ }
106
+ }
100
107
  const handle = provider.handle;
101
108
  this.configurationProviders.set(handle, provider);
102
109
  this.fireOnDidConfigurationProvidersChanged();
@@ -293,12 +300,94 @@ export class PluginDebugService implements DebugService {
293
300
  for (const contribution of this.debuggers) {
294
301
  if (contribution.configurationAttributes &&
295
302
  (contribution.type === debugType || contribution.type === '*' || debugType === '*')) {
296
- schemas = schemas.concat(contribution.configurationAttributes);
303
+ schemas = schemas.concat(this.resolveSchemaAttributes(contribution.type, contribution.configurationAttributes));
297
304
  }
298
305
  }
299
306
  return schemas;
300
307
  }
301
308
 
309
+ protected resolveSchemaAttributes(type: string, configurationAttributes: { [request: string]: IJSONSchema }): IJSONSchema[] {
310
+ const taskSchema = {};
311
+ return Object.keys(configurationAttributes).map(request => {
312
+ const attributes: IJSONSchema = deepClone(configurationAttributes[request]);
313
+ const defaultRequired = ['name', 'type', 'request'];
314
+ attributes.required = attributes.required && attributes.required.length ? defaultRequired.concat(attributes.required) : defaultRequired;
315
+ attributes.additionalProperties = false;
316
+ attributes.type = 'object';
317
+ if (!attributes.properties) {
318
+ attributes.properties = {};
319
+ }
320
+ const properties = attributes.properties;
321
+ properties['type'] = {
322
+ enum: [type],
323
+ description: nls.localizeByDefault('Type of configuration.'),
324
+ pattern: '^(?!node2)',
325
+ errorMessage: nls.localizeByDefault('The debug type is not recognized. Make sure that you have a corresponding debug extension installed and that it is enabled.'),
326
+ patternErrorMessage: nls.localizeByDefault('"node2" is no longer supported, use "node" instead and set the "protocol" attribute to "inspector".')
327
+ };
328
+ properties['name'] = {
329
+ type: 'string',
330
+ description: nls.localizeByDefault('Name of configuration; appears in the launch configuration dropdown menu.'),
331
+ default: 'Launch'
332
+ };
333
+ properties['request'] = {
334
+ enum: [request],
335
+ description: nls.localizeByDefault('Request type of configuration. Can be "launch" or "attach".'),
336
+ };
337
+ properties['debugServer'] = {
338
+ type: 'number',
339
+ description: nls.localizeByDefault(
340
+ 'For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode'
341
+ ),
342
+ default: 4711
343
+ };
344
+ properties['preLaunchTask'] = {
345
+ anyOf: [taskSchema, {
346
+ type: ['string'],
347
+ }],
348
+ default: '',
349
+ description: nls.localizeByDefault('Task to run before debug session starts.')
350
+ };
351
+ properties['postDebugTask'] = {
352
+ anyOf: [taskSchema, {
353
+ type: ['string'],
354
+ }],
355
+ default: '',
356
+ description: nls.localizeByDefault('Task to run after debug session ends.')
357
+ };
358
+ properties['internalConsoleOptions'] = {
359
+ enum: ['neverOpen', 'openOnSessionStart', 'openOnFirstSessionStart'],
360
+ default: 'openOnFirstSessionStart',
361
+ description: nls.localizeByDefault('Controls when the internal Debug Console should open.')
362
+ };
363
+
364
+ const osProperties = Object.assign({}, properties);
365
+ properties['windows'] = {
366
+ type: 'object',
367
+ description: nls.localizeByDefault('Windows specific launch configuration attributes.'),
368
+ properties: osProperties
369
+ };
370
+ properties['osx'] = {
371
+ type: 'object',
372
+ description: nls.localizeByDefault('OS X specific launch configuration attributes.'),
373
+ properties: osProperties
374
+ };
375
+ properties['linux'] = {
376
+ type: 'object',
377
+ description: nls.localizeByDefault('Linux specific launch configuration attributes.'),
378
+ properties: osProperties
379
+ };
380
+ Object.keys(attributes.properties).forEach(name => {
381
+ // Use schema allOf property to get independent error reporting #21113
382
+ attributes!.properties![name].pattern = attributes!.properties![name].pattern || '^(?!.*\\$\\{(env|config|command)\\.)';
383
+ attributes!.properties![name].patternErrorMessage = attributes!.properties![name].patternErrorMessage ||
384
+ nls.localizeByDefault("'env.', 'config.' and 'command.' are deprecated, use 'env:', 'config:' and 'command:' instead.");
385
+ });
386
+
387
+ return attributes;
388
+ });
389
+ }
390
+
302
391
  async getConfigurationSnippets(): Promise<IJSONSchemaSnippet[]> {
303
392
  let snippets = await this.delegated.getConfigurationSnippets();
304
393
 
@@ -167,6 +167,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
167
167
  wordPattern: reviveRegExp(configuration.wordPattern),
168
168
  indentationRules: reviveIndentationRule(configuration.indentationRules),
169
169
  onEnterRules: reviveOnEnterRules(configuration.onEnterRules),
170
+ autoClosingPairs: configuration.autoClosingPairs
170
171
  };
171
172
 
172
173
  this.register(handle, monaco.languages.setLanguageConfiguration(languageId, config));
@@ -23,10 +23,13 @@ import { ScmRepository } from '@theia/scm/lib/browser/scm-repository';
23
23
  import { ScmService } from '@theia/scm/lib/browser/scm-service';
24
24
  import { TimelineItem } from '@theia/timeline/lib/common/timeline-model';
25
25
  import { ScmCommandArg, TimelineCommandArg, TreeViewItemReference } from '../../../common';
26
+ import { TestItemReference, TestMessageArg } from '../../../common/test-types';
26
27
  import { PluginScmProvider, PluginScmResource, PluginScmResourceGroup } from '../scm-main';
27
28
  import { TreeViewWidget } from '../view/tree-view-widget';
28
29
  import { CodeEditorWidgetUtil, codeToTheiaMappings, ContributionPoint } from './vscode-theia-menu-mappings';
29
30
  import { TAB_BAR_TOOLBAR_CONTEXT_MENU } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
31
+ import { TestItem, TestMessage } from '@theia/test/lib/browser/test-service';
32
+ import { fromLocation } from '../hierarchy/hierarchy-types-converters';
30
33
 
31
34
  export type ArgumentAdapter = (...args: unknown[]) => unknown[];
32
35
 
@@ -79,6 +82,7 @@ export class PluginMenuCommandAdapter implements MenuCommandAdapter {
79
82
  @postConstruct()
80
83
  protected init(): void {
81
84
  const toCommentArgs: ArgumentAdapter = (...args) => this.toCommentArgs(...args);
85
+ const toTestMessageArgs: ArgumentAdapter = (...args) => this.toTestMessageArgs(...args);
82
86
  const firstArgOnly: ArgumentAdapter = (...args) => [args[0]];
83
87
  const noArgs: ArgumentAdapter = () => [];
84
88
  const toScmArgs: ArgumentAdapter = (...args) => this.toScmArgs(...args);
@@ -100,9 +104,11 @@ export class PluginMenuCommandAdapter implements MenuCommandAdapter {
100
104
  ['scm/resourceGroup/context', toScmArgs],
101
105
  ['scm/resourceState/context', toScmArgs],
102
106
  ['scm/title', () => [this.toScmArg(this.scmService.selectedRepository)]],
107
+ ['testing/message/context', toTestMessageArgs],
103
108
  ['timeline/item/context', (...args) => this.toTimelineArgs(...args)],
104
109
  ['view/item/context', (...args) => this.toTreeArgs(...args)],
105
110
  ['view/title', noArgs],
111
+ ['webview/context', noArgs]
106
112
  ]).forEach(([contributionPoint, adapter]) => {
107
113
  if (adapter) {
108
114
  const paths = codeToTheiaMappings.get(contributionPoint);
@@ -229,6 +235,30 @@ export class PluginMenuCommandAdapter implements MenuCommandAdapter {
229
235
  return timelineArgs;
230
236
  }
231
237
 
238
+ protected toTestMessageArgs(...args: any[]): any[] {
239
+ let testItem: TestItem | undefined;
240
+ let testMessage: TestMessage | undefined;
241
+ for (const arg of args) {
242
+ if (TestItem.is(arg)) {
243
+ testItem = arg;
244
+ } else if (Array.isArray(arg) && TestMessage.is(arg[0])) {
245
+ testMessage = arg[0];
246
+ }
247
+ }
248
+ if (testMessage) {
249
+ const testItemReference = (testItem && testItem.controller) ? TestItemReference.create(testItem.controller.id, testItem.path) : undefined;
250
+ const testMessageDTO = {
251
+ message: testMessage.message,
252
+ actual: testMessage.actual,
253
+ expected: testMessage.expected,
254
+ contextValue: testMessage.contextValue,
255
+ location: testMessage.location ? fromLocation(testMessage.location) : undefined
256
+ };
257
+ return [TestMessageArg.create(testItemReference, testMessageDTO)];
258
+ }
259
+ return [];
260
+ }
261
+
232
262
  protected toTimelineArg(arg: TimelineItem): TimelineCommandArg {
233
263
  return {
234
264
  timelineHandle: arg.handle,
@@ -29,9 +29,10 @@ import { ScmTreeWidget } from '@theia/scm/lib/browser/scm-tree-widget';
29
29
  import { TIMELINE_ITEM_CONTEXT_MENU } from '@theia/timeline/lib/browser/timeline-tree-widget';
30
30
  import { COMMENT_CONTEXT, COMMENT_THREAD_CONTEXT, COMMENT_TITLE } from '../comments/comment-thread-widget';
31
31
  import { VIEW_ITEM_CONTEXT_MENU } from '../view/tree-view-widget';
32
- import { WebviewWidget } from '../webview/webview';
32
+ import { WEBVIEW_CONTEXT_MENU, WebviewWidget } from '../webview/webview';
33
33
  import { EDITOR_LINENUMBER_CONTEXT_MENU } from '@theia/editor/lib/browser/editor-linenumber-contribution';
34
34
  import { TEST_VIEW_CONTEXT_MENU } from '@theia/test/lib/browser/view/test-view-contribution';
35
+ import { TEST_RUNS_CONTEXT_MENU } from '@theia/test/lib/browser/view/test-run-view-contribution';
35
36
 
36
37
  export const PLUGIN_EDITOR_TITLE_MENU = ['plugin_editor/title'];
37
38
  export const PLUGIN_EDITOR_TITLE_RUN_MENU = ['plugin_editor/title/run'];
@@ -57,8 +58,10 @@ export const implementedVSCodeContributionPoints = [
57
58
  'scm/title',
58
59
  'timeline/item/context',
59
60
  'testing/item/context',
61
+ 'testing/message/context',
60
62
  'view/item/context',
61
- 'view/title'
63
+ 'view/title',
64
+ 'webview/context'
62
65
  ] as const;
63
66
 
64
67
  export type ContributionPoint = (typeof implementedVSCodeContributionPoints)[number];
@@ -82,9 +85,11 @@ export const codeToTheiaMappings = new Map<ContributionPoint, MenuPath[]>([
82
85
  ['scm/resourceState/context', [ScmTreeWidget.RESOURCE_CONTEXT_MENU]],
83
86
  ['scm/title', [PLUGIN_SCM_TITLE_MENU]],
84
87
  ['testing/item/context', [TEST_VIEW_CONTEXT_MENU]],
88
+ ['testing/message/context', [TEST_RUNS_CONTEXT_MENU]],
85
89
  ['timeline/item/context', [TIMELINE_ITEM_CONTEXT_MENU]],
86
90
  ['view/item/context', [VIEW_ITEM_CONTEXT_MENU]],
87
91
  ['view/title', [PLUGIN_VIEW_TITLE_MENU]],
92
+ ['webview/context', [WEBVIEW_CONTEXT_MENU]]
88
93
  ]);
89
94
 
90
95
  type CodeEditorWidget = EditorWidget | WebviewWidget;