Merge VS Code 1.31.1 (#4283)

This commit is contained in:
Matt Irvine
2019-03-15 13:09:45 -07:00
committed by GitHub
parent 7d31575149
commit 86bac90001
1716 changed files with 53308 additions and 48375 deletions

View File

@@ -6,7 +6,6 @@
import * as path from 'vs/base/common/paths';
import * as nls from 'vs/nls';
import { Event, Emitter } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { guessMimeTypes } from 'vs/base/common/mime';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { URI } from 'vs/base/common/uri';
@@ -71,7 +70,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
private saveSequentializer: SaveSequentializer;
private disposed: boolean;
private lastSaveAttemptTime: number;
private createTextEditorModelPromise: TPromise<TextFileEditorModel>;
private createTextEditorModelPromise: Promise<TextFileEditorModel>;
private inConflictMode: boolean;
private inOrphanMode: boolean;
private inErrorMode: boolean;
@@ -79,18 +78,18 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
constructor(
resource: URI,
preferredEncoding: string,
@INotificationService private notificationService: INotificationService,
@INotificationService private readonly notificationService: INotificationService,
@IModeService modeService: IModeService,
@IModelService modelService: IModelService,
@IFileService private fileService: IFileService,
@IInstantiationService private instantiationService: IInstantiationService,
@ITelemetryService private telemetryService: ITelemetryService,
@ITextFileService private textFileService: ITextFileService,
@IBackupFileService private backupFileService: IBackupFileService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IHashService private hashService: IHashService,
@ILogService private logService: ILogService
@IFileService private readonly fileService: IFileService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
@ITextFileService private readonly textFileService: ITextFileService,
@IBackupFileService private readonly backupFileService: IBackupFileService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IHashService private readonly hashService: IHashService,
@ILogService private readonly logService: ILogService
) {
super(modelService, modeService);
@@ -151,7 +150,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
}
if (fileEventImpactsModel && this.inOrphanMode !== newInOrphanModeGuess) {
let checkOrphanedPromise: Thenable<boolean>;
let checkOrphanedPromise: Promise<boolean>;
if (newInOrphanModeGuess) {
// We have received reports of users seeing delete events even though the file still
// exists (network shares issue: https://github.com/Microsoft/vscode/issues/13665).
@@ -187,7 +186,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
const autoSaveAfterMilliesEnabled = (typeof config.autoSaveDelay === 'number') && config.autoSaveDelay > 0;
this.autoSaveAfterMilliesEnabled = autoSaveAfterMilliesEnabled;
this.autoSaveAfterMillies = autoSaveAfterMilliesEnabled ? config.autoSaveDelay : void 0;
this.autoSaveAfterMillies = autoSaveAfterMilliesEnabled ? config.autoSaveDelay : undefined;
}
private onFilesAssociationChange(): void {
@@ -196,7 +195,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
}
const firstLineText = this.getFirstLineText(this.textEditorModel);
const languageSelection = this.getOrCreateMode(this.modeService, void 0, firstLineText);
const languageSelection = this.getOrCreateMode(this.modeService, undefined, firstLineText);
this.modelService.setMode(this.textEditorModel, languageSelection);
}
@@ -205,9 +204,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return this.versionId;
}
revert(soft?: boolean): TPromise<void> {
revert(soft?: boolean): Promise<void> {
if (!this.isResolved()) {
return TPromise.wrap<void>(null);
return Promise.resolve(undefined);
}
// Cancel any running auto-save
@@ -216,9 +215,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// Unset flags
const undo = this.setDirty(false);
let loadPromise: TPromise<TextFileEditorModel>;
let loadPromise: Promise<TextFileEditorModel>;
if (soft) {
loadPromise = TPromise.as(this);
loadPromise = Promise.resolve();
} else {
loadPromise = this.load({ forceReadFromDisk: true });
}
@@ -232,11 +231,11 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// Set flags back to previous values, we are still dirty if revert failed
undo();
return TPromise.wrapError(error);
return Promise.reject(error);
});
}
load(options?: ILoadOptions): TPromise<TextFileEditorModel> {
load(options?: ILoadOptions): Promise<TextFileEditorModel> {
this.logService.trace('load() - enter', this.resource);
// It is very important to not reload the model when the model is dirty.
@@ -245,7 +244,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
if (this.dirty || this.saveSequentializer.hasPendingSave()) {
this.logService.trace('load() - exit - without loading because model is dirty or being saved', this.resource);
return TPromise.as(this);
return Promise.resolve(this);
}
// Only for new models we support to load from backup
@@ -257,12 +256,12 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return this.loadFromFile(options);
}
private loadFromBackup(options?: ILoadOptions): TPromise<TextFileEditorModel> {
private loadFromBackup(options?: ILoadOptions): Promise<TextFileEditorModel> {
return this.backupFileService.loadBackupResource(this.resource).then(backup => {
// Make sure meanwhile someone else did not suceed or start loading
if (this.createTextEditorModelPromise || this.textEditorModel) {
return this.createTextEditorModelPromise || TPromise.as(this);
return this.createTextEditorModelPromise || this;
}
// If we have a backup, continue loading with it
@@ -271,7 +270,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
resource: this.resource,
name: path.basename(this.resource.fsPath),
mtime: Date.now(),
etag: void 0,
etag: undefined,
value: createTextBufferFactory(''), /* will be filled later from backup */
encoding: this.fileService.encoding.getWriteEncoding(this.resource, this.preferredEncoding),
isReadonly: false
@@ -285,14 +284,14 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
});
}
private loadFromFile(options?: ILoadOptions): TPromise<TextFileEditorModel> {
private loadFromFile(options?: ILoadOptions): Promise<TextFileEditorModel> {
const forceReadFromDisk = options && options.forceReadFromDisk;
const allowBinary = this.isResolved() /* always allow if we resolved previously */ || (options && options.allowBinary);
// Decide on etag
let etag: string;
if (forceReadFromDisk) {
etag = void 0; // reset ETag if we enforce to read from disk
etag = undefined; // reset ETag if we enforce to read from disk
} else if (this.lastResolvedDiskStat) {
etag = this.lastResolvedDiskStat.etag; // otherwise respect etag to support caching
}
@@ -333,22 +332,22 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
this.setDirty(false); // Ensure we are not tracking a stale state
}
return TPromise.as<TextFileEditorModel>(this);
return this;
}
// Ignore when a model has been resolved once and the file was deleted meanwhile. Since
// we already have the model loaded, we can return to this state and update the orphaned
// flag to indicate that this model has no version on disk anymore.
if (this.isResolved() && result === FileOperationResult.FILE_NOT_FOUND) {
return TPromise.as<TextFileEditorModel>(this);
return this;
}
// Otherwise bubble up the error
return TPromise.wrapError<TextFileEditorModel>(error);
return Promise.reject<TextFileEditorModel>(error);
});
}
private loadWithContent(content: IRawTextContent, options?: ILoadOptions, backup?: URI): TPromise<TextFileEditorModel> {
private loadWithContent(content: IRawTextContent, options?: ILoadOptions, backup?: URI): Promise<TextFileEditorModel> {
return this.doLoadWithContent(content, backup).then(model => {
// Telemetry: We log the fileGet telemetry event after the model has been loaded to ensure a good mimetype
const settingsType = this.getTypeIfSettings();
@@ -374,7 +373,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
});
}
private doLoadWithContent(content: IRawTextContent, backup?: URI): TPromise<TextFileEditorModel> {
private doLoadWithContent(content: IRawTextContent, backup?: URI): Promise<TextFileEditorModel> {
this.logService.trace('load() - resolved content', this.resource);
// Update our resolved disk stat model
@@ -385,7 +384,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
etag: content.etag,
isDirectory: false,
isSymbolicLink: false,
children: void 0,
children: undefined,
isReadonly: content.isReadonly
} as IFileStat);
@@ -402,7 +401,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// Update Existing Model
if (this.textEditorModel) {
return this.doUpdateTextModel(content.value);
this.doUpdateTextModel(content.value);
return Promise.resolve(this);
}
// Join an existing request to create the editor model to avoid race conditions
@@ -416,7 +417,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return this.doCreateTextModel(content.resource, content.value, backup);
}
private doUpdateTextModel(value: ITextBufferFactory): TPromise<TextFileEditorModel> {
private doUpdateTextModel(value: ITextBufferFactory): void {
this.logService.trace('load() - updated text editor model', this.resource);
// Ensure we are not tracking a stale state
@@ -432,43 +433,41 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// Ensure we track the latest saved version ID given that the contents changed
this.updateSavedVersionId();
return TPromise.as<TextFileEditorModel>(this);
}
private doCreateTextModel(resource: URI, value: ITextBufferFactory, backup: URI): TPromise<TextFileEditorModel> {
private doCreateTextModel(resource: URI, value: ITextBufferFactory, backup: URI): Promise<TextFileEditorModel> {
this.logService.trace('load() - created text editor model', this.resource);
this.createTextEditorModelPromise = this.doLoadBackup(backup).then(backupContent => {
this.createTextEditorModelPromise = null;
// Create model
const hasBackupContent = !!backupContent;
this.createTextEditorModel(hasBackupContent ? backupContent : value, resource);
return this.createTextEditorModel(hasBackupContent ? backupContent : value, resource).then(() => {
this.createTextEditorModelPromise = null;
// We restored a backup so we have to set the model as being dirty
// We also want to trigger auto save if it is enabled to simulate the exact same behaviour
// you would get if manually making the model dirty (fixes https://github.com/Microsoft/vscode/issues/16977)
if (hasBackupContent) {
this.makeDirty();
if (this.autoSaveAfterMilliesEnabled) {
this.doAutoSave(this.versionId);
}
// We restored a backup so we have to set the model as being dirty
// We also want to trigger auto save if it is enabled to simulate the exact same behaviour
// you would get if manually making the model dirty (fixes https://github.com/Microsoft/vscode/issues/16977)
if (hasBackupContent) {
this.makeDirty();
if (this.autoSaveAfterMilliesEnabled) {
this.doAutoSave(this.versionId);
}
}
// Ensure we are not tracking a stale state
else {
this.setDirty(false);
}
// Ensure we are not tracking a stale state
else {
this.setDirty(false);
}
// Model Listeners
this.installModelListeners();
// Model Listeners
this.installModelListeners();
return this;
}, error => {
this.createTextEditorModelPromise = null;
return this;
}, error => {
this.createTextEditorModelPromise = null;
return TPromise.wrapError<TextFileEditorModel>(error);
});
return Promise.reject<TextFileEditorModel>(error);
});
return this.createTextEditorModelPromise;
@@ -484,9 +483,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
this._register(this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged()));
}
private doLoadBackup(backup: URI): TPromise<ITextBufferFactory> {
private doLoadBackup(backup: URI): Promise<ITextBufferFactory | null> {
if (!backup) {
return TPromise.as(null);
return Promise.resolve(null);
}
return this.backupFileService.resolveBackupContent(backup).then(backupContent => backupContent, error => null /* ignore errors */);
@@ -578,13 +577,13 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
private cancelPendingAutoSave(): void {
if (this.autoSaveDisposable) {
this.autoSaveDisposable.dispose();
this.autoSaveDisposable = void 0;
this.autoSaveDisposable = undefined;
}
}
save(options: ISaveOptions = Object.create(null)): TPromise<void> {
save(options: ISaveOptions = Object.create(null)): Promise<void> {
if (!this.isResolved()) {
return TPromise.wrap<void>(null);
return Promise.resolve(undefined);
}
this.logService.trace('save() - enter', this.resource);
@@ -595,7 +594,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return this.doSave(this.versionId, options);
}
private doSave(versionId: number, options: ISaveOptions): TPromise<void> {
private doSave(versionId: number, options: ISaveOptions): Promise<void> {
if (isUndefinedOrNull(options.reason)) {
options.reason = SaveReason.EXPLICIT;
}
@@ -623,7 +622,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
if ((!options.force && !this.dirty) || versionId !== this.versionId) {
this.logService.trace(`doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`, this.resource);
return TPromise.wrap<void>(null);
return Promise.resolve(undefined);
}
// Return if currently saving by storing this save request as the next save that should happen.
@@ -651,7 +650,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// we do not want to trigger another auto save or similar, so we block this
// In addition we update our version right after in case it changed because of a model change
// Save participants can also be skipped through API.
let saveParticipantPromise = TPromise.as(versionId);
let saveParticipantPromise: Promise<number> = Promise.resolve(versionId);
if (TextFileEditorModel.saveParticipant && !options.skipSaveParticipants) {
const onCompleteOrError = () => {
this.blockModelContentChange = false;
@@ -659,11 +658,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return this.versionId;
};
saveParticipantPromise = TPromise.as(undefined).then(() => {
this.blockModelContentChange = true;
return TextFileEditorModel.saveParticipant.participate(this, { reason: options.reason });
}).then(onCompleteOrError, onCompleteOrError);
this.blockModelContentChange = true;
saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError);
}
// mark the save participant as current pending save operation
@@ -676,7 +672,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// saving contents to disk that are stale (see https://github.com/Microsoft/vscode/issues/50942).
// To fix this issue, we will not store the contents to disk when we got disposed.
if (this.disposed) {
return void 0;
return undefined;
}
// Under certain conditions we do a short-cut of flushing contents to disk when we can assume that
@@ -799,9 +795,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// Check for workspace settings file
const folders = this.contextService.getWorkspace().folders;
for (let i = 0; i < folders.length; i++) {
for (const folder of folders) {
// {{SQL CARBON EDIT}}
if (isEqualOrParent(this.resource, folders[i].toResource('.azuredatastudio'))) {
if (isEqualOrParent(this.resource, folder.toResource('.azuredatastudio'))) {
const filename = path.basename(this.resource.fsPath);
if (TextFileEditorModel.WHITELIST_WORKSPACE_JSON.indexOf(filename) > -1) {
// {{SQL CARBON EDIT}}
@@ -839,7 +835,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return telemetryData;
}
private doTouch(versionId: number): TPromise<void> {
private doTouch(versionId: number): Promise<void> {
return this.saveSequentializer.setPending(versionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot(), {
mtime: this.lastResolvedDiskStat.mtime,
encoding: this.getEncoding(),
@@ -1041,14 +1037,14 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
interface IPendingSave {
versionId: number;
promise: Thenable<void>;
promise: Promise<void>;
}
interface ISaveOperation {
promise: Thenable<void>;
promise: Promise<void>;
promiseResolve: () => void;
promiseReject: (error: Error) => void;
run: () => Thenable<void>;
run: () => Promise<void>;
}
export class SaveSequentializer {
@@ -1067,11 +1063,11 @@ export class SaveSequentializer {
return !!this._pendingSave;
}
get pendingSave(): Thenable<void> {
return this._pendingSave ? this._pendingSave.promise : void 0;
get pendingSave(): Promise<void> {
return this._pendingSave ? this._pendingSave.promise : undefined;
}
setPending(versionId: number, promise: Thenable<void>): Thenable<void> {
setPending(versionId: number, promise: Promise<void>): Promise<void> {
this._pendingSave = { versionId, promise };
promise.then(() => this.donePending(versionId), () => this.donePending(versionId));
@@ -1083,7 +1079,7 @@ export class SaveSequentializer {
if (this._pendingSave && versionId === this._pendingSave.versionId) {
// only set pending to done if the promise finished that is associated with that versionId
this._pendingSave = void 0;
this._pendingSave = undefined;
// schedule the next save now that we are free if we have any
this.triggerNextSave();
@@ -1093,14 +1089,14 @@ export class SaveSequentializer {
private triggerNextSave(): void {
if (this._nextSave) {
const saveOperation = this._nextSave;
this._nextSave = void 0;
this._nextSave = undefined;
// Run next save and complete on the associated promise
saveOperation.run().then(saveOperation.promiseResolve, saveOperation.promiseReject);
}
}
setNext(run: () => Thenable<void>): Thenable<void> {
setNext(run: () => Promise<void>): Promise<void> {
// this is our first next save, so we create associated promise with it
// so that we can return a promise that completes when the save operation
@@ -1132,7 +1128,7 @@ export class SaveSequentializer {
class DefaultSaveErrorHandler implements ISaveErrorHandler {
constructor(@INotificationService private notificationService: INotificationService) { }
constructor(@INotificationService private readonly notificationService: INotificationService) { }
onSaveError(error: any, model: TextFileEditorModel): void {
this.notificationService.error(nls.localize('genericSaveError', "Failed to save '{0}': {1}", path.basename(model.getResource().fsPath), toErrorMessage(error, false)));

View File

@@ -3,8 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event, Emitter, debounceEvent } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { Event, Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { dispose, IDisposable, Disposable } from 'vs/base/common/lifecycle';
@@ -12,7 +11,6 @@ import { ITextFileEditorModel, ITextFileEditorModelManager, TextFileModelChangeE
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ResourceMap } from 'vs/base/common/map';
import { onUnexpectedError } from 'vs/base/common/errors';
export class TextFileEditorModelManager extends Disposable implements ITextFileEditorModelManager {
@@ -49,11 +47,11 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
private mapResourceToStateChangeListener: ResourceMap<IDisposable>;
private mapResourceToModelContentChangeListener: ResourceMap<IDisposable>;
private mapResourceToModel: ResourceMap<ITextFileEditorModel>;
private mapResourceToPendingModelLoaders: ResourceMap<TPromise<ITextFileEditorModel>>;
private mapResourceToPendingModelLoaders: ResourceMap<Promise<ITextFileEditorModel>>;
constructor(
@ILifecycleService private lifecycleService: ILifecycleService,
@IInstantiationService private instantiationService: IInstantiationService
@ILifecycleService private readonly lifecycleService: ILifecycleService,
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super();
@@ -61,7 +59,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
this.mapResourceToDisposeListener = new ResourceMap<IDisposable>();
this.mapResourceToStateChangeListener = new ResourceMap<IDisposable>();
this.mapResourceToModelContentChangeListener = new ResourceMap<IDisposable>();
this.mapResourceToPendingModelLoaders = new ResourceMap<TPromise<ITextFileEditorModel>>();
this.mapResourceToPendingModelLoaders = new ResourceMap<Promise<ITextFileEditorModel>>();
this.registerListeners();
}
@@ -105,7 +103,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
}
private debounce(event: Event<TextFileModelChangeEvent>): Event<TextFileModelChangeEvent[]> {
return debounceEvent(event, (prev: TextFileModelChangeEvent[], cur: TextFileModelChangeEvent) => {
return Event.debounce(event, (prev: TextFileModelChangeEvent[], cur: TextFileModelChangeEvent) => {
if (!prev) {
prev = [cur];
} else {
@@ -123,7 +121,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
return this.mapResourceToModel.get(resource);
}
loadOrCreate(resource: URI, options?: IModelLoadOrCreateOptions): TPromise<ITextFileEditorModel> {
loadOrCreate(resource: URI, options?: IModelLoadOrCreateOptions): Promise<ITextFileEditorModel> {
// Return early if model is currently being loaded
const pendingLoad = this.mapResourceToPendingModelLoaders.get(resource);
@@ -131,7 +129,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
return pendingLoad;
}
let modelPromise: TPromise<ITextFileEditorModel>;
let modelPromise: Promise<ITextFileEditorModel>;
// Model exists
let model = this.get(resource);
@@ -140,8 +138,8 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
// async reload: trigger a reload but return immediately
if (options.reload.async) {
modelPromise = TPromise.as(model);
model.load(options).then(null, onUnexpectedError);
modelPromise = Promise.resolve(model);
model.load(options);
}
// sync reload: do not return until model reloaded
@@ -149,13 +147,13 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
modelPromise = model.load(options);
}
} else {
modelPromise = TPromise.as(model);
modelPromise = Promise.resolve(model);
}
}
// Model does not exist
else {
model = this.instantiationService.createInstance(TextFileEditorModel, resource, options ? options.encoding : void 0);
model = this.instantiationService.createInstance(TextFileEditorModel, resource, options ? options.encoding : undefined);
modelPromise = model.load(options);
// Install state change listener
@@ -214,7 +212,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE
// Remove from pending loads
this.mapResourceToPendingModelLoaders.delete(resource);
return TPromise.wrapError<ITextFileEditorModel>(error);
return Promise.reject<ITextFileEditorModel>(error);
});
}

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { URI } from 'vs/base/common/uri';
import * as paths from 'vs/base/common/paths';
import * as errors from 'vs/base/common/errors';
@@ -97,11 +96,11 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this._models;
}
abstract resolveTextContent(resource: URI, options?: IResolveContentOptions): TPromise<IRawTextContent>;
abstract resolveTextContent(resource: URI, options?: IResolveContentOptions): Promise<IRawTextContent>;
abstract promptForPath(resource: URI, defaultPath: URI): TPromise<URI>;
abstract promptForPath(resource: URI, defaultPath: URI): Promise<URI>;
abstract confirmSave(resources?: URI[]): TPromise<ConfirmResult>;
abstract confirmSave(resources?: URI[]): Promise<ConfirmResult>;
private registerListeners(): void {
@@ -117,7 +116,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
}));
}
private beforeShutdown(reason: ShutdownReason): boolean | TPromise<boolean> {
private beforeShutdown(reason: ShutdownReason): boolean | Promise<boolean> {
// Dirty files need treatment on shutdown
const dirty = this.getDirty();
@@ -125,49 +124,51 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
// If auto save is enabled, save all files and then check again for dirty files
// We DO NOT run any save participant if we are in the shutdown phase for performance reasons
let handleAutoSave: TPromise<URI[] /* remaining dirty resources */>;
if (this.getAutoSaveMode() !== AutoSaveMode.OFF) {
handleAutoSave = this.saveAll(false /* files only */, { skipSaveParticipants: true }).then(() => this.getDirty());
} else {
handleAutoSave = TPromise.as(dirty);
}
return this.saveAll(false /* files only */, { skipSaveParticipants: true }).then(() => {
return handleAutoSave.then(dirty => {
// If we still have dirty files, we either have untitled ones or files that cannot be saved
// or auto save was not enabled and as such we did not save any dirty files to disk automatically
if (dirty.length) {
// If hot exit is enabled, backup dirty files and allow to exit without confirmation
if (this.isHotExitEnabled) {
return this.backupBeforeShutdown(dirty, this.models, reason).then(result => {
if (result.didBackup) {
return this.noVeto({ cleanUpBackups: false }); // no veto and no backup cleanup (since backup was successful)
}
// since a backup did not happen, we have to confirm for the dirty files now
return this.confirmBeforeShutdown();
}, errors => {
const firstError = errors[0];
this.notificationService.error(nls.localize('files.backup.failSave', "Files that are dirty could not be written to the backup location (Error: {0}). Try saving your files first and then exit.", firstError.message));
return true; // veto, the backups failed
});
// If we still have dirty files, we either have untitled ones or files that cannot be saved
const remainingDirty = this.getDirty();
if (remainingDirty.length) {
return this.handleDirtyBeforeShutdown(remainingDirty, reason);
}
// Otherwise just confirm from the user what to do with the dirty files
return this.confirmBeforeShutdown();
}
return undefined;
});
}
return void 0;
});
// Auto save is not enabled
return this.handleDirtyBeforeShutdown(dirty, reason);
}
// No dirty files: no veto
return this.noVeto({ cleanUpBackups: true });
}
private backupBeforeShutdown(dirtyToBackup: URI[], textFileEditorModelManager: ITextFileEditorModelManager, reason: ShutdownReason): TPromise<IBackupResult> {
private handleDirtyBeforeShutdown(dirty: URI[], reason: ShutdownReason): boolean | Promise<boolean> {
// If hot exit is enabled, backup dirty files and allow to exit without confirmation
if (this.isHotExitEnabled) {
return this.backupBeforeShutdown(dirty, this.models, reason).then(result => {
if (result.didBackup) {
return this.noVeto({ cleanUpBackups: false }); // no veto and no backup cleanup (since backup was successful)
}
// since a backup did not happen, we have to confirm for the dirty files now
return this.confirmBeforeShutdown();
}, errors => {
const firstError = errors[0];
this.notificationService.error(nls.localize('files.backup.failSave', "Files that are dirty could not be written to the backup location (Error: {0}). Try saving your files first and then exit.", firstError.message));
return true; // veto, the backups failed
});
}
// Otherwise just confirm from the user what to do with the dirty files
return this.confirmBeforeShutdown();
}
private backupBeforeShutdown(dirtyToBackup: URI[], textFileEditorModelManager: ITextFileEditorModelManager, reason: ShutdownReason): Promise<IBackupResult> {
return this.windowsService.getWindowCount().then(windowCount => {
// When quit is requested skip the confirm callback and attempt to backup all workspaces.
@@ -205,7 +206,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
}
if (!doBackup) {
return TPromise.as({ didBackup: false });
return { didBackup: false };
}
// Backup
@@ -213,7 +214,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
});
}
private backupAll(dirtyToBackup: URI[], textFileEditorModelManager: ITextFileEditorModelManager): TPromise<void> {
private backupAll(dirtyToBackup: URI[], textFileEditorModelManager: ITextFileEditorModelManager): Promise<void> {
// split up between files and untitled
const filesToBackup: ITextFileEditorModel[] = [];
@@ -229,27 +230,27 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.doBackupAll(filesToBackup, untitledToBackup);
}
private doBackupAll(dirtyFileModels: ITextFileEditorModel[], untitledResources: URI[]): TPromise<void> {
private doBackupAll(dirtyFileModels: ITextFileEditorModel[], untitledResources: URI[]): Promise<void> {
// Handle file resources first
return TPromise.join(dirtyFileModels.map(model => this.backupFileService.backupResource(model.getResource(), model.createSnapshot(), model.getVersionId()))).then(results => {
return Promise.all(dirtyFileModels.map(model => this.backupFileService.backupResource(model.getResource(), model.createSnapshot(), model.getVersionId()))).then(results => {
// Handle untitled resources
const untitledModelPromises = untitledResources
.filter(untitled => this.untitledEditorService.exists(untitled))
.map(untitled => this.untitledEditorService.loadOrCreate({ resource: untitled }));
return TPromise.join(untitledModelPromises).then(untitledModels => {
return Promise.all(untitledModelPromises).then(untitledModels => {
const untitledBackupPromises = untitledModels.map(model => {
return this.backupFileService.backupResource(model.getResource(), model.createSnapshot(), model.getVersionId());
});
return TPromise.join(untitledBackupPromises).then(() => void 0);
return Promise.all(untitledBackupPromises).then(() => undefined);
});
});
}
private confirmBeforeShutdown(): boolean | TPromise<boolean> {
private confirmBeforeShutdown(): boolean | Promise<boolean> {
return this.confirmSave().then(confirm => {
// Save
@@ -278,11 +279,11 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return true; // veto
}
return void 0;
return undefined;
});
}
private noVeto(options: { cleanUpBackups: boolean }): boolean | TPromise<boolean> {
private noVeto(options: { cleanUpBackups: boolean }): boolean | Promise<boolean> {
if (!options.cleanUpBackups) {
return false;
}
@@ -294,9 +295,9 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.cleanupBackupsBeforeShutdown().then(() => false, () => false);
}
protected cleanupBackupsBeforeShutdown(): TPromise<void> {
protected cleanupBackupsBeforeShutdown(): Promise<void> {
if (this.environmentService.isExtensionDevelopment) {
return TPromise.as(void 0);
return Promise.resolve(undefined);
}
return this.backupFileService.discardAllWorkspaceBackups();
@@ -315,19 +316,19 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
break;
case AutoSaveConfiguration.ON_FOCUS_CHANGE:
this.configuredAutoSaveDelay = void 0;
this.configuredAutoSaveDelay = undefined;
this.configuredAutoSaveOnFocusChange = true;
this.configuredAutoSaveOnWindowChange = false;
break;
case AutoSaveConfiguration.ON_WINDOW_CHANGE:
this.configuredAutoSaveDelay = void 0;
this.configuredAutoSaveDelay = undefined;
this.configuredAutoSaveOnFocusChange = false;
this.configuredAutoSaveOnWindowChange = true;
break;
default:
this.configuredAutoSaveDelay = void 0;
this.configuredAutoSaveDelay = undefined;
this.configuredAutoSaveOnFocusChange = false;
this.configuredAutoSaveOnWindowChange = false;
break;
@@ -379,16 +380,12 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.untitledEditorService.getDirty().some(dirty => !resource || dirty.toString() === resource.toString());
}
save(resource: URI, options?: ISaveOptions): TPromise<boolean> {
save(resource: URI, options?: ISaveOptions): Promise<boolean> {
// Run a forced save if we detect the file is not dirty so that save participants can still run
if (options && options.force && this.fileService.canHandleResource(resource) && !this.isDirty(resource)) {
const model = this._models.get(resource);
if (model) {
if (!options) {
options = Object.create(null);
}
options.reason = SaveReason.EXPLICIT;
return model.save(options).then(() => !model.isDirty());
@@ -398,9 +395,9 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.saveAll([resource], options).then(result => result.results.length === 1 && result.results[0].success);
}
saveAll(includeUntitled?: boolean, options?: ISaveOptions): TPromise<ITextFileOperationResult>;
saveAll(resources: URI[], options?: ISaveOptions): TPromise<ITextFileOperationResult>;
saveAll(arg1?: any, options?: ISaveOptions): TPromise<ITextFileOperationResult> {
saveAll(includeUntitled?: boolean, options?: ISaveOptions): Promise<ITextFileOperationResult>;
saveAll(resources: URI[], options?: ISaveOptions): Promise<ITextFileOperationResult>;
saveAll(arg1?: any, options?: ISaveOptions): Promise<ITextFileOperationResult> {
// get all dirty
let toSave: URI[] = [];
@@ -424,15 +421,14 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.doSaveAll(filesToSave, untitledToSave, options);
}
private doSaveAll(fileResources: URI[], untitledResources: URI[], options?: ISaveOptions): TPromise<ITextFileOperationResult> {
private doSaveAll(fileResources: URI[], untitledResources: URI[], options?: ISaveOptions): Promise<ITextFileOperationResult> {
// Handle files first that can just be saved
return this.doSaveAllFiles(fileResources, options).then(async result => {
// Preflight for untitled to handle cancellation from the dialog
const targetsForUntitled: URI[] = [];
for (let i = 0; i < untitledResources.length; i++) {
const untitled = untitledResources[i];
for (const untitled of untitledResources) {
if (this.untitledEditorService.exists(untitled)) {
let targetUri: URI;
@@ -445,12 +441,8 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
else {
const targetPath = await this.promptForPath(untitled, this.suggestFileName(untitled));
if (!targetPath) {
return TPromise.as({
results: [...fileResources, ...untitledResources].map(r => {
return {
source: r
};
})
return Promise.resolve({
results: [...fileResources, ...untitledResources].map(r => ({ source: r }))
});
}
@@ -462,7 +454,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
}
// Handle untitled
const untitledSaveAsPromises: TPromise<void>[] = [];
const untitledSaveAsPromises: Promise<void>[] = [];
targetsForUntitled.forEach((target, index) => {
const untitledSaveAsPromise = this.saveAs(untitledResources[index], target).then(uri => {
result.results.push({
@@ -475,14 +467,12 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
untitledSaveAsPromises.push(untitledSaveAsPromise);
});
return TPromise.join(untitledSaveAsPromises).then(() => {
return result;
});
return Promise.all(untitledSaveAsPromises).then(() => result);
});
}
private doSaveAllFiles(resources?: URI[], options: ISaveOptions = Object.create(null)): TPromise<ITextFileOperationResult> {
const dirtyFileModels = this.getDirtyFileModels(Array.isArray(resources) ? resources : void 0 /* Save All */)
private doSaveAllFiles(resources?: URI[], options: ISaveOptions = Object.create(null)): Promise<ITextFileOperationResult> {
const dirtyFileModels = this.getDirtyFileModels(Array.isArray(resources) ? resources : undefined /* Save All */)
.filter(model => {
if ((model.hasState(ModelState.CONFLICT) || model.hasState(ModelState.ERROR)) && (options.reason === SaveReason.AUTO || options.reason === SaveReason.FOCUS_CHANGE || options.reason === SaveReason.WINDOW_CHANGE)) {
return false; // if model is in save conflict or error, do not save unless save reason is explicit or not provided at all
@@ -498,17 +488,13 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
});
});
return TPromise.join(dirtyFileModels.map(model => {
return Promise.all(dirtyFileModels.map(model => {
return model.save(options).then(() => {
if (!model.isDirty()) {
mapResourceToResult.get(model.getResource()).success = true;
}
});
})).then(r => {
return {
results: mapResourceToResult.values()
};
});
})).then(r => ({ results: mapResourceToResult.values() }));
}
private getFileModels(resources?: URI[]): ITextFileEditorModel[];
@@ -532,12 +518,12 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.getFileModels(arg1).filter(model => model.isDirty());
}
saveAs(resource: URI, target?: URI, options?: ISaveOptions): TPromise<URI> {
saveAs(resource: URI, target?: URI, options?: ISaveOptions): Promise<URI> {
// Get to target resource
let targetPromise: TPromise<URI>;
let targetPromise: Promise<URI>;
if (target) {
targetPromise = TPromise.wrap(target);
targetPromise = Promise.resolve(target);
} else {
let dialogPath = resource;
if (resource.scheme === Schemas.untitled) {
@@ -549,7 +535,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return targetPromise.then(target => {
if (!target) {
return TPromise.as(null); // user canceled
return null; // user canceled
}
// Just save if target is same as models own resource
@@ -562,12 +548,12 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
});
}
private doSaveAs(resource: URI, target?: URI, options?: ISaveOptions): TPromise<URI> {
private doSaveAs(resource: URI, target?: URI, options?: ISaveOptions): Promise<URI> {
// Retrieve text model from provided resource if any
let modelPromise: TPromise<ITextFileEditorModel | UntitledEditorModel> = TPromise.as(null);
let modelPromise: Promise<ITextFileEditorModel | UntitledEditorModel> = Promise.resolve(null);
if (this.fileService.canHandleResource(resource)) {
modelPromise = TPromise.as(this._models.get(resource));
modelPromise = Promise.resolve(this._models.get(resource));
} else if (resource.scheme === Schemas.untitled && this.untitledEditorService.exists(resource)) {
modelPromise = this.untitledEditorService.loadOrCreate({ resource });
}
@@ -592,13 +578,13 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
});
}
private doSaveTextFileAs(sourceModel: ITextFileEditorModel | UntitledEditorModel, resource: URI, target: URI, options?: ISaveOptions): TPromise<void> {
let targetModelResolver: TPromise<ITextFileEditorModel>;
private doSaveTextFileAs(sourceModel: ITextFileEditorModel | UntitledEditorModel, resource: URI, target: URI, options?: ISaveOptions): Promise<void> {
let targetModelResolver: Promise<ITextFileEditorModel>;
// Prefer an existing model if it is already loaded for the given target resource
const targetModel = this.models.get(target);
if (targetModel && targetModel.isResolved()) {
targetModelResolver = TPromise.as(targetModel);
targetModelResolver = Promise.resolve(targetModel);
}
// Otherwise create the target file empty if it does not exist already and resolve it from there
@@ -623,7 +609,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.fileService.del(target).then(() => this.doSaveTextFileAs(sourceModel, resource, target, options));
}
return TPromise.wrapError(error);
return Promise.reject(error);
});
}
@@ -646,11 +632,11 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return URI.file(untitledFileName);
}
revert(resource: URI, options?: IRevertOptions): TPromise<boolean> {
revert(resource: URI, options?: IRevertOptions): Promise<boolean> {
return this.revertAll([resource], options).then(result => result.results.length === 1 && result.results[0].success);
}
revertAll(resources?: URI[], options?: IRevertOptions): TPromise<ITextFileOperationResult> {
revertAll(resources?: URI[], options?: IRevertOptions): Promise<ITextFileOperationResult> {
// Revert files first
return this.doRevertAllFiles(resources, options).then(operation => {
@@ -663,7 +649,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
});
}
private doRevertAllFiles(resources?: URI[], options?: IRevertOptions): TPromise<ITextFileOperationResult> {
private doRevertAllFiles(resources?: URI[], options?: IRevertOptions): Promise<ITextFileOperationResult> {
const fileModels = options && options.force ? this.getFileModels(resources) : this.getDirtyFileModels(resources);
const mapResourceToResult = new ResourceMap<IResult>();
@@ -673,7 +659,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
});
});
return TPromise.join(fileModels.map(model => {
return Promise.all(fileModels.map(model => {
return model.revert(options && options.soft).then(() => {
if (!model.isDirty()) {
mapResourceToResult.get(model.getResource()).success = true;
@@ -687,19 +673,15 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
// Otherwise bubble up the error
else {
return TPromise.wrapError(error);
return Promise.reject(error);
}
return void 0;
return undefined;
});
})).then(r => {
return {
results: mapResourceToResult.values()
};
});
})).then(r => ({ results: mapResourceToResult.values() }));
}
create(resource: URI, contents?: string, options?: { overwrite?: boolean }): TPromise<void> {
create(resource: URI, contents?: string, options?: { overwrite?: boolean }): Promise<void> {
const existingModel = this.models.get(resource);
return this.fileService.createFile(resource, contents, options).then(() => {
@@ -712,34 +694,35 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return existingModel.revert();
}
return void 0;
return undefined;
});
}
delete(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): TPromise<void> {
delete(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): Promise<void> {
const dirtyFiles = this.getDirty().filter(dirty => isEqualOrParent(dirty, resource, !platform.isLinux /* ignorecase */));
return this.revertAll(dirtyFiles, { soft: true }).then(() => this.fileService.del(resource, options));
}
move(source: URI, target: URI, overwrite?: boolean): TPromise<void> {
move(source: URI, target: URI, overwrite?: boolean): Promise<void> {
const waitForPromises: Promise<any>[] = [];
const waitForPromises: TPromise[] = [];
// Event
this._onWillMove.fire({
oldResource: source,
newResource: target,
waitUntil(p: Thenable<any>) {
waitForPromises.push(TPromise.wrap(p).then(undefined, errors.onUnexpectedError));
waitUntil(promise: Promise<any>) {
waitForPromises.push(promise.then(undefined, errors.onUnexpectedError));
}
});
// prevent async waitUntil-calls
Object.freeze(waitForPromises);
return TPromise.join(waitForPromises).then(() => {
return Promise.all(waitForPromises).then(() => {
// Handle target models if existing (if target URI is a folder, this can be multiple)
let handleTargetModelPromise: TPromise<any> = TPromise.as(void 0);
let handleTargetModelPromise: Promise<any> = Promise.resolve();
const dirtyTargetModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), target, false /* do not ignorecase, see https://github.com/Microsoft/vscode/issues/56384 */));
if (dirtyTargetModels.length) {
handleTargetModelPromise = this.revertAll(dirtyTargetModels.map(targetModel => targetModel.getResource()), { soft: true });
@@ -748,11 +731,11 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return handleTargetModelPromise.then(() => {
// Handle dirty source models if existing (if source URI is a folder, this can be multiple)
let handleDirtySourceModels: TPromise<any>;
let handleDirtySourceModels: Promise<any>;
const dirtySourceModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), source, !platform.isLinux /* ignorecase */));
const dirtyTargetModels: URI[] = [];
if (dirtySourceModels.length) {
handleDirtySourceModels = TPromise.join(dirtySourceModels.map(sourceModel => {
handleDirtySourceModels = Promise.all(dirtySourceModels.map(sourceModel => {
const sourceModelResource = sourceModel.getResource();
let targetModelResource: URI;
@@ -774,7 +757,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.backupFileService.backupResource(targetModelResource, sourceModel.createSnapshot(), sourceModel.getVersionId());
}));
} else {
handleDirtySourceModels = TPromise.as(void 0);
handleDirtySourceModels = Promise.resolve();
}
return handleDirtySourceModels.then(() => {
@@ -786,12 +769,12 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
return this.fileService.moveFile(source, target, overwrite).then(() => {
// Load models that were dirty before
return TPromise.join(dirtyTargetModels.map(dirtyTargetModel => this.models.loadOrCreate(dirtyTargetModel))).then(() => void 0);
return Promise.all(dirtyTargetModels.map(dirtyTargetModel => this.models.loadOrCreate(dirtyTargetModel))).then(() => undefined);
}, error => {
// In case of an error, discard any dirty target backups that were made
return TPromise.join(dirtyTargetModels.map(dirtyTargetModel => this.backupFileService.discardResourceBackup(dirtyTargetModel)))
.then(() => TPromise.wrapError(error));
return Promise.all(dirtyTargetModels.map(dirtyTargetModel => this.backupFileService.discardResourceBackup(dirtyTargetModel)))
.then(() => Promise.reject(error));
});
});
});
@@ -817,7 +800,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer
getAutoSaveConfiguration(): IAutoSaveConfiguration {
return {
autoSaveDelay: this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0 ? this.configuredAutoSaveDelay : void 0,
autoSaveDelay: this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0 ? this.configuredAutoSaveDelay : undefined,
autoSaveFocusChange: this.configuredAutoSaveOnFocusChange,
autoSaveApplicationChange: this.configuredAutoSaveOnWindowChange
};

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base';
import { URI } from 'vs/base/common/uri';
import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
@@ -30,7 +29,7 @@ export interface ISaveParticipant {
/**
* Participate in a save of a model. Allows to change the model before it is being saved to disk.
*/
participate(model: ITextFileEditorModel, env: { reason: SaveReason }): void;
participate(model: ITextFileEditorModel, env: { reason: SaveReason }): Promise<void>;
}
/**
@@ -194,7 +193,7 @@ export interface ITextFileEditorModelManager {
getAll(resource?: URI): ITextFileEditorModel[];
loadOrCreate(resource: URI, options?: IModelLoadOrCreateOptions): TPromise<ITextFileEditorModel>;
loadOrCreate(resource: URI, options?: IModelLoadOrCreateOptions): Promise<ITextFileEditorModel>;
disposeModel(model: ITextFileEditorModel): void;
}
@@ -241,11 +240,11 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
updatePreferredEncoding(encoding: string): void;
save(options?: ISaveOptions): TPromise<void>;
save(options?: ISaveOptions): Promise<void>;
load(options?: ILoadOptions): Thenable<ITextFileEditorModel>;
load(options?: ILoadOptions): Promise<ITextFileEditorModel>;
revert(soft?: boolean): TPromise<void>;
revert(soft?: boolean): Promise<void>;
createSnapshot(): ITextSnapshot;
@@ -260,7 +259,7 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
export interface IWillMoveEvent {
oldResource: URI;
newResource: URI;
waitUntil(p: Thenable<any>): void;
waitUntil(p: Promise<any>): void;
}
export interface ITextFileService extends IDisposable {
@@ -281,7 +280,7 @@ export interface ITextFileService extends IDisposable {
/**
* Resolve the contents of a file identified by the resource.
*/
resolveTextContent(resource: URI, options?: IResolveContentOptions): TPromise<IRawTextContent>;
resolveTextContent(resource: URI, options?: IResolveContentOptions): Promise<IRawTextContent>;
/**
* A resource is dirty if it has unsaved changes or is an untitled file not yet saved.
@@ -306,7 +305,7 @@ export interface ITextFileService extends IDisposable {
* @param options optional save options
* @return true if the resource was saved.
*/
save(resource: URI, options?: ISaveOptions): TPromise<boolean>;
save(resource: URI, options?: ISaveOptions): Promise<boolean>;
/**
* Saves the provided resource asking the user for a file name or using the provided one.
@@ -316,7 +315,7 @@ export interface ITextFileService extends IDisposable {
* @param options optional save options
* @return true if the file was saved.
*/
saveAs(resource: URI, targetResource?: URI, options?: ISaveOptions): TPromise<URI>;
saveAs(resource: URI, targetResource?: URI, options?: ISaveOptions): Promise<URI>;
/**
* Saves the set of resources and returns a promise with the operation result.
@@ -324,8 +323,8 @@ export interface ITextFileService extends IDisposable {
* @param resources can be null to save all.
* @param includeUntitled to save all resources and optionally exclude untitled ones.
*/
saveAll(includeUntitled?: boolean, options?: ISaveOptions): TPromise<ITextFileOperationResult>;
saveAll(resources: URI[], options?: ISaveOptions): TPromise<ITextFileOperationResult>;
saveAll(includeUntitled?: boolean, options?: ISaveOptions): Promise<ITextFileOperationResult>;
saveAll(resources: URI[], options?: ISaveOptions): Promise<ITextFileOperationResult>;
/**
* Reverts the provided resource.
@@ -333,28 +332,28 @@ export interface ITextFileService extends IDisposable {
* @param resource the resource of the file to revert.
* @param force to force revert even when the file is not dirty
*/
revert(resource: URI, options?: IRevertOptions): TPromise<boolean>;
revert(resource: URI, options?: IRevertOptions): Promise<boolean>;
/**
* Reverts all the provided resources and returns a promise with the operation result.
*/
revertAll(resources?: URI[], options?: IRevertOptions): TPromise<ITextFileOperationResult>;
revertAll(resources?: URI[], options?: IRevertOptions): Promise<ITextFileOperationResult>;
/**
* Create a file. If the file exists it will be overwritten with the contents if
* the options enable to overwrite.
*/
create(resource: URI, contents?: string, options?: { overwrite?: boolean }): TPromise<void>;
create(resource: URI, contents?: string, options?: { overwrite?: boolean }): Promise<void>;
/**
* Delete a file. If the file is dirty, it will get reverted and then deleted from disk.
*/
delete(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): TPromise<void>;
delete(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): Promise<void>;
/**
* Move a file. If the file is dirty, its contents will be preserved and restored.
*/
move(source: URI, target: URI, overwrite?: boolean): TPromise<void>;
move(source: URI, target: URI, overwrite?: boolean): Promise<void>;
/**
* Brings up the confirm dialog to either save, don't save or cancel.
@@ -362,7 +361,7 @@ export interface ITextFileService extends IDisposable {
* @param resources the resources of the files to ask for confirmation or null if
* confirming for all dirty resources.
*/
confirmSave(resources?: URI[]): TPromise<ConfirmResult>;
confirmSave(resources?: URI[]): Promise<ConfirmResult>;
/**
* Convinient fast access to the current auto save mode.