diff --git a/src/vs/platform/editor/common/editor.ts b/src/vs/platform/editor/common/editor.ts index 81dc32ec8bc88c076c11de64cc62882c1e215231..9beffac6e9cde04981aa9597256acdd850d19678 100644 --- a/src/vs/platform/editor/common/editor.ts +++ b/src/vs/platform/editor/common/editor.ts @@ -90,6 +90,11 @@ export interface IUntitledResourceInput extends IBaseResourceInput { * Optional contents of the untitled resource. */ contents?: string; + + /** + * Optional encoding of the untitled resource. + */ + encoding?: string; } export interface IResourceDiffInput extends IBaseResourceInput { diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 8c6275f0b55b95f909f050eba717d71f227a4cea..cd4bc5a15ea72239c0ed3d12b887f62636aaa72f 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -93,6 +93,7 @@ interface ISerializedUntitledEditorInput { resource: string; resourceJSON: any; modeId: string; + encoding: string; } // Register Editor Input Factory @@ -118,7 +119,8 @@ class UntitledEditorInputFactory implements IEditorInputFactory { const serialized: ISerializedUntitledEditorInput = { resource: resource.toString(), // Keep for backwards compatibility resourceJSON: resource.toJSON(), - modeId: untitledEditorInput.getModeId() + modeId: untitledEditorInput.getModeId(), + encoding: untitledEditorInput.getEncoding() }; return JSON.stringify(serialized); @@ -130,8 +132,9 @@ class UntitledEditorInputFactory implements IEditorInputFactory { const resource = !!deserialized.resourceJSON ? URI.revive(deserialized.resourceJSON) : URI.parse(deserialized.resource); const filePath = resource.scheme === 'file' ? resource.fsPath : void 0; const language = deserialized.modeId; + const encoding = deserialized.encoding; - return accessor.get(IWorkbenchEditorService).createInput({ resource, filePath, language }) as UntitledEditorInput; + return accessor.get(IWorkbenchEditorService).createInput({ resource, filePath, language, encoding }) as UntitledEditorInput; }); } } diff --git a/src/vs/workbench/common/editor/untitledEditorInput.ts b/src/vs/workbench/common/editor/untitledEditorInput.ts index 0d27f28551257dde9a5bb0542f079b3dac022fe9..081b9bd7df4196ed7681aeddea2d10f662035c2b 100644 --- a/src/vs/workbench/common/editor/untitledEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledEditorInput.ts @@ -27,10 +27,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport public static ID: string = 'workbench.editors.untitledEditorInput'; - private resource: URI; private _hasAssociatedFilePath: boolean; - private initialValue: string; - private modeId: string; private cachedModel: UntitledEditorModel; private modelResolve: TPromise; @@ -40,10 +37,11 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport private toUnbind: IDisposable[]; constructor( - resource: URI, + private resource: URI, hasAssociatedFilePath: boolean, - modeId: string, - initialValue: string, + private modeId: string, + private initialValue: string, + private preferredEncoding: string, @IInstantiationService private instantiationService: IInstantiationService, @IWorkspaceContextService private contextService: IWorkspaceContextService, @ITextFileService private textFileService: ITextFileService, @@ -51,11 +49,9 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport ) { super(); - this.resource = resource; - this.initialValue = initialValue; this._hasAssociatedFilePath = hasAssociatedFilePath; - this.modeId = modeId; this.toUnbind = []; + this._onDidModelChangeContent = new Emitter(); this._onDidModelChangeEncoding = new Emitter(); } @@ -146,10 +142,12 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport return this.cachedModel.getEncoding(); } - return null; + return this.preferredEncoding; } public setEncoding(encoding: string, mode: EncodingMode /* ignored, we only have Encode */): void { + this.preferredEncoding = encoding; + if (this.cachedModel) { this.cachedModel.setEncoding(encoding); } @@ -170,7 +168,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport } private createModel(): UntitledEditorModel { - const model = this.instantiationService.createInstance(UntitledEditorModel, this.modeId, this.resource, this.hasAssociatedFilePath, this.initialValue); + const model = this.instantiationService.createInstance(UntitledEditorModel, this.modeId, this.resource, this.hasAssociatedFilePath, this.initialValue, this.preferredEncoding); // re-emit some events from the model this.toUnbind.push(model.onDidChangeContent(() => this._onDidModelChangeContent.fire())); diff --git a/src/vs/workbench/common/editor/untitledEditorModel.ts b/src/vs/workbench/common/editor/untitledEditorModel.ts index bd0bb5300b1b064f9a01aa2daa5f41f136d6f53f..65e8c973201d6312403b6b711ab70ac028fbe5a3 100644 --- a/src/vs/workbench/common/editor/untitledEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledEditorModel.ts @@ -38,16 +38,13 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin private contentChangeEventScheduler: RunOnceScheduler; private configuredEncoding: string; - private preferredEncoding: string; - - private hasAssociatedFilePath: boolean; - private initialValue: string; constructor( private modeId: string, private resource: URI, - hasAssociatedFilePath: boolean, - initialValue: string, + private hasAssociatedFilePath: boolean, + private initialValue: string, + private preferredEncoding: string, @IModeService modeService: IModeService, @IModelService modelService: IModelService, @IBackupFileService private backupFileService: IBackupFileService, @@ -56,8 +53,6 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin ) { super(modelService, modeService); - this.hasAssociatedFilePath = hasAssociatedFilePath; - this.initialValue = initialValue; this.dirty = false; this.versionId = 0; diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index 2409a85a81138a4f341c4ea5e7d41dbbdcc37580..d2b5a8b9235b032d606d14cdc8deeb8cd5d0c36f 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -27,8 +27,6 @@ import { ITextModelResolverService } from 'vs/editor/common/services/resolverSer * A file editor input is the input type for the file editor of file system resources. */ export class FileEditorInput extends EditorInput implements IFileEditorInput { - private resource: URI; - private preferredEncoding: string; private forceOpenAsBinary: boolean; private textModelReference: TPromise>; @@ -46,8 +44,8 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { * An editor input who's contents are retrieved from file services. */ constructor( - resource: URI, - preferredEncoding: string, + private resource: URI, + private preferredEncoding: string, @IInstantiationService private instantiationService: IInstantiationService, @IWorkspaceContextService private contextService: IWorkspaceContextService, @ITextFileService private textFileService: ITextFileService, @@ -58,9 +56,6 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { this.toUnbind = []; - this.resource = resource; - this.preferredEncoding = preferredEncoding; - this.registerListeners(); } diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index afd412d0127b7eb0581aa113e64f312c5f3f2f3b..e8b52c75a1e7fcc020424b6484974765df4d0d9e 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -233,7 +233,7 @@ export class WorkbenchEditorService implements IWorkbenchEditorService { // Untitled file support const untitledInput = input; if (!untitledInput.resource || typeof untitledInput.filePath === 'string' || (untitledInput.resource instanceof URI && untitledInput.resource.scheme === UNTITLED_SCHEMA)) { - return this.untitledEditorService.createOrGet(untitledInput.filePath ? URI.file(untitledInput.filePath) : untitledInput.resource, untitledInput.language, untitledInput.contents); + return this.untitledEditorService.createOrGet(untitledInput.filePath ? URI.file(untitledInput.filePath) : untitledInput.resource, untitledInput.language, untitledInput.contents, untitledInput.encoding); } const resourceInput = input; diff --git a/src/vs/workbench/services/untitled/common/untitledEditorService.ts b/src/vs/workbench/services/untitled/common/untitledEditorService.ts index 264aa9275d42f44518a6bdc2bce71b8e9dbfc37b..89d3f6f43051b7656c530f02e5286be3ccb88ef3 100644 --- a/src/vs/workbench/services/untitled/common/untitledEditorService.ts +++ b/src/vs/workbench/services/untitled/common/untitledEditorService.ts @@ -24,6 +24,7 @@ export interface IModelLoadOrCreateOptions { resource?: URI; modeId?: string; initialValue?: string; + encoding?: string; } export interface IUntitledEditorService { @@ -77,7 +78,7 @@ export interface IUntitledEditorService { * It is valid to pass in a file resource. In that case the path will be used as identifier. * The use case is to be able to create a new file with a specific path with VSCode. */ - createOrGet(resource?: URI, modeId?: string, initialValue?: string): UntitledEditorInput; + createOrGet(resource?: URI, modeId?: string, initialValue?: string, encoding?: string): UntitledEditorInput; /** * Creates a new untitled model with the optional resource URI or returns an existing one @@ -194,10 +195,10 @@ export class UntitledEditorService implements IUntitledEditorService { } public loadOrCreate(options: IModelLoadOrCreateOptions = Object.create(null)): TPromise { - return this.createOrGet(options.resource, options.modeId, options.initialValue).resolve(); + return this.createOrGet(options.resource, options.modeId, options.initialValue, options.encoding).resolve(); } - public createOrGet(resource?: URI, modeId?: string, initialValue?: string): UntitledEditorInput { + public createOrGet(resource?: URI, modeId?: string, initialValue?: string, encoding?: string): UntitledEditorInput { // Massage resource if it comes with a file:// scheme let hasAssociatedFilePath = false; @@ -216,10 +217,10 @@ export class UntitledEditorService implements IUntitledEditorService { } // Create new otherwise - return this.doCreate(resource, hasAssociatedFilePath, modeId, initialValue); + return this.doCreate(resource, hasAssociatedFilePath, modeId, initialValue, encoding); } - private doCreate(resource?: URI, hasAssociatedFilePath?: boolean, modeId?: string, initialValue?: string): UntitledEditorInput { + private doCreate(resource?: URI, hasAssociatedFilePath?: boolean, modeId?: string, initialValue?: string, encoding?: string): UntitledEditorInput { if (!resource) { // Create new taking a resource URI that is not already taken @@ -238,7 +239,7 @@ export class UntitledEditorService implements IUntitledEditorService { } } - const input = this.instantiationService.createInstance(UntitledEditorInput, resource, hasAssociatedFilePath, modeId, initialValue); + const input = this.instantiationService.createInstance(UntitledEditorInput, resource, hasAssociatedFilePath, modeId, initialValue, encoding); const contentListener = input.onDidModelChangeContent(() => { this._onDidChangeContent.fire(resource);