From ffe5db3e36ba68aee0c8ecd19f5fd4d34dbce233 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 13 Apr 2019 19:21:55 +0200 Subject: [PATCH] files2 - textfile.read() --- .../workbench/contrib/files/common/files.ts | 2 +- .../common/walkThroughContentProvider.ts | 4 ++-- .../textfile/browser/textFileService.ts | 20 +++++++++++++++++++ .../textfile/common/textFileEditorModel.ts | 2 +- .../textfile/common/textFileService.ts | 12 ++++------- .../services/textfile/common/textfiles.ts | 4 ++-- .../textfile/test/textFileService.io.test.ts | 16 +++++++-------- .../workbench/test/workbenchTestServices.ts | 6 +++--- src/vs/workbench/workbench.nodeless.main.ts | 5 +---- 9 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 src/vs/workbench/services/textfile/browser/textFileService.ts diff --git a/src/vs/workbench/contrib/files/common/files.ts b/src/vs/workbench/contrib/files/common/files.ts index ab377e99bc8..ebf1358a266 100644 --- a/src/vs/workbench/contrib/files/common/files.ts +++ b/src/vs/workbench/contrib/files/common/files.ts @@ -176,7 +176,7 @@ export class FileOnDiskContentProvider implements ITextModelContentProvider { private resolveEditorModel(resource: URI, createAsNeeded: boolean = true): Promise { const savedFileResource = toLocalResource(resource, this.environmentService.configuration.remoteAuthority); - return this.textFileService.resolve(savedFileResource).then(content => { + return this.textFileService.read(savedFileResource).then(content => { let codeEditorModel = this.modelService.getModel(resource); if (codeEditorModel) { this.modelService.updateModel(codeEditorModel, content.value); diff --git a/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider.ts b/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider.ts index 1b74d9c8f35..7b2f981e34d 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider.ts @@ -35,7 +35,7 @@ export class WalkThroughContentProvider implements ITextModelContentProvider, IW reject(err); } }); - }) : this.textFileService.resolve(URI.file(resource.fsPath)).then(content => content.value)); + }) : this.textFileService.read(URI.file(resource.fsPath)).then(content => content.value)); return content.then(content => { let codeEditorModel = this.modelService.getModel(resource); if (!codeEditorModel) { @@ -61,7 +61,7 @@ export class WalkThroughSnippetContentProvider implements ITextModelContentProvi } public provideTextContent(resource: URI): Promise { - return this.textFileService.resolve(URI.file(resource.fsPath)).then(content => { + return this.textFileService.read(URI.file(resource.fsPath)).then(content => { let codeEditorModel = this.modelService.getModel(resource); if (!codeEditorModel) { const j = parseInt(resource.fragment); diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts new file mode 100644 index 00000000000..e8f23f9bc3e --- /dev/null +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; +import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IResourceEncodings, IResourceEncoding } from 'vs/platform/files/common/files'; + +export class BrowserTextFileService extends TextFileService { + + readonly encoding: IResourceEncodings = { + getPreferredWriteEncoding(): IResourceEncoding { + return { encoding: 'utf8', hasBOM: false }; + } + }; +} + +registerSingleton(ITextFileService, BrowserTextFileService); \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 6b95fb6a4ff..f2c46d785e0 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -306,7 +306,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Resolve Content try { - const content = await this.textFileService.resolve(this.resource, { acceptTextOnly: !allowBinary, etag, encoding: this.preferredEncoding }); + const content = await this.textFileService.read(this.resource, { acceptTextOnly: !allowBinary, etag, encoding: this.preferredEncoding }); // Clear orphaned state when loading was successful this.setOrphaned(false); diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index e45a561bd7e..34b0c0712c6 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, IResourceEncodings, IResourceEncoding } from 'vs/platform/files/common/files'; +import { IFileService, IResolveContentOptions, IFilesConfiguration, FileOperationError, FileOperationResult, AutoSaveConfiguration, HotExitConfiguration, ITextSnapshot, IWriteTextFileOptions, IFileStatWithMetadata, toBufferOrReadable, ICreateFileOptions, IResourceEncodings } 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'; @@ -41,7 +41,7 @@ import { trim } from 'vs/base/common/strings'; /** * The workbench file service implementation implements the raw file service spec and adds additional methods on top. */ -export class TextFileService extends Disposable implements ITextFileService { +export abstract class TextFileService extends Disposable implements ITextFileService { _serviceBrand: ServiceIdentifier; @@ -57,11 +57,7 @@ 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 }; - } - }; + abstract get encoding(): IResourceEncodings; private currentFilesAssociationConfig: { [key: string]: string; }; private configuredAutoSaveDelay?: number; @@ -372,7 +368,7 @@ export class TextFileService extends Disposable implements ITextFileService { //#region primitives (resolve, create, move, delete, update) - async resolve(resource: URI, options?: IResolveContentOptions): Promise { + async read(resource: URI, options?: IResolveContentOptions): Promise { const streamContent = await this.fileService.resolveStreamContent(resource, options); const value = await createTextBufferFactoryFromStream(streamContent.value); diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 63c6476de39..7e87f3efcc5 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -355,9 +355,9 @@ export interface ITextFileService extends IDisposable { create(resource: URI, contents?: string | ITextSnapshot, options?: { overwrite?: boolean }): Promise; /** - * Resolve the contents of a file identified by the resource. + * Read the contents of a file identified by the resource. */ - resolve(resource: URI, options?: IResolveContentOptions): Promise; + read(resource: URI, options?: IResolveContentOptions): Promise; /** * Update a file with given contents. 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 2e45f67e222..2cec90e2e43 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts @@ -246,7 +246,7 @@ suite('Files - TextFileService i/o', () => { const detectedEncoding = await detectEncodingByBOM(resource.fsPath); assert.equal(detectedEncoding, encoding); - const resolved = await service.resolve(resource); + const resolved = await service.read(resource); assert.equal(resolved.encoding, encoding); assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)), expectedContent); @@ -273,18 +273,18 @@ suite('Files - TextFileService i/o', () => { }); async function testEncodingKeepsData(resource: URI, encoding: string, expected: string) { - let resolved = await service.resolve(resource, { encoding }); + let resolved = await service.read(resource, { encoding }); const content = snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)); assert.equal(content, expected); await service.write(resource, content, { encoding }); - resolved = await service.resolve(resource, { encoding }); + resolved = await service.read(resource, { encoding }); assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).createSnapshot(false)), content); await service.write(resource, TextModel.createFromString(content).createSnapshot(), { encoding }); - resolved = await service.resolve(resource, { encoding }); + resolved = await service.read(resource, { encoding }); assert.equal(snapshotToString(resolved.value.create(DefaultEndOfLine.CRLF).createSnapshot(false)), content); } @@ -295,7 +295,7 @@ suite('Files - TextFileService i/o', () => { await service.write(resource, content); - const resolved = await service.resolve(resource); + const resolved = await service.read(resource); assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)), content); }); @@ -306,14 +306,14 @@ suite('Files - TextFileService i/o', () => { await service.write(resource, TextModel.createFromString(content).createSnapshot()); - const resolved = await service.resolve(resource); + const resolved = await service.read(resource); assert.equal(snapshotToString(resolved.value.create(isWindows ? DefaultEndOfLine.CRLF : DefaultEndOfLine.LF).createSnapshot(false)), content); }); test('write - encoding preserved (UTF 16 LE) - content as string', async () => { const resource = URI.file(join(testDir, 'some_utf16le.css')); - const resolved = await service.resolve(resource); + const resolved = await service.read(resource); assert.equal(resolved.encoding, UTF16le); await testEncoding(URI.file(join(testDir, 'some_utf16le.css')), UTF16le, 'Hello\nWorld', 'Hello\nWorld'); @@ -322,7 +322,7 @@ suite('Files - TextFileService i/o', () => { test('write - encoding preserved (UTF 16 LE) - content as snapshot', async () => { const resource = URI.file(join(testDir, 'some_utf16le.css')); - const resolved = await service.resolve(resource); + const resolved = await service.read(resource); assert.equal(resolved.encoding, UTF16le); await testEncoding(URI.file(join(testDir, 'some_utf16le.css')), UTF16le, TextModel.createFromString('Hello\nWorld').createSnapshot(), 'Hello\nWorld'); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 3ea17db1b0a..695ec7f31a3 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -25,7 +25,6 @@ import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/serv import { IWorkspaceContextService, IWorkspace as IWorkbenchWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, Workspace } from 'vs/platform/workspace/common/workspace'; 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, 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'; @@ -83,6 +82,7 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; +import { BrowserTextFileService } from 'vs/workbench/services/textfile/browser/textFileService'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined); @@ -176,7 +176,7 @@ export class TestContextService implements IWorkspaceContextService { } } -export class TestTextFileService extends TextFileService { +export class TestTextFileService extends BrowserTextFileService { public cleanupBackupsBeforeShutdownCalled: boolean; private promptPath: URI; @@ -235,7 +235,7 @@ export class TestTextFileService extends TextFileService { this.resolveTextContentError = error; } - public resolve(resource: URI, options?: IResolveContentOptions): Promise { + public read(resource: URI, options?: IResolveContentOptions): Promise { if (this.resolveTextContentError) { const error = this.resolveTextContentError; this.resolveTextContentError = null; diff --git a/src/vs/workbench/workbench.nodeless.main.ts b/src/vs/workbench/workbench.nodeless.main.ts index dadae15c171..f86d9d8af49 100644 --- a/src/vs/workbench/workbench.nodeless.main.ts +++ b/src/vs/workbench/workbench.nodeless.main.ts @@ -91,8 +91,6 @@ import { ContextViewService } from 'vs/platform/contextview/browser/contextViewS // import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; import { IHeapService, NullHeapService } from 'vs/workbench/services/heap/common/heap'; import { IBroadcastService, NullBroadcastService } from 'vs/workbench/services/broadcast/common/broadcast'; -import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; @@ -115,7 +113,7 @@ import 'vs/workbench/services/preferences/browser/preferencesService'; import 'vs/workbench/services/output/common/outputChannelModelService'; import 'vs/workbench/services/configuration/common/jsonEditingService'; import 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; -// import 'vs/workbench/services/textfile/node/textFileService'; +import 'vs/workbench/services/textfile/browser/textFileService'; import 'vs/workbench/services/dialogs/browser/fileDialogService'; // import 'vs/workbench/services/dialogs/electron-browser/dialogService'; // import 'vs/workbench/services/backup/node/backupFileService'; @@ -171,7 +169,6 @@ registerSingleton(IContextViewService, ContextViewService, true); registerSingleton(IHeapService, NullHeapService); registerSingleton(IBroadcastService, NullBroadcastService); registerSingleton(IContextMenuService, ContextMenuService); -registerSingleton(ITextFileService, TextFileService); registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); //#endregion