diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 84ac57a6ad1..4e92afd9c4e 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -9,13 +9,16 @@ import { TPromise } from 'vs/base/common/winjs.base'; import errors = require('vs/base/common/errors'); import platform = require('vs/base/common/platform'); import nls = require('vs/nls'); +import paths = require('vs/base/common/paths'); import URI from 'vs/base/common/uri'; import product from 'vs/platform/product'; import { IEditor as IBaseEditor } from 'vs/platform/editor/common/editor'; import { EditorInput, IGroupEvent, IEditorRegistry, Extensions, asFileEditorInput, IEditorGroup } from 'vs/workbench/common/editor'; import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IEventService } from 'vs/platform/event/common/event'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; +import { FileChangesEvent, EventType } from 'vs/platform/files/common/files'; import { Selection } from 'vs/editor/common/core/selection'; import { IEditorInput, ITextEditorOptions, IResourceInput } from 'vs/platform/editor/common/editor'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -262,6 +265,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic @IWorkspaceContextService contextService: IWorkspaceContextService, @IStorageService private storageService: IStorageService, @ILifecycleService private lifecycleService: ILifecycleService, + @IEventService private eventService: IEventService, @IInstantiationService private instantiationService: IInstantiationService, @IIntegrityService integrityService: IIntegrityService ) { @@ -280,6 +284,15 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic this.toUnbind.push(this.lifecycleService.onShutdown(() => this.save())); this.toUnbind.push(this.editorGroupService.onEditorOpenFail(editor => this.remove(editor))); this.toUnbind.push(this.editorGroupService.getStacksModel().onEditorClosed(event => this.onEditorClosed(event))); + + // File changes + this.toUnbind.push(this.eventService.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e))); + } + + private onFileChanges(e: FileChangesEvent): void { + e.getDeleted().forEach(deleted => { + this.remove(deleted.resource); // remove from history files that got deleted or moved + }); } private onEditorClosed(event: IGroupEvent): void { @@ -406,13 +419,15 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic } } - public remove(input: IEditorInput | IResourceInput): void { - this.removeFromHistory(input); - this.removeFromStack(input); - this.removeFromRecentlyClosedFiles(input); + public remove(input: IEditorInput | IResourceInput): void; + public remove(input: URI): void; + public remove(arg1: IEditorInput | IResourceInput | URI): void { + this.removeFromHistory(arg1); + this.removeFromStack(arg1); + this.removeFromRecentlyClosedFiles(arg1); } - private removeFromHistory(input: IEditorInput | IResourceInput, index?: number): void { + private removeFromHistory(input: IEditorInput | IResourceInput | URI, index?: number): void { this.ensureLoaded(); if (typeof index !== 'number') { @@ -424,7 +439,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic } } - private indexOf(input: IEditorInput | IResourceInput): number { + private indexOf(input: IEditorInput | IResourceInput | URI): number { for (let i = 0; i < this.history.length; i++) { const entry = this.history[i]; if (this.matches(input, entry)) { @@ -567,7 +582,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic return s1.startLineNumber === s2.startLineNumber; // we consider the history entry same if we are on the same line } - private removeFromStack(input: IEditorInput | IResourceInput): void { + private removeFromStack(input: IEditorInput | IResourceInput | URI): void { this.stack.forEach((e, i) => { if (this.matches(input, e.input)) { this.stack.splice(i, 1); @@ -578,7 +593,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic }); } - private removeFromRecentlyClosedFiles(input: IEditorInput | IResourceInput): void { + private removeFromRecentlyClosedFiles(input: IEditorInput | IResourceInput | URI): void { this.recentlyClosedFiles.forEach((e, i) => { if (this.matchesFile(e.resource, input)) { this.recentlyClosedFiles.splice(i, 1); @@ -598,7 +613,17 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic return group.getEditors().some(e => this.matchesFile(resource, e)); } - private matches(inputA: IEditorInput | IResourceInput, inputB: IEditorInput | IResourceInput): boolean { + private matches(inputA: IEditorInput | IResourceInput | URI, inputB: IEditorInput | IResourceInput): boolean { + if (inputA instanceof URI) { + if (inputB instanceof EditorInput) { + return false; // we only support this for IResourceInput + } + + const resourceInputB = inputB as IResourceInput; + + return resourceInputB && paths.isEqualOrParent(resourceInputB.resource.toString(), inputA.toString()); + } + if (inputA instanceof EditorInput && inputB instanceof EditorInput) { return inputA.matches(inputB); } @@ -617,7 +642,11 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic return resourceInputA && resourceInputB && resourceInputA.resource.toString() === resourceInputB.resource.toString(); } - private matchesFile(resource: URI, input: IEditorInput | IResourceInput): boolean { + private matchesFile(resource: URI, input: IEditorInput | IResourceInput | URI): boolean { + if (input instanceof URI) { + return paths.isEqualOrParent(resource.toString(), input.toString()); + } + if (input instanceof EditorInput) { const fileInput = asFileEditorInput(input);