提交 75576e3c 编写于 作者: J Joao Moreno

💥 scm id -> contextKey

上级 d4efff6c
......@@ -794,7 +794,7 @@ export class CommandCenter {
if (uri.scheme === 'git-resource') {
const {resourceGroupId} = JSON.parse(uri.query) as { resourceGroupId: string, sourceUri: string };
const [resourceGroup] = this.model.resources.filter(g => g.id === resourceGroupId);
const [resourceGroup] = this.model.resources.filter(g => g.contextKey === resourceGroupId);
if (!resourceGroup) {
return;
......
......@@ -150,9 +150,9 @@ export class Resource implements SCMResource {
export class ResourceGroup implements SCMResourceGroup {
@memoize
get uri(): Uri { return Uri.parse(`git-resource-group:${this.id}`); }
get uri(): Uri { return Uri.parse(`git-resource-group:${this.contextKey}`); }
get id(): string { return this._id; }
get contextKey(): string { return this._id; }
get label(): string { return this._label; }
get resources(): Resource[] { return this._resources; }
......
......@@ -14,7 +14,7 @@ export class GitSCMProvider implements SCMProvider {
private disposables: Disposable[] = [];
get id(): string { return 'git'; }
get contextKey(): string { return 'git'; }
get resources(): SCMResourceGroup[] { return this.model.resources; }
get onDidChange(): Event<SCMResourceGroup[]> {
......
......@@ -657,15 +657,15 @@ declare module 'vscode' {
readonly uri: Uri;
/**
* The identifier of the SCM resource group, which will be used to populate
* the value of the `scmResourceGroup` context key.
* The UI label of the SCM resource group.
*/
readonly id: string;
readonly label: string;
/**
* The UI label of the SCM resource group.
* The context key of the SCM resource group, which will be used to populate
* the value of the `scmResourceGroup` context key.
*/
readonly label: string;
readonly contextKey?: string;
/**
* The collection of [SCM resources](#SCMResource) within the SCM resource group.
......@@ -680,15 +680,15 @@ declare module 'vscode' {
export interface SCMProvider {
/**
* The identifier of the SCM provider, which will be used to populate
* the value of the `scmProvider` context key.
* A human-readable label for the name of the SCM Provider.
*/
readonly id: string;
readonly label: string;
/**
* A human-readable label for the name of the SCM Provider.
* The context key of the SCM provider, which will be used to populate
* the value of the `scmProvider` context key.
*/
readonly label: string;
readonly contextKey?: string;
/**
* The list of SCM resource groups.
......
......@@ -252,6 +252,7 @@ export abstract class MainProcessExtensionServiceShape {
export interface SCMProviderFeatures {
label: string;
contextKey?: string;
supportsOpen: boolean;
supportsOriginalResource: boolean;
}
......@@ -265,15 +266,15 @@ export type SCMRawResource = [
export type SCMRawResourceGroup = [
string /*uri*/,
string /*id*/,
string | undefined /*context key*/,
string /*label*/,
SCMRawResource[]
];
export abstract class MainThreadSCMShape {
$register(id: string, features: SCMProviderFeatures): void { throw ni(); }
$unregister(id: string): void { throw ni(); }
$onChange(id: string, resources: SCMRawResourceGroup[], count: number | undefined, state: string | undefined): void { throw ni(); }
$register(handle: number, features: SCMProviderFeatures): void { throw ni(); }
$unregister(handle: number): void { throw ni(); }
$onChange(handle: number, resources: SCMRawResourceGroup[], count: number | undefined, state: string | undefined): void { throw ni(); }
$setInputBoxValue(value: string): void { throw ni(); }
}
......@@ -417,8 +418,8 @@ export abstract class ExtHostTerminalServiceShape {
}
export abstract class ExtHostSCMShape {
$open(id: string, uri: string): TPromise<void> { throw ni(); }
$getOriginalResource(id: string, uri: URI): TPromise<URI> { throw ni(); }
$open(handle: number, uri: string): TPromise<void> { throw ni(); }
$getOriginalResource(handle: number, uri: URI): TPromise<URI> { throw ni(); }
$onInputBoxValueChange(value: string): TPromise<void> { throw ni(); }
$onInputBoxAcceptChanges(): TPromise<void> { throw ni(); }
}
......
......@@ -24,12 +24,6 @@ function getIconPath(decorations: vscode.SCMResourceThemableDecorations) {
return undefined;
}
export interface Cache {
[providerId: string]: {
[resourceUri: string]: vscode.SCMResource;
};
}
class ExtHostSCMInputBox {
private _value: string = '';
......@@ -73,10 +67,15 @@ class ExtHostSCMInputBox {
}
}
type ProviderHandle = number;
export class ExtHostSCM {
private static _handlePool: number = 0;
private _proxy: MainThreadSCMShape;
private _providers: { [id: string]: vscode.SCMProvider; } = Object.create(null);
private _providers: Map<ProviderHandle, vscode.SCMProvider> = new Map<ProviderHandle, vscode.SCMProvider>();
private _cache: Map<ProviderHandle, Map<string, vscode.SCMResource>> = new Map<ProviderHandle, Map<string, vscode.SCMResource>>();
private _onDidChangeActiveProvider = new Emitter<vscode.SCMProvider>();
get onDidChangeActiveProvider(): Event<vscode.SCMProvider> { return this._onDidChangeActiveProvider.event; }
......@@ -87,37 +86,32 @@ export class ExtHostSCM {
private _inputBox: ExtHostSCMInputBox;
get inputBox(): vscode.SCMInputBox { return this._inputBox; }
private cache: Cache = Object.create(null);
constructor(threadService: IThreadService) {
this._proxy = threadService.get(MainContext.MainThreadSCM);
this._inputBox = new ExtHostSCMInputBox(this._proxy);
}
registerSCMProvider(provider: vscode.SCMProvider): Disposable {
const providerId = provider.id;
const handle = ExtHostSCM._handlePool++;
if (this._providers[providerId]) {
throw new Error(`Provider ${providerId} already registered`);
}
this._providers.set(handle, provider);
// TODO@joao: should pluck all the things out of the provider
this._providers[providerId] = provider;
this._proxy.$register(providerId, {
this._proxy.$register(handle, {
label: provider.label,
contextKey: provider.contextKey,
supportsOpen: !!provider.open,
supportsOriginalResource: !!provider.getOriginalResource
});
const onDidChange = debounceEvent(provider.onDidChange, (l, e) => e, 100);
const onDidChangeListener = onDidChange(resourceGroups => {
this.cache[providerId] = Object.create(null);
const cache = new Map<string, vscode.SCMResource>();
this._cache.set(handle, cache);
const rawResourceGroups = resourceGroups.map(g => {
const rawResources = g.resources.map(r => {
const uri = r.uri.toString();
this.cache[providerId][uri] = r;
cache.set(uri, r);
const sourceUri = r.sourceUri.toString();
const iconPath = getIconPath(r.decorations);
......@@ -138,27 +132,33 @@ export class ExtHostSCM {
return [uri, sourceUri, icons, strikeThrough] as SCMRawResource;
});
return [g.uri.toString(), g.id, g.label, rawResources] as SCMRawResourceGroup;
return [g.uri.toString(), g.contextKey, g.label, rawResources] as SCMRawResourceGroup;
});
this._proxy.$onChange(providerId, rawResourceGroups, provider.count, provider.state);
this._proxy.$onChange(handle, rawResourceGroups, provider.count, provider.state);
});
return new Disposable(() => {
onDidChangeListener.dispose();
delete this._providers[providerId];
this._proxy.$unregister(providerId);
this._providers.delete(handle);
this._proxy.$unregister(handle);
});
}
$open(providerId: string, uri: string): TPromise<void> {
const provider = this._providers[providerId];
$open(handle: number, uri: string): TPromise<void> {
const provider = this._providers.get(handle);
if (!provider) {
return TPromise.as(null);
}
const resource = this.cache[providerId][uri];
const cache = this._cache.get(handle);
if (!cache) {
return TPromise.as(null);
}
const resource = cache.get(uri);
if (!resource) {
return TPromise.as(null);
......@@ -167,8 +167,8 @@ export class ExtHostSCM {
return asWinJsPromise(token => provider.open(resource, token));
}
$getOriginalResource(id: string, uri: URI): TPromise<URI> {
const provider = this._providers[id];
$getOriginalResource(handle: number, uri: URI): TPromise<URI> {
const provider = this._providers.get(handle);
if (!provider) {
return TPromise.as(null);
......
......@@ -24,8 +24,9 @@ class MainThreadSCMProvider implements ISCMProvider {
private disposables: IDisposable[] = [];
get id(): string { return this._id; }
get handle(): number { return this._handle; }
get label(): string { return this.features.label; }
get contextKey(): string { return this.features.contextKey; }
private _count: number | undefined = undefined;
get count(): number | undefined { return this._count; }
......@@ -34,7 +35,7 @@ class MainThreadSCMProvider implements ISCMProvider {
get state(): string | undefined { return this._state; }
constructor(
private _id: string,
private _handle: number,
private proxy: ExtHostSCMShape,
private features: SCMProviderFeatures,
@ISCMService scmService: ISCMService,
......@@ -49,7 +50,7 @@ class MainThreadSCMProvider implements ISCMProvider {
return TPromise.as(null);
}
return this.proxy.$open(this.id, resource.uri.toString());
return this.proxy.$open(this.handle, resource.uri.toString());
}
getOriginalResource(uri: URI): TPromise<URI> {
......@@ -57,7 +58,7 @@ class MainThreadSCMProvider implements ISCMProvider {
return TPromise.as(null);
}
return this.proxy.$getOriginalResource(this.id, uri);
return this.proxy.$getOriginalResource(this.handle, uri);
}
private onDidChangeProvider(provider: ISCMProvider): void {
......@@ -68,29 +69,29 @@ class MainThreadSCMProvider implements ISCMProvider {
$onChange(rawResourceGroups: SCMRawResourceGroup[], count: number | undefined, state: string | undefined): void {
this._resources = rawResourceGroups.map(rawGroup => {
const [uri, id, label, rawResources] = rawGroup;
const [uri, contextKey, label, rawResources] = rawGroup;
const resources: ISCMResource[] = [];
const group: ISCMResourceGroup = { uri: URI.parse(uri), contextKey, label, resources };
const resources = rawResources.map(rawResource => {
rawResources.forEach(rawResource => {
const [uri, sourceUri, icons, strikeThrough] = rawResource;
const icon = icons[0];
const iconDark = icons[1] || icon;
const decorations = {
icon: icon && URI.parse(icon),
iconDark: iconDark && URI.parse(iconDark),
strikeThrough
};
return {
resourceGroupId: id,
resources.push({
resourceGroup: group,
uri: URI.parse(uri),
sourceUri: URI.parse(sourceUri),
decorations
};
});
});
return { uri: URI.parse(uri), id, label, resources };
return group;
});
this._count = count;
......@@ -107,7 +108,7 @@ class MainThreadSCMProvider implements ISCMProvider {
export class MainThreadSCM extends MainThreadSCMShape {
private proxy: ExtHostSCMShape;
private providers: { [id: string]: MainThreadSCMProvider; } = Object.create(null);
private providers: { [handle: number]: MainThreadSCMProvider; } = Object.create(null);
private inputBoxListeners: IDisposable[] = [];
constructor(
......@@ -122,23 +123,23 @@ export class MainThreadSCM extends MainThreadSCMShape {
this.scmService.input.onDidAccept(this.proxy.$onInputBoxAcceptChanges, this.proxy, this.inputBoxListeners);
}
$register(id: string, features: SCMProviderFeatures): void {
this.providers[id] = this.instantiationService.createInstance(MainThreadSCMProvider, id, this.proxy, features);
$register(handle: number, features: SCMProviderFeatures): void {
this.providers[handle] = this.instantiationService.createInstance(MainThreadSCMProvider, handle, this.proxy, features);
}
$unregister(id: string): void {
const provider = this.providers[id];
$unregister(handle: number): void {
const provider = this.providers[handle];
if (!provider) {
return;
}
provider.dispose();
delete this.providers[id];
delete this.providers[handle];
}
$onChange(id: string, rawResourceGroups: SCMRawResourceGroup[], count: number | undefined, state: string | undefined): void {
const provider = this.providers[id];
$onChange(handle: number, rawResourceGroups: SCMRawResourceGroup[], count: number | undefined, state: string | undefined): void {
const provider = this.providers[handle];
if (!provider) {
return;
......
......@@ -50,7 +50,6 @@ export class SwitchProvider extends Action {
run(): TPromise<any> {
const picks = this.scmService.providers.map(provider => ({
id: provider.id,
label: provider.label,
run: () => this.scmService.activeProvider = provider
}));
......
......@@ -13,13 +13,12 @@ import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IAction } from 'vs/base/common/actions';
import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { ISCMService, ISCMProvider, ISCMResource, ISCMResourceGroup } from 'vs/workbench/services/scm/common/scm';
import { getSCMResourceGroupId } from './scmUtil';
import { getSCMResourceContextKey } from './scmUtil';
export class SCMMenus implements IDisposable {
private disposables: IDisposable[] = [];
private activeProviderId: string | undefined;
private titleDisposable: IDisposable = EmptyDisposable;
private titleActions: IAction[] = [];
private titleSecondaryActions: IAction[] = [];
......@@ -42,8 +41,6 @@ export class SCMMenus implements IDisposable {
this.titleDisposable = EmptyDisposable;
}
this.activeProviderId = activeProvider ? activeProvider.id : undefined;
if (!activeProvider) {
return;
}
......@@ -99,7 +96,7 @@ export class SCMMenus implements IDisposable {
}
const contextKeyService = this.contextKeyService.createScoped();
contextKeyService.createKey('scmResourceGroup', getSCMResourceGroupId(resource));
contextKeyService.createKey('scmResourceGroup', getSCMResourceContextKey(resource));
const menu = this.menuService.createMenu(menuId, contextKeyService);
const primary = [];
......
......@@ -11,6 +11,6 @@ export function isSCMResource(element: ISCMResourceGroup | ISCMResource): elemen
return !!(element as ISCMResource).sourceUri;
}
export function getSCMResourceGroupId(resource: ISCMResourceGroup | ISCMResource): string {
return isSCMResource(resource) ? resource.resourceGroupId : resource.id;
export function getSCMResourceContextKey(resource: ISCMResourceGroup | ISCMResource): string {
return isSCMResource(resource) ? resource.resourceGroup.contextKey : resource.contextKey;
}
\ No newline at end of file
......@@ -43,14 +43,6 @@ import URI from 'vs/base/common/uri';
import { isSCMResource } from './scmUtil';
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
function getElementId(element: ISCMResourceGroup | ISCMResource) {
if (isSCMResource(element)) {
return `${element.resourceGroupId}:${element.sourceUri.toString()}`;
} else {
return `${element.id}`;
}
}
interface SearchInputEvent extends Event {
target: HTMLInputElement;
immediate?: boolean;
......@@ -196,7 +188,6 @@ export class SCMViewlet extends Viewlet {
private listContainer: HTMLElement;
private list: List<ISCMResourceGroup | ISCMResource>;
private menus: SCMMenus;
private activeProviderId: string | undefined;
private providerChangeDisposable: IDisposable = EmptyDisposable;
private disposables: IDisposable[] = [];
......@@ -223,7 +214,6 @@ export class SCMViewlet extends Viewlet {
private setActiveProvider(activeProvider: ISCMProvider | undefined): void {
this.providerChangeDisposable.dispose();
this.activeProviderId = activeProvider ? activeProvider.id : undefined;
if (activeProvider) {
this.providerChangeDisposable = activeProvider.onDidChange(this.update, this);
......@@ -270,7 +260,7 @@ export class SCMViewlet extends Viewlet {
];
this.list = new List(this.listContainer, delegate, renderers, {
identityProvider: e => getElementId(e),
identityProvider: e => e.uri.toString(),
keyboardSupport: false
});
......
......@@ -24,7 +24,7 @@ export interface ISCMResourceDecorations {
}
export interface ISCMResource {
readonly resourceGroupId: string;
readonly resourceGroup: ISCMResourceGroup;
readonly uri: URI;
readonly sourceUri: URI;
readonly decorations: ISCMResourceDecorations;
......@@ -32,14 +32,14 @@ export interface ISCMResource {
export interface ISCMResourceGroup {
readonly uri: URI;
readonly id: string;
readonly label: string;
readonly contextKey?: string;
readonly resources: ISCMResource[];
}
export interface ISCMProvider extends IDisposable {
readonly id: string;
readonly label: string;
readonly contextKey?: string;
readonly resources: ISCMResourceGroup[];
readonly onDidChange: Event<ISCMResourceGroup[]>;
readonly count?: number;
......
......@@ -59,7 +59,7 @@ export class SCMService implements ISCMService {
}
this._activeProvider = provider;
this.activeProviderContextKey.set(provider ? provider.id : void 0);
this.activeProviderContextKey.set(provider ? provider.contextKey : void 0);
this.providerChangeDisposable.dispose();
this.providerChangeDisposable = provider.onDidChange(this.onDidChangeProviderState, this);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册