From dac2e270898ee812fd0923c47844a75e50a7bd0e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 13 Apr 2019 19:09:33 +0200 Subject: [PATCH] files2 - move encoding out of fileservice --- src/vs/platform/files/common/files.ts | 7 +-- .../workbench/services/files/node/encoding.ts | 2 +- .../services/files2/common/fileService2.ts | 10 +--- .../textfile/common/textFileEditorModel.ts | 47 +++++++++---------- .../textfile/common/textFileService.ts | 8 +++- .../services/textfile/common/textfiles.ts | 9 +++- .../services/textfile/node/textFileService.ts | 10 ++-- .../textfile/test/textFileService.io.test.ts | 2 +- .../workbench/test/workbenchTestServices.ts | 4 +- 9 files changed, 48 insertions(+), 51 deletions(-) diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index e0301ff7301..44b908f332b 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -18,7 +18,7 @@ import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; export const IFileService = createDecorator('fileService'); export interface IResourceEncodings { - getWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding; + getPreferredWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding; } export interface IResourceEncoding { @@ -65,11 +65,6 @@ export interface IFileService { //#endregion - /** - * Helper to determine read/write encoding for resources. - */ - encoding: IResourceEncodings; - /** * Allows to listen for file changes. The event will fire for every file within the opened workspace * (if any) as well as all files that have been watched explicitly using the #watch() API. diff --git a/src/vs/workbench/services/files/node/encoding.ts b/src/vs/workbench/services/files/node/encoding.ts index 65d55db2c0a..1db0727bb10 100644 --- a/src/vs/workbench/services/files/node/encoding.ts +++ b/src/vs/workbench/services/files/node/encoding.ts @@ -78,7 +78,7 @@ export class ResourceEncodings extends Disposable implements IResourceEncodings return this.getEncodingForResource(resource, preferredEncoding); } - getWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding { + getPreferredWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding { const resourceEncoding = this.getEncodingForResource(resource, preferredEncoding); return { diff --git a/src/vs/workbench/services/files2/common/fileService2.ts b/src/vs/workbench/services/files2/common/fileService2.ts index df43c4771c5..48a4c7a4459 100644 --- a/src/vs/workbench/services/files2/common/fileService2.ts +++ b/src/vs/workbench/services/files2/common/fileService2.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable, IDisposable, toDisposable, combinedDisposable, dispose } from 'vs/base/common/lifecycle'; -import { IFileService, IResolveFileOptions, IResourceEncodings, FileChangesEvent, FileOperationEvent, IFileSystemProviderRegistrationEvent, IFileSystemProvider, IFileStat, IResolveFileResult, IResolveContentOptions, IContent, IStreamContent, ICreateFileOptions, IFileSystemProviderActivationEvent, FileOperationError, FileOperationResult, FileOperation, FileSystemProviderCapabilities, FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, IStat, IFileStatWithMetadata, IResolveMetadataFileOptions, etag, hasReadWriteCapability, hasFileFolderCopyCapability, hasOpenReadWriteCloseCapability, toFileOperationResult, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IResolveFileResultWithMetadata, IWatchOptions, ILegacyFileService, IWriteFileOptions } from 'vs/platform/files/common/files'; +import { IFileService, IResolveFileOptions, FileChangesEvent, FileOperationEvent, IFileSystemProviderRegistrationEvent, IFileSystemProvider, IFileStat, IResolveFileResult, IResolveContentOptions, IContent, IStreamContent, ICreateFileOptions, IFileSystemProviderActivationEvent, FileOperationError, FileOperationResult, FileOperation, FileSystemProviderCapabilities, FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, IStat, IFileStatWithMetadata, IResolveMetadataFileOptions, etag, hasReadWriteCapability, hasFileFolderCopyCapability, hasOpenReadWriteCloseCapability, toFileOperationResult, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileSystemProviderWithFileReadWriteCapability, IResolveFileResultWithMetadata, IWatchOptions, ILegacyFileService, IWriteFileOptions } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; @@ -288,14 +288,6 @@ export class FileService2 extends Disposable implements IFileService { //#region File Reading/Writing - get encoding(): IResourceEncodings { - if (!this._legacy) { - throw new Error('Legacy file service not ready yet'); - } - - return this._legacy.encoding; - } - async createFile(resource: URI, bufferOrReadable: VSBuffer | VSBufferReadable = VSBuffer.fromString(''), options?: ICreateFileOptions): Promise { // validate overwrite diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 2ae22f2aea4..6b95fb6a4ff 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -273,7 +273,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil size: 0, etag: etag(Date.now(), 0), value: createTextBufferFactory(''), /* will be filled later from backup */ - encoding: this.fileService.encoding.getWriteEncoding(this.resource, this.preferredEncoding).encoding, + encoding: this.textFileService.encoding.getPreferredWriteEncoding(this.resource, this.preferredEncoding).encoding, isReadonly: false }; @@ -346,31 +346,30 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } } - private loadWithContent(content: IRawTextContent, options?: ILoadOptions, backup?: URI): Promise { - return this.doLoadWithContent(content, backup).then(model => { + private async loadWithContent(content: IRawTextContent, options?: ILoadOptions, backup?: URI): Promise { + const model = await this.doLoadWithContent(content, backup); - // Telemetry: We log the fileGet telemetry event after the model has been loaded to ensure a good mimetype - const settingsType = this.getTypeIfSettings(); - if (settingsType) { - /* __GDPR__ - "settingsRead" : { - "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('settingsRead', { settingsType }); // Do not log read to user settings.json and .vscode folder as a fileGet event as it ruins our JSON usage data - } else { - /* __GDPR__ - "fileGet" : { - "${include}": [ - "${FileTelemetryData}" - ] - } - */ - this.telemetryService.publicLog('fileGet', this.getTelemetryData(options && options.reason ? options.reason : LoadReason.OTHER)); - } + // Telemetry: We log the fileGet telemetry event after the model has been loaded to ensure a good mimetype + const settingsType = this.getTypeIfSettings(); + if (settingsType) { + /* __GDPR__ + "settingsRead" : { + "settingsType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('settingsRead', { settingsType }); // Do not log read to user settings.json and .vscode folder as a fileGet event as it ruins our JSON usage data + } else { + /* __GDPR__ + "fileGet" : { + "${include}": [ + "${FileTelemetryData}" + ] + } + */ + this.telemetryService.publicLog('fileGet', this.getTelemetryData(options && options.reason ? options.reason : LoadReason.OTHER)); + } - return model; - }); + return model; } private doLoadWithContent(content: IRawTextContent, backup?: URI): Promise { diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index a31288664c2..e45a561bd7e 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -15,7 +15,7 @@ import { IResult, ITextFileOperationResult, ITextFileService, IRawTextContent, I import { ConfirmResult, IRevertOptions } from 'vs/workbench/common/editor'; import { ILifecycleService, ShutdownReason, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { IFileService, IResolveContentOptions, IFilesConfiguration, FileOperationError, FileOperationResult, AutoSaveConfiguration, HotExitConfiguration, ITextSnapshot, IWriteTextFileOptions, IFileStatWithMetadata, toBufferOrReadable, ICreateFileOptions } from 'vs/platform/files/common/files'; +import { IFileService, IResolveContentOptions, IFilesConfiguration, FileOperationError, FileOperationResult, AutoSaveConfiguration, HotExitConfiguration, ITextSnapshot, IWriteTextFileOptions, IFileStatWithMetadata, toBufferOrReadable, ICreateFileOptions, IResourceEncodings, IResourceEncoding } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -57,6 +57,12 @@ export class TextFileService extends Disposable implements ITextFileService { private _models: TextFileEditorModelManager; get models(): ITextFileEditorModelManager { return this._models; } + readonly encoding: IResourceEncodings = { + getPreferredWriteEncoding(): IResourceEncoding { + return { encoding: 'utf8', hasBOM: false }; + } + }; + private currentFilesAssociationConfig: { [key: string]: string; }; private configuredAutoSaveDelay?: number; private configuredAutoSaveOnFocusChange: boolean; diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 39288a2ec69..63c6476de39 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IEncodingSupport, ConfirmResult, IRevertOptions } from 'vs/workbench/common/editor'; -import { IResolveContentOptions, ITextSnapshot, IBaseStatWithMetadata, IWriteTextFileOptions, IFileStatWithMetadata } from 'vs/platform/files/common/files'; +import { IResolveContentOptions, ITextSnapshot, IBaseStatWithMetadata, IWriteTextFileOptions, IFileStatWithMetadata, IResourceEncodings } from 'vs/platform/files/common/files'; import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { ITextBufferFactory, ITextModel } from 'vs/editor/common/model'; @@ -274,7 +274,9 @@ export interface ITextFileService extends IDisposable { _serviceBrand: ServiceIdentifier; readonly onWillMove: Event; + readonly onAutoSaveConfigurationChange: Event; + readonly onFilesAssociationChange: Event; readonly isHotExitEnabled: boolean; @@ -284,6 +286,11 @@ export interface ITextFileService extends IDisposable { */ readonly models: ITextFileEditorModelManager; + /** + * Helper to determine encoding for resources. + */ + readonly encoding: IResourceEncodings; + /** * A resource is dirty if it has unsaved changes or is an untitled file not yet saved. * diff --git a/src/vs/workbench/services/textfile/node/textFileService.ts b/src/vs/workbench/services/textfile/node/textFileService.ts index 87c164018a1..aac62dda25f 100644 --- a/src/vs/workbench/services/textfile/node/textFileService.ts +++ b/src/vs/workbench/services/textfile/node/textFileService.ts @@ -9,7 +9,7 @@ import { TextFileService } from 'vs/workbench/services/textfile/common/textFileS import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { URI } from 'vs/base/common/uri'; -import { ITextSnapshot, IWriteTextFileOptions, IFileStatWithMetadata, IResourceEncoding, IResolveContentOptions, stringToSnapshot, ICreateFileOptions, FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; +import { ITextSnapshot, IWriteTextFileOptions, IFileStatWithMetadata, IResourceEncoding, IResolveContentOptions, stringToSnapshot, ICreateFileOptions, FileOperationError, FileOperationResult, IResourceEncodings } from 'vs/platform/files/common/files'; import { Schemas } from 'vs/base/common/network'; import { exists, stat, chmod, rimraf } from 'vs/base/node/pfs'; import { join, dirname } from 'vs/base/common/path'; @@ -29,7 +29,7 @@ import { isUndefinedOrNull } from 'vs/base/common/types'; export class NodeTextFileService extends TextFileService { private _encoding: EncodingOracle; - protected get encoding(): EncodingOracle { + get encoding(): EncodingOracle { if (!this._encoding) { this._encoding = this._register(this.instantiationService.createInstance(EncodingOracle)); } @@ -246,7 +246,7 @@ export interface IEncodingOverride { encoding: string; } -export class EncodingOracle extends Disposable { +export class EncodingOracle extends Disposable implements IResourceEncodings { protected encodingOverrides: IEncodingOverride[]; constructor( @@ -285,7 +285,7 @@ export class EncodingOracle extends Disposable { } async getWriteEncoding(resource: URI, options?: IWriteTextFileOptions): Promise<{ encoding: string, addBOM: boolean }> { - const { encoding, hasBOM } = this.doGetWriteEncoding(resource, options ? options.encoding : undefined); + const { encoding, hasBOM } = this.getPreferredWriteEncoding(resource, options ? options.encoding : undefined); // Some encodings come with a BOM automatically if (hasBOM) { @@ -302,7 +302,7 @@ export class EncodingOracle extends Disposable { return { encoding, addBOM: false }; } - private doGetWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding { + getPreferredWriteEncoding(resource: URI, preferredEncoding?: string): IResourceEncoding { const resourceEncoding = this.getEncodingForResource(resource, preferredEncoding); return { diff --git a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts index 65b968a90c3..2e45f67e222 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts @@ -49,7 +49,7 @@ class ServiceAccessor { class TestNodeTextFileService extends NodeTextFileService { private _testEncoding: TestEncodingOracle; - protected get encoding(): TestEncodingOracle { + get encoding(): TestEncodingOracle { if (!this._testEncoding) { this._testEncoding = this._register(this.instantiationService.createInstance(TestEncodingOracle)); } diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 6204c5c1a56..3ea17db1b0a 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -26,7 +26,7 @@ import { IWorkspaceContextService, IWorkspace as IWorkbenchWorkspace, WorkbenchS import { ILifecycleService, BeforeShutdownEvent, ShutdownReason, StartupKind, LifecyclePhase, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; -import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, IContent, IStreamContent, ICreateFileOptions, ITextSnapshot, IResourceEncodings, IResourceEncoding, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, IFileStatWithMetadata, IResolveMetadataFileOptions, IWriteFileOptions } from 'vs/platform/files/common/files'; +import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, IContent, IStreamContent, ICreateFileOptions, ITextSnapshot, IResourceEncoding, IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, IFileStatWithMetadata, IResolveMetadataFileOptions, IWriteFileOptions } from 'vs/platform/files/common/files'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl'; import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; @@ -890,8 +890,6 @@ export class TestFileService implements IFileService { public _serviceBrand: any; - public encoding: IResourceEncodings; - private readonly _onFileChanges: Emitter; private readonly _onAfterOperation: Emitter; -- GitLab