@theia/plugin-ext 1.34.0-next.34 → 1.34.0-next.39

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 (77) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +12 -1
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js +12 -1
  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/hosted/browser/hosted-plugin.d.ts +1 -0
  9. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  10. package/lib/hosted/browser/hosted-plugin.js +3 -0
  11. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  12. package/lib/hosted/node/scanners/scanner-theia.d.ts +2 -1
  13. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  14. package/lib/hosted/node/scanners/scanner-theia.js +13 -0
  15. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  16. package/lib/main/browser/plugin-contribution-handler.d.ts +6 -0
  17. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  18. package/lib/main/browser/plugin-contribution-handler.js +35 -0
  19. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  20. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  21. package/lib/main/browser/plugin-ext-frontend-module.js +5 -1
  22. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  23. package/lib/main/browser/plugin-terminal-registry.d.ts +5 -0
  24. package/lib/main/browser/plugin-terminal-registry.d.ts.map +1 -0
  25. package/lib/main/browser/plugin-terminal-registry.js +35 -0
  26. package/lib/main/browser/plugin-terminal-registry.js.map +1 -0
  27. package/lib/main/browser/terminal-main.d.ts +4 -1
  28. package/lib/main/browser/terminal-main.d.ts.map +1 -1
  29. package/lib/main/browser/terminal-main.js +32 -28
  30. package/lib/main/browser/terminal-main.js.map +1 -1
  31. package/lib/main/browser/view/dnd-file-content-store.d.ts +8 -0
  32. package/lib/main/browser/view/dnd-file-content-store.d.ts.map +1 -0
  33. package/lib/main/browser/view/dnd-file-content-store.js +52 -0
  34. package/lib/main/browser/view/dnd-file-content-store.js.map +1 -0
  35. package/lib/main/browser/view/tree-view-widget.d.ts +19 -4
  36. package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
  37. package/lib/main/browser/view/tree-view-widget.js +165 -23
  38. package/lib/main/browser/view/tree-view-widget.js.map +1 -1
  39. package/lib/main/browser/view/tree-views-main.d.ts +4 -1
  40. package/lib/main/browser/view/tree-views-main.d.ts.map +1 -1
  41. package/lib/main/browser/view/tree-views-main.js +15 -2
  42. package/lib/main/browser/view/tree-views-main.js.map +1 -1
  43. package/lib/plugin/plugin-context.d.ts.map +1 -1
  44. package/lib/plugin/plugin-context.js +6 -0
  45. package/lib/plugin/plugin-context.js.map +1 -1
  46. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  47. package/lib/plugin/plugin-manager.js +1 -0
  48. package/lib/plugin/plugin-manager.js.map +1 -1
  49. package/lib/plugin/terminal-ext.d.ts +5 -1
  50. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  51. package/lib/plugin/terminal-ext.js +32 -3
  52. package/lib/plugin/terminal-ext.js.map +1 -1
  53. package/lib/plugin/tree/tree-views.d.ts +11 -3
  54. package/lib/plugin/tree/tree-views.d.ts.map +1 -1
  55. package/lib/plugin/tree/tree-views.js +64 -3
  56. package/lib/plugin/tree/tree-views.js.map +1 -1
  57. package/lib/plugin/types-impl.d.ts +30 -0
  58. package/lib/plugin/types-impl.d.ts.map +1 -1
  59. package/lib/plugin/types-impl.js +63 -3
  60. package/lib/plugin/types-impl.js.map +1 -1
  61. package/package.json +25 -25
  62. package/src/common/plugin-api-rpc.ts +12 -1
  63. package/src/common/plugin-protocol.ts +18 -0
  64. package/src/hosted/browser/hosted-plugin.ts +4 -0
  65. package/src/hosted/node/scanners/scanner-theia.ts +15 -1
  66. package/src/main/browser/plugin-contribution-handler.ts +35 -0
  67. package/src/main/browser/plugin-ext-frontend-module.ts +8 -3
  68. package/src/main/browser/plugin-terminal-registry.ts +27 -0
  69. package/src/main/browser/terminal-main.ts +35 -26
  70. package/src/main/browser/view/dnd-file-content-store.ts +42 -0
  71. package/src/main/browser/view/tree-view-widget.tsx +170 -20
  72. package/src/main/browser/view/tree-views-main.ts +19 -3
  73. package/src/plugin/plugin-context.ts +10 -1
  74. package/src/plugin/plugin-manager.ts +1 -0
  75. package/src/plugin/terminal-ext.ts +35 -5
  76. package/src/plugin/tree/tree-views.ts +74 -6
  77. package/src/plugin/types-impl.ts +57 -0
@@ -52,9 +52,9 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
52
52
 
53
53
  private readonly _pseudoTerminals = new Map<string, PseudoTerminal>();
54
54
 
55
- private static nextTerminalLinkProviderId = 0;
55
+ private static nextProviderId = 0;
56
56
  private readonly terminalLinkProviders = new Map<string, theia.TerminalLinkProvider>();
57
-
57
+ private readonly terminalProfileProviders = new Map<string, theia.TerminalProfileProvider>();
58
58
  private readonly onDidCloseTerminalEmitter = new Emitter<Terminal>();
59
59
  readonly onDidCloseTerminal: theia.Event<Terminal> = this.onDidCloseTerminalEmitter.event;
60
60
 
@@ -81,9 +81,9 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
81
81
  nameOrOptions: TerminalOptions | PseudoTerminalOptions | ExtensionTerminalOptions | (string | undefined),
82
82
  shellPath?: string, shellArgs?: string[] | string
83
83
  ): Terminal {
84
- let options: TerminalOptions | ExtensionTerminalOptions;
85
- let pseudoTerminal: theia.Pseudoterminal | undefined = undefined;
86
84
  const id = `plugin-terminal-${UUID.uuid4()}`;
85
+ let options: TerminalOptions;
86
+ let pseudoTerminal: theia.Pseudoterminal | undefined = undefined;
87
87
  if (typeof nameOrOptions === 'object') {
88
88
  if ('pty' in nameOrOptions) {
89
89
  pseudoTerminal = nameOrOptions.pty;
@@ -220,7 +220,7 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
220
220
  }
221
221
 
222
222
  registerTerminalLinkProvider(provider: theia.TerminalLinkProvider): theia.Disposable {
223
- const providerId = (TerminalServiceExtImpl.nextTerminalLinkProviderId++).toString();
223
+ const providerId = (TerminalServiceExtImpl.nextProviderId++).toString();
224
224
  this.terminalLinkProviders.set(providerId, provider);
225
225
  this.proxy.$registerTerminalLinkProvider(providerId);
226
226
  return Disposable.create(() => {
@@ -229,6 +229,36 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
229
229
  });
230
230
  }
231
231
 
232
+ registerTerminalProfileProvider(id: string, provider: theia.TerminalProfileProvider): theia.Disposable {
233
+ this.terminalProfileProviders.set(id, provider);
234
+ return Disposable.create(() => {
235
+ this.terminalProfileProviders.delete(id);
236
+ });
237
+ }
238
+
239
+ protected isExtensionTerminalOptions(options: theia.TerminalOptions | theia.ExtensionTerminalOptions): options is theia.ExtensionTerminalOptions {
240
+ return 'pty' in options;
241
+ }
242
+
243
+ async $startProfile(profileId: string, cancellationToken: theia.CancellationToken): Promise<string> {
244
+ const provider = this.terminalProfileProviders.get(profileId);
245
+ if (!provider) {
246
+ throw new Error(`No terminal profile provider with id '${profileId}'`);
247
+ }
248
+ const profile = await provider.provideTerminalProfile(cancellationToken);
249
+ if (!profile) {
250
+ throw new Error(`Profile with id ${profileId} could not be created`);
251
+ }
252
+ const id = `plugin-terminal-${UUID.uuid4()}`;
253
+ const options = profile.options;
254
+ if (this.isExtensionTerminalOptions(options)) {
255
+ this._pseudoTerminals.set(id, new PseudoTerminal(id, this.proxy, options.pty));
256
+ return this.proxy.$createTerminal(id, { name: options.name }, undefined, true);
257
+ } else {
258
+ return this.proxy.$createTerminal(id, profile.options);
259
+ }
260
+ }
261
+
232
262
  async $provideTerminalLinks(line: string, terminalId: string, token: theia.CancellationToken): Promise<ProvidedTerminalLink[]> {
233
263
  const links: ProvidedTerminalLink[] = [];
234
264
  const terminal = this._terminals.get(terminalId);
@@ -18,18 +18,20 @@
18
18
 
19
19
  import {
20
20
  TreeDataProvider, TreeView, TreeViewExpansionEvent, TreeItem, TreeItemLabel,
21
- TreeViewSelectionChangeEvent, TreeViewVisibilityChangeEvent, CancellationToken
21
+ TreeViewSelectionChangeEvent, TreeViewVisibilityChangeEvent, CancellationToken, TreeDragAndDropController, DataTransferFile
22
22
  } from '@theia/plugin';
23
23
  // TODO: extract `@theia/util` for event, disposable, cancellation and common types
24
24
  // don't use @theia/core directly from plugin host
25
25
  import { Emitter } from '@theia/core/lib/common/event';
26
26
  import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
27
- import { Disposable as PluginDisposable, ThemeIcon } from '../types-impl';
28
- import { Plugin, PLUGIN_RPC_CONTEXT, TreeViewsExt, TreeViewsMain, TreeViewItem, TreeViewRevealOptions } from '../../common/plugin-api-rpc';
27
+ import { DataTransfer, DataTransferItem, Disposable as PluginDisposable, ThemeIcon } from '../types-impl';
28
+ import { Plugin, PLUGIN_RPC_CONTEXT, TreeViewsExt, TreeViewsMain, TreeViewItem, TreeViewRevealOptions, DataTransferFileDTO } from '../../common/plugin-api-rpc';
29
29
  import { RPCProtocol } from '../../common/rpc-protocol';
30
30
  import { CommandRegistryImpl, CommandsConverter } from '../command-registry';
31
31
  import { TreeViewSelection } from '../../common';
32
32
  import { PluginIconPath } from '../plugin-icon-path';
33
+ import { URI } from '@theia/core/shared/vscode-uri';
34
+ import { UriComponents } from '@theia/core/lib/common/uri';
33
35
 
34
36
  export class TreeViewsExtImpl implements TreeViewsExt {
35
37
 
@@ -50,6 +52,13 @@ export class TreeViewsExtImpl implements TreeViewsExt {
50
52
  }
51
53
  });
52
54
  }
55
+ $dragStarted(treeViewId: string, treeItemIds: string[], token: CancellationToken): Promise<UriComponents[] | undefined> {
56
+ return this.getTreeView(treeViewId).onDragStarted(treeItemIds, token);
57
+ }
58
+
59
+ $drop(treeViewId: string, treeItemId: string | undefined, dataTransferItems: [string, string | DataTransferFileDTO][], token: CancellationToken): Promise<void> {
60
+ return this.getTreeView(treeViewId).handleDrop!(treeItemId, dataTransferItems, token);
61
+ }
53
62
 
54
63
  registerTreeDataProvider<T>(plugin: Plugin, treeViewId: string, treeDataProvider: TreeDataProvider<T>): PluginDisposable {
55
64
  const treeView = this.createTreeView(plugin, treeViewId, { treeDataProvider });
@@ -60,12 +69,12 @@ export class TreeViewsExtImpl implements TreeViewsExt {
60
69
  });
61
70
  }
62
71
 
63
- createTreeView<T>(plugin: Plugin, treeViewId: string, options: { treeDataProvider: TreeDataProvider<T> }): TreeView<T> {
72
+ createTreeView<T>(plugin: Plugin, treeViewId: string, options: { treeDataProvider: TreeDataProvider<T>, dragAndDropController?: TreeDragAndDropController<T> }): TreeView<T> {
64
73
  if (!options || !options.treeDataProvider) {
65
74
  throw new Error('Options with treeDataProvider is mandatory');
66
75
  }
67
76
 
68
- const treeView = new TreeViewExtImpl(plugin, treeViewId, options.treeDataProvider, this.proxy, this.commandRegistry.converter);
77
+ const treeView = new TreeViewExtImpl(plugin, treeViewId, options.treeDataProvider, options.dragAndDropController, this.proxy, this.commandRegistry.converter);
69
78
  this.treeViews.set(treeViewId, treeView);
70
79
 
71
80
  return {
@@ -187,6 +196,8 @@ class TreeViewExtImpl<T> implements Disposable {
187
196
  private readonly nodes = new Map<string, TreeExtNode<T>>();
188
197
  private pendingRefresh = Promise.resolve();
189
198
 
199
+ private localDataTransfer = new DataTransfer();
200
+
190
201
  private readonly toDispose = new DisposableCollection(
191
202
  Disposable.create(() => this.clearAll()),
192
203
  this.onDidExpandElementEmitter,
@@ -199,10 +210,15 @@ class TreeViewExtImpl<T> implements Disposable {
199
210
  private plugin: Plugin,
200
211
  private treeViewId: string,
201
212
  private treeDataProvider: TreeDataProvider<T>,
213
+ private dragAndDropController: TreeDragAndDropController<T> | undefined,
202
214
  private proxy: TreeViewsMain,
203
215
  readonly commandsConverter: CommandsConverter) {
204
216
 
205
- proxy.$registerTreeDataProvider(treeViewId);
217
+ const dragTypes = dragAndDropController?.dragMimeTypes ? [...dragAndDropController.dragMimeTypes] : undefined;
218
+ const dropTypes = dragAndDropController?.dropMimeTypes ? [...dragAndDropController.dropMimeTypes] : undefined;
219
+
220
+ proxy.$registerTreeDataProvider(treeViewId, dragTypes, dropTypes);
221
+
206
222
  this.toDispose.push(Disposable.create(() => this.proxy.$unregisterTreeDataProvider(treeViewId)));
207
223
 
208
224
  if (treeDataProvider.onDidChangeTreeData) {
@@ -535,4 +551,56 @@ class TreeViewExtImpl<T> implements Disposable {
535
551
  }
536
552
  }
537
553
 
554
+ async onDragStarted(treeItemIds: string[], token: CancellationToken): Promise<UriComponents[] | undefined> {
555
+ const treeItems: T[] = [];
556
+ for (const id of treeItemIds) {
557
+ const item = this.getTreeItem(id);
558
+ if (item) {
559
+ treeItems.push(item);
560
+ }
561
+ }
562
+ if (this.dragAndDropController && this.dragAndDropController.handleDrag) {
563
+ this.localDataTransfer.clear();
564
+ await this.dragAndDropController.handleDrag(treeItems, this.localDataTransfer, token);
565
+ const uriList = await this.localDataTransfer.get('text/uri-list')?.asString();
566
+ if (uriList) {
567
+ return uriList.split('\n').map(str => URI.parse(str));
568
+ }
569
+ }
570
+ return undefined;
571
+ }
572
+
573
+ async handleDrop(treeItemId: string | undefined, dataTransferItems: [string, string | DataTransferFileDTO][], token: CancellationToken): Promise<void> {
574
+ const treeItem = treeItemId ? this.getTreeItem(treeItemId) : undefined;
575
+ const dropTransfer = new DataTransfer();
576
+ if (this.dragAndDropController && this.dragAndDropController.handleDrop) {
577
+ this.localDataTransfer.forEach((item, type) => {
578
+ dropTransfer.set(type, item);
579
+ });
580
+ for (const [type, item] of dataTransferItems) {
581
+ // prefer the item the plugin has set in `onDragStarted`;
582
+ if (!dropTransfer.has(type)) {
583
+ if (typeof item === 'string') {
584
+ dropTransfer.set(type, new DataTransferItem(item));
585
+ } else {
586
+ const file: DataTransferFile = {
587
+ name: item.name,
588
+ data: () => this.proxy.$readDroppedFile(item.contentId).then(buffer => buffer.buffer),
589
+ uri: item.uri ? URI.revive(item.uri) : undefined
590
+ };
591
+
592
+ const fileItem = new class extends DataTransferItem {
593
+ override asFile(): DataTransferFile | undefined {
594
+ return file;
595
+ }
596
+ }(file);
597
+
598
+ dropTransfer.set(type, fileItem);
599
+ }
600
+ }
601
+ }
602
+
603
+ return Promise.resolve(this.dragAndDropController.handleDrop(treeItem, dropTransfer, token));
604
+ }
605
+ }
538
606
  }
@@ -1814,6 +1814,55 @@ export class WorkspaceEdit implements theia.WorkspaceEdit {
1814
1814
  }
1815
1815
  }
1816
1816
 
1817
+ export class DataTransferItem {
1818
+ asString(): Thenable<string> {
1819
+ return Promise.resolve(typeof this.value === 'string' ? this.value : JSON.stringify(this.value));
1820
+ }
1821
+
1822
+ asFile(): theia.DataTransferFile | undefined {
1823
+ return undefined;
1824
+ }
1825
+
1826
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1827
+ constructor(readonly value: any) {
1828
+ }
1829
+ }
1830
+
1831
+ /**
1832
+ * A map containing a mapping of the mime type of the corresponding transferred data.
1833
+ *
1834
+ * Drag and drop controllers that implement {@link TreeDragAndDropController.handleDrag `handleDrag`} can add additional mime types to the
1835
+ * data transfer. These additional mime types will only be included in the `handleDrop` when the the drag was initiated from
1836
+ * an element in the same drag and drop controller.
1837
+ */
1838
+ @es5ClassCompat
1839
+ export class DataTransfer implements Iterable<[mimeType: string, item: DataTransferItem]> {
1840
+ private items = new Map<string, DataTransferItem>();
1841
+ get(mimeType: string): DataTransferItem | undefined {
1842
+ return this.items.get(mimeType);
1843
+ }
1844
+ set(mimeType: string, value: DataTransferItem): void {
1845
+ this.items.set(mimeType, value);
1846
+ }
1847
+
1848
+ has(mimeType: string): boolean {
1849
+ return this.items.has(mimeType);
1850
+ }
1851
+
1852
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1853
+ forEach(callbackfn: (item: DataTransferItem, mimeType: string, dataTransfer: DataTransfer) => void, thisArg?: any): void {
1854
+ this.items.forEach((item, mimetype) => {
1855
+ callbackfn.call(thisArg, item, mimetype, this);
1856
+ });
1857
+ }
1858
+ [Symbol.iterator](): IterableIterator<[mimeType: string, item: DataTransferItem]> {
1859
+ return this.items[Symbol.iterator]();
1860
+ }
1861
+
1862
+ clear(): void {
1863
+ this.items.clear();
1864
+ }
1865
+ }
1817
1866
  @es5ClassCompat
1818
1867
  export class TreeItem {
1819
1868
 
@@ -1974,6 +2023,14 @@ export enum TerminalLocation {
1974
2023
  Panel = 1,
1975
2024
  Editor = 2
1976
2025
  }
2026
+ export class TerminalProfile {
2027
+ /**
2028
+ * Creates a new terminal profile.
2029
+ * @param options The options that the terminal will launch with.
2030
+ */
2031
+ constructor(readonly options: theia.TerminalOptions | theia.ExtensionTerminalOptions) {
2032
+ }
2033
+ }
1977
2034
 
1978
2035
  @es5ClassCompat
1979
2036
  export class FileDecoration {