@theia/plugin-ext 1.34.0-next.7 → 1.34.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 (175) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +30 -10
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js +23 -11
  4. package/lib/common/plugin-api-rpc.js.map +1 -1
  5. package/lib/common/plugin-protocol.d.ts +15 -0
  6. package/lib/common/plugin-protocol.d.ts.map +1 -1
  7. package/lib/common/plugin-protocol.js.map +1 -1
  8. package/lib/common/rpc-protocol.d.ts.map +1 -1
  9. package/lib/common/rpc-protocol.js +3 -4
  10. package/lib/common/rpc-protocol.js.map +1 -1
  11. package/lib/common/types.d.ts +1 -1
  12. package/lib/common/types.d.ts.map +1 -1
  13. package/lib/common/types.js +2 -3
  14. package/lib/common/types.js.map +1 -1
  15. package/lib/hosted/browser/hosted-plugin.d.ts +1 -0
  16. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  17. package/lib/hosted/browser/hosted-plugin.js +3 -0
  18. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  19. package/lib/hosted/node/hosted-plugin-localization-service.d.ts.map +1 -1
  20. package/lib/hosted/node/hosted-plugin-localization-service.js +2 -2
  21. package/lib/hosted/node/hosted-plugin-localization-service.js.map +1 -1
  22. package/lib/hosted/node/plugin-host.d.ts +1 -1
  23. package/lib/hosted/node/plugin-host.d.ts.map +1 -1
  24. package/lib/hosted/node/plugin-host.js +1 -2
  25. package/lib/hosted/node/plugin-host.js.map +1 -1
  26. package/lib/hosted/node/scanners/scanner-theia.d.ts +2 -1
  27. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  28. package/lib/hosted/node/scanners/scanner-theia.js +13 -0
  29. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  30. package/lib/main/browser/authentication-main.js +1 -1
  31. package/lib/main/browser/authentication-main.js.map +1 -1
  32. package/lib/main/browser/commands.js +1 -1
  33. package/lib/main/browser/commands.js.map +1 -1
  34. package/lib/main/browser/debug/debug-main.d.ts.map +1 -1
  35. package/lib/main/browser/debug/debug-main.js +1 -0
  36. package/lib/main/browser/debug/debug-main.js.map +1 -1
  37. package/lib/main/browser/dialogs-main.d.ts.map +1 -1
  38. package/lib/main/browser/dialogs-main.js +2 -1
  39. package/lib/main/browser/dialogs-main.js.map +1 -1
  40. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts +2 -2
  41. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
  42. package/lib/main/browser/menus/plugin-menu-command-adapter.js +6 -2
  43. package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
  44. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +2 -2
  45. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
  46. package/lib/main/browser/menus/vscode-theia-menu-mappings.js +6 -0
  47. package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
  48. package/lib/main/browser/plugin-contribution-handler.d.ts +6 -0
  49. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  50. package/lib/main/browser/plugin-contribution-handler.js +35 -0
  51. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  52. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  53. package/lib/main/browser/plugin-ext-frontend-module.js +8 -3
  54. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  55. package/lib/main/browser/plugin-terminal-registry.d.ts +5 -0
  56. package/lib/main/browser/plugin-terminal-registry.d.ts.map +1 -0
  57. package/lib/main/browser/plugin-terminal-registry.js +35 -0
  58. package/lib/main/browser/plugin-terminal-registry.js.map +1 -0
  59. package/lib/main/browser/scm-main.d.ts +1 -0
  60. package/lib/main/browser/scm-main.d.ts.map +1 -1
  61. package/lib/main/browser/scm-main.js +7 -0
  62. package/lib/main/browser/scm-main.js.map +1 -1
  63. package/lib/main/browser/terminal-main.d.ts +10 -4
  64. package/lib/main/browser/terminal-main.d.ts.map +1 -1
  65. package/lib/main/browser/terminal-main.js +51 -25
  66. package/lib/main/browser/terminal-main.js.map +1 -1
  67. package/lib/main/browser/view/dnd-file-content-store.d.ts +8 -0
  68. package/lib/main/browser/view/dnd-file-content-store.d.ts.map +1 -0
  69. package/lib/main/browser/view/dnd-file-content-store.js +52 -0
  70. package/lib/main/browser/view/dnd-file-content-store.js.map +1 -0
  71. package/lib/main/browser/view/plugin-view-registry.d.ts.map +1 -1
  72. package/lib/main/browser/view/plugin-view-registry.js +1 -1
  73. package/lib/main/browser/view/plugin-view-registry.js.map +1 -1
  74. package/lib/main/browser/view/tree-view-decorator-service.d.ts +2 -4
  75. package/lib/main/browser/view/tree-view-decorator-service.d.ts.map +1 -1
  76. package/lib/main/browser/view/tree-view-decorator-service.js +1 -2
  77. package/lib/main/browser/view/tree-view-decorator-service.js.map +1 -1
  78. package/lib/main/browser/view/tree-view-widget.d.ts +25 -9
  79. package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
  80. package/lib/main/browser/view/tree-view-widget.js +184 -38
  81. package/lib/main/browser/view/tree-view-widget.js.map +1 -1
  82. package/lib/main/browser/view/tree-views-main.d.ts +5 -2
  83. package/lib/main/browser/view/tree-views-main.d.ts.map +1 -1
  84. package/lib/main/browser/view/tree-views-main.js +16 -2
  85. package/lib/main/browser/view/tree-views-main.js.map +1 -1
  86. package/lib/main/browser/webview/webview.d.ts +1 -1
  87. package/lib/main/browser/webview/webview.d.ts.map +1 -1
  88. package/lib/main/browser/webview/webview.js +7 -2
  89. package/lib/main/browser/webview/webview.js.map +1 -1
  90. package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts +1 -1
  91. package/lib/main/node/handlers/plugin-theia-directory-handler.d.ts.map +1 -1
  92. package/lib/plugin/debug/debug-ext.d.ts +3 -0
  93. package/lib/plugin/debug/debug-ext.d.ts.map +1 -1
  94. package/lib/plugin/debug/debug-ext.js +10 -0
  95. package/lib/plugin/debug/debug-ext.js.map +1 -1
  96. package/lib/plugin/languages/code-action.d.ts.map +1 -1
  97. package/lib/plugin/languages/code-action.js +8 -8
  98. package/lib/plugin/languages/code-action.js.map +1 -1
  99. package/lib/plugin/plugin-context.d.ts.map +1 -1
  100. package/lib/plugin/plugin-context.js +8 -0
  101. package/lib/plugin/plugin-context.js.map +1 -1
  102. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  103. package/lib/plugin/plugin-manager.js +1 -0
  104. package/lib/plugin/plugin-manager.js.map +1 -1
  105. package/lib/plugin/preference-registry.d.ts.map +1 -1
  106. package/lib/plugin/preference-registry.js +4 -2
  107. package/lib/plugin/preference-registry.js.map +1 -1
  108. package/lib/plugin/quick-open.d.ts +3 -0
  109. package/lib/plugin/quick-open.d.ts.map +1 -1
  110. package/lib/plugin/quick-open.js +7 -0
  111. package/lib/plugin/quick-open.js.map +1 -1
  112. package/lib/plugin/scm.d.ts +3 -0
  113. package/lib/plugin/scm.d.ts.map +1 -1
  114. package/lib/plugin/scm.js +7 -0
  115. package/lib/plugin/scm.js.map +1 -1
  116. package/lib/plugin/tabs.js +2 -2
  117. package/lib/plugin/tabs.js.map +1 -1
  118. package/lib/plugin/terminal-ext.d.ts +9 -1
  119. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  120. package/lib/plugin/terminal-ext.js +63 -7
  121. package/lib/plugin/terminal-ext.js.map +1 -1
  122. package/lib/plugin/tree/tree-views.d.ts +13 -7
  123. package/lib/plugin/tree/tree-views.d.ts.map +1 -1
  124. package/lib/plugin/tree/tree-views.js +93 -24
  125. package/lib/plugin/tree/tree-views.js.map +1 -1
  126. package/lib/plugin/type-converters.d.ts +4 -0
  127. package/lib/plugin/type-converters.d.ts.map +1 -1
  128. package/lib/plugin/type-converters.js +48 -46
  129. package/lib/plugin/type-converters.js.map +1 -1
  130. package/lib/plugin/type-converters.spec.js +19 -0
  131. package/lib/plugin/type-converters.spec.js.map +1 -1
  132. package/lib/plugin/types-impl.d.ts +61 -6
  133. package/lib/plugin/types-impl.d.ts.map +1 -1
  134. package/lib/plugin/types-impl.js +117 -17
  135. package/lib/plugin/types-impl.js.map +1 -1
  136. package/package.json +26 -26
  137. package/src/common/plugin-api-rpc.ts +36 -18
  138. package/src/common/plugin-protocol.ts +18 -0
  139. package/src/common/rpc-protocol.ts +2 -3
  140. package/src/common/types.ts +4 -4
  141. package/src/hosted/browser/hosted-plugin.ts +4 -0
  142. package/src/hosted/node/hosted-plugin-localization-service.ts +3 -3
  143. package/src/hosted/node/plugin-host.ts +1 -2
  144. package/src/hosted/node/scanners/scanner-theia.ts +15 -1
  145. package/src/main/browser/authentication-main.ts +1 -1
  146. package/src/main/browser/commands.ts +1 -1
  147. package/src/main/browser/debug/debug-main.ts +1 -0
  148. package/src/main/browser/dialogs-main.ts +2 -1
  149. package/src/main/browser/menus/plugin-menu-command-adapter.ts +7 -4
  150. package/src/main/browser/menus/vscode-theia-menu-mappings.ts +6 -0
  151. package/src/main/browser/plugin-contribution-handler.ts +35 -0
  152. package/src/main/browser/plugin-ext-frontend-module.ts +10 -4
  153. package/src/main/browser/plugin-terminal-registry.ts +27 -0
  154. package/src/main/browser/scm-main.ts +10 -0
  155. package/src/main/browser/terminal-main.ts +55 -25
  156. package/src/main/browser/view/dnd-file-content-store.ts +42 -0
  157. package/src/main/browser/view/plugin-view-registry.ts +4 -1
  158. package/src/main/browser/view/tree-view-decorator-service.ts +4 -5
  159. package/src/main/browser/view/tree-view-widget.tsx +189 -35
  160. package/src/main/browser/view/tree-views-main.ts +20 -4
  161. package/src/main/browser/webview/pre/main.js +112 -111
  162. package/src/main/browser/webview/webview.ts +7 -3
  163. package/src/plugin/debug/debug-ext.ts +12 -0
  164. package/src/plugin/languages/code-action.ts +8 -8
  165. package/src/plugin/plugin-context.ts +16 -3
  166. package/src/plugin/plugin-manager.ts +1 -0
  167. package/src/plugin/preference-registry.ts +4 -2
  168. package/src/plugin/quick-open.ts +10 -0
  169. package/src/plugin/scm.ts +11 -0
  170. package/src/plugin/tabs.ts +2 -2
  171. package/src/plugin/terminal-ext.ts +68 -8
  172. package/src/plugin/tree/tree-views.ts +98 -31
  173. package/src/plugin/type-converters.spec.ts +20 -0
  174. package/src/plugin/type-converters.ts +51 -50
  175. package/src/plugin/types-impl.ts +143 -21
@@ -22,7 +22,7 @@
22
22
 
23
23
  /* eslint-disable @typescript-eslint/no-explicit-any */
24
24
 
25
- import { Channel, Disposable, DisposableCollection, ReadBuffer, WriteBuffer } from '@theia/core';
25
+ import { Channel, Disposable, DisposableCollection, isObject, ReadBuffer, URI, WriteBuffer } from '@theia/core';
26
26
  import { Emitter, Event } from '@theia/core/lib/common/event';
27
27
  import { ChannelMultiplexer, MessageProvider } from '@theia/core/lib/common/message-rpc/channel';
28
28
  import { MsgPackMessageDecoder, MsgPackMessageEncoder } from '@theia/core/lib/common/message-rpc/rpc-message-encoder';
@@ -30,7 +30,6 @@ import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '@theia/core/lib/com
30
30
  import { ClientProxyHandler, RpcInvocationHandler } from './proxy-handler';
31
31
  import { MsgPackExtensionManager } from '@theia/core/lib/common/message-rpc/msg-pack-extension-manager';
32
32
  import { URI as VSCodeURI } from '@theia/core/shared/vscode-uri';
33
- import URI from '@theia/core/lib/common/uri';
34
33
  import { BinaryBuffer } from '@theia/core/lib/common/buffer';
35
34
  import { Range, Position } from '../plugin/types-impl';
36
35
 
@@ -74,7 +73,7 @@ export namespace ConnectionClosedError {
74
73
  return Object.assign(new Error(message), { code });
75
74
  }
76
75
  export function is(error: unknown): error is ConnectionClosedError {
77
- return !!error && typeof error === 'object' && 'code' in error && (error as ConnectionClosedError).code === code;
76
+ return isObject(error) && 'code' in error && (error as ConnectionClosedError).code === code;
78
77
  }
79
78
  }
80
79
 
@@ -19,13 +19,13 @@
19
19
  * Licensed under the MIT License. See License.txt in the project root for license information.
20
20
  *--------------------------------------------------------------------------------------------*/
21
21
 
22
+ import { isObject as isObject0 } from '@theia/core/lib/common';
23
+
22
24
  /**
23
25
  * Returns `true` if the parameter has type "object" and not null, an array, a regexp, a date.
24
26
  */
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- export function isObject(obj: any): boolean {
27
- return typeof obj === 'object'
28
- && obj !== null // eslint-disable-line @typescript-eslint/no-explicit-any
27
+ export function isObject(obj: unknown): boolean {
28
+ return isObject0(obj)
29
29
  && !Array.isArray(obj)
30
30
  && !(obj instanceof RegExp)
31
31
  && !(obj instanceof Date);
@@ -616,6 +616,10 @@ export class HostedPluginSupport {
616
616
  return this.activateByEvent(`onFileSystem:${event.scheme}`);
617
617
  }
618
618
 
619
+ activateByTerminalProfile(profileId: string): Promise<void> {
620
+ return this.activateByEvent(`onTerminalProfile:${profileId}`);
621
+ }
622
+
619
623
  protected ensureFileSystemActivation(event: FileSystemProviderActivationEvent): void {
620
624
  event.waitUntil(this.activateByFileSystem(event));
621
625
  }
@@ -23,7 +23,7 @@ import { DeployedPlugin, Localization as PluginLocalization, PluginIdentifiers }
23
23
  import { URI } from '@theia/core/shared/vscode-uri';
24
24
  import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
25
25
  import { BackendApplicationContribution } from '@theia/core/lib/node';
26
- import { Disposable, MaybePromise } from '@theia/core';
26
+ import { Disposable, isObject, MaybePromise } from '@theia/core';
27
27
  import { Deferred } from '@theia/core/lib/common/promise-util';
28
28
 
29
29
  export interface VSCodeNlsConfig {
@@ -205,7 +205,7 @@ interface LocalizeInfo {
205
205
  }
206
206
 
207
207
  function isLocalizeInfo(obj: unknown): obj is LocalizeInfo {
208
- return typeof obj === 'object' && obj && 'message' in obj || false;
208
+ return isObject(obj) && 'message' in obj || false;
209
209
  }
210
210
 
211
211
  function coerceLocalizations(translations: Record<string, string | LocalizeInfo>): Record<string, string> {
@@ -243,7 +243,7 @@ function localizePackage(value: unknown, translations: PackageTranslation, callb
243
243
  }
244
244
  return result;
245
245
  }
246
- if (typeof value === 'object' && value) {
246
+ if (isObject(value)) {
247
247
  const result: Record<string, unknown> = {};
248
248
  for (const [name, item] of Object.entries(value)) {
249
249
  result[name] = localizePackage(item, translations, callback);
@@ -13,8 +13,7 @@
13
13
  //
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
- // eslint-disable-next-line import/no-extraneous-dependencies
17
- import 'reflect-metadata';
16
+ import '@theia/core/shared/reflect-metadata';
18
17
  import { ConnectionClosedError, RPCProtocolImpl } from '../../common/rpc-protocol';
19
18
  import { ProcessTerminatedMessage, ProcessTerminateMessage } from './hosted-plugin-protocol';
20
19
  import { PluginHostRPC } from './plugin-host-rpc';
@@ -59,7 +59,8 @@ import {
59
59
  Localization,
60
60
  PluginPackageTranslation,
61
61
  Translation,
62
- PluginIdentifiers
62
+ PluginIdentifiers,
63
+ TerminalProfile
63
64
  } from '../../../common/plugin-protocol';
64
65
  import * as fs from 'fs';
65
66
  import * as path from 'path';
@@ -358,9 +359,22 @@ export class TheiaPluginScanner implements PluginScanner {
358
359
  console.error(`Could not read '${rawPlugin.name}' contribution 'localizations'.`, rawPlugin.contributes.colors, err);
359
360
  }
360
361
 
362
+ try {
363
+ contributions.terminalProfiles = this.readTerminals(rawPlugin);
364
+ } catch (err) {
365
+ console.error(`Could not read '${rawPlugin.name}' contribution 'terminals'.`, rawPlugin.contributes.terminal, err);
366
+ }
367
+
361
368
  return contributions;
362
369
  }
363
370
 
371
+ protected readTerminals(pck: PluginPackage): TerminalProfile[] | undefined {
372
+ if (!pck?.contributes?.terminal?.profiles) {
373
+ return undefined;
374
+ }
375
+ return pck.contributes.terminal.profiles.filter(profile => profile.id && profile.title);
376
+ }
377
+
364
378
  protected readLocalizations(pck: PluginPackage): Localization[] | undefined {
365
379
  if (!pck.contributes || !pck.contributes.localizations) {
366
380
  return undefined;
@@ -199,7 +199,7 @@ export class AuthenticationMainImpl implements AuthenticationMain {
199
199
 
200
200
  protected async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean, _detail?: string): Promise<boolean> {
201
201
  const message = recreatingSession
202
- ? nls.localize('theia/plugin-ext/signInAgain', "The extension '{0}' wants you to sign in again using {1}.", extensionName, providerName)
202
+ ? nls.localizeByDefault("The extension '{0}' wants you to sign in again using {1}.", extensionName, providerName)
203
203
  : nls.localizeByDefault("The extension '{0}' wants to sign in using {1}.", extensionName, providerName);
204
204
  const choice = await this.messageService.info(message, 'Allow', 'Cancel');
205
205
  return choice === 'Allow';
@@ -71,7 +71,7 @@ class OpenNewTabDialog extends AbstractDialog<string> {
71
71
 
72
72
  constructor(windowService: WindowService) {
73
73
  super({
74
- title: 'Your browser prevented opening of a new tab'
74
+ title: nls.localize('theia/plugin/blockNewTab', 'Your browser prevented opening of a new tab')
75
75
  });
76
76
  this.windowService = windowService;
77
77
 
@@ -114,6 +114,7 @@ export class DebugMainImpl implements DebugMain, Disposable {
114
114
  this.breakpointsManager.onDidChangeBreakpoints(fireDidChangeBreakpoints),
115
115
  this.breakpointsManager.onDidChangeFunctionBreakpoints(fireDidChangeBreakpoints),
116
116
  this.sessionManager.onDidCreateDebugSession(debugSession => this.debugExt.$sessionDidCreate(debugSession.id)),
117
+ this.sessionManager.onDidStartDebugSession(debugSession => this.debugExt.$sessionDidStart(debugSession.id)),
117
118
  this.sessionManager.onDidDestroyDebugSession(debugSession => this.debugExt.$sessionDidDestroy(debugSession.id)),
118
119
  this.sessionManager.onDidChangeActiveDebugSession(event => this.debugExt.$sessionDidChange(event.current && event.current.id)),
119
120
  this.sessionManager.onDidReceiveDebugSessionCustomEvent(event => this.debugExt.$onSessionCustomEvent(event.session.id, event.event, event.body))
@@ -24,6 +24,7 @@ import { FileUploadService } from '@theia/filesystem/lib/browser/file-upload-ser
24
24
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
25
25
  import { FileStat } from '@theia/filesystem/lib/common/files';
26
26
  import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
27
+ import { nls } from '@theia/core';
27
28
 
28
29
  export class DialogsMainImpl implements DialogsMain {
29
30
 
@@ -146,7 +147,7 @@ export class DialogsMainImpl implements DialogsMain {
146
147
  try {
147
148
  // Create save file dialog props
148
149
  const dialogProps = {
149
- title: options.title ?? 'Save',
150
+ title: options.title ?? nls.localizeByDefault('Save'),
150
151
  saveLabel: options.saveLabel,
151
152
  filters: options.filters,
152
153
  inputValue: fileNameValue
@@ -22,7 +22,7 @@ import { TreeWidgetSelection } from '@theia/core/lib/browser/tree/tree-widget-se
22
22
  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
- import { ScmCommandArg, TimelineCommandArg, TreeViewSelection } from '../../../common';
25
+ import { ScmCommandArg, TimelineCommandArg, TreeViewItemReference } from '../../../common';
26
26
  import { PluginScmProvider, PluginScmResource, PluginScmResourceGroup } from '../scm-main';
27
27
  import { TreeViewWidget } from '../view/tree-view-widget';
28
28
  import { CodeEditorWidgetUtil, codeToTheiaMappings, ContributionPoint } from './vscode-theia-menu-mappings';
@@ -89,6 +89,7 @@ export class PluginMenuCommandAdapter implements MenuCommandAdapter {
89
89
  ['comments/comment/title', toCommentArgs],
90
90
  ['comments/commentThread/context', toCommentArgs],
91
91
  ['debug/callstack/context', firstArgOnly],
92
+ ['debug/variables/context', firstArgOnly],
92
93
  ['debug/toolBar', noArgs],
93
94
  ['editor/context', selectedResource],
94
95
  ['editor/title', widgetURI],
@@ -238,19 +239,21 @@ export class PluginMenuCommandAdapter implements MenuCommandAdapter {
238
239
  protected toTreeArgs(...args: any[]): any[] {
239
240
  const treeArgs: any[] = [];
240
241
  for (const arg of args) {
241
- if (TreeViewSelection.is(arg)) {
242
+ if (TreeViewItemReference.is(arg)) {
242
243
  treeArgs.push(arg);
244
+ } else if (Array.isArray(arg)) {
245
+ treeArgs.push(arg.filter(TreeViewItemReference.is));
243
246
  }
244
247
  }
245
248
  return treeArgs;
246
249
  }
247
250
 
248
- protected getSelectedResources(): [CodeUri | TreeViewSelection | undefined, CodeUri[] | undefined] {
251
+ protected getSelectedResources(): [CodeUri | TreeViewItemReference | undefined, CodeUri[] | undefined] {
249
252
  const selection = this.selectionService.selection;
250
253
  const resourceKey = this.resourceContextKey.get();
251
254
  const resourceUri = resourceKey ? CodeUri.parse(resourceKey) : undefined;
252
255
  const firstMember = TreeWidgetSelection.is(selection) && selection.source instanceof TreeViewWidget && selection[0]
253
- ? selection.source.toTreeViewSelection(selection[0])
256
+ ? selection.source.toTreeViewItemReference(selection[0])
254
257
  : UriSelection.getUri(selection)?.['codeUri'] ?? resourceUri;
255
258
  const secondMember = TreeWidgetSelection.is(selection)
256
259
  ? UriSelection.getUris(selection).map(uri => uri['codeUri'])
@@ -21,6 +21,8 @@ import { injectable } from '@theia/core/shared/inversify';
21
21
  import { URI as CodeUri } from '@theia/core/shared/vscode-uri';
22
22
  import { DebugStackFramesWidget } from '@theia/debug/lib/browser/view/debug-stack-frames-widget';
23
23
  import { DebugThreadsWidget } from '@theia/debug/lib/browser/view/debug-threads-widget';
24
+ import { DebugToolBar } from '@theia/debug/lib/browser/view/debug-toolbar-widget';
25
+ import { DebugVariablesWidget } from '@theia/debug/lib/browser/view/debug-variables-widget';
24
26
  import { EditorWidget, EDITOR_CONTEXT_MENU } from '@theia/editor/lib/browser';
25
27
  import { NAVIGATOR_CONTEXT_MENU } from '@theia/navigator/lib/browser/navigator-contribution';
26
28
  import { ScmTreeWidget } from '@theia/scm/lib/browser/scm-tree-widget';
@@ -38,6 +40,8 @@ export const implementedVSCodeContributionPoints = [
38
40
  'comments/comment/title',
39
41
  'comments/commentThread/context',
40
42
  'debug/callstack/context',
43
+ 'debug/variables/context',
44
+ 'debug/toolBar',
41
45
  'editor/context',
42
46
  'editor/title',
43
47
  'editor/title/context',
@@ -59,6 +63,8 @@ export const codeToTheiaMappings = new Map<ContributionPoint, MenuPath[]>([
59
63
  ['comments/comment/title', [COMMENT_TITLE]],
60
64
  ['comments/commentThread/context', [COMMENT_THREAD_CONTEXT]],
61
65
  ['debug/callstack/context', [DebugStackFramesWidget.CONTEXT_MENU, DebugThreadsWidget.CONTEXT_MENU]],
66
+ ['debug/variables/context', [DebugVariablesWidget.CONTEXT_MENU]],
67
+ ['debug/toolBar', [DebugToolBar.MENU]],
62
68
  ['editor/context', [EDITOR_CONTEXT_MENU]],
63
69
  ['editor/title', [PLUGIN_EDITOR_TITLE_MENU]],
64
70
  ['editor/title/context', [SHELL_TABBAR_CONTEXT_MENU]],
@@ -43,6 +43,10 @@ import { PluginIconThemeService } from './plugin-icon-theme-service';
43
43
  import { ContributionProvider } from '@theia/core/lib/common';
44
44
  import * as monaco from '@theia/monaco-editor-core';
45
45
  import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService';
46
+ import { ContributedTerminalProfileStore, TerminalProfileStore } from '@theia/terminal/lib/browser/terminal-profile-service';
47
+ import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
48
+ import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service';
49
+ import { PluginTerminalRegistry } from './plugin-terminal-registry';
46
50
 
47
51
  @injectable()
48
52
  export class PluginContributionHandler {
@@ -106,6 +110,15 @@ export class PluginContributionHandler {
106
110
  @inject(PluginIconThemeService)
107
111
  protected readonly iconThemeService: PluginIconThemeService;
108
112
 
113
+ @inject(TerminalService)
114
+ protected readonly terminalService: TerminalService;
115
+
116
+ @inject(PluginTerminalRegistry)
117
+ protected readonly pluginTerminalRegistry: PluginTerminalRegistry;
118
+
119
+ @inject(ContributedTerminalProfileStore)
120
+ protected readonly contributedProfileStore: TerminalProfileStore;
121
+
109
122
  @inject(ContributionProvider) @named(LabelProviderContribution)
110
123
  protected readonly contributionProvider: ContributionProvider<LabelProviderContribution>;
111
124
 
@@ -356,6 +369,28 @@ export class PluginContributionHandler {
356
369
  }
357
370
  }
358
371
 
372
+ const self = this;
373
+ if (contributions.terminalProfiles) {
374
+ for (const profile of contributions.terminalProfiles) {
375
+ pushContribution(`terminalProfiles.${profile.id}`, () => {
376
+ this.contributedProfileStore.registerTerminalProfile(profile.title, {
377
+ async start(): Promise<TerminalWidget> {
378
+ const terminalId = await self.pluginTerminalRegistry.start(profile.id);
379
+ const result = self.terminalService.getById(terminalId);
380
+ if (!result) {
381
+ throw new Error(`Error starting terminal from profile ${profile.id}`);
382
+ }
383
+ return result;
384
+
385
+ }
386
+ });
387
+ return Disposable.create(() => {
388
+ this.contributedProfileStore.unregisterTerminalProfile(profile.id);
389
+ });
390
+ });
391
+ }
392
+ }
393
+
359
394
  return toDispose;
360
395
  }
361
396
 
@@ -50,7 +50,7 @@ import { SelectionProviderCommandContribution } from './selection-provider-comma
50
50
  import { ViewColumnService } from './view-column-service';
51
51
  import { ViewContextKeyService } from './view/view-context-key-service';
52
52
  import { PluginViewWidget, PluginViewWidgetIdentifier } from './view/plugin-view-widget';
53
- import { TreeViewWidgetIdentifier, VIEW_ITEM_CONTEXT_MENU, PluginTree, TreeViewWidget, PluginTreeModel } from './view/tree-view-widget';
53
+ import { TreeViewWidgetOptions, VIEW_ITEM_CONTEXT_MENU, PluginTree, TreeViewWidget, PluginTreeModel } from './view/tree-view-widget';
54
54
  import { RPCProtocol } from '../../common/rpc-protocol';
55
55
  import { LanguagesMainFactory, OutputChannelRegistryFactory } from '../../common';
56
56
  import { LanguagesMainImpl } from './languages-main';
@@ -80,6 +80,8 @@ import { bindTreeViewDecoratorUtilities, TreeViewDecoratorService } from './view
80
80
  import { CodeEditorWidgetUtil } from './menus/vscode-theia-menu-mappings';
81
81
  import { PluginMenuCommandAdapter } from './menus/plugin-menu-command-adapter';
82
82
  import './theme-icon-override';
83
+ import { PluginTerminalRegistry } from './plugin-terminal-registry';
84
+ import { DnDFileContentStore } from './view/dnd-file-content-store';
83
85
 
84
86
  export default new ContainerModule((bind, unbind, isBound, rebind) => {
85
87
 
@@ -143,16 +145,18 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
143
145
  bindTreeViewDecoratorUtilities(bind);
144
146
  bind(PluginTreeViewNodeLabelProvider).toSelf().inSingletonScope();
145
147
  bind(LabelProviderContribution).toService(PluginTreeViewNodeLabelProvider);
148
+ bind(DnDFileContentStore).toSelf().inSingletonScope();
146
149
  bind(WidgetFactory).toDynamicValue(({ container }) => ({
147
150
  id: PLUGIN_VIEW_DATA_FACTORY_ID,
148
- createWidget: (identifier: TreeViewWidgetIdentifier) => {
151
+ createWidget: (options: TreeViewWidgetOptions) => {
149
152
  const props = {
150
153
  contextMenuPath: VIEW_ITEM_CONTEXT_MENU,
151
154
  expandOnlyOnExpansionToggleClick: true,
152
155
  expansionTogglePadding: 22,
153
156
  globalSelection: true,
154
157
  leftPadding: 8,
155
- search: true
158
+ search: true,
159
+ multiSelect: options.multiSelect
156
160
  };
157
161
  const child = createTreeContainer(container, {
158
162
  props,
@@ -161,7 +165,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
161
165
  widget: TreeViewWidget,
162
166
  decoratorService: TreeViewDecoratorService
163
167
  });
164
- child.bind(TreeViewWidgetIdentifier).toConstantValue(identifier);
168
+ child.bind(TreeViewWidgetOptions).toConstantValue(options);
165
169
  return child.get(TreeWidget);
166
170
  }
167
171
  })).inSingletonScope();
@@ -240,4 +244,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
240
244
 
241
245
  bind(PluginAuthenticationServiceImpl).toSelf().inSingletonScope();
242
246
  rebind(AuthenticationService).toService(PluginAuthenticationServiceImpl);
247
+
248
+ bind(PluginTerminalRegistry).toSelf().inSingletonScope();
243
249
  });
@@ -0,0 +1,27 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2022 STMicroelectronics and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { injectable } from '@theia/core/shared/inversify';
18
+
19
+ @injectable()
20
+ export class PluginTerminalRegistry {
21
+
22
+ startCallback: (id: string) => Promise<string>;
23
+
24
+ start(profileId: string): Promise<string> {
25
+ return this.startCallback(profileId);
26
+ }
27
+ }
@@ -440,4 +440,14 @@ export class ScmMainImpl implements ScmMain {
440
440
 
441
441
  repository.input.visible = visible;
442
442
  }
443
+
444
+ $setInputBoxEnabled(sourceControlHandle: number, enabled: boolean): void {
445
+ const repository = this.repositories.get(sourceControlHandle);
446
+
447
+ if (!repository) {
448
+ return;
449
+ }
450
+
451
+ repository.input.enabled = enabled;
452
+ }
443
453
  }
@@ -16,9 +16,8 @@
16
16
 
17
17
  import { interfaces } from '@theia/core/shared/inversify';
18
18
  import { ApplicationShell, WidgetOpenerOptions } from '@theia/core/lib/browser';
19
- import { TerminalOptions } from '@theia/plugin';
20
- import { CancellationToken } from '@theia/core/shared/vscode-languageserver-protocol';
21
- import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
19
+ import { TerminalEditorLocationOptions, TerminalOptions } from '@theia/plugin';
20
+ import { TerminalLocation, TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
22
21
  import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service';
23
22
  import { TerminalServiceMain, TerminalServiceExt, MAIN_RPC_CONTEXT } from '../../common/plugin-api-rpc';
24
23
  import { RPCProtocol } from '../../common/rpc-protocol';
@@ -27,6 +26,10 @@ import { SerializableEnvironmentVariableCollection } from '@theia/terminal/lib/c
27
26
  import { ShellTerminalServerProxy } from '@theia/terminal/lib/common/shell-terminal-protocol';
28
27
  import { TerminalLink, TerminalLinkProvider } from '@theia/terminal/lib/browser/terminal-link-provider';
29
28
  import { URI } from '@theia/core/lib/common/uri';
29
+ import { getIconClass } from '../../plugin/terminal-ext';
30
+ import { PluginTerminalRegistry } from './plugin-terminal-registry';
31
+ import { CancellationToken } from '@theia/core';
32
+ import { HostedPluginSupport } from '../../hosted/browser/hosted-plugin';
30
33
 
31
34
  /**
32
35
  * Plugin api service allows working with terminal emulator.
@@ -34,6 +37,8 @@ import { URI } from '@theia/core/lib/common/uri';
34
37
  export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLinkProvider, Disposable {
35
38
 
36
39
  private readonly terminals: TerminalService;
40
+ private readonly pluginTerminalRegistry: PluginTerminalRegistry;
41
+ private readonly hostedPluginSupport: HostedPluginSupport;
37
42
  private readonly shell: ApplicationShell;
38
43
  private readonly extProxy: TerminalServiceExt;
39
44
  private readonly shellTerminalServer: ShellTerminalServerProxy;
@@ -43,6 +48,8 @@ export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLin
43
48
 
44
49
  constructor(rpc: RPCProtocol, container: interfaces.Container) {
45
50
  this.terminals = container.get(TerminalService);
51
+ this.pluginTerminalRegistry = container.get(PluginTerminalRegistry);
52
+ this.hostedPluginSupport = container.get(HostedPluginSupport);
46
53
  this.shell = container.get(ApplicationShell);
47
54
  this.shellTerminalServer = container.get(ShellTerminalServerProxy);
48
55
  this.extProxy = rpc.getProxy(MAIN_RPC_CONTEXT.TERMINAL_EXT);
@@ -58,9 +65,16 @@ export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLin
58
65
  this.extProxy.$initEnvironmentVariableCollections(serializedCollections);
59
66
  }
60
67
 
68
+ this.pluginTerminalRegistry.startCallback = id => this.startProfile(id);
69
+
61
70
  container.bind(TerminalLinkProvider).toDynamicValue(() => this);
62
71
  }
63
72
 
73
+ async startProfile(id: string): Promise<string> {
74
+ await this.hostedPluginSupport.activateByTerminalProfile(id);
75
+ return this.extProxy.$startProfile(id, CancellationToken.None);
76
+ }
77
+
64
78
  $setEnvironmentVariableCollection(extensionIdentifier: string, persistent: boolean, collection: SerializableEnvironmentVariableCollection | undefined): void {
65
79
  if (collection) {
66
80
  this.shellTerminalServer.setCollection(extensionIdentifier, persistent, collection);
@@ -122,30 +136,46 @@ export class TerminalServiceMainImpl implements TerminalServiceMain, TerminalLin
122
136
  terminal.resize(cols, rows);
123
137
  }
124
138
 
125
- async $createTerminal(id: string, options: TerminalOptions, isPseudoTerminal?: boolean): Promise<string> {
126
- try {
127
- const terminal = await this.terminals.newTerminal({
128
- id,
129
- title: options.name,
130
- shellPath: options.shellPath,
131
- shellArgs: options.shellArgs,
132
- cwd: options.cwd ? new URI(options.cwd) : undefined,
133
- env: options.env,
134
- strictEnv: options.strictEnv,
135
- destroyTermOnClose: true,
136
- useServerTitle: false,
137
- attributes: options.attributes,
138
- hideFromUser: options.hideFromUser,
139
- isPseudoTerminal
140
- });
141
- if (options.message) {
142
- terminal.writeLine(options.message);
139
+ async $createTerminal(id: string, options: TerminalOptions, parentId?: string, isPseudoTerminal?: boolean): Promise<string> {
140
+ const terminal = await this.terminals.newTerminal({
141
+ id,
142
+ title: options.name,
143
+ iconClass: getIconClass(options),
144
+ shellPath: options.shellPath,
145
+ shellArgs: options.shellArgs,
146
+ cwd: options.cwd ? new URI(options.cwd) : undefined,
147
+ env: options.env,
148
+ strictEnv: options.strictEnv,
149
+ destroyTermOnClose: true,
150
+ useServerTitle: false,
151
+ attributes: options.attributes,
152
+ hideFromUser: options.hideFromUser,
153
+ location: this.getTerminalLocation(options, parentId),
154
+ isPseudoTerminal,
155
+ isTransient: options.isTransient
156
+ });
157
+ if (options.message) {
158
+ terminal.writeLine(options.message);
159
+ }
160
+ terminal.start();
161
+ return terminal.id;
162
+ }
163
+
164
+ protected getTerminalLocation(options: TerminalOptions, parentId?: string): TerminalLocation | TerminalEditorLocationOptions | { parentTerminal: string; } | undefined {
165
+ if (typeof options.location === 'number' && Object.values(TerminalLocation).includes(options.location)) {
166
+ return options.location;
167
+ } else if (options.location && typeof options.location === 'object') {
168
+ if ('parentTerminal' in options.location) {
169
+ if (!parentId) {
170
+ throw new Error('parentTerminal is set but no parentId is provided');
171
+ }
172
+ return { 'parentTerminal': parentId };
173
+ } else {
174
+ return options.location;
143
175
  }
144
- terminal.start();
145
- return terminal.id;
146
- } catch (error) {
147
- throw new Error('Failed to create terminal. Cause: ' + error);
148
176
  }
177
+
178
+ return undefined;
149
179
  }
150
180
 
151
181
  $sendText(id: string, text: string, addNewLine?: boolean): void {
@@ -0,0 +1,42 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2022 STMicroelectronics and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { injectable } from '@theia/core/shared/inversify';
18
+
19
+ @injectable()
20
+ export class DnDFileContentStore {
21
+ private static id: number = 0;
22
+ private files: Map<string, File> = new Map();
23
+
24
+ addFile(f: File): string {
25
+ const id = (DnDFileContentStore.id++).toString();
26
+ this.files.set(id, f);
27
+ return id;
28
+ }
29
+
30
+ removeFile(id: string): boolean {
31
+ return this.files.delete(id);
32
+ }
33
+
34
+ getFile(id: string): File {
35
+ const file = this.files.get(id);
36
+ if (file) {
37
+ return file;
38
+ }
39
+
40
+ throw new Error(`File with id ${id} not found in dnd operation`);
41
+ }
42
+ }
@@ -148,7 +148,10 @@ export class PluginViewRegistry implements FrontendApplicationContribution {
148
148
  const disposable = new DisposableCollection();
149
149
  disposable.push(this.registerViewWelcome({
150
150
  view: 'explorer',
151
- content: nls.localizeByDefault('You have not yet opened a folder.\n[Open Folder](command:{0})', 'workbench.action.files.openFolder'),
151
+ content: nls.localizeByDefault(
152
+ 'You have not yet opened a folder.\n{0}',
153
+ `[${nls.localizeByDefault('Open Folder')}](command:workbench.action.files.openFolder)`
154
+ ),
152
155
  order: 0
153
156
  }));
154
157
  disposable.push(event.widget.onDidDispose(() => disposable.dispose()));
@@ -16,9 +16,9 @@
16
16
 
17
17
  import { inject, injectable, interfaces, named } from '@theia/core/shared/inversify';
18
18
  import { AbstractTreeDecoratorService, TreeDecorator } from '@theia/core/lib/browser/tree/tree-decorator';
19
- import { bindContributionProvider, ContributionProvider } from '@theia/core';
19
+ import { bindContributionProvider, ContributionProvider, isObject } from '@theia/core';
20
20
  import { TreeNode } from '@theia/core/lib/browser';
21
- import { TreeItem, Uri } from '@theia/plugin';
21
+ import { TreeItem } from '@theia/plugin';
22
22
  import URI from '@theia/core/lib/common/uri';
23
23
  import { FileTreeDecoratorAdapter } from '@theia/filesystem/lib/browser';
24
24
 
@@ -32,9 +32,8 @@ export class TreeViewDecoratorAdapter extends FileTreeDecoratorAdapter {
32
32
  }
33
33
  }
34
34
 
35
- protected isTreeItem(node: unknown): node is TreeItem & { resourceUri: Uri } {
36
- const candidate = node as TreeItem;
37
- return !!candidate && typeof node === 'object' && 'resourceUri' in candidate && !!candidate.resourceUri;
35
+ protected isTreeItem(node: unknown): node is TreeItem {
36
+ return isObject<TreeItem>(node) && !!node.resourceUri;
38
37
  }
39
38
  }
40
39