@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
@@ -18,18 +18,20 @@
18
18
 
19
19
  import {
20
20
  TreeDataProvider, TreeView, TreeViewExpansionEvent, TreeItem, TreeItemLabel,
21
- TreeViewSelectionChangeEvent, TreeViewVisibilityChangeEvent, CancellationToken
21
+ TreeViewSelectionChangeEvent, TreeViewVisibilityChangeEvent, CancellationToken, DataTransferFile, TreeViewOptions
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
- import { TreeViewSelection } from '../../common';
31
+ import { TreeViewItemReference } 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
 
@@ -39,17 +41,30 @@ export class TreeViewsExtImpl implements TreeViewsExt {
39
41
 
40
42
  constructor(rpc: RPCProtocol, readonly commandRegistry: CommandRegistryImpl) {
41
43
  this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.TREE_VIEWS_MAIN);
44
+
42
45
  commandRegistry.registerArgumentProcessor({
43
46
  processArgument: arg => {
44
- if (!TreeViewSelection.is(arg)) {
47
+ if (TreeViewItemReference.is(arg)) {
48
+ return this.toTreeItem(arg);
49
+ } else if (Array.isArray(arg)) {
50
+ return arg.map(param => TreeViewItemReference.is(param) ? this.toTreeItem(param) : param);
51
+ } else {
45
52
  return arg;
46
53
  }
47
- const { treeViewId, treeItemId } = arg;
48
- const treeView = this.treeViews.get(treeViewId);
49
- return treeView && treeView.getTreeItem(treeItemId);
50
54
  }
51
55
  });
52
56
  }
57
+ $dragStarted(treeViewId: string, treeItemIds: string[], token: CancellationToken): Promise<UriComponents[] | undefined> {
58
+ return this.getTreeView(treeViewId).onDragStarted(treeItemIds, token);
59
+ }
60
+
61
+ $drop(treeViewId: string, treeItemId: string | undefined, dataTransferItems: [string, string | DataTransferFileDTO][], token: CancellationToken): Promise<void> {
62
+ return this.getTreeView(treeViewId).handleDrop!(treeItemId, dataTransferItems, token);
63
+ }
64
+
65
+ protected toTreeItem(treeViewItemRef: TreeViewItemReference): any {
66
+ return this.treeViews.get(treeViewItemRef.viewId)?.getTreeItem(treeViewItemRef.itemId);
67
+ }
53
68
 
54
69
  registerTreeDataProvider<T>(plugin: Plugin, treeViewId: string, treeDataProvider: TreeDataProvider<T>): PluginDisposable {
55
70
  const treeView = this.createTreeView(plugin, treeViewId, { treeDataProvider });
@@ -60,12 +75,12 @@ export class TreeViewsExtImpl implements TreeViewsExt {
60
75
  });
61
76
  }
62
77
 
63
- createTreeView<T>(plugin: Plugin, treeViewId: string, options: { treeDataProvider: TreeDataProvider<T> }): TreeView<T> {
78
+ createTreeView<T>(plugin: Plugin, treeViewId: string, options: TreeViewOptions<T>): TreeView<T> {
64
79
  if (!options || !options.treeDataProvider) {
65
80
  throw new Error('Options with treeDataProvider is mandatory');
66
81
  }
67
82
 
68
- const treeView = new TreeViewExtImpl(plugin, treeViewId, options.treeDataProvider, this.proxy, this.commandRegistry.converter);
83
+ const treeView = new TreeViewExtImpl<T>(plugin, treeViewId, options, this.proxy, this.commandRegistry.converter);
69
84
  this.treeViews.set(treeViewId, treeView);
70
85
 
71
86
  return {
@@ -187,6 +202,8 @@ class TreeViewExtImpl<T> implements Disposable {
187
202
  private readonly nodes = new Map<string, TreeExtNode<T>>();
188
203
  private pendingRefresh = Promise.resolve();
189
204
 
205
+ private localDataTransfer = new DataTransfer();
206
+
190
207
  private readonly toDispose = new DisposableCollection(
191
208
  Disposable.create(() => this.clearAll()),
192
209
  this.onDidExpandElementEmitter,
@@ -198,18 +215,18 @@ class TreeViewExtImpl<T> implements Disposable {
198
215
  constructor(
199
216
  private plugin: Plugin,
200
217
  private treeViewId: string,
201
- private treeDataProvider: TreeDataProvider<T>,
218
+ private options: TreeViewOptions<T>,
202
219
  private proxy: TreeViewsMain,
203
- readonly commandsConverter: CommandsConverter) {
204
-
205
- proxy.$registerTreeDataProvider(treeViewId);
220
+ readonly commandsConverter: CommandsConverter
221
+ ) {
222
+ // make copies of optionally provided MIME types:
223
+ const dragMimeTypes = options.dragAndDropController?.dragMimeTypes?.slice();
224
+ const dropMimeTypes = options.dragAndDropController?.dropMimeTypes?.slice();
225
+ proxy.$registerTreeDataProvider(treeViewId, { canSelectMany: options.canSelectMany, dragMimeTypes, dropMimeTypes });
206
226
  this.toDispose.push(Disposable.create(() => this.proxy.$unregisterTreeDataProvider(treeViewId)));
207
-
208
- if (treeDataProvider.onDidChangeTreeData) {
209
- treeDataProvider.onDidChangeTreeData(() => {
210
- this.pendingRefresh = proxy.$refresh(treeViewId);
211
- });
212
- }
227
+ options.treeDataProvider.onDidChangeTreeData?.(() => {
228
+ this.pendingRefresh = proxy.$refresh(treeViewId);
229
+ });
213
230
  }
214
231
 
215
232
  dispose(): void {
@@ -258,8 +275,7 @@ class TreeViewExtImpl<T> implements Disposable {
258
275
  }
259
276
 
260
277
  getTreeItem(treeItemId: string): T | undefined {
261
- const element = this.nodes.get(treeItemId);
262
- return element && element.value;
278
+ return this.nodes.get(treeItemId)?.value;
263
279
  }
264
280
 
265
281
  /**
@@ -276,15 +292,14 @@ class TreeViewExtImpl<T> implements Disposable {
276
292
  // root
277
293
  return [];
278
294
  }
279
- const result = this.treeDataProvider.getParent && await this.treeDataProvider.getParent(element);
280
- const parent = result ? result : undefined;
295
+ const parent = await this.options.treeDataProvider.getParent?.(element) ?? undefined;
281
296
  const chain = await this.calculateRevealParentChain(parent);
282
297
  if (!chain) {
283
298
  // parents are inconsistent
284
299
  return undefined;
285
300
  }
286
301
  const parentId = chain.length ? chain[chain.length - 1] : '';
287
- const treeItem = await this.treeDataProvider.getTreeItem(element);
302
+ const treeItem = await this.options.treeDataProvider.getTreeItem(element);
288
303
  if (treeItem.id) {
289
304
  return chain.concat(treeItem.id);
290
305
  }
@@ -294,7 +309,8 @@ class TreeViewExtImpl<T> implements Disposable {
294
309
  // If not in cache, getChildren fills this.nodes and generate ids for them which are needed later
295
310
  const children = cachedParentNode?.children || await this.getChildren(parentId);
296
311
  if (!children) {
297
- return undefined; // parent is inconsistent
312
+ // parent is inconsistent
313
+ return undefined;
298
314
  }
299
315
  const idLabel = this.getTreeItemIdLabel(treeItem);
300
316
  let possibleIndex = children.length;
@@ -351,13 +367,13 @@ class TreeViewExtImpl<T> implements Disposable {
351
367
  this.nodes.set(parentId, { id: '', disposables: rootNodeDisposables, dispose: () => { rootNodeDisposables.dispose(); } });
352
368
  }
353
369
  // ask data provider for children for cached element
354
- const result = await this.treeDataProvider.getChildren(parent);
370
+ const result = await this.options.treeDataProvider.getChildren(parent);
355
371
  if (result) {
356
372
  const treeItemPromises = result.map(async (value, index) => {
357
373
 
358
374
  // Ask data provider for a tree item for the value
359
375
  // Data provider must return theia.TreeItem
360
- const treeItem = await this.treeDataProvider.getTreeItem(value);
376
+ const treeItem = await this.options.treeDataProvider.getTreeItem(value);
361
377
  // Convert theia.TreeItem to the TreeViewItem
362
378
 
363
379
  const label = this.getTreeItemLabel(treeItem);
@@ -474,13 +490,13 @@ class TreeViewExtImpl<T> implements Disposable {
474
490
  }
475
491
 
476
492
  async resolveTreeItem(treeItemId: string, token: CancellationToken): Promise<TreeViewItem | undefined> {
477
- if (!this.treeDataProvider.resolveTreeItem) {
493
+ if (!this.options.treeDataProvider.resolveTreeItem) {
478
494
  return undefined;
479
495
  }
480
496
 
481
497
  const node = this.nodes.get(treeItemId);
482
498
  if (node && node.treeViewItem && node.pluginTreeItem && node.value) {
483
- const resolved = await this.treeDataProvider.resolveTreeItem(node.pluginTreeItem, node.value, token) ?? node.pluginTreeItem;
499
+ const resolved = await this.options.treeDataProvider.resolveTreeItem(node.pluginTreeItem, node.value, token) ?? node.pluginTreeItem;
484
500
  node.treeViewItem.command = this.commandsConverter.toSafeCommand(resolved.command, node.disposables);
485
501
  node.treeViewItem.tooltip = resolved.tooltip;
486
502
  return node.treeViewItem;
@@ -490,7 +506,7 @@ class TreeViewExtImpl<T> implements Disposable {
490
506
  }
491
507
 
492
508
  hasResolveTreeItem(): boolean {
493
- return !!this.treeDataProvider.resolveTreeItem;
509
+ return !!this.options.treeDataProvider.resolveTreeItem;
494
510
  }
495
511
 
496
512
  private selectedItemIds = new Set<string>();
@@ -535,4 +551,55 @@ 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.options.dragAndDropController?.handleDrag) {
563
+ this.localDataTransfer.clear();
564
+ await this.options.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.options.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
+ return this.options.dragAndDropController.handleDrop(treeItem, dropTransfer, token);
603
+ }
604
+ }
538
605
  }
@@ -453,4 +453,24 @@ describe('Type converters:', () => {
453
453
  assert.deepStrictEqual(result, showOptions);
454
454
  });
455
455
  });
456
+
457
+ describe('#convertCode', () => {
458
+ it('should convert a "code" of type "string"', () => {
459
+ assert.strictEqual(Converter.convertCode('string'), 'string');
460
+ });
461
+ it('should convert a "code" of type "number"', () => {
462
+ assert.strictEqual(Converter.convertCode(4), '4');
463
+ });
464
+ it('should convert an undefined "code"', () => {
465
+ assert.strictEqual(Converter.convertCode(undefined), undefined);
466
+ });
467
+ it('should convert a "code" of type "{ value: number, target: Uri }"', () => {
468
+ const uri = types.URI.parse('foo://example.com:8042/over/there?name=ferret#nose');
469
+ assert.strictEqual(Converter.convertCode({ value: 4, target: uri }), '4');
470
+ });
471
+ it('should convert a "code" of type "{ value: number, target: Uri }"', () => {
472
+ const uri = types.URI.parse('foo://example.com:8042/over/there?name=ferret#nose');
473
+ assert.strictEqual(Converter.convertCode({ value: 'string', target: uri }), 'string');
474
+ });
475
+ });
456
476
  });
@@ -28,6 +28,7 @@ import * as types from './types-impl';
28
28
  import { UriComponents } from '../common/uri-components';
29
29
  import { isReadonlyArray } from '../common/arrays';
30
30
  import { MarkdownString as MarkdownStringDTO } from '@theia/core/lib/common/markdown-rendering';
31
+ import { isObject } from '@theia/core/lib/common';
31
32
 
32
33
  const SIDE_GROUP = -2;
33
34
  const ACTIVE_GROUP = -1;
@@ -136,7 +137,7 @@ export function toPosition(position: Position): types.Position {
136
137
  }
137
138
 
138
139
  function isDecorationOptions(arg: unknown): arg is theia.DecorationOptions {
139
- return !!arg && typeof arg === 'object' && typeof (arg as theia.DecorationOptions).range !== 'undefined';
140
+ return isObject<theia.DecorationOptions>(arg) && typeof arg.range !== 'undefined';
140
141
  }
141
142
 
142
143
  export function isDecorationOptionsArr(something: theia.Range[] | theia.DecorationOptions[]): something is theia.DecorationOptions[] {
@@ -180,9 +181,9 @@ interface Codeblock {
180
181
  }
181
182
 
182
183
  function isCodeblock(arg: unknown): arg is Codeblock {
183
- return !!arg && typeof arg === 'object'
184
- && typeof (arg as Codeblock).language === 'string'
185
- && typeof (arg as Codeblock).value === 'string';
184
+ return isObject<Codeblock>(arg)
185
+ && typeof arg.language === 'string'
186
+ && typeof arg.value === 'string';
186
187
  }
187
188
 
188
189
  export function fromMarkdown(markup: theia.MarkdownString | theia.MarkedString): MarkdownStringDTO {
@@ -315,6 +316,14 @@ export function fromTextEdit(edit: theia.TextEdit): model.TextEdit {
315
316
  };
316
317
  }
317
318
 
319
+ function fromSnippetTextEdit(edit: theia.SnippetTextEdit): model.TextEdit & { insertAsSnippet?: boolean } {
320
+ return {
321
+ text: edit.snippet.value,
322
+ range: fromRange(edit.range),
323
+ insertAsSnippet: true
324
+ };
325
+ }
326
+
318
327
  export function convertDiagnosticToMarkerData(diagnostic: theia.Diagnostic): model.MarkerData {
319
328
  return {
320
329
  code: convertCode(diagnostic.code),
@@ -330,12 +339,15 @@ export function convertDiagnosticToMarkerData(diagnostic: theia.Diagnostic): mod
330
339
  };
331
340
  }
332
341
 
333
- function convertCode(code: string | number | undefined): string | undefined {
342
+ export function convertCode(code: string | number | { value: string | number; target: theia.Uri } | undefined): string | undefined {
334
343
  if (typeof code === 'number') {
335
344
  return String(code);
336
- } else {
337
- return code;
338
345
  }
346
+ if (typeof code === 'string' || typeof code === 'undefined') {
347
+ return code;
348
+ } else {
349
+ return String(code.value);
350
+ };
339
351
  }
340
352
 
341
353
  function convertSeverity(severity: types.DiagnosticSeverity): types.MarkerSeverity {
@@ -566,7 +578,7 @@ export function fromWorkspaceEdit(value: theia.WorkspaceEdit, documents?: any):
566
578
  const workspaceTextEditDto: WorkspaceTextEditDto = {
567
579
  resource: uri,
568
580
  modelVersionId: doc?.version,
569
- textEdit: uriOrEdits.map(fromTextEdit)[0],
581
+ textEdit: uriOrEdits.map(edit => (edit instanceof types.TextEdit) ? fromTextEdit(edit) : fromSnippetTextEdit(edit))[0],
570
582
  metadata: entry[2] as types.WorkspaceEditMetadata
571
583
  };
572
584
  result.edits.push(workspaceTextEditDto);
@@ -677,57 +689,47 @@ export function toSymbolTag(kind: model.SymbolTag): types.SymbolTag {
677
689
  }
678
690
 
679
691
  export function isModelLocation(arg: unknown): arg is model.Location {
680
- if (!arg) {
681
- return false;
682
- }
683
- return !!arg &&
684
- typeof arg === 'object' &&
685
- isModelRange((arg as model.Location).range) &&
686
- isUriComponents((arg as model.Location).uri);
692
+ return isObject<model.Location>(arg) &&
693
+ isModelRange(arg.range) &&
694
+ isUriComponents(arg.uri);
687
695
  }
688
696
 
689
697
  export function isModelRange(arg: unknown): arg is model.Range {
690
- const range = arg as model.Range;
691
- return !!arg && typeof arg === 'object' &&
692
- typeof range.startLineNumber === 'number' &&
693
- typeof range.startColumn === 'number' &&
694
- typeof range.endLineNumber === 'number' &&
695
- typeof range.endColumn === 'number';
698
+ return isObject<model.Range>(arg) &&
699
+ typeof arg.startLineNumber === 'number' &&
700
+ typeof arg.startColumn === 'number' &&
701
+ typeof arg.endLineNumber === 'number' &&
702
+ typeof arg.endColumn === 'number';
696
703
  }
697
704
 
698
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
699
705
  export function isUriComponents(arg: unknown): arg is UriComponents {
700
- const uriComponents = arg as UriComponents;
701
- return !!arg && typeof arg === 'object' &&
702
- typeof uriComponents.scheme === 'string' &&
703
- typeof uriComponents.path === 'string' &&
704
- typeof uriComponents.query === 'string' &&
705
- typeof uriComponents.fragment === 'string';
706
+ return isObject<UriComponents>(arg) &&
707
+ typeof arg.scheme === 'string' &&
708
+ typeof arg.path === 'string' &&
709
+ typeof arg.query === 'string' &&
710
+ typeof arg.fragment === 'string';
706
711
  }
707
712
 
708
713
  export function isModelCallHierarchyItem(arg: unknown): arg is model.CallHierarchyItem {
709
- const item = arg as model.CallHierarchyItem;
710
- return !!item && typeof item === 'object'
711
- && isModelRange(item.range)
712
- && isModelRange(item.selectionRange)
713
- && isUriComponents(item.uri)
714
- && !!item.name;
714
+ return isObject<model.CallHierarchyItem>(arg)
715
+ && isModelRange(arg.range)
716
+ && isModelRange(arg.selectionRange)
717
+ && isUriComponents(arg.uri)
718
+ && !!arg.name;
715
719
  }
716
720
 
717
721
  export function isModelCallHierarchyIncomingCall(arg: unknown): arg is model.CallHierarchyIncomingCall {
718
- const maybeIncomingCall = arg as model.CallHierarchyIncomingCall;
719
- return !!arg && typeof arg === 'object' &&
720
- 'from' in maybeIncomingCall &&
721
- 'fromRanges' in maybeIncomingCall &&
722
- isModelCallHierarchyItem(maybeIncomingCall.from);
722
+ return isObject<model.CallHierarchyIncomingCall>(arg) &&
723
+ 'from' in arg &&
724
+ 'fromRanges' in arg &&
725
+ isModelCallHierarchyItem(arg.from);
723
726
  }
724
727
 
725
728
  export function isModelCallHierarchyOutgoingCall(arg: unknown): arg is model.CallHierarchyOutgoingCall {
726
- const maybeOutgoingCall = arg as model.CallHierarchyOutgoingCall;
727
- return !!arg && typeof arg === 'object' &&
728
- 'to' in maybeOutgoingCall &&
729
- 'fromRanges' in maybeOutgoingCall &&
730
- isModelCallHierarchyItem(maybeOutgoingCall.to);
729
+ return isObject<model.CallHierarchyOutgoingCall>(arg) &&
730
+ 'to' in arg &&
731
+ 'fromRanges' in arg &&
732
+ isModelCallHierarchyItem(arg.to);
731
733
  }
732
734
 
733
735
  export function toLocation(value: model.Location): types.Location {
@@ -781,12 +783,11 @@ export function toCallHierarchyOutgoingCall(value: model.CallHierarchyOutgoingCa
781
783
  }
782
784
 
783
785
  export function isModelTypeHierarchyItem(arg: unknown): arg is model.TypeHierarchyItem {
784
- const item = arg as model.TypeHierarchyItem;
785
- return !!item && typeof item === 'object'
786
- && isModelRange(item.range)
787
- && isModelRange(item.selectionRange)
788
- && isUriComponents(item.uri)
789
- && !!item.name;
786
+ return isObject<model.TypeHierarchyItem>(arg)
787
+ && isModelRange(arg.range)
788
+ && isModelRange(arg.selectionRange)
789
+ && isUriComponents(arg.uri)
790
+ && !!arg.name;
790
791
  }
791
792
 
792
793
  export function fromTypeHierarchyItem(item: types.TypeHierarchyItem): model.TypeHierarchyItem {