mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-14 03:58:33 -05:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
@@ -14,7 +14,7 @@ import Event, { Emitter } from 'vs/base/common/event';
|
||||
import platform = require('vs/base/common/platform');
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
|
||||
import { IRevertOptions, IResult, ITextFileOperationResult, ITextFileService, IRawTextContent, IAutoSaveConfiguration, AutoSaveMode, SaveReason, ITextFileEditorModelManager, ITextFileEditorModel, ModelState, ISaveOptions } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IResult, ITextFileOperationResult, ITextFileService, IRawTextContent, IAutoSaveConfiguration, AutoSaveMode, SaveReason, ITextFileEditorModelManager, ITextFileEditorModel, ModelState, ISaveOptions, AutoSaveContext } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ConfirmResult } from 'vs/workbench/common/editor';
|
||||
import { ILifecycleService, ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
@@ -22,14 +22,18 @@ import { IFileService, IResolveContentOptions, IFilesConfiguration, FileOperatio
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IUntitledEditorService, UNTITLED_SCHEMA } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
|
||||
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IMessageService, Severity } from 'vs/platform/message/common/message';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IRevertOptions } from 'vs/platform/editor/common/editor';
|
||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
export interface IBackupResult {
|
||||
didBackup: boolean;
|
||||
@@ -55,6 +59,8 @@ export abstract class TextFileService implements ITextFileService {
|
||||
private configuredAutoSaveOnFocusChange: boolean;
|
||||
private configuredAutoSaveOnWindowChange: boolean;
|
||||
|
||||
private autoSaveContext: IContextKey<string>;
|
||||
|
||||
private configuredHotExit: string;
|
||||
|
||||
constructor(
|
||||
@@ -64,11 +70,13 @@ export abstract class TextFileService implements ITextFileService {
|
||||
protected fileService: IFileService,
|
||||
private untitledEditorService: IUntitledEditorService,
|
||||
private instantiationService: IInstantiationService,
|
||||
private messageService: IMessageService,
|
||||
private notificationService: INotificationService,
|
||||
protected environmentService: IEnvironmentService,
|
||||
private backupFileService: IBackupFileService,
|
||||
private windowsService: IWindowsService,
|
||||
private historyService: IHistoryService
|
||||
private historyService: IHistoryService,
|
||||
contextKeyService: IContextKeyService,
|
||||
private modelService: IModelService
|
||||
) {
|
||||
this.toUnbind = [];
|
||||
|
||||
@@ -79,6 +87,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
this.toUnbind.push(this._onFilesAssociationChange);
|
||||
|
||||
this._models = this.instantiationService.createInstance(TextFileEditorModelManager);
|
||||
this.autoSaveContext = AutoSaveContext.bindTo(contextKeyService);
|
||||
|
||||
const configuration = this.configurationService.getValue<IFilesConfiguration>();
|
||||
this.currentFilesAssociationConfig = configuration && configuration.files && configuration.files.associations;
|
||||
@@ -94,9 +103,9 @@ export abstract class TextFileService implements ITextFileService {
|
||||
|
||||
abstract resolveTextContent(resource: URI, options?: IResolveContentOptions): TPromise<IRawTextContent>;
|
||||
|
||||
abstract promptForPath(defaultPath: string): string;
|
||||
abstract promptForPath(defaultPath: string): TPromise<string>;
|
||||
|
||||
abstract confirmSave(resources?: URI[]): ConfirmResult;
|
||||
abstract confirmSave(resources?: URI[]): TPromise<ConfirmResult>;
|
||||
|
||||
public get onAutoSaveConfigurationChange(): Event<IAutoSaveConfiguration> {
|
||||
return this._onAutoSaveConfigurationChange.event;
|
||||
@@ -152,7 +161,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
return this.confirmBeforeShutdown();
|
||||
}, errors => {
|
||||
const firstError = errors[0];
|
||||
this.messageService.show(Severity.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));
|
||||
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
|
||||
});
|
||||
@@ -222,9 +231,9 @@ export abstract class TextFileService implements ITextFileService {
|
||||
const filesToBackup: ITextFileEditorModel[] = [];
|
||||
const untitledToBackup: URI[] = [];
|
||||
dirtyToBackup.forEach(s => {
|
||||
if (s.scheme === Schemas.file) {
|
||||
if (this.fileService.canHandleResource(s)) {
|
||||
filesToBackup.push(textFileEditorModelManager.get(s));
|
||||
} else if (s.scheme === UNTITLED_SCHEMA) {
|
||||
} else if (s.scheme === Schemas.untitled) {
|
||||
untitledToBackup.push(s);
|
||||
}
|
||||
});
|
||||
@@ -235,7 +244,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
private doBackupAll(dirtyFileModels: ITextFileEditorModel[], untitledResources: URI[]): TPromise<void> {
|
||||
|
||||
// Handle file resources first
|
||||
return TPromise.join(dirtyFileModels.map(model => this.backupFileService.backupResource(model.getResource(), model.getValue(), model.getVersionId()))).then(results => {
|
||||
return TPromise.join(dirtyFileModels.map(model => this.backupFileService.backupResource(model.getResource(), model.createSnapshot(), model.getVersionId()))).then(results => {
|
||||
|
||||
// Handle untitled resources
|
||||
const untitledModelPromises = untitledResources
|
||||
@@ -244,7 +253,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
|
||||
return TPromise.join(untitledModelPromises).then(untitledModels => {
|
||||
const untitledBackupPromises = untitledModels.map(model => {
|
||||
return this.backupFileService.backupResource(model.getResource(), model.getValue(), model.getVersionId());
|
||||
return this.backupFileService.backupResource(model.getResource(), model.createSnapshot(), model.getVersionId());
|
||||
});
|
||||
|
||||
return TPromise.join(untitledBackupPromises).then(() => void 0);
|
||||
@@ -253,35 +262,36 @@ export abstract class TextFileService implements ITextFileService {
|
||||
}
|
||||
|
||||
private confirmBeforeShutdown(): boolean | TPromise<boolean> {
|
||||
const confirm = this.confirmSave();
|
||||
return this.confirmSave().then(confirm => {
|
||||
|
||||
// Save
|
||||
if (confirm === ConfirmResult.SAVE) {
|
||||
return this.saveAll(true /* includeUntitled */, { skipSaveParticipants: true }).then(result => {
|
||||
if (result.results.some(r => !r.success)) {
|
||||
return true; // veto if some saves failed
|
||||
}
|
||||
// Save
|
||||
if (confirm === ConfirmResult.SAVE) {
|
||||
return this.saveAll(true /* includeUntitled */, { skipSaveParticipants: true }).then(result => {
|
||||
if (result.results.some(r => !r.success)) {
|
||||
return true; // veto if some saves failed
|
||||
}
|
||||
|
||||
return this.noVeto({ cleanUpBackups: true });
|
||||
});
|
||||
}
|
||||
|
||||
// Don't Save
|
||||
else if (confirm === ConfirmResult.DONT_SAVE) {
|
||||
|
||||
// Make sure to revert untitled so that they do not restore
|
||||
// see https://github.com/Microsoft/vscode/issues/29572
|
||||
this.untitledEditorService.revertAll();
|
||||
|
||||
return this.noVeto({ cleanUpBackups: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Don't Save
|
||||
else if (confirm === ConfirmResult.DONT_SAVE) {
|
||||
// Cancel
|
||||
else if (confirm === ConfirmResult.CANCEL) {
|
||||
return true; // veto
|
||||
}
|
||||
|
||||
// Make sure to revert untitled so that they do not restore
|
||||
// see https://github.com/Microsoft/vscode/issues/29572
|
||||
this.untitledEditorService.revertAll();
|
||||
|
||||
return this.noVeto({ cleanUpBackups: true });
|
||||
}
|
||||
|
||||
// Cancel
|
||||
else if (confirm === ConfirmResult.CANCEL) {
|
||||
return true; // veto
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return void 0;
|
||||
});
|
||||
}
|
||||
|
||||
private noVeto(options: { cleanUpBackups: boolean }): boolean | TPromise<boolean> {
|
||||
@@ -304,6 +314,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
const wasAutoSaveEnabled = (this.getAutoSaveMode() !== AutoSaveMode.OFF);
|
||||
|
||||
const autoSaveMode = (configuration && configuration.files && configuration.files.autoSave) || AutoSaveConfiguration.OFF;
|
||||
this.autoSaveContext.set(autoSaveMode);
|
||||
switch (autoSaveMode) {
|
||||
case AutoSaveConfiguration.AFTER_DELAY:
|
||||
this.configuredAutoSaveDelay = configuration && configuration.files && configuration.files.autoSaveDelay;
|
||||
@@ -379,7 +390,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
public save(resource: URI, options?: ISaveOptions): TPromise<boolean> {
|
||||
|
||||
// Run a forced save if we detect the file is not dirty so that save participants can still run
|
||||
if (options && options.force && resource.scheme === Schemas.file && !this.isDirty(resource)) {
|
||||
if (options && options.force && this.fileService.canHandleResource(resource) && !this.isDirty(resource)) {
|
||||
const model = this._models.get(resource);
|
||||
if (model) {
|
||||
model.save({ force: true, reason: SaveReason.EXPLICIT }).then(() => !model.isDirty());
|
||||
@@ -405,11 +416,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
const filesToSave: URI[] = [];
|
||||
const untitledToSave: URI[] = [];
|
||||
toSave.forEach(s => {
|
||||
// TODO@remote
|
||||
// if (s.scheme === Schemas.file) {
|
||||
// filesToSave.push(s);
|
||||
// } else
|
||||
if ((Array.isArray(arg1) || arg1 === true /* includeUntitled */) && s.scheme === UNTITLED_SCHEMA) {
|
||||
if ((Array.isArray(arg1) || arg1 === true /* includeUntitled */) && s.scheme === Schemas.untitled) {
|
||||
untitledToSave.push(s);
|
||||
} else {
|
||||
filesToSave.push(s);
|
||||
@@ -422,7 +429,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
private doSaveAll(fileResources: URI[], untitledResources: URI[], options?: ISaveOptions): TPromise<ITextFileOperationResult> {
|
||||
|
||||
// Handle files first that can just be saved
|
||||
return this.doSaveAllFiles(fileResources, options).then(result => {
|
||||
return this.doSaveAllFiles(fileResources, options).then(async result => {
|
||||
|
||||
// Preflight for untitled to handle cancellation from the dialog
|
||||
const targetsForUntitled: URI[] = [];
|
||||
@@ -438,7 +445,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
|
||||
// Otherwise ask user
|
||||
else {
|
||||
targetPath = this.promptForPath(this.suggestFileName(untitled));
|
||||
targetPath = await this.promptForPath(this.suggestFileName(untitled));
|
||||
if (!targetPath) {
|
||||
return TPromise.as({
|
||||
results: [...fileResources, ...untitledResources].map(r => {
|
||||
@@ -525,41 +532,49 @@ export abstract class TextFileService implements ITextFileService {
|
||||
return this.getFileModels(arg1).filter(model => model.isDirty());
|
||||
}
|
||||
|
||||
public saveAs(resource: URI, target?: URI): TPromise<URI> {
|
||||
public saveAs(resource: URI, target?: URI, options?: ISaveOptions): TPromise<URI> {
|
||||
|
||||
// Get to target resource
|
||||
if (!target) {
|
||||
let targetPromise: TPromise<URI>;
|
||||
if (target) {
|
||||
targetPromise = TPromise.wrap(target);
|
||||
} else {
|
||||
let dialogPath = resource.fsPath;
|
||||
if (resource.scheme === UNTITLED_SCHEMA) {
|
||||
if (resource.scheme === Schemas.untitled) {
|
||||
dialogPath = this.suggestFileName(resource);
|
||||
}
|
||||
|
||||
const pathRaw = this.promptForPath(dialogPath);
|
||||
if (pathRaw) {
|
||||
target = URI.file(pathRaw);
|
||||
targetPromise = this.promptForPath(dialogPath).then(pathRaw => {
|
||||
if (pathRaw) {
|
||||
return URI.file(pathRaw);
|
||||
}
|
||||
|
||||
return void 0;
|
||||
});
|
||||
}
|
||||
|
||||
return targetPromise.then(target => {
|
||||
if (!target) {
|
||||
return TPromise.as(null); // user canceled
|
||||
}
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
return TPromise.as(null); // user canceled
|
||||
}
|
||||
// Just save if target is same as models own resource
|
||||
if (resource.toString() === target.toString()) {
|
||||
return this.save(resource, options).then(() => resource);
|
||||
}
|
||||
|
||||
// Just save if target is same as models own resource
|
||||
if (resource.toString() === target.toString()) {
|
||||
return this.save(resource).then(() => resource);
|
||||
}
|
||||
|
||||
// Do it
|
||||
return this.doSaveAs(resource, target);
|
||||
// Do it
|
||||
return this.doSaveAs(resource, target, options);
|
||||
});
|
||||
}
|
||||
|
||||
private doSaveAs(resource: URI, target?: URI): TPromise<URI> {
|
||||
private doSaveAs(resource: URI, target?: URI, options?: ISaveOptions): TPromise<URI> {
|
||||
|
||||
// Retrieve text model from provided resource if any
|
||||
let modelPromise: TPromise<ITextFileEditorModel | UntitledEditorModel> = TPromise.as(null);
|
||||
if (resource.scheme === Schemas.file) {
|
||||
if (this.fileService.canHandleResource(resource)) {
|
||||
modelPromise = TPromise.as(this._models.get(resource));
|
||||
} else if (resource.scheme === UNTITLED_SCHEMA && this.untitledEditorService.exists(resource)) {
|
||||
} else if (resource.scheme === Schemas.untitled && this.untitledEditorService.exists(resource)) {
|
||||
modelPromise = this.untitledEditorService.loadOrCreate({ resource });
|
||||
}
|
||||
|
||||
@@ -567,7 +582,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
|
||||
// We have a model: Use it (can be null e.g. if this file is binary and not a text file or was never opened before)
|
||||
if (model) {
|
||||
return this.doSaveTextFileAs(model, resource, target);
|
||||
return this.doSaveTextFileAs(model, resource, target, options);
|
||||
}
|
||||
|
||||
// Otherwise we can only copy
|
||||
@@ -583,7 +598,7 @@ export abstract class TextFileService implements ITextFileService {
|
||||
});
|
||||
}
|
||||
|
||||
private doSaveTextFileAs(sourceModel: ITextFileEditorModel | UntitledEditorModel, resource: URI, target: URI): TPromise<void> {
|
||||
private doSaveTextFileAs(sourceModel: ITextFileEditorModel | UntitledEditorModel, resource: URI, target: URI, options?: ISaveOptions): TPromise<void> {
|
||||
let targetModelResolver: TPromise<ITextFileEditorModel>;
|
||||
|
||||
// Prefer an existing model if it is already loaded for the given target resource
|
||||
@@ -603,15 +618,15 @@ export abstract class TextFileService implements ITextFileService {
|
||||
|
||||
// take over encoding and model value from source model
|
||||
targetModel.updatePreferredEncoding(sourceModel.getEncoding());
|
||||
targetModel.textEditorModel.setValue(sourceModel.getValue());
|
||||
this.modelService.updateModel(targetModel.textEditorModel, createTextBufferFactoryFromSnapshot(sourceModel.createSnapshot()));
|
||||
|
||||
// save model
|
||||
return targetModel.save();
|
||||
return targetModel.save(options);
|
||||
}, error => {
|
||||
|
||||
// binary model: delete the file and run the operation again
|
||||
if ((<FileOperationError>error).fileOperationResult === FileOperationResult.FILE_IS_BINARY || (<FileOperationError>error).fileOperationResult === FileOperationResult.FILE_TOO_LARGE) {
|
||||
return this.fileService.del(target).then(() => this.doSaveTextFileAs(sourceModel, resource, target));
|
||||
return this.fileService.del(target).then(() => this.doSaveTextFileAs(sourceModel, resource, target, options));
|
||||
}
|
||||
|
||||
return TPromise.wrapError(error);
|
||||
|
||||
Reference in New Issue
Block a user