未验证 提交 e8d3a7b8 编写于 作者: J João Moreno

fixes #108046

上级 0bdc508b
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import { URI, UriComponents } from 'vs/base/common/uri'; import { URI, UriComponents } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle'; import { IDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle';
import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation } from 'vs/workbench/contrib/scm/common/scm'; import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation, ISCMViewService } from 'vs/workbench/contrib/scm/common/scm';
import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResourceSplices, SCMGroupFeatures, MainContext, IExtHostContext } from '../common/extHost.protocol'; import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResourceSplices, SCMGroupFeatures, MainContext, IExtHostContext } from '../common/extHost.protocol';
import { Command } from 'vs/editor/common/modes'; import { Command } from 'vs/editor/common/modes';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
...@@ -273,7 +273,8 @@ export class MainThreadSCM implements MainThreadSCMShape { ...@@ -273,7 +273,8 @@ export class MainThreadSCM implements MainThreadSCMShape {
constructor( constructor(
extHostContext: IExtHostContext, extHostContext: IExtHostContext,
@ISCMService private readonly scmService: ISCMService @ISCMService private readonly scmService: ISCMService,
@ISCMViewService private readonly scmViewService: ISCMViewService
) { ) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostSCM); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostSCM);
} }
...@@ -294,11 +295,11 @@ export class MainThreadSCM implements MainThreadSCMShape { ...@@ -294,11 +295,11 @@ export class MainThreadSCM implements MainThreadSCMShape {
this._repositories.set(handle, repository); this._repositories.set(handle, repository);
const disposable = combinedDisposable( const disposable = combinedDisposable(
Event.filter(repository.onDidChangeSelection, selected => selected)(_ => this._proxy.$setSelectedSourceControl(handle)), Event.filter(this.scmViewService.onDidFocusRepository, r => r === repository)(_ => this._proxy.$setSelectedSourceControl(handle)),
repository.input.onDidChange(({ value }) => this._proxy.$onInputBoxValueChange(handle, value)) repository.input.onDidChange(({ value }) => this._proxy.$onInputBoxValueChange(handle, value))
); );
if (repository.selected) { if (this.scmViewService.focusedRepository === repository) {
setTimeout(() => this._proxy.$setSelectedSourceControl(handle), 0); setTimeout(() => this._proxy.$setSelectedSourceControl(handle), 0);
} }
......
...@@ -7,7 +7,7 @@ import { localize } from 'vs/nls'; ...@@ -7,7 +7,7 @@ import { localize } from 'vs/nls';
import { basename } from 'vs/base/common/resources'; import { basename } from 'vs/base/common/resources';
import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event'; import { Event } from 'vs/base/common/event';
import { VIEW_PANE_ID, ISCMService, ISCMRepository } from 'vs/workbench/contrib/scm/common/scm'; import { VIEW_PANE_ID, ISCMService, ISCMRepository, ISCMViewService } from 'vs/workbench/contrib/scm/common/scm';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
...@@ -32,10 +32,12 @@ export class SCMStatusController implements IWorkbenchContribution { ...@@ -32,10 +32,12 @@ export class SCMStatusController implements IWorkbenchContribution {
private focusedRepository: ISCMRepository | undefined = undefined; private focusedRepository: ISCMRepository | undefined = undefined;
private focusedProviderContextKey: IContextKey<string | undefined>; private focusedProviderContextKey: IContextKey<string | undefined>;
private readonly badgeDisposable = new MutableDisposable<IDisposable>(); private readonly badgeDisposable = new MutableDisposable<IDisposable>();
private disposables: IDisposable[] = []; private disposables = new DisposableStore();
private repositoryDisposables = new Set<IDisposable>();
constructor( constructor(
@ISCMService private readonly scmService: ISCMService, @ISCMService private readonly scmService: ISCMService,
@ISCMViewService private readonly scmViewService: ISCMViewService,
@IStatusbarService private readonly statusbarService: IStatusbarService, @IStatusbarService private readonly statusbarService: IStatusbarService,
@IContextKeyService readonly contextKeyService: IContextKeyService, @IContextKeyService readonly contextKeyService: IContextKeyService,
@IActivityService private readonly activityService: IActivityService, @IActivityService private readonly activityService: IActivityService,
...@@ -54,6 +56,9 @@ export class SCMStatusController implements IWorkbenchContribution { ...@@ -54,6 +56,9 @@ export class SCMStatusController implements IWorkbenchContribution {
this.onDidAddRepository(repository); this.onDidAddRepository(repository);
} }
this.scmViewService.onDidFocusRepository(this.focusRepository, this, this.disposables);
this.focusRepository(this.scmViewService.focusedRepository);
editorService.onDidActiveEditorChange(this.tryFocusRepositoryBasedOnActiveEditor, this, this.disposables); editorService.onDidActiveEditorChange(this.tryFocusRepositoryBasedOnActiveEditor, this, this.disposables);
this.renderActivityCount(); this.renderActivityCount();
} }
...@@ -92,35 +97,18 @@ export class SCMStatusController implements IWorkbenchContribution { ...@@ -92,35 +97,18 @@ export class SCMStatusController implements IWorkbenchContribution {
} }
private onDidAddRepository(repository: ISCMRepository): void { private onDidAddRepository(repository: ISCMRepository): void {
const selectedDisposable = Event.filter(repository.onDidChangeSelection, selected => selected)(() => this.focusRepository(repository));
const onDidChange = Event.any(repository.provider.onDidChange, repository.provider.onDidChangeResources); const onDidChange = Event.any(repository.provider.onDidChange, repository.provider.onDidChangeResources);
const changeDisposable = onDidChange(() => this.renderActivityCount()); const changeDisposable = onDidChange(() => this.renderActivityCount());
const onDidRemove = Event.filter(this.scmService.onDidRemoveRepository, e => e === repository); const onDidRemove = Event.filter(this.scmService.onDidRemoveRepository, e => e === repository);
const removeDisposable = onDidRemove(() => { const removeDisposable = onDidRemove(() => {
disposable.dispose(); disposable.dispose();
this.disposables = this.disposables.filter(d => d !== removeDisposable); this.repositoryDisposables.delete(disposable);
if (this.scmService.repositories.length === 0) {
this.focusRepository(undefined);
}
this.renderActivityCount(); this.renderActivityCount();
}); });
const disposable = combinedDisposable(selectedDisposable, changeDisposable, removeDisposable); const disposable = combinedDisposable(changeDisposable, removeDisposable);
this.disposables.push(disposable); this.repositoryDisposables.add(disposable);
if (this.focusedRepository) {
return;
}
if (this.tryFocusRepositoryBasedOnActiveEditor()) {
return;
}
this.focusRepository(repository);
} }
private onDidRemoveRepository(repository: ISCMRepository): void { private onDidRemoveRepository(repository: ISCMRepository): void {
...@@ -201,5 +189,7 @@ export class SCMStatusController implements IWorkbenchContribution { ...@@ -201,5 +189,7 @@ export class SCMStatusController implements IWorkbenchContribution {
this.statusBarDisposable.dispose(); this.statusBarDisposable.dispose();
this.badgeDisposable.dispose(); this.badgeDisposable.dispose();
this.disposables = dispose(this.disposables); this.disposables = dispose(this.disposables);
dispose(this.repositoryDisposables.values());
this.repositoryDisposables.clear();
} }
} }
...@@ -1419,6 +1419,7 @@ class SCMInputWidget extends Disposable { ...@@ -1419,6 +1419,7 @@ class SCMInputWidget extends Disposable {
@IKeybindingService private keybindingService: IKeybindingService, @IKeybindingService private keybindingService: IKeybindingService,
@IConfigurationService private configurationService: IConfigurationService, @IConfigurationService private configurationService: IConfigurationService,
@IInstantiationService instantiationService: IInstantiationService, @IInstantiationService instantiationService: IInstantiationService,
@ISCMViewService private readonly scmViewService: ISCMViewService,
@IContextViewService private readonly contextViewService: IContextViewService @IContextViewService private readonly contextViewService: IContextViewService
) { ) {
super(); super();
...@@ -1466,7 +1467,10 @@ class SCMInputWidget extends Disposable { ...@@ -1466,7 +1467,10 @@ class SCMInputWidget extends Disposable {
this._register(this.inputEditor); this._register(this.inputEditor);
this._register(this.inputEditor.onDidFocusEditorText(() => { this._register(this.inputEditor.onDidFocusEditorText(() => {
this.input?.repository.setSelected(true); // TODO@joao: remove if (this.input?.repository) {
this.scmViewService.focus(this.input.repository);
}
this.editorContainer.classList.add('synthetic-focus'); this.editorContainer.classList.add('synthetic-focus');
this.renderValidation(); this.renderValidation();
})); }));
...@@ -1838,21 +1842,25 @@ export class SCMViewPane extends ViewPane { ...@@ -1838,21 +1842,25 @@ export class SCMViewPane extends ViewPane {
private async open(e: IOpenEvent<TreeElement | null>): Promise<void> { private async open(e: IOpenEvent<TreeElement | null>): Promise<void> {
if (!e.element) { if (!e.element) {
return; return;
} else if (isSCMRepository(e.element)) { // TODO@joao: remove } else if (isSCMRepository(e.element)) {
e.element.setSelected(true); this.scmViewService.focus(e.element);
return; return;
} else if (isSCMResourceGroup(e.element)) { // TODO@joao: remove } else if (isSCMResourceGroup(e.element)) {
const provider = e.element.provider; const provider = e.element.provider;
const repository = this.scmService.repositories.find(r => r.provider === provider); const repository = this.scmService.repositories.find(r => r.provider === provider);
repository?.setSelected(true); if (repository) {
this.scmViewService.focus(repository);
}
return; return;
} else if (ResourceTree.isResourceNode(e.element)) { // TODO@joao: remove } else if (ResourceTree.isResourceNode(e.element)) {
const provider = e.element.context.provider; const provider = e.element.context.provider;
const repository = this.scmService.repositories.find(r => r.provider === provider); const repository = this.scmService.repositories.find(r => r.provider === provider);
repository?.setSelected(true); if (repository) {
this.scmViewService.focus(repository);
}
return; return;
} else if (isSCMInput(e.element)) { } else if (isSCMInput(e.element)) {
e.element.repository.setSelected(true); // TODO@joao: remove this.scmViewService.focus(e.element.repository);
const widget = this.inputRenderer.getRenderedInputWidget(e.element); const widget = this.inputRenderer.getRenderedInputWidget(e.element);
...@@ -1880,10 +1888,12 @@ export class SCMViewPane extends ViewPane { ...@@ -1880,10 +1888,12 @@ export class SCMViewPane extends ViewPane {
} }
} }
// TODO@joao: remove
const provider = e.element.resourceGroup.provider; const provider = e.element.resourceGroup.provider;
const repository = this.scmService.repositories.find(r => r.provider === provider); const repository = this.scmService.repositories.find(r => r.provider === provider);
repository?.setSelected(true);
if (repository) {
this.scmViewService.focus(repository);
}
} }
private onListContextMenu(e: ITreeContextMenuEvent<TreeElement | null>): void { private onListContextMenu(e: ITreeContextMenuEvent<TreeElement | null>): void {
......
...@@ -49,6 +49,10 @@ export class SCMViewService implements ISCMViewService { ...@@ -49,6 +49,10 @@ export class SCMViewService implements ISCMViewService {
this._visibleRepositories = visibleRepositories; this._visibleRepositories = visibleRepositories;
this._visibleRepositoriesSet = set; this._visibleRepositoriesSet = set;
this._onDidSetVisibleRepositories.fire({ added, removed }); this._onDidSetVisibleRepositories.fire({ added, removed });
if (this._focusedRepository && removed.has(this._focusedRepository)) {
this.focus(this._visibleRepositories[0]);
}
} }
private _onDidChangeRepositories = new Emitter<ISCMViewVisibleRepositoryChangeEvent>(); private _onDidChangeRepositories = new Emitter<ISCMViewVisibleRepositoryChangeEvent>();
...@@ -69,6 +73,15 @@ export class SCMViewService implements ISCMViewService { ...@@ -69,6 +73,15 @@ export class SCMViewService implements ISCMViewService {
}, 0) }, 0)
); );
private _focusedRepository: ISCMRepository | undefined;
get focusedRepository(): ISCMRepository | undefined {
return this._focusedRepository;
}
private _onDidFocusRepository = new Emitter<ISCMRepository | undefined>();
readonly onDidFocusRepository = this._onDidFocusRepository.event;
constructor( constructor(
@ISCMService private readonly scmService: ISCMService, @ISCMService private readonly scmService: ISCMService,
@IInstantiationService instantiationService: IInstantiationService @IInstantiationService instantiationService: IInstantiationService
...@@ -88,6 +101,10 @@ export class SCMViewService implements ISCMViewService { ...@@ -88,6 +101,10 @@ export class SCMViewService implements ISCMViewService {
this._visibleRepositoriesSet.add(repository); this._visibleRepositoriesSet.add(repository);
this._onDidChangeRepositories.fire({ added: [repository], removed: Iterable.empty() }); this._onDidChangeRepositories.fire({ added: [repository], removed: Iterable.empty() });
if (!this._focusedRepository) {
this.focus(repository);
}
} }
private onDidRemoveRepository(repository: ISCMRepository): void { private onDidRemoveRepository(repository: ISCMRepository): void {
...@@ -109,6 +126,10 @@ export class SCMViewService implements ISCMViewService { ...@@ -109,6 +126,10 @@ export class SCMViewService implements ISCMViewService {
this._onDidChangeRepositories.fire({ added, removed: [repository] }); this._onDidChangeRepositories.fire({ added, removed: [repository] });
} }
if (this._focusedRepository === repository) {
this.focus(this._visibleRepositories[0]);
}
} }
isVisible(repository: ISCMRepository): boolean { isVisible(repository: ISCMRepository): boolean {
...@@ -136,6 +157,15 @@ export class SCMViewService implements ISCMViewService { ...@@ -136,6 +157,15 @@ export class SCMViewService implements ISCMViewService {
} }
} }
focus(repository: ISCMRepository | undefined): void {
if (repository && !this.visibleRepositories.includes(repository)) {
return;
}
this._focusedRepository = repository;
this._onDidFocusRepository.fire(repository);
}
dispose(): void { dispose(): void {
this.disposables.dispose(); this.disposables.dispose();
this._onDidChangeRepositories.dispose(); this._onDidChangeRepositories.dispose();
......
...@@ -19,7 +19,7 @@ import { Iterable } from 'vs/base/common/iterator'; ...@@ -19,7 +19,7 @@ import { Iterable } from 'vs/base/common/iterator';
import { reset } from 'vs/base/browser/dom'; import { reset } from 'vs/base/browser/dom';
export function isSCMRepository(element: any): element is ISCMRepository { export function isSCMRepository(element: any): element is ISCMRepository {
return !!(element as ISCMRepository).provider && typeof (element as ISCMRepository).setSelected === 'function'; return !!(element as ISCMRepository).provider && !!(element as ISCMRepository).input;
} }
export function isSCMInput(element: any): element is ISCMInput { export function isSCMInput(element: any): element is ISCMInput {
......
...@@ -114,11 +114,8 @@ export interface ISCMInput { ...@@ -114,11 +114,8 @@ export interface ISCMInput {
} }
export interface ISCMRepository extends IDisposable { export interface ISCMRepository extends IDisposable {
readonly selected: boolean;
readonly onDidChangeSelection: Event<boolean>;
readonly provider: ISCMProvider; readonly provider: ISCMProvider;
readonly input: ISCMInput; readonly input: ISCMInput;
setSelected(selected: boolean): void;
} }
export interface ISCMService { export interface ISCMService {
...@@ -168,4 +165,8 @@ export interface ISCMViewService { ...@@ -168,4 +165,8 @@ export interface ISCMViewService {
isVisible(repository: ISCMRepository): boolean; isVisible(repository: ISCMRepository): boolean;
toggleVisibility(repository: ISCMRepository, visible?: boolean): void; toggleVisibility(repository: ISCMRepository, visible?: boolean): void;
readonly focusedRepository: ISCMRepository | undefined;
readonly onDidFocusRepository: Event<ISCMRepository | undefined>;
focus(repository: ISCMRepository): void;
} }
...@@ -185,10 +185,6 @@ export class SCMService implements ISCMService { ...@@ -185,10 +185,6 @@ export class SCMService implements ISCMService {
get repositories(): ISCMRepository[] { return [...this._repositories]; } get repositories(): ISCMRepository[] { return [...this._repositories]; }
private providerCount: IContextKey<number>; private providerCount: IContextKey<number>;
private _selectedRepository: ISCMRepository | undefined;
private readonly _onDidSelectRepository = new Emitter<ISCMRepository | undefined>();
readonly onDidSelectRepository: Event<ISCMRepository | undefined> = this._onDidSelectRepository.event;
private readonly _onDidAddProvider = new Emitter<ISCMRepository>(); private readonly _onDidAddProvider = new Emitter<ISCMRepository>();
readonly onDidAddRepository: Event<ISCMRepository> = this._onDidAddProvider.event; readonly onDidAddRepository: Event<ISCMRepository> = this._onDidAddProvider.event;
...@@ -220,38 +216,18 @@ export class SCMService implements ISCMService { ...@@ -220,38 +216,18 @@ export class SCMService implements ISCMService {
return; return;
} }
selectedDisposable.dispose();
this._providerIds.delete(provider.id); this._providerIds.delete(provider.id);
this._repositories.splice(index, 1); this._repositories.splice(index, 1);
this._onDidRemoveProvider.fire(repository); this._onDidRemoveProvider.fire(repository);
if (this._selectedRepository === repository) {
this.select(this._repositories[0]);
}
this.providerCount.set(this._repositories.length); this.providerCount.set(this._repositories.length);
}); });
const repository = new SCMRepository(provider, disposable, this.storageService); const repository = new SCMRepository(provider, disposable, this.storageService);
const selectedDisposable = Event.map(Event.filter(repository.onDidChangeSelection, selected => selected), _ => repository)(this.select, this);
this._repositories.push(repository); this._repositories.push(repository);
this._onDidAddProvider.fire(repository); this._onDidAddProvider.fire(repository);
if (!this._selectedRepository) {
repository.setSelected(true);
}
this.providerCount.set(this._repositories.length); this.providerCount.set(this._repositories.length);
return repository; return repository;
} }
private select(repository: ISCMRepository | undefined): void {
if (this._selectedRepository) {
this._selectedRepository.setSelected(false);
}
this._selectedRepository = repository;
this._onDidSelectRepository.fire(this._selectedRepository);
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册