From 4e7161caf3252de38b1cce8da6726a0059317446 Mon Sep 17 00:00:00 2001 From: FernandoAscencio Date: Wed, 17 May 2023 22:57:12 -0400 Subject: [PATCH] Some changes to use of VS Code code. In progress. --- .../plugin-ext/src/common/plugin-api-rpc.ts | 2 +- .../plugin-ext/src/main/browser/scm-main.ts | 43 ++++++++++--------- .../plugin-ext/src/plugin/plugin-icon-path.ts | 9 ++-- packages/plugin-ext/src/plugin/scm.ts | 41 +++++++++++------- packages/scm/src/browser/scm-provider.ts | 3 +- packages/scm/src/browser/scm-tree-widget.tsx | 6 +-- 6 files changed, 56 insertions(+), 48 deletions(-) diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts index 63b9a0e74a82e..966835995578d 100644 --- a/packages/plugin-ext/src/common/plugin-api-rpc.ts +++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts @@ -963,7 +963,7 @@ export interface SourceControlGroupFeatures { export interface ScmRawResource { handle: number, sourceUri: UriComponents, - icon: IconUrl, /* icons: light, dark */ + icons: (UriComponents | ThemeIcon | undefined)[], /* icons: light, dark */ tooltip: string, strikeThrough: boolean, faded: boolean, diff --git a/packages/plugin-ext/src/main/browser/scm-main.ts b/packages/plugin-ext/src/main/browser/scm-main.ts index e8b54ff7a39c4..5dc58bb8f6d88 100644 --- a/packages/plugin-ext/src/main/browser/scm-main.ts +++ b/packages/plugin-ext/src/main/browser/scm-main.ts @@ -41,7 +41,7 @@ import { Splice } from '../../common/arrays'; import { UriComponents } from '../../common/uri-components'; import { ColorRegistry } from '@theia/core/lib/browser/color-registry'; import { PluginSharedStyle } from './plugin-shared-style'; -import { IconUrl } from '../../common'; +import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; export class PluginScmResourceGroup implements ScmResourceGroup { @@ -149,10 +149,12 @@ export class PluginScmProvider implements ScmProvider { constructor( private readonly proxy: ScmExt, private readonly colors: ColorRegistry, + private readonly sharedStyle: PluginSharedStyle, private readonly _handle: number, private readonly _contextValue: string, private readonly _label: string, - private readonly _rootUri: vscodeURI | undefined + private readonly _rootUri: vscodeURI | undefined, + private disposables: DisposableCollection ) { } updateSourceControl(features: SourceControlProviderFeatures): void { @@ -206,7 +208,7 @@ export class PluginScmProvider implements ScmProvider { group.updateGroupLabel(label); } - spliceGroupResourceStates(splices: ScmRawResourceSplices[], sharedStyle: PluginSharedStyle, disposables: DisposableCollection): void { + spliceGroupResourceStates(splices: ScmRawResourceSplices[]): void { for (const splice of splices) { const groupHandle = splice.handle; const groupSlices = splice.splices; @@ -223,12 +225,14 @@ export class PluginScmProvider implements ScmProvider { for (const groupSlice of groupSlices) { const { start, deleteCount, rawResources } = groupSlice; const resources = rawResources.map(rawResource => { - const { handle, sourceUri, icon, tooltip, strikeThrough, faded, contextValue, command } = rawResource; - const iconClass = this.toIconClass(icon, sharedStyle, disposables); + const { handle, sourceUri, icons, tooltip, strikeThrough, faded, contextValue, command } = rawResource; + const icon = ThemeIcon.isThemeIcon(icons[0]) ? icons[0] : vscodeURI.revive(icons[0]); + const iconDark = ThemeIcon.isThemeIcon(icons[1]) ? icons[1] : vscodeURI.revive(icons[1]) || icon; // eslint-disable-next-line @typescript-eslint/no-explicit-any const colorVariable = (rawResource as any).colorId && this.colors.toCssVariableName((rawResource as any).colorId); const decorations = { - icon: iconClass, + icon: this.toIconClass(icon), + iconDark: this.toIconClass(iconDark), tooltip, strikeThrough, // TODO remove the letter and colorId fields when the FileDecorationProvider is applied, see https://github.com/eclipse-theia/theia/pull/8911 @@ -258,20 +262,17 @@ export class PluginScmProvider implements ScmProvider { this.onDidChangeResourcesEmitter.fire(); } - private toReferencedIcon(icon: string, style: PluginSharedStyle, disposables: DisposableCollection): string { - if (icon.includes('codicon')) { - return icon; + private toIconClass(icon: vscodeURI | ThemeIcon | undefined): string { + if (!icon) { + return ''; } - const reference = style.toIconClass(icon); - disposables.push(reference); - return reference.object.iconClass; - } - - private toIconClass(icons: IconUrl, style: PluginSharedStyle, disposables: DisposableCollection): string | { light: string, dark: string } { - if (typeof icons === 'object') { - return { light: this.toReferencedIcon(icons.light, style, disposables), dark: this.toReferencedIcon(icons.dark, style, disposables) }; + if (ThemeIcon.isThemeIcon(icon)) { + return ThemeIcon.asClassName(icon); } - return this.toReferencedIcon(icons, style, disposables); + console.log(icon.path); + const reference = this.sharedStyle.toIconClass(icon.path); + this.disposables.push(reference); + return reference.object.iconClass; } unregisterGroup(handle: number): void { @@ -316,7 +317,7 @@ export class ScmMainImpl implements ScmMain { } async $registerSourceControl(handle: number, id: string, label: string, rootUri: UriComponents | undefined): Promise { - const provider = new PluginScmProvider(this.proxy, this.colors, handle, id, label, rootUri ? vscodeURI.revive(rootUri) : undefined); + const provider = new PluginScmProvider(this.proxy, this.colors, this.sharedStyle, handle, id, label, rootUri ? vscodeURI.revive(rootUri) : undefined, this.disposables); const repository = this.scmService.registerScmProvider(provider, { input: { validator: async value => { @@ -382,7 +383,7 @@ export class ScmMainImpl implements ScmMain { const provider = repository.provider as PluginScmProvider; provider.registerGroups(groups); - provider.spliceGroupResourceStates(splices, this.sharedStyle, this.disposables); + provider.spliceGroupResourceStates(splices); } $updateGroup(sourceControlHandle: number, groupHandle: number, features: SourceControlGroupFeatures): void { @@ -415,7 +416,7 @@ export class ScmMainImpl implements ScmMain { } const provider = repository.provider as PluginScmProvider; - provider.spliceGroupResourceStates(splices, this.sharedStyle, this.disposables); + provider.spliceGroupResourceStates(splices); } $unregisterGroup(sourceControlHandle: number, handle: number): void { diff --git a/packages/plugin-ext/src/plugin/plugin-icon-path.ts b/packages/plugin-ext/src/plugin/plugin-icon-path.ts index bebd184d345e0..0e61a5f7f485f 100644 --- a/packages/plugin-ext/src/plugin/plugin-icon-path.ts +++ b/packages/plugin-ext/src/plugin/plugin-icon-path.ts @@ -20,9 +20,9 @@ import { IconUrl, PluginPackage } from '../common/plugin-protocol'; import { Plugin } from '../common/plugin-api-rpc'; import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; -export type PluginIconPath = string | URI | ThemeIcon | { // TODO: check if light-dark separation is necessary - light: string | URI | ThemeIcon, - dark: string | URI | ThemeIcon +export type PluginIconPath = string | URI | { + light: string | URI, + dark: string | URI }; export namespace PluginIconPath { export function toUrl(iconPath: PluginIconPath | undefined, plugin: Plugin): IconUrl | undefined { @@ -39,9 +39,6 @@ export namespace PluginIconPath { } export function asString(arg: string | URI | ThemeIcon, plugin: Plugin): string { arg = arg instanceof URI && arg.scheme === 'file' ? arg.fsPath : arg; - if (ThemeIcon.isThemeIcon(arg)) { - return ThemeIcon.asClassName(arg); - } if (typeof arg !== 'string') { return arg.toString(true); } diff --git a/packages/plugin-ext/src/plugin/scm.ts b/packages/plugin-ext/src/plugin/scm.ts index 890ae662abe47..d5b5079e49c52 100644 --- a/packages/plugin-ext/src/plugin/scm.ts +++ b/packages/plugin-ext/src/plugin/scm.ts @@ -23,7 +23,6 @@ import * as theia from '@theia/plugin'; import { Emitter, Event } from '@theia/core/lib/common/event'; import { - IconUrl, Plugin, PLUGIN_RPC_CONTEXT, ScmExt, ScmMain, ScmRawResource, ScmRawResourceGroup, @@ -36,23 +35,23 @@ import { Splice } from '../common/arrays'; import { UriComponents } from '../common/uri-components'; import { Command } from '../common/plugin-api-rpc-model'; import { RPCProtocol } from '../common/rpc-protocol'; -import { URI } from './types-impl'; +import { URI, ThemeIcon } from './types-impl'; import { ScmCommandArg } from '../common/plugin-api-rpc'; import { sep } from '@theia/core/lib/common/paths'; -import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; +// import { ThemeIcon } from '@theia/monaco-editor-core/esm/vs/platform/theme/common/themeService'; import { PluginIconPath } from './plugin-icon-path'; type ProviderHandle = number; type GroupHandle = number; type ResourceStateHandle = number; -function getIconResource(decorations?: theia.SourceControlResourceThemableDecorations): theia.Uri | ThemeIcon | undefined { +function getIconResource(decorations?: theia.SourceControlResourceThemableDecorations): UriComponents | ThemeIcon | undefined { if (!decorations || !decorations.iconPath) { return undefined; } else if (typeof decorations.iconPath === 'string') { return URI.file(decorations.iconPath); } else if (URI.isUri(decorations.iconPath)) { return decorations.iconPath; - } else if (ThemeIcon.isThemeIcon(decorations.iconPath)) { + } else if (ThemeIcon.is(decorations.iconPath)) { return decorations.iconPath; } else { console.warn('Unexpected Source Control Resource Themable Decoration'); @@ -119,8 +118,8 @@ function compareResourceThemableDecorations(a: theia.SourceControlResourceThemab return 1; } - const aPath = typeof a.iconPath === 'string' ? a.iconPath : URI.isUri(a.iconPath) ? a.iconPath.fsPath : (a.iconPath as theia.ThemeIcon).id; - const bPath = typeof b.iconPath === 'string' ? b.iconPath : URI.isUri(b.iconPath) ? b.iconPath.fsPath : (b.iconPath as theia.ThemeIcon).id; + const aPath = typeof a.iconPath === 'string' ? a.iconPath : URI.isUri(a.iconPath) ? a.iconPath.fsPath : (a.iconPath as ThemeIcon).id; + const bPath = typeof b.iconPath === 'string' ? b.iconPath : URI.isUri(b.iconPath) ? b.iconPath.fsPath : (b.iconPath as ThemeIcon).id; return comparePaths(aPath, bPath); } @@ -452,7 +451,11 @@ class ScmResourceGroupImpl implements theia.SourceControlResourceGroup { this.resourceStatesMap.set(handle, r); const sourceUri = r.resourceUri; - const icon = this.getIcon(r.decorations); + + const icon = getIconResource(r.decorations); + const lightIcon = r.decorations && getIconResource(r.decorations.light) || icon; + const darkIcon = r.decorations && getIconResource(r.decorations.dark) || icon; + const icons = [this.getThemableIcon(lightIcon), this.getThemableIcon(darkIcon)]; let command: Command | undefined; if (r.command) { @@ -473,7 +476,7 @@ class ScmResourceGroupImpl implements theia.SourceControlResourceGroup { // TODO remove the letter and colorId fields when the FileDecorationProvider is applied, see https://github.com/eclipse-theia/theia/pull/8911 const rawResource = { // eslint-disable-next-line @typescript-eslint/no-explicit-any - handle, sourceUri, letter: (r as any).letter, colorId: (r as any).color.id, icon, + handle, sourceUri, letter: (r as any).letter, colorId: (r as any).color.id, icons, tooltip, strikeThrough, faded, contextValue, command } as ScmRawResource; @@ -509,12 +512,20 @@ class ScmResourceGroupImpl implements theia.SourceControlResourceGroup { return rawResourceSplices; } - private getIcon(decorations: theia.SourceControlResourceDecorations | undefined): IconUrl | undefined { - const iconUri = getIconResource(decorations); - const lightIconUri = decorations && getIconResource(decorations.light) || iconUri; - const darkIconUri = decorations && getIconResource(decorations.dark) || iconUri; - const iconPair = { light: lightIconUri ? lightIconUri : '', dark: darkIconUri ? darkIconUri : '' }; - return PluginIconPath.toUrl(iconUri ? iconUri : iconPair, this.plugin); + private getThemableIcon(icon: UriComponents | ThemeIcon | undefined): UriComponents | ThemeIcon | undefined { + if (!icon) { + return undefined; + } else if (ThemeIcon.is(icon)) { + return icon; + } + const uri: UriComponents = { + scheme: '', + authority: '', + path: PluginIconPath.asString(URI.revive(icon), this.plugin), + query: '', + fragment: '', + }; + return uri; } dispose(): void { diff --git a/packages/scm/src/browser/scm-provider.ts b/packages/scm/src/browser/scm-provider.ts index 1db3259e731de..7e0b87999ddd6 100644 --- a/packages/scm/src/browser/scm-provider.ts +++ b/packages/scm/src/browser/scm-provider.ts @@ -58,7 +58,8 @@ export interface ScmResource { } export interface ScmResourceDecorations { - icon?: string | { light: string, dark: string }; + icon?: string; + iconDark?: string; tooltip?: string; source?: string; letter?: string; diff --git a/packages/scm/src/browser/scm-tree-widget.tsx b/packages/scm/src/browser/scm-tree-widget.tsx index de5e100564c9f..45400f34ede7a 100644 --- a/packages/scm/src/browser/scm-tree-widget.tsx +++ b/packages/scm/src/browser/scm-tree-widget.tsx @@ -545,10 +545,8 @@ export class ScmResourceComponent extends ScmElement const { model, treeNode, colors, parentPath, sourceUri, decoration, labelProvider, commandExecutor, menus, contextKeys, caption, isLightTheme } = this.props; const resourceUri = new URI(sourceUri); - const decorationIcon = treeNode.decorations?.icon; - const themedIcon = typeof decorationIcon === 'string' - ? decorationIcon - : isLightTheme ? decorationIcon?.light : decorationIcon?.dark; + const decorationIcon = treeNode.decorations; + const themedIcon = isLightTheme ? decorationIcon?.icon : decorationIcon?.iconDark; const classNames: string[] = themedIcon ? ['decoration-icon', themedIcon] : ['status']; const icon = labelProvider.getIcon(resourceUri);