提交 e3b15fca 编写于 作者: J Joao Moreno

wip: register multiple source control providers

上级 eb04eaa1
...@@ -12,8 +12,8 @@ import { findGit, Git, IGit } from './git'; ...@@ -12,8 +12,8 @@ import { findGit, Git, IGit } from './git';
import { Repository } from './repository'; import { Repository } from './repository';
import { Model } from './model'; import { Model } from './model';
import { CommandCenter } from './commands'; import { CommandCenter } from './commands';
import { GitContentProvider } from './contentProvider'; // import { GitContentProvider } from './contentProvider';
import { AutoFetcher } from './autofetch'; // import { AutoFetcher } from './autofetch';
import { Askpass } from './askpass'; import { Askpass } from './askpass';
import { toDisposable } from './util'; import { toDisposable } from './util';
import TelemetryReporter from 'vscode-extension-telemetry'; import TelemetryReporter from 'vscode-extension-telemetry';
...@@ -28,24 +28,26 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi ...@@ -28,24 +28,26 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
const config = workspace.getConfiguration('git'); const config = workspace.getConfiguration('git');
const enabled = config.get<boolean>('enabled') === true; const enabled = config.get<boolean>('enabled') === true;
const workspaceRootPath = workspace.rootPath;
const pathHint = workspace.getConfiguration('git').get<string>('path'); const pathHint = workspace.getConfiguration('git').get<string>('path');
const info = await findGit(pathHint); const info = await findGit(pathHint);
const askpass = new Askpass(); const askpass = new Askpass();
const env = await askpass.getEnv(); const env = await askpass.getEnv();
const git = new Git({ gitPath: info.path, version: info.version, env }); const git = new Git({ gitPath: info.path, version: info.version, env });
const model = new Model(); const model = new Model();
disposables.push(model);
if (!workspaceRootPath || !enabled) { if (!enabled) {
const commandCenter = new CommandCenter(git, model, outputChannel, telemetryReporter); const commandCenter = new CommandCenter(git, model, outputChannel, telemetryReporter);
disposables.push(commandCenter); disposables.push(commandCenter);
return; return;
} }
const workspaceRoot = Uri.file(workspaceRootPath); for (const folder of workspace.workspaceFolders || []) {
const repository = new Repository(git, workspaceRoot); const repositoryRoot = await git.getRepositoryRoot(folder.uri.fsPath);
model.register(workspaceRoot, repository); const repository = new Repository(git.open(repositoryRoot));
model.register(repository);
}
outputChannel.appendLine(localize('using git', "Using git {0} from {1}", info.version, info.path)); outputChannel.appendLine(localize('using git', "Using git {0} from {1}", info.version, info.path));
...@@ -54,14 +56,14 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi ...@@ -54,14 +56,14 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput))); disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
const commandCenter = new CommandCenter(git, model, outputChannel, telemetryReporter); const commandCenter = new CommandCenter(git, model, outputChannel, telemetryReporter);
const contentProvider = new GitContentProvider(repository); // const contentProvider = new GitContentProvider(repository);
const autoFetcher = new AutoFetcher(repository); // const autoFetcher = new AutoFetcher(repository);
disposables.push( disposables.push(
commandCenter, commandCenter,
contentProvider, // contentProvider,
autoFetcher, // autoFetcher,
repository // repository
); );
await checkGitVersion(info); await checkGitVersion(info);
......
...@@ -15,28 +15,30 @@ import * as nls from 'vscode-nls'; ...@@ -15,28 +15,30 @@ import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle(); const localize = nls.loadMessageBundle();
class RepositoryPick implements QuickPickItem { class RepositoryPick implements QuickPickItem {
@memoize get label(): string { return path.basename(this.repositoryRoot.fsPath); } @memoize get label(): string { return path.basename(this.repositoryRoot); }
@memoize get description(): string { return path.dirname(this.repositoryRoot.fsPath); } @memoize get description(): string { return path.dirname(this.repositoryRoot); }
constructor(protected repositoryRoot: Uri, public readonly repository: Repository) { } constructor(protected repositoryRoot: string, public readonly repository: Repository) { }
} }
export class Model { export class Model {
private repositories: Map<Uri, Repository> = new Map<Uri, Repository>(); private repositories: Map<string, Repository> = new Map<string, Repository>();
register(uri: Uri, repository: Repository): Disposable { register(repository: Repository): Disposable {
if (this.repositories.has(uri)) { const root = repository.root;
if (this.repositories.has(root)) {
// TODO@Joao: what should happen? // TODO@Joao: what should happen?
throw new Error('Cant register repository with the same URI'); throw new Error('Cant register repository with the same URI');
} }
this.repositories.set(uri, repository); this.repositories.set(root, repository);
const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === State.NotAGitRepository); const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === State.NotAGitRepository);
const listener = onDidDisappearRepository(() => disposable.dispose()); const listener = onDidDisappearRepository(() => disposable.dispose());
const disposable = toDisposable(once(() => { const disposable = toDisposable(once(() => {
this.repositories.delete(uri); this.repositories.delete(root);
listener.dispose(); listener.dispose();
})); }));
...@@ -72,8 +74,7 @@ export class Model { ...@@ -72,8 +74,7 @@ export class Model {
const resourcePath = hint.fsPath; const resourcePath = hint.fsPath;
for (let [root, repository] of this.repositories) { for (let [root, repository] of this.repositories) {
const repositoryRootPath = root.fsPath; const relativePath = path.relative(root, resourcePath);
const relativePath = path.relative(repositoryRootPath, resourcePath);
if (!/^\./.test(relativePath)) { if (!/^\./.test(relativePath)) {
return repository; return repository;
...@@ -95,4 +96,36 @@ export class Model { ...@@ -95,4 +96,36 @@ export class Model {
return undefined; return undefined;
} }
// private async assertIdleState(): Promise<void> {
// if (this.state === State.Idle) {
// return;
// }
// const disposables: Disposable[] = [];
// const repositoryRoot = await this.git.getRepositoryRoot(this.workspaceRoot.fsPath);
// this.repository = this.git.open(repositoryRoot);
// const onGitChange = filterEvent(this.onWorkspaceChange, uri => /\/\.git\//.test(uri.path));
// const onRelevantGitChange = filterEvent(onGitChange, uri => !/\/\.git\/index\.lock$/.test(uri.path));
// onRelevantGitChange(this.onFSChange, this, disposables);
// onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, disposables);
// const onNonGitChange = filterEvent(this.onWorkspaceChange, uri => !/\/\.git\//.test(uri.path));
// onNonGitChange(this.onFSChange, this, disposables);
// this.repositoryDisposable = combinedDisposable(disposables);
// this.isRepositoryHuge = false;
// this.didWarnAboutLimit = false;
// this.state = State.Idle;
// }
dispose(): void {
for (let [, repository] of this.repositories) {
repository.dispose();
}
this.repositories.clear();
}
} }
\ No newline at end of file
...@@ -141,8 +141,10 @@ export class Resource implements SourceControlResourceState { ...@@ -141,8 +141,10 @@ export class Resource implements SourceControlResourceState {
@memoize @memoize
private get faded(): boolean { private get faded(): boolean {
const workspaceRootPath = this.workspaceRoot.fsPath; // TODO@joao
return this.resourceUri.fsPath.substr(0, workspaceRootPath.length) !== workspaceRootPath; return false;
// const workspaceRootPath = this.workspaceRoot.fsPath;
// return this.resourceUri.fsPath.substr(0, workspaceRootPath.length) !== workspaceRootPath;
} }
get decorations(): SourceControlResourceDecorations { get decorations(): SourceControlResourceDecorations {
...@@ -155,7 +157,6 @@ export class Resource implements SourceControlResourceState { ...@@ -155,7 +157,6 @@ export class Resource implements SourceControlResourceState {
} }
constructor( constructor(
private workspaceRoot: Uri,
private _resourceGroupType: ResourceGroupType, private _resourceGroupType: ResourceGroupType,
private _resourceUri: Uri, private _resourceUri: Uri,
private _type: Status, private _type: Status,
...@@ -269,6 +270,8 @@ export interface GitResourceGroup extends SourceControlResourceGroup { ...@@ -269,6 +270,8 @@ export interface GitResourceGroup extends SourceControlResourceGroup {
export class Repository implements Disposable { export class Repository implements Disposable {
private static handle = 0;
private _onDidChangeRepository = new EventEmitter<Uri>(); private _onDidChangeRepository = new EventEmitter<Uri>();
readonly onDidChangeRepository: Event<Uri> = this._onDidChangeRepository.event; readonly onDidChangeRepository: Event<Uri> = this._onDidChangeRepository.event;
...@@ -321,8 +324,6 @@ export class Repository implements Disposable { ...@@ -321,8 +324,6 @@ export class Repository implements Disposable {
private _operations = new OperationsImpl(); private _operations = new OperationsImpl();
get operations(): Operations { return this._operations; } get operations(): Operations { return this._operations; }
private repository: BaseRepository;
private _state = State.Uninitialized; private _state = State.Uninitialized;
get state(): State { return this._state; } get state(): State { return this._state; }
set state(state: State) { set state(state: State) {
...@@ -339,22 +340,27 @@ export class Repository implements Disposable { ...@@ -339,22 +340,27 @@ export class Repository implements Disposable {
commands.executeCommand('setContext', 'gitState', ''); commands.executeCommand('setContext', 'gitState', '');
} }
private onWorkspaceChange: Event<Uri>; get root(): string {
return this.repository.root;
}
private isRepositoryHuge = false; private isRepositoryHuge = false;
private didWarnAboutLimit = false; private didWarnAboutLimit = false;
private repositoryDisposable: Disposable = EmptyDisposable;
private disposables: Disposable[] = []; private disposables: Disposable[] = [];
constructor( constructor(
private _git: Git, private readonly repository: BaseRepository
private workspaceRoot: Uri
) { ) {
const fsWatcher = workspace.createFileSystemWatcher('**'); const fsWatcher = workspace.createFileSystemWatcher('**');
this.onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
this.disposables.push(fsWatcher); this.disposables.push(fsWatcher);
const label = `Git - ${path.basename(workspaceRoot.fsPath)}`; const onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
this._sourceControl = scm.createSourceControl('git', label); onWorkspaceChange(this.onFSChange, this, this.disposables);
const id = `git${Repository.handle++}`;
const label = `Git - ${path.basename(repository.root)}`;
this._sourceControl = scm.createSourceControl(id, label);
this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit") }; this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit") };
this._sourceControl.quickDiffProvider = this; this._sourceControl.quickDiffProvider = this;
this.disposables.push(this._sourceControl); this.disposables.push(this._sourceControl);
...@@ -391,15 +397,15 @@ export class Repository implements Disposable { ...@@ -391,15 +397,15 @@ export class Repository implements Disposable {
} }
} }
@throttle // @throttle
async init(): Promise<void> { // async init(): Promise<void> {
if (this.state !== State.NotAGitRepository) { // if (this.state !== State.NotAGitRepository) {
return; // return;
} // }
await this._git.init(this.workspaceRoot.fsPath); // await this.git.init(this.workspaceRoot.fsPath);
await this.status(); // await this.status();
} // }
@throttle @throttle
async status(): Promise<void> { async status(): Promise<void> {
...@@ -594,13 +600,15 @@ export class Repository implements Disposable { ...@@ -594,13 +600,15 @@ export class Repository implements Disposable {
} }
private async run<T>(operation: Operation, runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> { private async run<T>(operation: Operation, runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> {
if (this.state !== State.Idle) {
throw new Error('Repository not initialized');
}
const run = async () => { const run = async () => {
this._operations = this._operations.start(operation); this._operations = this._operations.start(operation);
this._onRunOperation.fire(operation); this._onRunOperation.fire(operation);
try { try {
await this.assertIdleState();
const result = await this.retryRun(runOperation); const result = await this.retryRun(runOperation);
if (!isReadOnly(operation)) { if (!isReadOnly(operation)) {
...@@ -610,12 +618,6 @@ export class Repository implements Disposable { ...@@ -610,12 +618,6 @@ export class Repository implements Disposable {
return result; return result;
} catch (err) { } catch (err) {
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) { if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
this.repositoryDisposable.dispose();
const disposables: Disposable[] = [];
this.onWorkspaceChange(this.onFSChange, this, disposables);
this.repositoryDisposable = combinedDisposable(disposables);
this.state = State.NotAGitRepository; this.state = State.NotAGitRepository;
} }
...@@ -649,37 +651,6 @@ export class Repository implements Disposable { ...@@ -649,37 +651,6 @@ export class Repository implements Disposable {
} }
} }
/* We use the native Node `watch` for faster, non debounced events.
* That way we hopefully get the events during the operations we're
* performing, thus sparing useless `git status` calls to refresh
* the model's state.
*/
private async assertIdleState(): Promise<void> {
if (this.state === State.Idle) {
return;
}
this.repositoryDisposable.dispose();
const disposables: Disposable[] = [];
const repositoryRoot = await this._git.getRepositoryRoot(this.workspaceRoot.fsPath);
this.repository = this._git.open(repositoryRoot);
const onGitChange = filterEvent(this.onWorkspaceChange, uri => /\/\.git\//.test(uri.path));
const onRelevantGitChange = filterEvent(onGitChange, uri => !/\/\.git\/index\.lock$/.test(uri.path));
onRelevantGitChange(this.onFSChange, this, disposables);
onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, disposables);
const onNonGitChange = filterEvent(this.onWorkspaceChange, uri => !/\/\.git\//.test(uri.path));
onNonGitChange(this.onFSChange, this, disposables);
this.repositoryDisposable = combinedDisposable(disposables);
this.isRepositoryHuge = false;
this.didWarnAboutLimit = false;
this.state = State.Idle;
}
@throttle @throttle
private async updateModelState(): Promise<void> { private async updateModelState(): Promise<void> {
const { status, didHitLimit } = await this.repository.getStatus(); const { status, didHitLimit } = await this.repository.getStatus();
...@@ -732,30 +703,30 @@ export class Repository implements Disposable { ...@@ -732,30 +703,30 @@ export class Repository implements Disposable {
const renameUri = raw.rename ? Uri.file(path.join(this.repository.root, raw.rename)) : undefined; const renameUri = raw.rename ? Uri.file(path.join(this.repository.root, raw.rename)) : undefined;
switch (raw.x + raw.y) { switch (raw.x + raw.y) {
case '??': return workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.UNTRACKED)); case '??': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.UNTRACKED));
case '!!': return workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.IGNORED)); case '!!': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.IGNORED));
case 'DD': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.BOTH_DELETED)); case 'DD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_DELETED));
case 'AU': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.ADDED_BY_US)); case 'AU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.ADDED_BY_US));
case 'UD': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM)); case 'UD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM));
case 'UA': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.ADDED_BY_THEM)); case 'UA': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.ADDED_BY_THEM));
case 'DU': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.DELETED_BY_US)); case 'DU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.DELETED_BY_US));
case 'AA': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.BOTH_ADDED)); case 'AA': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_ADDED));
case 'UU': return merge.push(new Resource(this.workspaceRoot, ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED)); case 'UU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED));
} }
let isModifiedInIndex = false; let isModifiedInIndex = false;
switch (raw.x) { switch (raw.x) {
case 'M': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break; case 'M': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break;
case 'A': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_ADDED)); break; case 'A': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_ADDED)); break;
case 'D': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_DELETED)); break; case 'D': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_DELETED)); break;
case 'R': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_RENAMED, renameUri)); break; case 'R': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_RENAMED, renameUri)); break;
case 'C': index.push(new Resource(this.workspaceRoot, ResourceGroupType.Index, uri, Status.INDEX_COPIED, renameUri)); break; case 'C': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_COPIED, renameUri)); break;
} }
switch (raw.y) { switch (raw.y) {
case 'M': workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.MODIFIED, renameUri)); break; case 'M': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.MODIFIED, renameUri)); break;
case 'D': workingTree.push(new Resource(this.workspaceRoot, ResourceGroupType.WorkingTree, uri, Status.DELETED, renameUri)); break; case 'D': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.DELETED, renameUri)); break;
} }
}); });
...@@ -825,7 +796,6 @@ export class Repository implements Disposable { ...@@ -825,7 +796,6 @@ export class Repository implements Disposable {
} }
dispose(): void { dispose(): void {
this.repositoryDisposable.dispose();
this.disposables = dispose(this.disposables); this.disposables = dispose(this.disposables);
} }
} }
...@@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; ...@@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { chain } from 'vs/base/common/event'; import { chain } from 'vs/base/common/event';
import { memoize } from 'vs/base/common/decorators'; import { memoize } from 'vs/base/common/decorators';
import { onUnexpectedError } from 'vs/base/common/errors'; import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose, empty as EmptyDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { IDisposable, dispose, empty as EmptyDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Builder, Dimension } from 'vs/base/browser/builder'; import { Builder, Dimension } from 'vs/base/browser/builder';
import { ComposedViewsViewlet, CollapsibleView, ICollapsibleViewOptions, IViewletViewOptions, IView, IViewOptions } from 'vs/workbench/parts/views/browser/views'; import { ComposedViewsViewlet, CollapsibleView, ICollapsibleViewOptions, IViewletViewOptions, IView, IViewOptions } from 'vs/workbench/parts/views/browser/views';
import { append, $, toggleClass } from 'vs/base/browser/dom'; import { append, $, toggleClass } from 'vs/base/browser/dom';
...@@ -399,10 +399,10 @@ class InstallAdditionalSCMProvidersAction extends Action { ...@@ -399,10 +399,10 @@ class InstallAdditionalSCMProvidersAction extends Action {
export class SCMViewlet extends ComposedViewsViewlet { export class SCMViewlet extends ComposedViewsViewlet {
private activeProvider: ISCMProvider | undefined; // private activeProvider: ISCMProvider | undefined;
private cachedDimension: Dimension; // private cachedDimension: Dimension;
private inputBoxContainer: HTMLElement; // private inputBoxContainer: HTMLElement;
private inputBox: InputBox; // private inputBox: InputBox;
private providerChangeDisposable: IDisposable = EmptyDisposable; private providerChangeDisposable: IDisposable = EmptyDisposable;
private disposables: IDisposable[] = []; private disposables: IDisposable[] = [];
...@@ -428,30 +428,37 @@ export class SCMViewlet extends ComposedViewsViewlet { ...@@ -428,30 +428,37 @@ export class SCMViewlet extends ComposedViewsViewlet {
telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService); telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService);
} }
private setActiveProvider(activeProvider: ISCMProvider | undefined): void { private onDidProvidersChange(): void {
this.providerChangeDisposable.dispose(); this.providerChangeDisposable.dispose();
this.activeProvider = activeProvider; // this.activeProvider = activeProvider;
if (activeProvider) { const providers = this.scmService.providers;
const disposables = []; const ids = providers.map(provider => provider.id);
const views = providers.map(provider => new SourceControlViewDescriptor(provider));
// if (activeProvider.onDidChangeCommitTemplate) { ViewsRegistry.registerViews(views);
// disposables.push(activeProvider.onDidChangeCommitTemplate(this.updateInputBox, this)); this.providerChangeDisposable = toDisposable(() => ViewsRegistry.deregisterViews(ids, ViewLocation.SCM));
// }
const id = activeProvider.id; // if (activeProvider) {
ViewsRegistry.registerViews([new SourceControlViewDescriptor(activeProvider)]); // const disposables = [];
disposables.push({ // // if (activeProvider.onDidChangeCommitTemplate) {
dispose: () => { // // disposables.push(activeProvider.onDidChangeCommitTemplate(this.updateInputBox, this));
ViewsRegistry.deregisterViews([id], ViewLocation.SCM); // // }
}
});
this.providerChangeDisposable = combinedDisposable(disposables); // const id = activeProvider.id;
} else { // ViewsRegistry.registerViews([new SourceControlViewDescriptor(activeProvider)]);
this.providerChangeDisposable = EmptyDisposable;
} // disposables.push({
// dispose: () => {
// ViewsRegistry.deregisterViews([id], ViewLocation.SCM);
// }
// });
// this.providerChangeDisposable = combinedDisposable(disposables);
// } else {
// this.providerChangeDisposable = EmptyDisposable;
// }
// this.updateInputBox(); // this.updateInputBox();
// this.updateTitleArea(); // this.updateTitleArea();
...@@ -483,8 +490,8 @@ export class SCMViewlet extends ComposedViewsViewlet { ...@@ -483,8 +490,8 @@ export class SCMViewlet extends ComposedViewsViewlet {
// .on(this.onDidAcceptInput, this, this.disposables); // .on(this.onDidAcceptInput, this, this.disposables);
this.setActiveProvider(this.scmService.activeProvider); this.onDidProvidersChange();
this.scmService.onDidChangeProvider(this.setActiveProvider, this, this.disposables); this.scmService.onDidChangeProviders(this.onDidProvidersChange, this, this.disposables);
// this.themeService.onThemeChange(this.update, this, this.disposables); // this.themeService.onThemeChange(this.update, this, this.disposables);
// return TPromise.as(null); // return TPromise.as(null);
...@@ -498,33 +505,33 @@ export class SCMViewlet extends ComposedViewsViewlet { ...@@ -498,33 +505,33 @@ export class SCMViewlet extends ComposedViewsViewlet {
return this.instantiationService.createInstance(viewDescriptor.ctor, options); return this.instantiationService.createInstance(viewDescriptor.ctor, options);
} }
private onDidAcceptInput(): void { // private onDidAcceptInput(): void {
if (!this.activeProvider) { // if (!this.activeProvider) {
return; // return;
} // }
if (!this.activeProvider.acceptInputCommand) { // if (!this.activeProvider.acceptInputCommand) {
return; // return;
} // }
const id = this.activeProvider.acceptInputCommand.id; // const id = this.activeProvider.acceptInputCommand.id;
const args = this.activeProvider.acceptInputCommand.arguments; // const args = this.activeProvider.acceptInputCommand.arguments;
this.commandService.executeCommand(id, ...args) // this.commandService.executeCommand(id, ...args)
.done(undefined, onUnexpectedError); // .done(undefined, onUnexpectedError);
} // }
private updateInputBox(): void { // private updateInputBox(): void {
if (!this.activeProvider) { // if (!this.activeProvider) {
return; // return;
} // }
if (typeof this.activeProvider.commitTemplate === 'undefined') { // if (typeof this.activeProvider.commitTemplate === 'undefined') {
return; // return;
} // }
this.inputBox.value = this.activeProvider.commitTemplate; // this.inputBox.value = this.activeProvider.commitTemplate;
} // }
// layout(dimension: Dimension = this.cachedDimension): void { // layout(dimension: Dimension = this.cachedDimension): void {
// if (!dimension) { // if (!dimension) {
......
...@@ -63,6 +63,9 @@ export interface ISCMService { ...@@ -63,6 +63,9 @@ export interface ISCMService {
readonly _serviceBrand: any; readonly _serviceBrand: any;
readonly onDidChangeProvider: Event<ISCMProvider>; readonly onDidChangeProvider: Event<ISCMProvider>;
// TODO@joao fix name
readonly onDidChangeProviders: Event<void>;
readonly providers: ISCMProvider[]; readonly providers: ISCMProvider[];
readonly input: ISCMInput; readonly input: ISCMInput;
activeProvider: ISCMProvider | undefined; activeProvider: ISCMProvider | undefined;
......
...@@ -51,6 +51,9 @@ export class SCMService implements ISCMService { ...@@ -51,6 +51,9 @@ export class SCMService implements ISCMService {
private _providers: ISCMProvider[] = []; private _providers: ISCMProvider[] = [];
get providers(): ISCMProvider[] { return [...this._providers]; } get providers(): ISCMProvider[] { return [...this._providers]; }
private _onDidChangeProviders = new Emitter<void>();
get onDidChangeProviders(): Event<void> { return this._onDidChangeProviders.event; }
private _onDidChangeProvider = new Emitter<ISCMProvider>(); private _onDidChangeProvider = new Emitter<ISCMProvider>();
get onDidChangeProvider(): Event<ISCMProvider> { return this._onDidChangeProvider.event; } get onDidChangeProvider(): Event<ISCMProvider> { return this._onDidChangeProvider.event; }
...@@ -91,6 +94,8 @@ export class SCMService implements ISCMService { ...@@ -91,6 +94,8 @@ export class SCMService implements ISCMService {
this.setActiveSCMProvider(provider); this.setActiveSCMProvider(provider);
} }
this._onDidChangeProviders.fire();
return toDisposable(() => { return toDisposable(() => {
const index = this._providers.indexOf(provider); const index = this._providers.indexOf(provider);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册