@theia/plugin-ext 1.38.0 → 1.39.0-next.12

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 (33) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +1 -1
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/main/browser/custom-editors/custom-editors-main.d.ts +4 -5
  4. package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
  5. package/lib/main/browser/custom-editors/custom-editors-main.js +10 -16
  6. package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
  7. package/lib/main/browser/scm-main.d.ts +7 -1
  8. package/lib/main/browser/scm-main.d.ts.map +1 -1
  9. package/lib/main/browser/scm-main.js +22 -6
  10. package/lib/main/browser/scm-main.js.map +1 -1
  11. package/lib/main/browser/webview/webview-context-keys.d.ts +1 -1
  12. package/lib/main/browser/webview/webview-context-keys.d.ts.map +1 -1
  13. package/lib/main/browser/webview/webview-context-keys.js +2 -2
  14. package/lib/main/browser/webview/webview-context-keys.js.map +1 -1
  15. package/lib/main/browser/webview/webview-environment.d.ts +2 -1
  16. package/lib/main/browser/webview/webview-environment.d.ts.map +1 -1
  17. package/lib/main/browser/webview/webview-environment.js +5 -2
  18. package/lib/main/browser/webview/webview-environment.js.map +1 -1
  19. package/lib/main/node/plugin-service.d.ts +1 -1
  20. package/lib/main/node/plugin-service.d.ts.map +1 -1
  21. package/lib/main/node/plugin-service.js +2 -2
  22. package/lib/main/node/plugin-service.js.map +1 -1
  23. package/lib/plugin/scm.d.ts.map +1 -1
  24. package/lib/plugin/scm.js +32 -19
  25. package/lib/plugin/scm.js.map +1 -1
  26. package/package.json +26 -26
  27. package/src/common/plugin-api-rpc.ts +1 -1
  28. package/src/main/browser/custom-editors/custom-editors-main.ts +8 -19
  29. package/src/main/browser/scm-main.ts +25 -6
  30. package/src/main/browser/webview/webview-context-keys.ts +1 -1
  31. package/src/main/browser/webview/webview-environment.ts +5 -1
  32. package/src/main/node/plugin-service.ts +1 -1
  33. package/src/plugin/scm.ts +36 -27
@@ -964,7 +964,7 @@ export interface SourceControlGroupFeatures {
964
964
  export interface ScmRawResource {
965
965
  handle: number,
966
966
  sourceUri: UriComponents,
967
- icons: UriComponents[],
967
+ icons: (IconUrl | ThemeIcon | undefined)[], /* icons: light, dark */
968
968
  tooltip: string,
969
969
  strikeThrough: boolean,
970
970
  faded: boolean,
@@ -185,7 +185,7 @@ export class CustomEditorsMainImpl implements CustomEditorsMain, Disposable {
185
185
 
186
186
  switch (modelType) {
187
187
  case CustomEditorModelType.Text: {
188
- const model = CustomTextEditorModel.create(viewType, resource, this.textModelService, this.fileService, this.editorPreferences);
188
+ const model = CustomTextEditorModel.create(viewType, resource, this.textModelService, this.fileService);
189
189
  return this.customEditorService.models.add(resource, viewType, model);
190
190
  }
191
191
  case CustomEditorModelType.Custom: {
@@ -521,19 +521,16 @@ export class CustomTextEditorModel implements CustomEditorModel {
521
521
  private readonly toDispose = new DisposableCollection();
522
522
  private readonly onDirtyChangedEmitter = new Emitter<void>();
523
523
  readonly onDirtyChanged = this.onDirtyChangedEmitter.event;
524
- autoSave: 'off' | 'afterDelay' | 'onFocusChange' | 'onWindowChange';
525
- autoSaveDelay: number;
526
524
 
527
525
  static async create(
528
526
  viewType: string,
529
527
  resource: TheiaURI,
530
528
  editorModelService: EditorModelService,
531
529
  fileService: FileService,
532
- editorPreferences: EditorPreferences,
533
530
  ): Promise<CustomTextEditorModel> {
534
531
  const model = await editorModelService.createModelReference(resource);
535
532
  model.object.suppressOpenEditorWhenDirty = true;
536
- return new CustomTextEditorModel(viewType, resource, model, fileService, editorPreferences);
533
+ return new CustomTextEditorModel(viewType, resource, model, fileService);
537
534
  }
538
535
 
539
536
  constructor(
@@ -541,7 +538,6 @@ export class CustomTextEditorModel implements CustomEditorModel {
541
538
  readonly editorResource: TheiaURI,
542
539
  private readonly model: Reference<MonacoEditorModel>,
543
540
  private readonly fileService: FileService,
544
- private readonly editorPreferences: EditorPreferences
545
541
  ) {
546
542
  this.toDispose.push(
547
543
  this.editorTextModel.onDirtyChanged(e => {
@@ -549,21 +545,14 @@ export class CustomTextEditorModel implements CustomEditorModel {
549
545
  })
550
546
  );
551
547
  this.toDispose.push(this.onDirtyChangedEmitter);
548
+ }
552
549
 
553
- this.autoSave = this.editorPreferences.get('files.autoSave', undefined, editorResource.toString());
554
- this.autoSaveDelay = this.editorPreferences.get('files.autoSaveDelay', undefined, editorResource.toString());
550
+ get autoSave(): 'off' | 'afterDelay' | 'onFocusChange' | 'onWindowChange' {
551
+ return this.editorTextModel.autoSave;
552
+ }
555
553
 
556
- this.toDispose.push(
557
- this.editorPreferences.onPreferenceChanged(event => {
558
- if (event.preferenceName === 'files.autoSave') {
559
- this.autoSave = this.editorPreferences.get('files.autoSave', undefined, editorResource.toString());
560
- }
561
- if (event.preferenceName === 'files.autoSaveDelay') {
562
- this.autoSaveDelay = this.editorPreferences.get('files.autoSaveDelay', undefined, editorResource.toString());
563
- }
564
- })
565
- );
566
- this.toDispose.push(this.onDirtyChangedEmitter);
554
+ get autoSaveDelay(): number {
555
+ return this.editorTextModel.autoSaveDelay;
567
556
  }
568
557
 
569
558
  dispose(): void {
@@ -40,6 +40,9 @@ import { URI as vscodeURI } from '@theia/core/shared/vscode-uri';
40
40
  import { Splice } from '../../common/arrays';
41
41
  import { UriComponents } from '../../common/uri-components';
42
42
  import { ColorRegistry } from '@theia/core/lib/browser/color-registry';
43
+ import { PluginSharedStyle } from './plugin-shared-style';
44
+ import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService';
45
+ import { IconUrl } from '../../common';
43
46
 
44
47
  export class PluginScmResourceGroup implements ScmResourceGroup {
45
48
 
@@ -147,10 +150,12 @@ export class PluginScmProvider implements ScmProvider {
147
150
  constructor(
148
151
  private readonly proxy: ScmExt,
149
152
  private readonly colors: ColorRegistry,
153
+ private readonly sharedStyle: PluginSharedStyle,
150
154
  private readonly _handle: number,
151
155
  private readonly _contextValue: string,
152
156
  private readonly _label: string,
153
- private readonly _rootUri: vscodeURI | undefined
157
+ private readonly _rootUri: vscodeURI | undefined,
158
+ private disposables: DisposableCollection
154
159
  ) { }
155
160
 
156
161
  updateSourceControl(features: SourceControlProviderFeatures): void {
@@ -222,13 +227,13 @@ export class PluginScmProvider implements ScmProvider {
222
227
  const { start, deleteCount, rawResources } = groupSlice;
223
228
  const resources = rawResources.map(rawResource => {
224
229
  const { handle, sourceUri, icons, tooltip, strikeThrough, faded, contextValue, command } = rawResource;
225
- const icon = icons[0];
226
- const iconDark = icons[1] || icon;
230
+ const icon = this.toIconClass(icons[0]);
231
+ const iconDark = this.toIconClass(icons[1]) || icon;
227
232
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
228
233
  const colorVariable = (rawResource as any).colorId && this.colors.toCssVariableName((rawResource as any).colorId);
229
234
  const decorations = {
230
- icon: icon ? vscodeURI.revive(icon) : undefined,
231
- iconDark: iconDark ? vscodeURI.revive(iconDark) : undefined,
235
+ icon,
236
+ iconDark,
232
237
  tooltip,
233
238
  strikeThrough,
234
239
  // TODO remove the letter and colorId fields when the FileDecorationProvider is applied, see https://github.com/eclipse-theia/theia/pull/8911
@@ -258,6 +263,18 @@ export class PluginScmProvider implements ScmProvider {
258
263
  this.onDidChangeResourcesEmitter.fire();
259
264
  }
260
265
 
266
+ private toIconClass(icon: IconUrl | ThemeIcon | undefined): string | undefined {
267
+ if (!icon) {
268
+ return undefined;
269
+ }
270
+ if (ThemeIcon.isThemeIcon(icon)) {
271
+ return ThemeIcon.asClassName(icon);
272
+ }
273
+ const reference = this.sharedStyle.toIconClass(icon);
274
+ this.disposables.push(reference);
275
+ return reference.object.iconClass;
276
+ }
277
+
261
278
  unregisterGroup(handle: number): void {
262
279
  const group = this.groupsByHandle[handle];
263
280
 
@@ -280,11 +297,13 @@ export class ScmMainImpl implements ScmMain {
280
297
  private repositoryDisposables = new Map<number, DisposableCollection>();
281
298
  private readonly disposables = new DisposableCollection();
282
299
  private readonly colors: ColorRegistry;
300
+ private readonly sharedStyle: PluginSharedStyle;
283
301
 
284
302
  constructor(rpc: RPCProtocol, container: interfaces.Container) {
285
303
  this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.SCM_EXT);
286
304
  this.scmService = container.get(ScmService);
287
305
  this.colors = container.get(ColorRegistry);
306
+ this.sharedStyle = container.get(PluginSharedStyle);
288
307
  }
289
308
 
290
309
  dispose(): void {
@@ -298,7 +317,7 @@ export class ScmMainImpl implements ScmMain {
298
317
  }
299
318
 
300
319
  async $registerSourceControl(handle: number, id: string, label: string, rootUri: UriComponents | undefined): Promise<void> {
301
- const provider = new PluginScmProvider(this.proxy, this.colors, handle, id, label, rootUri ? vscodeURI.revive(rootUri) : undefined);
320
+ const provider = new PluginScmProvider(this.proxy, this.colors, this.sharedStyle, handle, id, label, rootUri ? vscodeURI.revive(rootUri) : undefined, this.disposables);
302
321
  const repository = this.scmService.registerScmProvider(provider, {
303
322
  input: {
304
323
  validator: async value => {
@@ -34,7 +34,7 @@ export class WebviewContextKeys {
34
34
  protected contextKeyService: ContextKeyService;
35
35
 
36
36
  @postConstruct()
37
- protected postConstruct(): void {
37
+ protected init(): void {
38
38
  this.activeWebviewPanelId = this.contextKeyService.createKey('activeWebviewPanelId', '');
39
39
  this.applicationShell.onDidChangeCurrentWidget(this.handleDidChangeCurrentWidget, this);
40
40
  }
@@ -33,7 +33,11 @@ export class WebviewEnvironment {
33
33
  protected readonly environments: EnvVariablesServer;
34
34
 
35
35
  @postConstruct()
36
- protected async init(): Promise<void> {
36
+ protected init(): void {
37
+ this.doInit();
38
+ }
39
+
40
+ protected async doInit(): Promise<void> {
37
41
  this._hostPatternPromise = this.getHostPattern();
38
42
  try {
39
43
  const endpointPattern = await this.hostPatternPromise;
@@ -34,7 +34,7 @@ export class PluginApiContribution implements BackendApplicationContribution, Ws
34
34
  protected serveSameOrigin: boolean = false;
35
35
 
36
36
  @postConstruct()
37
- protected postConstruct(): void {
37
+ protected init(): void {
38
38
  const webviewExternalEndpoint = this.webviewExternalEndpoint();
39
39
  console.log(`Configuring to accept webviews on '${webviewExternalEndpoint}' hostname.`);
40
40
  this.webviewExternalEndpointRegExp = new RegExp(webviewExternalEndpoint, 'i');
package/src/plugin/scm.ts CHANGED
@@ -35,20 +35,26 @@ import { Splice } from '../common/arrays';
35
35
  import { UriComponents } from '../common/uri-components';
36
36
  import { Command } from '../common/plugin-api-rpc-model';
37
37
  import { RPCProtocol } from '../common/rpc-protocol';
38
- import { URI } from './types-impl';
38
+ import { URI, ThemeIcon } from './types-impl';
39
39
  import { ScmCommandArg } from '../common/plugin-api-rpc';
40
40
  import { sep } from '@theia/core/lib/common/paths';
41
+ import { PluginIconPath } from './plugin-icon-path';
41
42
  type ProviderHandle = number;
42
43
  type GroupHandle = number;
43
44
  type ResourceStateHandle = number;
44
45
 
45
- function getIconResource(decorations?: theia.SourceControlResourceThemableDecorations): theia.Uri | undefined {
46
- if (!decorations) {
46
+ function getIconResource(decorations?: theia.SourceControlResourceThemableDecorations): UriComponents | ThemeIcon | undefined {
47
+ if (!decorations || !decorations.iconPath) {
47
48
  return undefined;
48
49
  } else if (typeof decorations.iconPath === 'string') {
49
50
  return URI.file(decorations.iconPath);
50
- } else {
51
+ } else if (URI.isUri(decorations.iconPath)) {
52
+ return decorations.iconPath;
53
+ } else if (ThemeIcon.is(decorations.iconPath)) {
51
54
  return decorations.iconPath;
55
+ } else {
56
+ console.warn(`Unexpected Value ${decorations.iconPath} in Source Control Resource Themable Decoration. URI, ThemeIcon or string expected.`);
57
+ return undefined;
52
58
  }
53
59
  }
54
60
 
@@ -111,8 +117,8 @@ function compareResourceThemableDecorations(a: theia.SourceControlResourceThemab
111
117
  return 1;
112
118
  }
113
119
 
114
- const aPath = typeof a.iconPath === 'string' ? a.iconPath : a.iconPath.fsPath;
115
- const bPath = typeof b.iconPath === 'string' ? b.iconPath : b.iconPath.fsPath;
120
+ const aPath = typeof a.iconPath === 'string' ? a.iconPath : URI.isUri(a.iconPath) ? a.iconPath.fsPath : (a.iconPath as ThemeIcon).id;
121
+ const bPath = typeof b.iconPath === 'string' ? b.iconPath : URI.isUri(b.iconPath) ? b.iconPath.fsPath : (b.iconPath as ThemeIcon).id;
116
122
  return comparePaths(aPath, bPath);
117
123
  }
118
124
 
@@ -361,7 +367,7 @@ export class ScmInputBoxImpl implements theia.SourceControlInputBox {
361
367
  }
362
368
  }
363
369
 
364
- class SsmResourceGroupImpl implements theia.SourceControlResourceGroup {
370
+ class ScmResourceGroupImpl implements theia.SourceControlResourceGroup {
365
371
 
366
372
  private static handlePool: number = 0;
367
373
  private resourceHandlePool: number = 0;
@@ -409,12 +415,13 @@ class SsmResourceGroupImpl implements theia.SourceControlResourceGroup {
409
415
  this.onDidUpdateResourceStatesEmitter.fire();
410
416
  }
411
417
 
412
- readonly handle = SsmResourceGroupImpl.handlePool++;
418
+ readonly handle = ScmResourceGroupImpl.handlePool++;
413
419
 
414
420
  constructor(
415
421
  private proxy: ScmMain,
416
422
  private commands: CommandRegistryImpl,
417
423
  private sourceControlHandle: number,
424
+ private plugin: Plugin,
418
425
  private _id: string,
419
426
  private _label: string,
420
427
  ) { }
@@ -443,10 +450,11 @@ class SsmResourceGroupImpl implements theia.SourceControlResourceGroup {
443
450
  this.resourceStatesMap.set(handle, r);
444
451
 
445
452
  const sourceUri = r.resourceUri;
446
- const iconUri = getIconResource(r.decorations);
447
- const lightIconUri = r.decorations && getIconResource(r.decorations.light) || iconUri;
448
- const darkIconUri = r.decorations && getIconResource(r.decorations.dark) || iconUri;
449
- const icons: UriComponents[] = [];
453
+
454
+ const icon = getIconResource(r.decorations);
455
+ const lightIcon = r.decorations && getIconResource(r.decorations.light) || icon;
456
+ const darkIcon = r.decorations && getIconResource(r.decorations.dark) || icon;
457
+ const icons = [this.getThemableIcon(lightIcon), this.getThemableIcon(darkIcon)];
450
458
  let command: Command | undefined;
451
459
 
452
460
  if (r.command) {
@@ -459,14 +467,6 @@ class SsmResourceGroupImpl implements theia.SourceControlResourceGroup {
459
467
  }
460
468
  }
461
469
 
462
- if (lightIconUri) {
463
- icons.push(lightIconUri);
464
- }
465
-
466
- if (darkIconUri && (darkIconUri.toString() !== lightIconUri?.toString())) {
467
- icons.push(darkIconUri);
468
- }
469
-
470
470
  const tooltip = (r.decorations && r.decorations.tooltip) || '';
471
471
  const strikeThrough = r.decorations && !!r.decorations.strikeThrough;
472
472
  const faded = r.decorations && !!r.decorations.faded;
@@ -511,6 +511,15 @@ class SsmResourceGroupImpl implements theia.SourceControlResourceGroup {
511
511
  return rawResourceSplices;
512
512
  }
513
513
 
514
+ private getThemableIcon(icon: UriComponents | ThemeIcon | undefined): string | ThemeIcon | undefined {
515
+ if (!icon) {
516
+ return undefined;
517
+ } else if (ThemeIcon.is(icon)) {
518
+ return icon;
519
+ }
520
+ return PluginIconPath.asString(URI.revive(icon), this.plugin);
521
+ }
522
+
514
523
  dispose(): void {
515
524
  this._disposed = true;
516
525
  this.onDidDisposeEmitter.fire();
@@ -520,7 +529,7 @@ class SsmResourceGroupImpl implements theia.SourceControlResourceGroup {
520
529
  class SourceControlImpl implements theia.SourceControl {
521
530
 
522
531
  private static handlePool: number = 0;
523
- private groups: Map<GroupHandle, SsmResourceGroupImpl> = new Map<GroupHandle, SsmResourceGroupImpl>();
532
+ private groups: Map<GroupHandle, ScmResourceGroupImpl> = new Map<GroupHandle, ScmResourceGroupImpl>();
524
533
 
525
534
  get id(): string {
526
535
  return this._id;
@@ -626,7 +635,7 @@ class SourceControlImpl implements theia.SourceControl {
626
635
  private handle: number = SourceControlImpl.handlePool++;
627
636
 
628
637
  constructor(
629
- plugin: Plugin,
638
+ private plugin: Plugin,
630
639
  private proxy: ScmMain,
631
640
  private commands: CommandRegistryImpl,
632
641
  private _id: string,
@@ -637,11 +646,11 @@ class SourceControlImpl implements theia.SourceControl {
637
646
  this.proxy.$registerSourceControl(this.handle, _id, _label, _rootUri);
638
647
  }
639
648
 
640
- private createdResourceGroups = new Map<SsmResourceGroupImpl, Disposable>();
641
- private updatedResourceGroups = new Set<SsmResourceGroupImpl>();
649
+ private createdResourceGroups = new Map<ScmResourceGroupImpl, Disposable>();
650
+ private updatedResourceGroups = new Set<ScmResourceGroupImpl>();
642
651
 
643
- createResourceGroup(id: string, label: string): SsmResourceGroupImpl {
644
- const group = new SsmResourceGroupImpl(this.proxy, this.commands, this.handle, id, label);
652
+ createResourceGroup(id: string, label: string): ScmResourceGroupImpl {
653
+ const group = new ScmResourceGroupImpl(this.proxy, this.commands, this.handle, this.plugin, id, label);
645
654
  const disposable = group.onDidDispose(() => this.createdResourceGroups.delete(group));
646
655
  this.createdResourceGroups.set(group, disposable);
647
656
  this.eventuallyAddResourceGroups();
@@ -703,7 +712,7 @@ class SourceControlImpl implements theia.SourceControl {
703
712
  this.updatedResourceGroups.clear();
704
713
  }
705
714
 
706
- getResourceGroup(handle: GroupHandle): SsmResourceGroupImpl | undefined {
715
+ getResourceGroup(handle: GroupHandle): ScmResourceGroupImpl | undefined {
707
716
  return this.groups.get(handle);
708
717
  }
709
718