@theia/plugin-ext 1.32.0-next.5 → 1.32.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 (85) hide show
  1. package/lib/common/plugin-api-rpc-model.d.ts +3 -3
  2. package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.d.ts +7 -3
  4. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  5. package/lib/common/plugin-api-rpc.js +3 -3
  6. package/lib/common/plugin-api-rpc.js.map +1 -1
  7. package/lib/hosted/node/hosted-plugin-localization-service.d.ts +2 -2
  8. package/lib/hosted/node/hosted-plugin-localization-service.d.ts.map +1 -1
  9. package/lib/hosted/node/hosted-plugin-localization-service.js +4 -4
  10. package/lib/hosted/node/hosted-plugin-localization-service.js.map +1 -1
  11. package/lib/main/browser/authentication-main.js +2 -2
  12. package/lib/main/browser/authentication-main.js.map +1 -1
  13. package/lib/main/browser/languages-main.d.ts +5 -2
  14. package/lib/main/browser/languages-main.d.ts.map +1 -1
  15. package/lib/main/browser/languages-main.js +20 -11
  16. package/lib/main/browser/languages-main.js.map +1 -1
  17. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
  18. package/lib/main/browser/menus/plugin-menu-command-adapter.js +3 -1
  19. package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
  20. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  21. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  22. package/lib/main/browser/tasks-main.d.ts.map +1 -1
  23. package/lib/main/browser/tasks-main.js +2 -2
  24. package/lib/main/browser/tasks-main.js.map +1 -1
  25. package/lib/main/browser/text-editor-main.d.ts.map +1 -1
  26. package/lib/main/browser/text-editor-main.js +3 -2
  27. package/lib/main/browser/text-editor-main.js.map +1 -1
  28. package/lib/main/browser/theme-icon-override.js +31 -0
  29. package/lib/main/browser/theme-icon-override.js.map +1 -1
  30. package/lib/main/browser/view/plugin-tree-view-node-label-provider.js +1 -1
  31. package/lib/main/browser/view/plugin-tree-view-node-label-provider.js.map +1 -1
  32. package/lib/main/browser/view/tree-view-widget.d.ts +3 -5
  33. package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
  34. package/lib/main/browser/view/tree-view-widget.js +59 -35
  35. package/lib/main/browser/view/tree-view-widget.js.map +1 -1
  36. package/lib/main/browser/view/tree-views-main.d.ts.map +1 -1
  37. package/lib/main/browser/view/tree-views-main.js +0 -7
  38. package/lib/main/browser/view/tree-views-main.js.map +1 -1
  39. package/lib/plugin/languages.d.ts.map +1 -1
  40. package/lib/plugin/languages.js.map +1 -1
  41. package/lib/plugin/plugin-context.d.ts +2 -5
  42. package/lib/plugin/plugin-context.d.ts.map +1 -1
  43. package/lib/plugin/plugin-context.js +26 -8
  44. package/lib/plugin/plugin-context.js.map +1 -1
  45. package/lib/plugin/preference-registry.d.ts.map +1 -1
  46. package/lib/plugin/preference-registry.js +3 -3
  47. package/lib/plugin/preference-registry.js.map +1 -1
  48. package/lib/plugin/quick-open.d.ts.map +1 -1
  49. package/lib/plugin/quick-open.js +15 -10
  50. package/lib/plugin/quick-open.js.map +1 -1
  51. package/lib/plugin/terminal-ext.d.ts +1 -1
  52. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  53. package/lib/plugin/terminal-ext.js.map +1 -1
  54. package/lib/plugin/type-converters.d.ts.map +1 -1
  55. package/lib/plugin/type-converters.js +17 -3
  56. package/lib/plugin/type-converters.js.map +1 -1
  57. package/lib/plugin/type-converters.spec.js +17 -2
  58. package/lib/plugin/type-converters.spec.js.map +1 -1
  59. package/lib/plugin/types-impl.d.ts +7 -0
  60. package/lib/plugin/types-impl.d.ts.map +1 -1
  61. package/lib/plugin/types-impl.js +17 -3
  62. package/lib/plugin/types-impl.js.map +1 -1
  63. package/package.json +28 -28
  64. package/src/common/plugin-api-rpc-model.ts +3 -3
  65. package/src/common/plugin-api-rpc.ts +11 -6
  66. package/src/hosted/node/hosted-plugin-localization-service.ts +5 -5
  67. package/src/main/browser/authentication-main.ts +2 -2
  68. package/src/main/browser/languages-main.ts +46 -28
  69. package/src/main/browser/menus/plugin-menu-command-adapter.ts +3 -1
  70. package/src/main/browser/plugin-contribution-handler.ts +2 -1
  71. package/src/main/browser/style/index.css +11 -6
  72. package/src/main/browser/tasks-main.ts +2 -1
  73. package/src/main/browser/text-editor-main.ts +3 -2
  74. package/src/main/browser/theme-icon-override.ts +31 -0
  75. package/src/main/browser/view/plugin-tree-view-node-label-provider.ts +1 -1
  76. package/src/main/browser/view/tree-view-widget.tsx +63 -42
  77. package/src/main/browser/view/tree-views-main.ts +0 -7
  78. package/src/plugin/languages.ts +2 -1
  79. package/src/plugin/plugin-context.ts +32 -13
  80. package/src/plugin/preference-registry.ts +11 -3
  81. package/src/plugin/quick-open.ts +15 -9
  82. package/src/plugin/terminal-ext.ts +4 -1
  83. package/src/plugin/type-converters.spec.ts +17 -2
  84. package/src/plugin/type-converters.ts +18 -3
  85. package/src/plugin/types-impl.ts +17 -0
@@ -247,9 +247,11 @@ export class PluginMenuCommandAdapter implements MenuCommandAdapter {
247
247
 
248
248
  protected getSelectedResources(): [CodeUri | TreeViewSelection | undefined, CodeUri[] | undefined] {
249
249
  const selection = this.selectionService.selection;
250
+ const resourceKey = this.resourceContextKey.get();
251
+ const resourceUri = resourceKey ? CodeUri.parse(resourceKey) : undefined;
250
252
  const firstMember = TreeWidgetSelection.is(selection) && selection.source instanceof TreeViewWidget && selection[0]
251
253
  ? selection.source.toTreeViewSelection(selection[0])
252
- : (UriSelection.getUri(selection) ?? this.resourceContextKey.get())?.['codeUri'];
254
+ : UriSelection.getUri(selection)?.['codeUri'] ?? resourceUri;
253
255
  const secondMember = TreeWidgetSelection.is(selection)
254
256
  ? UriSelection.getUris(selection).map(uri => uri['codeUri'])
255
257
  : undefined;
@@ -15,7 +15,8 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { injectable, inject, named } from '@theia/core/shared/inversify';
18
- import { ITokenTypeMap, IEmbeddedLanguagesMap, StandardTokenType } from 'vscode-textmate';
18
+ import { ITokenTypeMap, IEmbeddedLanguagesMap } from 'vscode-textmate';
19
+ import { StandardTokenType } from 'vscode-textmate/release/encodedTokenAttributes';
19
20
  import { TextmateRegistry, getEncodedLanguageId, MonacoTextmateService, GrammarDefinition } from '@theia/monaco/lib/browser/textmate';
20
21
  import { MenusContributionPointHandler } from './menus/menus-contribution-handler';
21
22
  import { PluginViewRegistry } from './view/plugin-view-registry';
@@ -35,8 +35,13 @@
35
35
  }
36
36
 
37
37
  .theia-plugin-view-container {
38
- -webkit-mask: url('');
39
- mask: url('');
38
+ /*
39
+ It might take a second or two until the real plugin mask is loaded
40
+ To prevent flickering on the icon, we set a transparent mask instead
41
+ Since masks only support images, svg or gradients, we create a transparent gradient here
42
+ */
43
+ -webkit-mask: linear-gradient(transparent, transparent);
44
+ mask: linear-gradient(transparent, transparent);
40
45
  background-color: var(--theia-activityBar-inactiveForeground);
41
46
  }
42
47
 
@@ -51,10 +56,10 @@
51
56
  .theia-plugin-root-folder-expanded-icon,
52
57
  .theia-plugin-root-folder-expanded-icon::before {
53
58
  padding-right: var(--theia-ui-padding);
54
- width: var(--theia-icon-size);
55
- height: var(--theia-content-line-height);
56
- line-height: inherit !important;
57
- display: inline-block;
59
+ width: var(--theia-icon-size);
60
+ height: var(--theia-content-line-height);
61
+ line-height: inherit !important;
62
+ display: inline-block;
58
63
  }
59
64
 
60
65
  .p-TabBar.theia-app-sides .theia-plugin-file-icon,
@@ -202,7 +202,7 @@ export class TasksMainImpl implements TasksMain, Disposable {
202
202
  }
203
203
 
204
204
  protected toTaskConfiguration(taskDto: TaskDto): TaskConfiguration {
205
- const { group, presentation, scope, source, ...common } = taskDto ?? {};
205
+ const { group, presentation, scope, source, runOptions, ...common } = taskDto ?? {};
206
206
  const partialConfig: Partial<TaskConfiguration> = {};
207
207
  if (presentation) {
208
208
  partialConfig.presentation = this.convertTaskPresentation(presentation);
@@ -213,6 +213,7 @@ export class TasksMainImpl implements TasksMain, Disposable {
213
213
  return {
214
214
  ...common,
215
215
  ...partialConfig,
216
+ runOptions,
216
217
  _scope: scope,
217
218
  _source: source,
218
219
  };
@@ -282,7 +282,8 @@ export class TextEditorMain implements Disposable {
282
282
  if (!this.editor) {
283
283
  return;
284
284
  }
285
- (this.editor.getControl() as unknown as StandaloneCodeEditor).setDecorations('Plugin decorations', key, ranges.map(option => Object.assign(option, { color: undefined })));
285
+ (this.editor.getControl() as unknown as StandaloneCodeEditor)
286
+ .setDecorationsByType('Plugin decorations', key, ranges.map(option => Object.assign(option, { color: undefined })));
286
287
  }
287
288
 
288
289
  setDecorationsFast(key: string, _ranges: number[]): void {
@@ -294,7 +295,7 @@ export class TextEditorMain implements Disposable {
294
295
  for (let i = 0; i < len; i++) {
295
296
  ranges[i] = new monaco.Range(_ranges[4 * i], _ranges[4 * i + 1], _ranges[4 * i + 2], _ranges[4 * i + 3]);
296
297
  }
297
- (this.editor.getControl() as unknown as StandaloneCodeEditor).setDecorationsFast(key, ranges);
298
+ (this.editor.getControl() as unknown as StandaloneCodeEditor).setDecorationsByTypeFast(key, ranges);
298
299
  }
299
300
 
300
301
  private static toMonacoSelections(selection: Selection): monaco.Selection {
@@ -28,13 +28,44 @@ const codeIconMap: Record<string, string> = {
28
28
  'callstack-view-icon': 'debug-alt',
29
29
  'callstack-view-session': 'bug',
30
30
  'comments-view-icon': 'comment-discussion',
31
+ 'debug-breakpoint': 'debug-breakpoint',
32
+ 'debug-breakpoint-conditional': 'debug-breakpoint-conditional',
33
+ 'debug-breakpoint-conditional-disabled': 'debug-breakpoint-conditional-disabled',
34
+ 'debug-breakpoint-conditional-verified': 'debug-breakpoint-conditional-unverified',
35
+ 'debug-breakpoint-data': 'debug-breakpoint-data',
36
+ 'debug-breakpoint-data-disabled': 'debug-breakpoint-data-disabled',
37
+ 'debug-breakpoint-data-unverified': 'debug-breakpoint-data-unverified',
38
+ 'debug-breakpoint-disabled': 'debug-breakpoint-disabled',
39
+ 'debug-breakpoint-function': 'debug-breakpoint-function',
40
+ 'debug-breakpoint-function-disabled': 'debug-breakpoint-function-disabled',
41
+ 'debug-breakpoint-function-unverified': 'debug-breakpoint-function-unverified',
42
+ 'debug-breakpoint-log': 'debug-breakpoint-log',
43
+ 'debug-breakpoint-log-disabled': 'debug-breakpoint-log-disabled',
44
+ 'debug-breakpoint-log-unverified': 'debug-breakpoint-log-unverified',
45
+ 'debug-breakpoint-unsupported': 'debug-breakpoint-unsupported',
46
+ 'debug-breakpoint-unverified': 'debug-breakpoint-unverified',
31
47
  'debug-collapse-all': 'collapse-all',
32
48
  'debug-configure': 'gear',
33
49
  'debug-console-clear-all': 'clear-all',
34
50
  'debug-console-evaluation-input': 'arrow-small-right',
35
51
  'debug-console-evaluation-prompt': 'chevron-right',
36
52
  'debug-console-view-icon': 'debug-console',
53
+ 'debug-continue': 'debug-continue',
54
+ 'debug-disconnect': 'debug-disconnect',
37
55
  'debug-gripper': 'gripper',
56
+ 'debug-hint': 'debug-hint',
57
+ 'debug-pause': 'debug-pause',
58
+ 'debug-restart': 'debug-restart',
59
+ 'debug-restart-frame': 'debug-restart-frame',
60
+ 'debug-reverse-continue': 'debug-reverse-continue',
61
+ 'debug-stackframe': 'debug-stackframe',
62
+ 'debug-stackframe-focused': 'debug-stackframe-focused',
63
+ 'debug-start': 'debug-start',
64
+ 'debug-step-back': 'debug-step-back',
65
+ 'debug-step-into': 'debug-step-into',
66
+ 'debug-step-out': 'debug-step-out',
67
+ 'debug-step-over': 'debug-step-over',
68
+ 'debug-stop': 'debug-stop',
38
69
  'default-view-icon': 'window',
39
70
  'diff-editor-next-change': 'arrow-down',
40
71
  'diff-editor-previous-change': 'arrow-up',
@@ -34,7 +34,7 @@ export class PluginTreeViewNodeLabelProvider implements LabelProviderContributio
34
34
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
35
  canHandle(element: TreeViewNode | any): number {
36
36
  if (TreeNode.is(element) && ('resourceUri' in element || 'themeIcon' in element)) {
37
- return this.treeLabelProvider.canHandle(element) + 1;
37
+ return Number.MAX_SAFE_INTEGER - 512;
38
38
  }
39
39
  return 0;
40
40
  }
@@ -30,19 +30,19 @@ import {
30
30
  TREE_NODE_TAIL_CLASS,
31
31
  TreeModelImpl,
32
32
  TreeViewWelcomeWidget,
33
- TooltipService,
34
- TooltipAttributes
33
+ TooltipAttributes,
34
+ TreeSelection,
35
+ HoverService
35
36
  } from '@theia/core/lib/browser';
36
37
  import { MenuPath, MenuModelRegistry, ActionMenuNode } from '@theia/core/lib/common/menu';
37
38
  import * as React from '@theia/core/shared/react';
38
39
  import { PluginSharedStyle } from '../plugin-shared-style';
39
- import { ACTION_ITEM, codicon, Widget } from '@theia/core/lib/browser/widgets/widget';
40
+ import { ACTION_ITEM, Widget } from '@theia/core/lib/browser/widgets/widget';
40
41
  import { Emitter, Event } from '@theia/core/lib/common/event';
41
42
  import { MessageService } from '@theia/core/lib/common/message-service';
42
43
  import { View } from '../../../common/plugin-protocol';
43
44
  import CoreURI from '@theia/core/lib/common/uri';
44
45
  import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
45
- import * as markdownit from '@theia/core/shared/markdown-it';
46
46
  import { MarkdownString } from '@theia/core/lib/common/markdown-rendering';
47
47
  import { LabelParser } from '@theia/core/lib/browser/label-parser';
48
48
  import { AccessibilityInformation } from '@theia/plugin';
@@ -408,8 +408,8 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
408
408
  @inject(ContextKeyService)
409
409
  protected readonly contextKeyService: ContextKeyService;
410
410
 
411
- @inject(TooltipService)
412
- protected readonly tooltipService: TooltipService;
411
+ @inject(HoverService)
412
+ protected readonly hoverService: HoverService;
413
413
 
414
414
  @inject(LabelParser)
415
415
  protected readonly labelParser: LabelParser;
@@ -417,33 +417,18 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
417
417
  @inject(ColorRegistry)
418
418
  protected readonly colorRegistry: ColorRegistry;
419
419
 
420
- protected readonly markdownIt = markdownit();
421
-
422
420
  @postConstruct()
423
421
  protected override init(): void {
424
422
  super.init();
425
423
  this.id = this.identifier.id;
426
424
  this.addClass('theia-tree-view');
427
425
  this.node.style.height = '100%';
428
- this.markdownItPlugin();
429
426
  this.model.onDidChangeWelcomeState(this.update, this);
430
427
  this.toDispose.push(this.model.onDidChangeWelcomeState(this.update, this));
431
428
  this.toDispose.push(this.onDidChangeVisibilityEmitter);
432
429
  this.toDispose.push(this.contextKeyService.onDidChange(() => this.update()));
433
430
  }
434
431
 
435
- protected markdownItPlugin(): void {
436
- this.markdownIt.renderer.rules.text = (tokens, idx) => {
437
- const content = tokens[idx].content;
438
- return this.labelParser.parse(content).map(chunk => {
439
- if (typeof chunk === 'string') {
440
- return chunk;
441
- }
442
- return `<i class="${codicon(chunk.name)} ${chunk.animation ? `fa-${chunk.animation}` : ''} icon-inline"></i>`;
443
- }).join('');
444
- };
445
- }
446
-
447
432
  protected override renderIcon(node: TreeNode, props: NodeProps): React.ReactNode {
448
433
  const icon = this.toNodeIcon(node);
449
434
  if (icon) {
@@ -480,16 +465,21 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
480
465
  };
481
466
  }
482
467
 
483
- const elementRef = React.createRef<HTMLDivElement & Partial<TooltipAttributes>>();
484
468
  if (!node.tooltip && node instanceof ResolvableTreeViewNode) {
485
469
  let configuredTip = false;
486
470
  let source: CancellationTokenSource | undefined;
487
471
  attrs = {
488
472
  ...attrs,
489
- 'data-for': this.tooltipService.tooltipId,
490
473
  onMouseLeave: () => source?.cancel(),
491
- onMouseEnter: async () => {
474
+ onMouseEnter: async event => {
492
475
  if (configuredTip) {
476
+ if (MarkdownString.is(node.tooltip)) {
477
+ this.hoverService.requestHover({
478
+ content: node.tooltip,
479
+ target: event.target as HTMLElement,
480
+ position: 'right'
481
+ });
482
+ }
493
483
  return;
494
484
  }
495
485
  if (!node.resolved) {
@@ -500,27 +490,31 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
500
490
  return;
501
491
  }
502
492
  }
503
- if (elementRef.current) {
504
- // Set the resolved tooltip. After an HTML element was created data-* properties must be accessed via the dataset
505
- elementRef.current.dataset.tip = MarkdownString.is(node.tooltip) ? this.markdownIt.render(node.tooltip.value) : node.tooltip;
506
- this.tooltipService.update();
507
- configuredTip = true;
508
- // Manually fire another mouseenter event to get react-tooltip to update the tooltip content.
509
- // Without this, the resolved tooltip is only shown after re-entering the tree item with the mouse.
510
- elementRef.current.dispatchEvent(new MouseEvent('mouseenter'));
493
+ if (MarkdownString.is(node.tooltip)) {
494
+ this.hoverService.requestHover({
495
+ content: node.tooltip,
496
+ target: event.target as HTMLElement,
497
+ position: 'right'
498
+ });
511
499
  } else {
512
- console.error(`Could not set resolved tooltip for tree node '${node.id}' because its React Ref was not set.`);
500
+ const title = node.tooltip ||
501
+ (node.resourceUri && this.labelProvider.getLongName(new CoreURI(node.resourceUri)))
502
+ || this.toNodeName(node);
503
+ event.currentTarget.title = title;
513
504
  }
505
+ configuredTip = true;
514
506
  }
515
507
  };
516
508
  } else if (MarkdownString.is(node.tooltip)) {
517
- // Render markdown in custom tooltip
518
- const tooltip = this.markdownIt.render(node.tooltip.value);
519
-
520
509
  attrs = {
521
510
  ...attrs,
522
- 'data-tip': tooltip,
523
- 'data-for': this.tooltipService.tooltipId
511
+ onMouseEnter: event => {
512
+ this.hoverService.requestHover({
513
+ content: node.tooltip!,
514
+ target: event.target as HTMLElement,
515
+ position: 'right'
516
+ });
517
+ }
524
518
  };
525
519
  } else {
526
520
  const title = node.tooltip ||
@@ -549,7 +543,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
549
543
  if (description) {
550
544
  children.push(<span className='theia-tree-view-description'>{description}</span>);
551
545
  }
552
- return <div {...attrs} ref={elementRef}>{...children}</div>;
546
+ return <div {...attrs}>{...children}</div>;
553
547
  }
554
548
 
555
549
  protected override renderTailDecorations(node: TreeViewNode, props: NodeProps): React.ReactNode {
@@ -666,9 +660,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
666
660
  }
667
661
 
668
662
  protected override render(): React.ReactNode {
669
- const node = React.createElement('div', this.createContainerAttributes(), this.renderSearchInfo(), this.renderTree(this.model));
670
- this.tooltipService.update();
671
- return node;
663
+ return React.createElement('div', this.createContainerAttributes(), this.renderSearchInfo(), this.renderTree(this.model));
672
664
  }
673
665
 
674
666
  protected renderSearchInfo(): React.ReactNode {
@@ -681,4 +673,33 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
681
673
  override shouldShowWelcomeView(): boolean {
682
674
  return (this.model.proxy === undefined || this.model.isTreeEmpty) && this.message === undefined;
683
675
  }
676
+
677
+ protected override handleContextMenuEvent(node: TreeNode | undefined, event: React.MouseEvent<HTMLElement, MouseEvent>): void {
678
+ if (SelectableTreeNode.is(node)) {
679
+ // Keep the selection for the context menu, if the widget support multi-selection and the right click happens on an already selected node.
680
+ if (!this.props.multiSelect || !node.selected) {
681
+ const type = !!this.props.multiSelect && this.hasCtrlCmdMask(event) ? TreeSelection.SelectionType.TOGGLE : TreeSelection.SelectionType.DEFAULT;
682
+ this.model.addSelection({ node, type });
683
+ }
684
+ this.focusService.setFocus(node);
685
+ const contextMenuPath = this.props.contextMenuPath;
686
+ if (contextMenuPath) {
687
+ const { x, y } = event.nativeEvent;
688
+ const args = this.toContextMenuArgs(node);
689
+ const contextKeyService = this.contextKeyService.createOverlay([
690
+ ['viewItem', (TreeViewNode.is(node) && node.contextValue) || undefined],
691
+ ['view', this.identifier.id]
692
+ ]);
693
+ setTimeout(() => this.contextMenuRenderer.render({
694
+ menuPath: contextMenuPath,
695
+ anchor: { x, y },
696
+ args,
697
+ contextKeyService,
698
+ onHide: () => contextKeyService.dispose(),
699
+ }), 10);
700
+ }
701
+ }
702
+ event.stopPropagation();
703
+ event.preventDefault();
704
+ }
684
705
  }
@@ -163,14 +163,7 @@ export class TreeViewsMainImpl implements TreeViewsMain, Disposable {
163
163
  }));
164
164
 
165
165
  this.toDispose.push(treeViewWidget.model.onSelectionChanged(event => {
166
- if (event.length === 1) {
167
- const { contextValue } = event[0] as TreeViewNode;
168
- this.contextKeys.viewItem.set(contextValue);
169
- } else {
170
- this.contextKeys.viewItem.set('');
171
- }
172
166
  this.contextKeys.view.set(treeViewId);
173
-
174
167
  this.proxy.$setSelection(treeViewId, event.map((node: TreeViewNode) => node.id));
175
168
  }));
176
169
 
@@ -520,7 +520,8 @@ export class LanguagesExtImpl implements LanguagesExt {
520
520
  return this.createDisposable(callId, disposables?.dispose);
521
521
  }
522
522
 
523
- $provideCodeActions(handle: number,
523
+ $provideCodeActions(
524
+ handle: number,
524
525
  resource: UriComponents,
525
526
  rangeOrSelection: Range | Selection,
526
527
  context: CodeActionContext,
@@ -158,7 +158,8 @@ import {
158
158
  TestRunProfileKind,
159
159
  TestTag,
160
160
  TestRunRequest,
161
- TestMessage
161
+ TestMessage,
162
+ ExtensionKind
162
163
  } from './types-impl';
163
164
  import { AuthenticationExtImpl } from './authentication-ext';
164
165
  import { SymbolKind } from '../common/plugin-api-rpc-model';
@@ -180,7 +181,6 @@ import { ConnectionImpl } from '../common/connection';
180
181
  import { TasksExtImpl } from './tasks/tasks';
181
182
  import { DebugExtImpl } from './debug/debug-ext';
182
183
  import { FileSystemExtImpl } from './file-system-ext-impl';
183
- import { QuickPick, QuickPickItem, ResourceLabelFormatter, LineChange } from '@theia/plugin';
184
184
  import { ScmExtImpl } from './scm';
185
185
  import { DecorationsExtImpl } from './decorations';
186
186
  import { TextEditorExt } from './text-editor';
@@ -308,7 +308,7 @@ export function createAPIFactory(
308
308
  getCommands(filterInternal: boolean = false): PromiseLike<string[]> {
309
309
  return commandRegistry.getCommands(filterInternal);
310
310
  },
311
- registerDiffInformationCommand(command: string, callback: (diff: LineChange[], ...args: any[]) => any, thisArg?: any): Disposable {
311
+ registerDiffInformationCommand(command: string, callback: (diff: theia.LineChange[], ...args: any[]) => any, thisArg?: any): Disposable {
312
312
  // Dummy implementation.
313
313
  return new Disposable(() => { });
314
314
  }
@@ -385,7 +385,7 @@ export function createAPIFactory(
385
385
  showQuickPick(items: any, options?: theia.QuickPickOptions, token?: theia.CancellationToken): any {
386
386
  return quickOpenExt.showQuickPick(items, options, token);
387
387
  },
388
- createQuickPick<T extends QuickPickItem>(): QuickPick<T> {
388
+ createQuickPick<T extends theia.QuickPickItem>(): theia.QuickPick<T> {
389
389
  return quickOpenExt.createQuickPick(plugin);
390
390
  },
391
391
  showWorkspaceFolderPick(options?: theia.WorkspaceFolderPickOptions): PromiseLike<theia.WorkspaceFolder | undefined> {
@@ -461,7 +461,7 @@ export function createAPIFactory(
461
461
  },
462
462
  createTerminal(nameOrOptions: theia.TerminalOptions | theia.PseudoTerminalOptions | theia.ExtensionTerminalOptions | (string | undefined),
463
463
  shellPath?: string,
464
- shellArgs?: string[]): theia.Terminal {
464
+ shellArgs?: string[] | string): theia.Terminal {
465
465
  return terminalExt.createTerminal(nameOrOptions, shellPath, shellArgs);
466
466
  },
467
467
  onDidChangeTerminalState,
@@ -476,6 +476,10 @@ export function createAPIFactory(
476
476
  createTreeView<T>(viewId: string, options: { treeDataProvider: theia.TreeDataProvider<T> }): theia.TreeView<T> {
477
477
  return treeViewsExt.createTreeView(plugin, viewId, options);
478
478
  },
479
+ withScmProgress<R>(task: (progress: theia.Progress<number>) => Thenable<R>) {
480
+ const options: ProgressOptions = { location: ProgressLocation.SourceControl };
481
+ return notificationExt.withProgress(options, () => task({ report() { /* noop */ } }));
482
+ },
479
483
  withProgress<R>(
480
484
  options: ProgressOptions,
481
485
  task: (progress: Progress<{ message?: string; increment?: number }>, token: theia.CancellationToken) => PromiseLike<R>
@@ -610,7 +614,7 @@ export function createAPIFactory(
610
614
  registerTaskProvider(type: string, provider: theia.TaskProvider): theia.Disposable {
611
615
  return tasks.registerTaskProvider(type, provider);
612
616
  },
613
- registerResourceLabelFormatter(formatter: ResourceLabelFormatter): theia.Disposable {
617
+ registerResourceLabelFormatter(formatter: theia.ResourceLabelFormatter): theia.Disposable {
614
618
  return labelServiceExt.$registerResourceLabelFormatter(formatter);
615
619
  },
616
620
  registerTimelineProvider(scheme: string | string[], provider: theia.TimelineProvider): theia.Disposable {
@@ -667,6 +671,24 @@ export function createAPIFactory(
667
671
  get onDidChangeLogLevel(): theia.Event<theia.LogLevel> { return onDidChangeLogLevel.event; }
668
672
  });
669
673
 
674
+ const extensions: typeof theia.extensions = Object.freeze({
675
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
676
+ getExtension<T = any>(extensionId: string): theia.Extension<T> | undefined {
677
+ const plg = pluginManager.getPluginById(extensionId.toLowerCase());
678
+ if (plg) {
679
+ return new PluginExt(pluginManager, plg);
680
+ }
681
+ return undefined;
682
+ },
683
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
684
+ get all(): readonly theia.Extension<any>[] {
685
+ return pluginManager.getAllPlugins().map(plg => new PluginExt(pluginManager, plg));
686
+ },
687
+ get onDidChange(): theia.Event<void> {
688
+ return pluginManager.onDidChange;
689
+ }
690
+ });
691
+
670
692
  const languages: typeof theia.languages = {
671
693
  getLanguages(): PromiseLike<string[]> {
672
694
  return languagesExt.getLanguages();
@@ -967,6 +989,7 @@ export function createAPIFactory(
967
989
  window,
968
990
  workspace,
969
991
  env,
992
+ extensions,
970
993
  languages,
971
994
  plugins,
972
995
  debug,
@@ -1100,16 +1123,12 @@ export function createAPIFactory(
1100
1123
  TestRunProfileKind,
1101
1124
  TestTag,
1102
1125
  TestRunRequest,
1103
- TestMessage
1126
+ TestMessage,
1127
+ ExtensionKind
1104
1128
  };
1105
1129
  };
1106
1130
  }
1107
1131
 
1108
- export enum ExtensionKind {
1109
- UI = 1,
1110
- Workspace = 2
1111
- }
1112
-
1113
1132
  /**
1114
1133
  * Represents a Theia plugin as well as a VSCode extension.
1115
1134
  */
@@ -1131,7 +1150,7 @@ export interface ExtensionPlugin<T> extends theia.Plugin<T> {
1131
1150
  * is defined in the `package.json`-file of extensions. When no remote extension host exists,
1132
1151
  * the value is {@linkcode ExtensionKind.UI}.
1133
1152
  */
1134
- extensionKind: ExtensionKind;
1153
+ extensionKind: theia.ExtensionKind;
1135
1154
  }
1136
1155
 
1137
1156
  export class Plugin<T> implements theia.Plugin<T> {
@@ -17,13 +17,13 @@
17
17
  /* eslint-disable @typescript-eslint/no-explicit-any */
18
18
 
19
19
  import { Emitter, Event } from '@theia/core/lib/common/event';
20
+ import { isOSX, isWindows } from '@theia/core/lib/common/os';
20
21
  import { URI } from '@theia/core/shared/vscode-uri';
21
22
  import { ResourceMap } from '@theia/monaco-editor-core/esm/vs/base/common/map';
22
23
  import { IConfigurationOverrides, IOverrides } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configuration';
23
24
  import { Configuration, ConfigurationModel } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configurationModels';
24
25
  import { Workspace, WorkspaceFolder } from '@theia/monaco-editor-core/esm/vs/platform/workspace/common/workspace';
25
26
  import * as theia from '@theia/plugin';
26
- import { platform } from 'os';
27
27
  import { v4 } from 'uuid';
28
28
  import {
29
29
  PLUGIN_RPC_CONTEXT, PreferenceChangeExt, PreferenceData, PreferenceRegistryExt,
@@ -74,7 +74,7 @@ function lookUp(tree: any, key: string): any {
74
74
  export class TheiaWorkspace extends Workspace {
75
75
  constructor(ext: WorkspaceExtImpl) {
76
76
  const folders = (ext.workspaceFolders ?? []).map(folder => new WorkspaceFolder(folder));
77
- super(v4(), folders, false, ext.workspaceFile ?? null, () => ['win32', 'darwin'].includes(platform()));
77
+ super(v4(), folders, false, ext.workspaceFile ?? null, () => isOSX || isWindows);
78
78
  }
79
79
  }
80
80
 
@@ -239,7 +239,15 @@ export class PreferenceRegistryExtImpl implements PreferenceRegistryExt {
239
239
  Object.keys(data[PreferenceScope.Folder]).forEach(resource => {
240
240
  folderConfigurations.set(URI.parse(resource), this.getConfigurationModel(data[PreferenceScope.Folder][resource]));
241
241
  });
242
- return new Configuration(defaultConfiguration, userConfiguration, undefined, workspaceConfiguration, folderConfigurations);
242
+ return new Configuration(
243
+ defaultConfiguration,
244
+ new ConfigurationModel(), /** policy configuration. */
245
+ new ConfigurationModel(), /** application configuration. */
246
+ userConfiguration,
247
+ new ConfigurationModel(), /** remote configuration. */
248
+ workspaceConfiguration,
249
+ folderConfigurations
250
+ );
243
251
  }
244
252
 
245
253
  private getConfigurationModel(data: { [key: string]: any }): ConfigurationModel {
@@ -635,16 +635,18 @@ export class QuickPickExt<T extends theia.QuickPickItem> extends QuickInputExt i
635
635
  this._handlesToItems.set(i, item);
636
636
  this._itemsToHandles.set(item, i);
637
637
  });
638
- this.update({
639
- items: items.map((item, i) => {
640
- if (item.kind === QuickPickItemKind.Separator) {
641
- return { kind: item.kind, label: item.label };
642
- }
643
- return {
638
+
639
+ const pickItems: TransferQuickPickItems[] = [];
640
+ for (let handle = 0; handle < items.length; handle++) {
641
+ const item = items[handle];
642
+ if (item.kind === QuickPickItemKind.Separator) {
643
+ pickItems.push({ type: 'separator', label: item.label, handle });
644
+ } else {
645
+ pickItems.push({
644
646
  kind: item.kind,
645
647
  label: item.label,
646
648
  description: item.description,
647
- handle: i,
649
+ handle,
648
650
  detail: item.detail,
649
651
  picked: item.picked,
650
652
  alwaysShow: item.alwaysShow,
@@ -654,8 +656,12 @@ export class QuickPickExt<T extends theia.QuickPickItem> extends QuickInputExt i
654
656
  tooltip: button.tooltip,
655
657
  handle: button === QuickInputButtons.Back ? -1 : index,
656
658
  }))
657
- };
658
- })
659
+ });
660
+ }
661
+ }
662
+
663
+ this.update({
664
+ items: pickItems,
659
665
  });
660
666
  }
661
667
 
@@ -61,7 +61,10 @@ export class TerminalServiceExtImpl implements TerminalServiceExt {
61
61
  return [...this._terminals.values()];
62
62
  }
63
63
 
64
- createTerminal(nameOrOptions: TerminalOptions | PseudoTerminalOptions | ExtensionTerminalOptions | (string | undefined), shellPath?: string, shellArgs?: string[]): Terminal {
64
+ createTerminal(
65
+ nameOrOptions: TerminalOptions | PseudoTerminalOptions | ExtensionTerminalOptions | (string | undefined),
66
+ shellPath?: string, shellArgs?: string[] | string
67
+ ): Terminal {
65
68
  let options: TerminalOptions;
66
69
  let pseudoTerminal: theia.Pseudoterminal | undefined = undefined;
67
70
  const id = `plugin-terminal-${UUID.uuid4()}`;
@@ -202,7 +202,10 @@ describe('Type converters:', () => {
202
202
  reveal: 3,
203
203
  focus: true
204
204
  },
205
- group: groupDto
205
+ group: groupDto,
206
+ runOptions: {
207
+ reevaluateOnRerun: false
208
+ }
206
209
  };
207
210
 
208
211
  const shellTaskDtoWithCommandLine: TaskDto = {
@@ -213,7 +216,10 @@ describe('Type converters:', () => {
213
216
  scope: 2,
214
217
  command: commandLine,
215
218
  options: { cwd },
216
- additionalProperty
219
+ additionalProperty,
220
+ runOptions: {
221
+ reevaluateOnRerun: false
222
+ }
217
223
  };
218
224
 
219
225
  const shellPluginTask: theia.Task = {
@@ -235,6 +241,9 @@ describe('Type converters:', () => {
235
241
  options: {
236
242
  cwd
237
243
  }
244
+ },
245
+ runOptions: {
246
+ reevaluateOnRerun: false
238
247
  }
239
248
  };
240
249
 
@@ -264,6 +273,9 @@ describe('Type converters:', () => {
264
273
  options: {
265
274
  cwd
266
275
  }
276
+ },
277
+ runOptions: {
278
+ reevaluateOnRerun: false
267
279
  }
268
280
  };
269
281
 
@@ -291,6 +303,9 @@ describe('Type converters:', () => {
291
303
  options: {
292
304
  cwd
293
305
  }
306
+ },
307
+ runOptions: {
308
+ reevaluateOnRerun: false
294
309
  }
295
310
  };
296
311