working copy - support initial working copies

This commit is contained in:
Benjamin Pasero 2020-02-04 08:34:55 +01:00
parent 6501bd65a9
commit 29a15dd045
8 changed files with 62 additions and 43 deletions

View file

@ -118,6 +118,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
// Working Copies
this.dirtyWorkingCopiesContext = DirtyWorkingCopiesContext.bindTo(this.contextKeyService);
this.dirtyWorkingCopiesContext.set(this.workingCopyService.hasDirty);
// Inputs
this.inputFocusedContext = InputFocusedContext.bindTo(this.contextKeyService);
@ -187,7 +188,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
this._register(this.layoutService.onPartVisibilityChange(() => this.editorAreaVisibleContext.set(this.layoutService.isVisible(Parts.EDITOR_PART))));
this._register(this.workingCopyService.onDidChangeDirty(w => this.dirtyWorkingCopiesContext.set(w.isDirty() || this.workingCopyService.hasDirty)));
this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.dirtyWorkingCopiesContext.set(workingCopy.isDirty() || this.workingCopyService.hasDirty)));
}
private updateEditorContextKeys(): void {

View file

@ -38,6 +38,9 @@ export class EditorAutoSave extends Disposable implements IWorkbenchContribution
// Figure out initial auto save config
this.onAutoSaveConfigurationChange(filesConfigurationService.getAutoSaveConfiguration(), false);
// Fill in initial dirty working copies
this.workingCopyService.dirtyWorkingCopies.forEach(workingCopy => this.onDidRegister(workingCopy));
this.registerListeners();
}
@ -47,10 +50,10 @@ export class EditorAutoSave extends Disposable implements IWorkbenchContribution
this._register(this.filesConfigurationService.onAutoSaveConfigurationChange(config => this.onAutoSaveConfigurationChange(config, true)));
// Working Copy events
this._register(this.workingCopyService.onDidRegister(c => this.onDidRegister(c)));
this._register(this.workingCopyService.onDidUnregister(c => this.onDidUnregister(c)));
this._register(this.workingCopyService.onDidChangeDirty(c => this.onDidChangeDirty(c)));
this._register(this.workingCopyService.onDidChangeContent(c => this.onDidChangeContent(c)));
this._register(this.workingCopyService.onDidRegister(workingCopy => this.onDidRegister(workingCopy)));
this._register(this.workingCopyService.onDidUnregister(workingCopy => this.onDidUnregister(workingCopy)));
this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.onDidChangeDirty(workingCopy)));
this._register(this.workingCopyService.onDidChangeContent(workingCopy => this.onDidChangeContent(workingCopy)));
}
private onWindowFocusChange(focused: boolean): void {
@ -141,7 +144,9 @@ export class EditorAutoSave extends Disposable implements IWorkbenchContribution
}
private onDidRegister(workingCopy: IWorkingCopy): void {
this.scheduleAutoSave(workingCopy);
if (workingCopy.isDirty()) {
this.scheduleAutoSave(workingCopy);
}
}
private onDidUnregister(workingCopy: IWorkingCopy): void {
@ -149,13 +154,18 @@ export class EditorAutoSave extends Disposable implements IWorkbenchContribution
}
private onDidChangeDirty(workingCopy: IWorkingCopy): void {
if (!workingCopy.isDirty()) {
if (workingCopy.isDirty()) {
this.scheduleAutoSave(workingCopy);
} else {
this.discardAutoSave(workingCopy);
}
}
private onDidChangeContent(workingCopy: IWorkingCopy): void {
if (workingCopy.isDirty()) {
// this listener will make sure that the auto save is
// pushed out for as long as the user is still changing
// the content of the working copy.
this.scheduleAutoSave(workingCopy);
}
}

View file

@ -46,16 +46,19 @@ export abstract class BackupTracker extends Disposable {
// Figure out initial auto save config
this.onAutoSaveConfigurationChange(filesConfigurationService.getAutoSaveConfiguration());
// Fill in initial dirty working copies
this.workingCopyService.dirtyWorkingCopies.forEach(workingCopy => this.onDidRegister(workingCopy));
this.registerListeners();
}
private registerListeners() {
// Working Copy events
this._register(this.workingCopyService.onDidRegister(c => this.onDidRegister(c)));
this._register(this.workingCopyService.onDidUnregister(c => this.onDidUnregister(c)));
this._register(this.workingCopyService.onDidChangeDirty(c => this.onDidChangeDirty(c)));
this._register(this.workingCopyService.onDidChangeContent(c => this.onDidChangeContent(c)));
this._register(this.workingCopyService.onDidRegister(workingCopy => this.onDidRegister(workingCopy)));
this._register(this.workingCopyService.onDidUnregister(workingCopy => this.onDidUnregister(workingCopy)));
this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.onDidChangeDirty(workingCopy)));
this._register(this.workingCopyService.onDidChangeContent(workingCopy => this.onDidChangeContent(workingCopy)));
// Listen to auto save config changes
this._register(this.filesConfigurationService.onAutoSaveConfigurationChange(c => this.onAutoSaveConfigurationChange(c)));
@ -65,7 +68,9 @@ export abstract class BackupTracker extends Disposable {
}
private onDidRegister(workingCopy: IWorkingCopy): void {
this.scheduleBackup(workingCopy);
if (workingCopy.isDirty()) {
this.scheduleBackup(workingCopy);
}
}
private onDidUnregister(workingCopy: IWorkingCopy): void {
@ -78,7 +83,9 @@ export abstract class BackupTracker extends Disposable {
}
private onDidChangeDirty(workingCopy: IWorkingCopy): void {
if (!workingCopy.isDirty()) {
if (workingCopy.isDirty()) {
this.scheduleBackup(workingCopy);
} else {
this.discardBackup(workingCopy);
}
}
@ -91,6 +98,9 @@ export abstract class BackupTracker extends Disposable {
// Schedule backup if dirty
if (workingCopy.isDirty()) {
// this listener will make sure that the backup is
// pushed out for as long as the user is still changing
// the content of the working copy.
this.scheduleBackup(workingCopy);
}
}

View file

@ -522,7 +522,7 @@ export class ToggleAutoSaveAction extends Action {
}
export abstract class BaseSaveAllAction extends Action {
private lastIsDirty: boolean;
private lastDirtyState: boolean;
constructor(
id: string,
@ -533,8 +533,8 @@ export abstract class BaseSaveAllAction extends Action {
) {
super(id, label);
this.lastIsDirty = this.workingCopyService.hasDirty;
this.enabled = this.lastIsDirty;
this.lastDirtyState = this.workingCopyService.hasDirty;
this.enabled = this.lastDirtyState;
this.registerListeners();
}
@ -544,14 +544,14 @@ export abstract class BaseSaveAllAction extends Action {
private registerListeners(): void {
// update enablement based on working copy changes
this._register(this.workingCopyService.onDidChangeDirty(w => this.updateEnablement(w)));
this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.updateEnablement(workingCopy)));
}
private updateEnablement(workingCopy: IWorkingCopy): void {
const hasDirty = workingCopy.isDirty() || this.workingCopyService.hasDirty;
if (this.lastIsDirty !== hasDirty) {
if (this.lastDirtyState !== hasDirty) {
this.enabled = hasDirty;
this.lastIsDirty = this.enabled;
this.lastDirtyState = this.enabled;
}
}

View file

@ -104,7 +104,7 @@ export class OpenEditorsView extends ViewPane {
this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationChange(e)));
// Handle dirty counter
this._register(this.workingCopyService.onDidChangeDirty(c => this.updateDirtyIndicator(c)));
this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.updateDirtyIndicator(workingCopy)));
}
private registerUpdateEvents(): void {

View file

@ -15,11 +15,7 @@ import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/
export class DirtyFilesIndicator extends Disposable implements IWorkbenchContribution {
private readonly badgeHandle = this._register(new MutableDisposable());
private lastKnownDirtyCount: number | undefined;
private get hasDirtyCount(): boolean {
return typeof this.lastKnownDirtyCount === 'number' && this.lastKnownDirtyCount > 0;
}
private lastKnownDirtyCount = 0;
constructor(
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@ -29,13 +25,15 @@ export class DirtyFilesIndicator extends Disposable implements IWorkbenchContrib
) {
super();
this.updateActivityBadge();
this.registerListeners();
}
private registerListeners(): void {
// Working copy dirty indicator
this._register(this.workingCopyService.onDidChangeDirty(c => this.onWorkingCopyDidChangeDirty(c)));
this._register(this.workingCopyService.onDidChangeDirty(workingCopy => this.onWorkingCopyDidChangeDirty(workingCopy)));
// Lifecycle
this.lifecycleService.onShutdown(this.dispose, this);
@ -47,14 +45,13 @@ export class DirtyFilesIndicator extends Disposable implements IWorkbenchContrib
return; // do not indicate dirty of working copies that are auto saved after short delay
}
if (gotDirty || this.hasDirtyCount) {
if (gotDirty || this.lastKnownDirtyCount > 0) {
this.updateActivityBadge();
}
}
private updateActivityBadge(): void {
const dirtyCount = this.workingCopyService.dirtyCount;
this.lastKnownDirtyCount = dirtyCount;
const dirtyCount = this.lastKnownDirtyCount = this.workingCopyService.dirtyCount;
// Indicate dirty count in badge if any
if (dirtyCount > 0) {

View file

@ -172,14 +172,9 @@ export class SearchEditorInput extends EditorInput {
return null;
}
async setDirty(dirty: boolean) {
setDirty(dirty: boolean) {
this.dirty = dirty;
this._onDidChangeDirty.fire();
await this.model;
// fire again because some listeners dont attach early enough. See #89406 and #89267.
this._onDidChangeDirty.fire();
}
isDirty() {

View file

@ -272,13 +272,10 @@ export class ElectronWindow extends Disposable {
return; // do not indicate dirty of working copies that are auto saved after short delay
}
if ((!this.isDocumentedEdited && gotDirty) || (this.isDocumentedEdited && !gotDirty)) {
const hasDirtyFiles = this.workingCopyService.hasDirty;
this.isDocumentedEdited = hasDirtyFiles;
this.electronService.setDocumentEdited(hasDirtyFiles);
}
this.updateDocumentEdited(gotDirty);
}));
this.updateDocumentEdited();
}
// Detect minimize / maximize
@ -290,6 +287,15 @@ export class ElectronWindow extends Disposable {
this.onDidChangeMaximized(this.environmentService.configuration.maximized ?? false);
}
private updateDocumentEdited(isDirty = this.workingCopyService.hasDirty): void {
if ((!this.isDocumentedEdited && isDirty) || (this.isDocumentedEdited && !isDirty)) {
const hasDirtyFiles = this.workingCopyService.hasDirty;
this.isDocumentedEdited = hasDirtyFiles;
this.electronService.setDocumentEdited(hasDirtyFiles);
}
}
private onDidChangeMaximized(maximized: boolean): void {
this.layoutService.updateWindowMaximizedState(maximized);
}
@ -650,8 +656,8 @@ export class ElectronWindow extends Disposable {
}
// Otherwise resolve promise when resource is saved
const listener = this.workingCopyService.onDidChangeDirty(e => {
if (!e.isDirty() && isEqual(resource, e.resource)) {
const listener = this.workingCopyService.onDidChangeDirty(workingCopy => {
if (!workingCopy.isDirty() && isEqual(resource, workingCopy.resource)) {
listener.dispose();
resolve();