diff --git a/extensions/package.json b/extensions/package.json index d18865ad4d..dcce9525ef 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "3.4.0-rc" + "typescript": "3.4.1" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 0c1d37b29a..a011714b22 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -typescript@3.4.0-rc: - version "3.4.0-rc" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.0-rc.tgz#bc4026c3c517a30fa514b896f2684c6ba92caadb" - integrity sha512-wtm2GwuV0Yy2zvmpFaMDtWHnRbzfERi9FLpL+K+JqGkHoclgEQ6TmD1AMxMIjs80NWRIq0Xp1veQyuZbGsUYsg== +typescript@3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.1.tgz#b6691be11a881ffa9a05765a205cb7383f3b63c6" + integrity sha512-3NSMb2VzDQm8oBTLH6Nj55VVtUEpe/rgkIzMir0qVoLyjDZlnMBva0U6vDiV3IH+sl/Yu6oP5QwsAQtHPmDd2Q== diff --git a/src/main.js b/src/main.js index 0bad7713e4..e5f1b02a72 100644 --- a/src/main.js +++ b/src/main.js @@ -11,7 +11,6 @@ const lp = require('./vs/base/node/languagePacks'); perf.mark('main:started'); -const fs = require('fs'); const path = require('path'); const bootstrap = require('./bootstrap'); const paths = require('./paths'); @@ -29,21 +28,6 @@ bootstrap.enableASARSupport(); // Set userData path before app 'ready' event and call to process.chdir const args = parseCLIArgs(); const userDataPath = getUserDataPath(args); - -// global storage migration needs to happen very early before app.on("ready") -// TODO@Ben remove after a while -try { - const globalStorageHome = path.join(userDataPath, 'User', 'globalStorage', 'state.vscdb'); - const localStorageHome = path.join(userDataPath, 'Local Storage'); - const localStorageDB = path.join(localStorageHome, 'file__0.localstorage'); - const localStorageDBBackup = path.join(localStorageHome, 'file__0.vscmig'); - if (!fs.existsSync(globalStorageHome) && fs.existsSync(localStorageDB)) { - fs.renameSync(localStorageDB, localStorageDBBackup); - } -} catch (error) { - console.error(error); -} - app.setPath('userData', userDataPath); // Update cwd based on environment and platform diff --git a/src/vs/base/node/extfs.ts b/src/vs/base/node/extfs.ts index 2ed2e1188e..8844eea666 100644 --- a/src/vs/base/node/extfs.ts +++ b/src/vs/base/node/extfs.ts @@ -366,18 +366,23 @@ export interface IWriteFileOptions { }; } +interface IEnsuredWriteFileOptions extends IWriteFileOptions { + mode: number; + flag: string; +} + let canFlush = true; export function writeFileAndFlush(path: string, data: string | Buffer | NodeJS.ReadableStream | Uint8Array, options: IWriteFileOptions, callback: (error?: Error) => void): void { - options = ensureOptions(options); + const ensuredOptions = ensureWriteOptions(options); if (typeof data === 'string' || Buffer.isBuffer(data) || data instanceof Uint8Array) { - doWriteFileAndFlush(path, data, options, callback); + doWriteFileAndFlush(path, data, ensuredOptions, callback); } else { - doWriteFileStreamAndFlush(path, data, options, callback); + doWriteFileStreamAndFlush(path, data, ensuredOptions, callback); } } -function doWriteFileStreamAndFlush(path: string, reader: NodeJS.ReadableStream, options: IWriteFileOptions, callback: (error?: Error) => void): void { +function doWriteFileStreamAndFlush(path: string, reader: NodeJS.ReadableStream, options: IEnsuredWriteFileOptions, callback: (error?: Error) => void): void { // finish only once let finished = false; @@ -468,7 +473,7 @@ function doWriteFileStreamAndFlush(path: string, reader: NodeJS.ReadableStream, // not in some cache. // // See https://github.com/nodejs/node/blob/v5.10.0/lib/fs.js#L1194 -function doWriteFileAndFlush(path: string, data: string | Buffer | Uint8Array, options: IWriteFileOptions, callback: (error?: Error) => void): void { +function doWriteFileAndFlush(path: string, data: string | Buffer | Uint8Array, options: IEnsuredWriteFileOptions, callback: (error?: Error) => void): void { if (options.encoding) { data = encode(data instanceof Uint8Array ? Buffer.from(data) : data, options.encoding.charset, { addBOM: options.encoding.addBOM }); } @@ -478,7 +483,7 @@ function doWriteFileAndFlush(path: string, data: string | Buffer | Uint8Array, o } // Open the file with same flags and mode as fs.writeFile() - fs.open(path, typeof options.flag === 'string' ? options.flag : 'r', options.mode, (openError, fd) => { + fs.open(path, options.flag, options.mode, (openError, fd) => { if (openError) { return callback(openError); } @@ -506,18 +511,18 @@ function doWriteFileAndFlush(path: string, data: string | Buffer | Uint8Array, o } export function writeFileAndFlushSync(path: string, data: string | Buffer, options?: IWriteFileOptions): void { - options = ensureOptions(options); + const ensuredOptions = ensureWriteOptions(options); - if (options.encoding) { - data = encode(data, options.encoding.charset, { addBOM: options.encoding.addBOM }); + if (ensuredOptions.encoding) { + data = encode(data, ensuredOptions.encoding.charset, { addBOM: ensuredOptions.encoding.addBOM }); } if (!canFlush) { - return fs.writeFileSync(path, data, { mode: options.mode, flag: options.flag }); + return fs.writeFileSync(path, data, { mode: ensuredOptions.mode, flag: ensuredOptions.flag }); } // Open the file with same flags and mode as fs.writeFile() - const fd = fs.openSync(path, typeof options.flag === 'string' ? options.flag : 'r', options.mode); + const fd = fs.openSync(path, ensuredOptions.flag, ensuredOptions.mode); try { @@ -536,22 +541,16 @@ export function writeFileAndFlushSync(path: string, data: string | Buffer, optio } } -function ensureOptions(options?: IWriteFileOptions): IWriteFileOptions { +function ensureWriteOptions(options?: IWriteFileOptions): IEnsuredWriteFileOptions { if (!options) { return { mode: 0o666, flag: 'w' }; } - const ensuredOptions: IWriteFileOptions = { mode: options.mode, flag: options.flag, encoding: options.encoding }; - - if (typeof ensuredOptions.mode !== 'number') { - ensuredOptions.mode = 0o666; - } - - if (typeof ensuredOptions.flag !== 'string') { - ensuredOptions.flag = 'w'; - } - - return ensuredOptions; + return { + mode: typeof options.mode === 'number' ? options.mode : 0o666, + flag: typeof options.flag === 'string' ? options.flag : 'w', + encoding: options.encoding + }; } /** diff --git a/src/vs/platform/configuration/node/configuration.ts b/src/vs/platform/configuration/node/configuration.ts index 96a4615a61..9e91bb3152 100644 --- a/src/vs/platform/configuration/node/configuration.ts +++ b/src/vs/platform/configuration/node/configuration.ts @@ -70,8 +70,8 @@ export class FileServiceBasedUserConfiguration extends Disposable { this._register(fileService.onFileChanges(e => this.handleFileEvents(e))); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50)); - this.fileService.watchFileChanges(this.configurationResource); - this._register(toDisposable(() => this.fileService.unwatchFileChanges(this.configurationResource))); + this.fileService.watch(this.configurationResource); + this._register(toDisposable(() => this.fileService.unwatch(this.configurationResource))); } initialize(): Promise { diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index b8a691bdf6..44733191d6 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -70,7 +70,7 @@ export interface IFileService { /** * 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 #watchFileChanges() API. + * (if any) as well as all files that have been watched explicitly using the #watch() API. */ readonly onFileChanges: Event; @@ -80,7 +80,7 @@ export interface IFileService { readonly onAfterOperation: Event; /** - * Resolve the properties of a file identified by the resource. + * Resolve the properties of a file/folder identified by the resource. * * If the optional parameter "resolveTo" is specified in options, the stat service is asked * to provide a stat object that should contain the full graph of folders up to all of the @@ -93,20 +93,20 @@ export interface IFileService { * If the optional parameter "resolveMetadata" is specified in options, * the stat will contain metadata information such as size, mtime and etag. */ - resolveFile(resource: URI, options: IResolveMetadataFileOptions): Promise; - resolveFile(resource: URI, options?: IResolveFileOptions): Promise; + resolve(resource: URI, options: IResolveMetadataFileOptions): Promise; + resolve(resource: URI, options?: IResolveFileOptions): Promise; /** - * Same as resolveFile but supports resolving multiple resources in parallel. + * Same as resolve() but supports resolving multiple resources in parallel. * If one of the resolve targets fails to resolve returns a fake IFileStat instead of making the whole call fail. */ - resolveFiles(toResolve: { resource: URI, options: IResolveMetadataFileOptions }[]): Promise; - resolveFiles(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise; + resolveAll(toResolve: { resource: URI, options: IResolveMetadataFileOptions }[]): Promise; + resolveAll(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise; /** - * Finds out if a file identified by the resource exists. + * Finds out if a file/folder identified by the resource exists. */ - existsFile(resource: URI): Promise; + exists(resource: URI): Promise; /** * Resolve the contents of a file identified by the resource. @@ -128,18 +128,18 @@ export interface IFileService { updateContent(resource: URI, value: string | ITextSnapshot, options?: IUpdateContentOptions): Promise; /** - * Moves the file to a new path identified by the resource. + * Moves the file/folder to a new path identified by the resource. * * The optional parameter overwrite can be set to replace an existing file at the location. */ - moveFile(source: URI, target: URI, overwrite?: boolean): Promise; + move(source: URI, target: URI, overwrite?: boolean): Promise; /** - * Copies the file to a path identified by the resource. + * Copies the file/folder to a path identified by the resource. * * The optional parameter overwrite can be set to replace an existing file at the location. */ - copyFile(source: URI, target: URI, overwrite?: boolean): Promise; + copy(source: URI, target: URI, overwrite?: boolean): Promise; /** * Creates a new file with the given path. The returned promise @@ -165,12 +165,12 @@ export interface IFileService { /** * Allows to start a watcher that reports file change events on the provided resource. */ - watchFileChanges(resource: URI): void; + watch(resource: URI): void; /** * Allows to stop a watcher on the provided resource or absolute fs path. */ - unwatchFileChanges(resource: URI): void; + unwatch(resource: URI): void; /** * Frees up any resources occupied by this service. @@ -371,19 +371,14 @@ export const enum FileOperation { export class FileOperationEvent { - constructor(private _resource: URI, private _operation: FileOperation, private _target?: IFileStatWithMetadata) { - } + constructor(resource: URI, operation: FileOperation.DELETE); + constructor(resource: URI, operation: FileOperation.CREATE | FileOperation.MOVE | FileOperation.COPY, target: IFileStatWithMetadata); + constructor(public readonly resource: URI, public readonly operation: FileOperation, public readonly target?: IFileStatWithMetadata) { } - get resource(): URI { - return this._resource; - } - - get target(): IFileStat | undefined { - return this._target; - } - - get operation(): FileOperation { - return this._operation; + isOperation(operation: FileOperation.DELETE): boolean; + isOperation(operation: FileOperation.MOVE | FileOperation.COPY | FileOperation.CREATE): this is { readonly target: IFileStatWithMetadata }; + isOperation(operation: FileOperation): boolean { + return this.operation === operation; } } @@ -1140,7 +1135,7 @@ export interface ILegacyFileService { createFile(resource: URI, content?: string, options?: ICreateFileOptions): Promise; - watchFileChanges(resource: URI): void; + watch(resource: URI): void; - unwatchFileChanges(resource: URI): void; -} + unwatch(resource: URI): void; +} \ No newline at end of file diff --git a/src/vs/platform/storage/node/storageMainService.ts b/src/vs/platform/storage/node/storageMainService.ts index 1d24f79e3a..fede5a8d81 100644 --- a/src/vs/platform/storage/node/storageMainService.ts +++ b/src/vs/platform/storage/node/storageMainService.ts @@ -10,9 +10,7 @@ import { ILogService, LogLevel } from 'vs/platform/log/common/log'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IStorage, Storage, SQLiteStorageDatabase, ISQLiteStorageDatabaseLoggingOptions, InMemoryStorageDatabase } from 'vs/base/node/storage'; import { join } from 'vs/base/common/path'; -import { exists, readdir } from 'vs/base/node/pfs'; -import { Database } from 'vscode-sqlite3'; -import { endsWith, startsWith } from 'vs/base/common/strings'; +import { exists } from 'vs/base/node/pfs'; export const IStorageMainService = createDecorator('storageMainService'); @@ -140,213 +138,7 @@ export class StorageMainService extends Disposable implements IStorageMainServic this._register(this.storage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key }))); - return this.storage.init().then(() => { - - // Migrate storage if this is the first start and we are not using in-memory - let migrationPromise: Promise; - if (!useInMemoryStorage && !exists) { - // TODO@Ben remove global storage migration and move Storage creation back to ctor - migrationPromise = this.migrateGlobalStorage().then(() => this.logService.info('[storage] migrated global storage'), error => this.logService.error(`[storage] migration error ${error}`)); - } else { - migrationPromise = Promise.resolve(); - } - - return migrationPromise; - }); - }); - } - - private migrateGlobalStorage(): Promise { - this.logService.info('[storage] migrating global storage from localStorage into SQLite'); - - const localStorageDBBackup = join(this.environmentService.userDataPath, 'Local Storage', 'file__0.vscmig'); - - return exists(localStorageDBBackup).then(exists => { - if (!exists) { - return Promise.resolve(); // return if there is no DB to migrate from - } - - return readdir(this.environmentService.extensionsPath).then(extensions => { - const supportedKeys = new Map(); - [ - 'editorFontInfo', - 'peekViewLayout', - 'expandSuggestionDocs', - 'extensionsIdentifiers/disabled', - 'integrityService', - 'telemetry.lastSessionDate', - 'telemetry.instanceId', - 'telemetry.firstSessionDate', - 'workbench.sidebar.width', - 'workbench.panel.width', - 'workbench.panel.height', - 'workbench.panel.sizeBeforeMaximized', - 'workbench.activity.placeholderViewlets', - 'colorThemeData', - 'iconThemeData', - 'workbench.telemetryOptOutShown', - 'workbench.hide.welcome', - 'releaseNotes/lastVersion', - 'debug.actionswidgetposition', - 'debug.actionswidgety', - 'editor.neverPromptForLargeFiles', - 'menubar/electronFixRecommended', - 'learnMoreDirtyWriteError', - 'extensions.ignoredAutoUpdateExtension', - 'askToInstallRemoteServerExtension', - 'hasNotifiedOfSettingsAutosave', - 'commandPalette.mru.cache', - 'commandPalette.mru.counter', - 'parts-splash-data', - 'terminal.integrated.neverMeasureRenderTime', - 'terminal.integrated.neverSuggestSelectWindowsShell', - 'memento/workbench.parts.editor', - 'memento/workbench.view.search', - 'langugage.update.donotask', - 'extensionsAssistant/languagePackSuggestionIgnore', - 'workbench.panel.pinnedPanels', - 'workbench.activity.pinnedViewlets', - 'extensionsAssistant/ignored_recommendations', - 'extensionsAssistant/recommendations', - 'extensionsAssistant/importantRecommendationsIgnore', - 'extensionsAssistant/fileExtensionsSuggestionIgnore', - 'nps/skipVersion', - 'nps/lastSessionDate', - 'nps/sessionCount', - 'nps/isCandidate', - 'allExperiments', - 'currentOrPreviouslyRunExperiments', - 'update/win32-64bits', - 'update/win32-fast-updates', - 'update/lastKnownVersion', - 'update/updateNotificationTime' - ].forEach(key => supportedKeys.set(key.toLowerCase(), key)); - - // https://github.com/Microsoft/vscode/issues/68468 - const wellKnownPublishers = ['Microsoft', 'GitHub']; - const wellKnownExtensions = ['ms-vscode.Go', 'WallabyJs.quokka-vscode', 'Telerik.nativescript', 'Shan.code-settings-sync', 'ritwickdey.LiveServer', 'PKief.material-icon-theme', 'PeterJausovec.vscode-docker', 'ms-vscode.PowerShell', 'LaurentTreguier.vscode-simple-icons', 'KnisterPeter.vscode-github', 'DotJoshJohnson.xml', 'Dart-Code.dart-code', 'alefragnani.Bookmarks']; - - // Support extension storage as well (always the ID of the extension) - extensions.forEach(extension => { - let extensionId: string; - if (extension.indexOf('-') >= 0) { - extensionId = extension.substring(0, extension.lastIndexOf('-')); // convert "author.extension-0.2.5" => "author.extension" - } else { - extensionId = extension; - } - - if (extensionId) { - for (let i = 0; i < wellKnownPublishers.length; i++) { - const publisher = wellKnownPublishers[i]; - if (startsWith(extensionId, `${publisher.toLowerCase()}.`)) { - extensionId = `${publisher}${extensionId.substr(publisher.length)}`; - break; - } - } - - for (let j = 0; j < wellKnownExtensions.length; j++) { - const wellKnownExtension = wellKnownExtensions[j]; - if (extensionId === wellKnownExtension.toLowerCase()) { - extensionId = wellKnownExtension; - break; - } - } - - supportedKeys.set(extensionId.toLowerCase(), extensionId); - } - }); - - return import('vscode-sqlite3').then(sqlite3 => { - - return new Promise((resolve, reject) => { - const handleSuffixKey = (row: any, key: string, suffix: string) => { - if (endsWith(key, suffix.toLowerCase())) { - const value: string = row.value.toString('utf16le'); - const normalizedKey = key.substring(0, key.length - suffix.length) + suffix; - - this.store(normalizedKey, value); - - return true; - } - - return false; - }; - - const db: Database = new (sqlite3.Database)(localStorageDBBackup, error => { - if (error) { - if (db) { - db.close(); - } - - return reject(error); - } - - db.all('SELECT key, value FROM ItemTable', (error, rows) => { - if (error) { - db.close(); - - return reject(error); - } - - try { - rows.forEach(row => { - let key: string = row.key; - if (key.indexOf('storage://global/') !== 0) { - return; // not a global key - } - - // convert storage://global/colorthemedata => colorthemedata - key = key.substr('storage://global/'.length); - - const supportedKey = supportedKeys.get(key); - if (supportedKey) { - const value: string = row.value.toString('utf16le'); - - this.store(supportedKey, value); - } - - // dynamic values - else if ( - endsWith(key, '.hidden') || - startsWith(key, 'experiments.') - ) { - const value: string = row.value.toString('utf16le'); - - this.store(key, value); - } - - // fix lowercased ".sessionCount" - else if (handleSuffixKey(row, key, '.sessionCount')) { } - - // fix lowercased ".lastSessionDate" - else if (handleSuffixKey(row, key, '.lastSessionDate')) { } - - // fix lowercased ".skipVersion" - else if (handleSuffixKey(row, key, '.skipVersion')) { } - - // fix lowercased ".isCandidate" - else if (handleSuffixKey(row, key, '.isCandidate')) { } - - // fix lowercased ".editedCount" - else if (handleSuffixKey(row, key, '.editedCount')) { } - - // fix lowercased ".editedDate" - else if (handleSuffixKey(row, key, '.editedDate')) { } - }); - - db.close(); - } catch (error) { - db.close(); - - return reject(error); - } - - resolve(); - }); - }); - }); - }); - }); + return this.storage.init(); }); } diff --git a/src/vs/workbench/api/browser/mainThreadDocuments.ts b/src/vs/workbench/api/browser/mainThreadDocuments.ts index 24eab2b36b..a95f8c32f4 100644 --- a/src/vs/workbench/api/browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/browser/mainThreadDocuments.ts @@ -215,7 +215,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { private _handleUntitledScheme(uri: URI): Promise { const asFileUri = uri.with({ scheme: Schemas.file }); - return this._fileService.resolveFile(asFileUri).then(stats => { + return this._fileService.resolve(asFileUri).then(stats => { // don't create a new file ontop of an existing file return Promise.reject(new Error('file already exists on disk')); }, err => { diff --git a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts index 1cce198c98..f6e2a42865 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts @@ -51,8 +51,8 @@ export class MainThreadFileSystemEventService { // file operation events - (changes the editor makes) fileService.onAfterOperation(e => { - if (e.operation === FileOperation.MOVE) { - proxy.$onFileRename(e.resource, e.target!.resource); + if (e.isOperation(FileOperation.MOVE)) { + proxy.$onFileRename(e.resource, e.target.resource); } }, undefined, this._listener); diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 443e14fc4b..5fa0f3592c 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -269,7 +269,7 @@ export class ResourcesDropHandler { } // Check for Folder - return this.fileService.resolveFile(fileOnDiskResource).then(stat => { + return this.fileService.resolve(fileOnDiskResource).then(stat => { if (stat.isDirectory) { workspaceResources.folders.push({ uri: stat.resource, typeHint: 'folder' }); } diff --git a/src/vs/workbench/browser/nodeless.simpleservices.ts b/src/vs/workbench/browser/nodeless.simpleservices.ts index f9a9e16e9c..97e24e8a6a 100644 --- a/src/vs/workbench/browser/nodeless.simpleservices.ts +++ b/src/vs/workbench/browser/nodeless.simpleservices.ts @@ -695,16 +695,16 @@ export class SimpleRemoteFileService implements IFileService { readonly onDidChangeFileSystemProviderRegistrations = Event.None; readonly onWillActivateFileSystemProvider = Event.None; - resolveFile(resource: URI, options?: IResolveFileOptions): Promise { + resolve(resource: URI, options?: IResolveFileOptions): Promise { // @ts-ignore return Promise.resolve(fileMap.get(resource)); } - resolveFiles(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise { - return Promise.all(toResolve.map(resourceAndOption => this.resolveFile(resourceAndOption.resource, resourceAndOption.options))).then(stats => stats.map(stat => ({ stat, success: true }))); + resolveAll(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise { + return Promise.all(toResolve.map(resourceAndOption => this.resolve(resourceAndOption.resource, resourceAndOption.options))).then(stats => stats.map(stat => ({ stat, success: true }))); } - existsFile(resource: URI): Promise { + exists(resource: URI): Promise { return Promise.resolve(fileMap.has(resource)); } @@ -761,9 +761,9 @@ export class SimpleRemoteFileService implements IFileService { }); } - moveFile(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } + move(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } - copyFile(_source: URI, _target: URI, _overwrite?: boolean): Promise { + copy(_source: URI, _target: URI, _overwrite?: boolean): Promise { const parent = fileMap.get(dirname(_target)); if (!parent) { return Promise.resolve(undefined); @@ -802,9 +802,9 @@ export class SimpleRemoteFileService implements IFileService { del(_resource: URI, _options?: { useTrash?: boolean, recursive?: boolean }): Promise { return Promise.resolve(); } - watchFileChanges(_resource: URI): void { } + watch(_resource: URI): void { } - unwatchFileChanges(_resource: URI): void { } + unwatch(_resource: URI): void { } getWriteEncoding(_resource: URI): IResourceEncoding { return { encoding: 'utf8', hasBOM: false }; } diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 2c2ce90a26..55decba633 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -228,7 +228,7 @@ class FileDataSource implements IAsyncDataSource { + return this._fileService.resolve(uri).then(stat => { for (const child of stat.children || []) { this._parents.set(stat, child); } diff --git a/src/vs/workbench/common/editor/binaryEditorModel.ts b/src/vs/workbench/common/editor/binaryEditorModel.ts index 5336d9faca..f2901e1655 100644 --- a/src/vs/workbench/common/editor/binaryEditorModel.ts +++ b/src/vs/workbench/common/editor/binaryEditorModel.ts @@ -76,7 +76,7 @@ export class BinaryEditorModel extends EditorModel { // Make sure to resolve up to date stat for file resources if (this.fileService.canHandleResource(this.resource)) { - return this.fileService.resolveFile(this.resource, { resolveMetadata: true }).then(stat => { + return this.fileService.resolve(this.resource, { resolveMetadata: true }).then(stat => { this.etag = stat.etag; if (typeof stat.size === 'number') { this.size = stat.size; diff --git a/src/vs/workbench/contrib/debug/browser/debugANSIHandling.ts b/src/vs/workbench/contrib/debug/browser/debugANSIHandling.ts index 31c8ccf311..611668dbb6 100644 --- a/src/vs/workbench/contrib/debug/browser/debugANSIHandling.ts +++ b/src/vs/workbench/contrib/debug/browser/debugANSIHandling.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector'; +import { RGBA, Color } from 'vs/base/common/color'; /** * @param text The content to stylize. @@ -15,6 +16,8 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML const textLength: number = text.length; let styleNames: string[] = []; + let customFgColor: RGBA | undefined; + let customBgColor: RGBA | undefined; let currentPos: number = 0; let buffer: string = ''; @@ -48,45 +51,33 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML if (sequenceFound) { // Flush buffer with previous styles. - appendStylizedStringToContainer(root, buffer, styleNames, linkDetector); + appendStylizedStringToContainer(root, buffer, styleNames, linkDetector, customFgColor, customBgColor); buffer = ''; /* - * Certain ranges that are matched here do not contain real graphics rendition sequences. For - * the sake of having a simpler expression, they have been included anyway. - */ - if (ansiSequence.match(/^(?:[349][0-7]|10[0-7]|[013]|4|[34]9)(?:;(?:[349][0-7]|10[0-7]|[013]|4|[34]9))*;?m$/)) { + * Certain ranges that are matched here do not contain real graphics rendition sequences. For + * the sake of having a simpler expression, they have been included anyway. + */ + if (ansiSequence.match(/^(?:[34][0-8]|9[0-7]|10[0-7]|[013]|4|[34]9)(?:;[349][0-7]|10[0-7]|[013]|[245]|[34]9)?(?:;[012]?[0-9]?[0-9])*;?m$/)) { - const styleCodes: number[] = ansiSequence.slice(0, -1) // Remove final 'm' character. - .split(';') // Separate style codes. - .filter(elem => elem !== '') // Filter empty elems as '34;m' -> ['34', '']. - .map(elem => parseInt(elem, 10)); // Convert to numbers. + const styleCodes: number[] = ansiSequence.slice(0, -1) // Remove final 'm' character. + .split(';') // Separate style codes. + .filter(elem => elem !== '') // Filter empty elems as '34;m' -> ['34', '']. + .map(elem => parseInt(elem, 10)); // Convert to numbers. - for (let code of styleCodes) { - if (code === 0) { - styleNames = []; - } else if (code === 1) { - styleNames.push('code-bold'); - } else if (code === 3) { - styleNames.push('code-italic'); - } else if (code === 4) { - styleNames.push('code-underline'); - } else if (code === 39 || (code >= 30 && code <= 37) || (code >= 90 && code <= 97)) { - // Remove all previous foreground colour codes - styleNames = styleNames.filter(style => !style.match(/^code-foreground-\d+$/)); + if (styleCodes[0] === 38 || styleCodes[0] === 48) { + // Advanced color code - can't be combined with formatting codes like simple colors can + // Ignores invalid colors and additional info beyond what is necessary + const colorType = (styleCodes[0] === 38) ? 'foreground' : 'background'; - if (code !== 39) { - styleNames.push('code-foreground-' + code); - } - } else if (code === 49 || (code >= 40 && code <= 47) || (code >= 100 && code <= 107)) { - // Remove all previous background colour codes - styleNames = styleNames.filter(style => !style.match(/^code-background-\d+$/)); - - if (code !== 49) { - styleNames.push('code-background-' + code); - } + if (styleCodes[1] === 5) { + set8BitColor(styleCodes, colorType); + } else if (styleCodes[1] === 2) { + set24BitColor(styleCodes, colorType); } + } else { + setBasicFormatters(styleCodes); } } else { @@ -96,23 +87,121 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML } else { currentPos = startPos; } - } if (sequenceFound === false) { buffer += text.charAt(currentPos); currentPos++; } - } // Flush remaining text buffer if not empty. if (buffer) { - appendStylizedStringToContainer(root, buffer, styleNames, linkDetector); + appendStylizedStringToContainer(root, buffer, styleNames, linkDetector, customFgColor, customBgColor); } return root; + /** + * Change the foreground or background color by clearing the current color + * and adding the new one. + * @param newClass If string or number, new class will be + * `code-(foreground or background)-newClass`. If `undefined`, no new class + * will be added. + * @param colorType If `'foreground'`, will change the foreground color, if + * `'background'`, will change the background color. + * @param customColor If provided, this custom color will be used instead of + * a class-defined color. + */ + function changeColor(newClass: string | number | undefined, colorType: 'foreground' | 'background', customColor?: RGBA): void { + styleNames = styleNames.filter(style => !style.match(new RegExp(`^code-${colorType}-(\\d+|custom)$`))); + if (newClass) { + styleNames.push(`code-${colorType}-${newClass}`); + } + if (colorType === 'foreground') { + customFgColor = customColor; + } else { + customBgColor = customColor; + } + } + + /** + * Calculate and set basic ANSI formatting. Supports bold, italic, underline, + * normal foreground and background colors, and bright foreground and + * background colors. Not to be used for codes containing advanced colors. + * Will ignore invalid codes. + * @param styleCodes Array of ANSI basic styling numbers, which will be + * applied in order. New colors and backgrounds clear old ones; new formatting + * does not. + * @see {@link https://en.wikipedia.org/wiki/ANSI_escape_code } + */ + function setBasicFormatters(styleCodes: number[]): void { + for (let code of styleCodes) { + if (code === 0) { + styleNames = []; + } else if (code === 1) { + styleNames.push('code-bold'); + } else if (code === 3) { + styleNames.push('code-italic'); + } else if (code === 4) { + styleNames.push('code-underline'); + } else if ((code >= 30 && code <= 37) || (code >= 90 && code <= 97)) { + changeColor(code, 'foreground'); + } else if ((code >= 40 && code <= 47) || (code >= 100 && code <= 107)) { + changeColor(code, 'background'); + } else if (code === 39) { + changeColor(undefined, 'foreground'); + } else if (code === 49) { + changeColor(undefined, 'background'); + } + } + } + + /** + * Calculate and set styling for complicated 24-bit ANSI color codes. + * @param styleCodes Full list of integer codes that make up the full ANSI + * sequence, including the two defining codes and the three RGB codes. + * @param colorType If `'foreground'`, will set foreground color, if + * `'background'`, will set background color. + * @see {@link https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit } + */ + function set24BitColor(styleCodes: number[], colorType: 'foreground' | 'background'): void { + if (styleCodes.length >= 5 && + styleCodes[2] >= 0 && styleCodes[2] <= 255 && + styleCodes[3] >= 0 && styleCodes[3] <= 255 && + styleCodes[4] >= 0 && styleCodes[4] <= 255) { + const customColor = new RGBA(styleCodes[2], styleCodes[3], styleCodes[4]); + changeColor('custom', colorType, customColor); + } + } + + /** + * Calculate and set styling for advanced 8-bit ANSI color codes. + * @param styleCodes Full list of integer codes that make up the ANSI + * sequence, including the two defining codes and the one color code. + * @param colorType If `'foreground'`, will set foreground color, if + * `'background'`, will set background color. + * @see {@link https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit } + */ + function set8BitColor(styleCodes: number[], colorType: 'foreground' | 'background'): void { + let colorNumber = styleCodes[2]; + const color = calcANSI8bitColor(colorNumber); + + if (color) { + changeColor('custom', colorType, color); + } else if (colorNumber >= 0 && colorNumber <= 15) { + // Need to map to one of the four basic color ranges (30-37, 90-97, 40-47, 100-107) + colorNumber += 30; + if (colorNumber >= 38) { + // Bright colors + colorNumber += 52; + } + if (colorType === 'background') { + colorNumber += 10; + } + changeColor(colorNumber, colorType); + } + } } /** @@ -120,8 +209,17 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML * @param stringContent The text content to be appended. * @param cssClasses The list of CSS styles to apply to the text content. * @param linkDetector The {@link LinkDetector} responsible for generating links from {@param stringContent}. + * @param customTextColor If provided, will apply custom color with inline style. + * @param customBackgroundColor If provided, will apply custom color with inline style. */ -export function appendStylizedStringToContainer(root: HTMLElement, stringContent: string, cssClasses: string[], linkDetector: LinkDetector): void { +export function appendStylizedStringToContainer( + root: HTMLElement, + stringContent: string, + cssClasses: string[], + linkDetector: LinkDetector, + customTextColor?: RGBA, + customBackgroundColor?: RGBA +): void { if (!root || !stringContent) { return; } @@ -129,5 +227,55 @@ export function appendStylizedStringToContainer(root: HTMLElement, stringContent const container = linkDetector.handleLinks(stringContent); container.className = cssClasses.join(' '); + if (customTextColor) { + container.style.color = + Color.Format.CSS.formatRGB(new Color(customTextColor)); + } + if (customBackgroundColor) { + container.style.backgroundColor = + Color.Format.CSS.formatRGB(new Color(customBackgroundColor)); + } + root.appendChild(container); } + +/** + * Calculate the color from the color set defined in the ANSI 8-bit standard. + * Standard and high intensity colors are not defined in the standard as specific + * colors, so these and invalid colors return `undefined`. + * @see {@link https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit } for info. + * @param colorNumber The number (ranging from 16 to 255) referring to the color + * desired. + */ +export function calcANSI8bitColor(colorNumber: number): RGBA | undefined { + if (colorNumber % 1 !== 0) { + // Should be integer + // {{SQL CARBON EDIT}} @todo anthonydresser this is necessary because we don't use strict null checks + return undefined; + } if (colorNumber >= 16 && colorNumber <= 231) { + // Converts to one of 216 RGB colors + colorNumber -= 16; + + let blue: number = colorNumber % 6; + colorNumber = (colorNumber - blue) / 6; + let green: number = colorNumber % 6; + colorNumber = (colorNumber - green) / 6; + let red: number = colorNumber; + + // red, green, blue now range on [0, 5], need to map to [0,255] + const convFactor: number = 255 / 5; + blue = Math.round(blue * convFactor); + green = Math.round(green * convFactor); + red = Math.round(red * convFactor); + + return new RGBA(red, green, blue); + } else if (colorNumber >= 232 && colorNumber <= 255) { + // Converts to a grayscale value + colorNumber -= 232; + const colorLevel: number = Math.round(colorNumber / 23 * 255); + return new RGBA(colorLevel, colorLevel, colorLevel); + } else { + // {{SQL CARBON EDIT}} @todo anthonydresser this is necessary because we don't use strict null checks + return undefined; + } +} diff --git a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts index 5a38d590b6..804611228c 100644 --- a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts @@ -6,10 +6,11 @@ import * as assert from 'assert'; import * as dom from 'vs/base/browser/dom'; import { generateUuid } from 'vs/base/common/uuid'; -import { appendStylizedStringToContainer, handleANSIOutput } from 'vs/workbench/contrib/debug/browser/debugANSIHandling'; +import { appendStylizedStringToContainer, handleANSIOutput, calcANSI8bitColor } from 'vs/workbench/contrib/debug/browser/debugANSIHandling'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices'; import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector'; +import { Color, RGBA } from 'vs/base/common/color'; suite('Debug - ANSI Handling', () => { test('appendStylizedStringToContainer', () => { diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index 6c114f38f3..6c929fab6b 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -349,7 +349,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private resolveWorkspaceFolderExtensionConfig(workspaceFolder: IWorkspaceFolder): Promise { const extensionsJsonUri = workspaceFolder.toResource(EXTENSIONS_CONFIG); - return Promise.resolve(this.fileService.resolveFile(extensionsJsonUri) + return Promise.resolve(this.fileService.resolve(extensionsJsonUri) .then(() => this.fileService.resolveContent(extensionsJsonUri)) .then(content => json.parse(content.value), err => null)); } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts index cf0dc8be78..e5f3d81fdd 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts @@ -2555,7 +2555,7 @@ export class OpenExtensionsFolderAction extends Action { run(): Promise { const extensionsHome = URI.file(this.environmentService.extensionsPath); - return Promise.resolve(this.fileService.resolveFile(extensionsHome)).then(file => { + return Promise.resolve(this.fileService.resolve(extensionsHome)).then(file => { let itemToShow: URI; if (file.children && file.children.length > 0) { itemToShow = file.children[0].resource; diff --git a/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts index 6ba526d561..5ab15d55b2 100644 --- a/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts +++ b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts @@ -90,7 +90,7 @@ CommandsRegistry.registerCommand({ const terminalService = accessor.get(IExternalTerminalService); const resources = getMultiSelectedResources(resource, accessor.get(IListService), editorService); - return fileService.resolveFiles(resources.map(r => ({ resource: r }))).then(stats => { + return fileService.resolveAll(resources.map(r => ({ resource: r }))).then(stats => { const directoriesToOpen = distinct(stats.filter(data => data.success).map(({ stat }) => stat!.isDirectory ? stat!.resource.fsPath : paths.dirname(stat!.resource.fsPath))); return directoriesToOpen.map(dir => { if (configurationService.getValue().terminal.explorerKind === 'integrated') { diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts index 3a89ebd105..31f3096447 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts @@ -114,12 +114,12 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut private onFileOperation(e: FileOperationEvent): void { // Handle moves specially when file is opened - if (e.operation === FileOperation.MOVE && e.target) { + if (e.isOperation(FileOperation.MOVE)) { this.handleMovedFileInOpenedEditors(e.resource, e.target.resource); } // Handle deletes - if (e.operation === FileOperation.DELETE || e.operation === FileOperation.MOVE) { + if (e.isOperation(FileOperation.DELETE) || e.isOperation(FileOperation.MOVE)) { this.handleDeletes(e.resource, false, e.target ? e.target.resource : undefined); } } @@ -176,7 +176,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // flag. let checkExists: Promise; if (isExternal) { - checkExists = timeout(100).then(() => this.fileService.existsFile(resource)); + checkExists = timeout(100).then(() => this.fileService.exists(resource)); } else { checkExists = Promise.resolve(false); } @@ -360,7 +360,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // Handle no longer visible out of workspace resources this.activeOutOfWorkspaceWatchers.forEach(resource => { if (!visibleOutOfWorkspacePaths.get(resource)) { - this.fileService.unwatchFileChanges(resource); + this.fileService.unwatch(resource); this.activeOutOfWorkspaceWatchers.delete(resource); } }); @@ -368,7 +368,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // Handle newly visible out of workspace resources visibleOutOfWorkspacePaths.forEach(resource => { if (!this.activeOutOfWorkspaceWatchers.get(resource)) { - this.fileService.watchFileChanges(resource); + this.fileService.watch(resource); this.activeOutOfWorkspaceWatchers.set(resource, resource); } }); @@ -378,7 +378,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut super.dispose(); // Dispose watchers if any - this.activeOutOfWorkspaceWatchers.forEach(resource => this.fileService.unwatchFileChanges(resource)); + this.activeOutOfWorkspaceWatchers.forEach(resource => this.fileService.unwatch(resource)); this.activeOutOfWorkspaceWatchers.clear(); } } diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index fa22b6587f..493c3d2817 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -503,7 +503,7 @@ class PasteFileAction extends BaseErrorReportingAction { throw new Error(nls.localize('fileIsAncestor', "File to paste is an ancestor of the destination folder")); } - return this.fileService.resolveFile(fileToPaste).then(fileToPasteStat => { + return this.fileService.resolve(fileToPaste).then(fileToPasteStat => { // Find target let target: ExplorerItem; @@ -516,7 +516,7 @@ class PasteFileAction extends BaseErrorReportingAction { const targetFile = findValidPasteFileTarget(target, { resource: fileToPaste, isDirectory: fileToPasteStat.isDirectory, allowOverwirte: pasteShouldMove }); // Copy File - const promise = pasteShouldMove ? this.fileService.moveFile(fileToPaste, targetFile) : this.fileService.copyFile(fileToPaste, targetFile); + const promise = pasteShouldMove ? this.fileService.move(fileToPaste, targetFile) : this.fileService.copy(fileToPaste, targetFile); return promise.then(stat => { if (pasteShouldMove) { // Cut is done. Make sure to clear cut state. diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index f484c4467b..c2ce3c514f 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -300,7 +300,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ // Set side input if (resources.length) { - return fileService.resolveFiles(resources.map(resource => ({ resource }))).then(resolved => { + return fileService.resolveAll(resources.map(resource => ({ resource }))).then(resolved => { const editors = resolved.filter(r => r.stat && r.success && !r.stat.isDirectory).map(r => ({ resource: r.stat!.resource })); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 5c8d1cf2ad..fdeb56faab 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -608,7 +608,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { const droppedResources = extractResources(originalEvent, true); // Check for dropped external files to be folders - return this.fileService.resolveFiles(droppedResources).then(result => { + return this.fileService.resolveAll(droppedResources).then(result => { // Pass focus to window this.windowService.focusWindow(); @@ -649,7 +649,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { if (resources && resources.length > 0) { // Resolve target to check for name collisions and ask user - return this.fileService.resolveFile(target.resource).then(targetStat => { + return this.fileService.resolve(target.resource).then(targetStat => { // Check for name collisions const targetNames = new Set(); @@ -695,7 +695,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { return revertPromise.then(() => { const copyTarget = joinPath(target.resource, basename(sourceFile)); - return this.fileService.copyFile(sourceFile, copyTarget, true).then(stat => { + return this.fileService.copy(sourceFile, copyTarget, true).then(stat => { // if we only add one file, just open it directly if (resources.length === 1) { @@ -794,7 +794,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { // Reuse duplicate action if user copies if (isCopy) { - return this.fileService.copyFile(source.resource, findValidPasteFileTarget(target, { resource: source.resource, isDirectory: source.isDirectory, allowOverwirte: false })).then(stat => { + return this.fileService.copy(source.resource, findValidPasteFileTarget(target, { resource: source.resource, isDirectory: source.isDirectory, allowOverwirte: false })).then(stat => { if (!stat.isDirectory) { return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }).then(() => undefined); } diff --git a/src/vs/workbench/contrib/files/common/explorerModel.ts b/src/vs/workbench/contrib/files/common/explorerModel.ts index 8999b4a54f..fe9660e44a 100644 --- a/src/vs/workbench/contrib/files/common/explorerModel.ts +++ b/src/vs/workbench/contrib/files/common/explorerModel.ts @@ -249,7 +249,7 @@ export class ExplorerItem { // Resolve metadata only when the mtime is needed since this can be expensive // Mtime is only used when the sort order is 'modified' const resolveMetadata = explorerService.sortOrder === 'modified'; - promise = fileService.resolveFile(this.resource, { resolveSingleChildDescendants: true, resolveMetadata }).then(stat => { + promise = fileService.resolve(this.resource, { resolveSingleChildDescendants: true, resolveMetadata }).then(stat => { const resolved = ExplorerItem.create(stat, this); ExplorerItem.mergeLocalWithDisk(resolved, this); this._isDirectoryResolved = true; diff --git a/src/vs/workbench/contrib/files/common/explorerService.ts b/src/vs/workbench/contrib/files/common/explorerService.ts index 21582210ca..b7ed79cc89 100644 --- a/src/vs/workbench/contrib/files/common/explorerService.ts +++ b/src/vs/workbench/contrib/files/common/explorerService.ts @@ -40,7 +40,6 @@ export class ExplorerService implements IExplorerService { private editable: { stat: ExplorerItem, data: IEditableData } | undefined; private _sortOrder: SortOrder; private cutItems: ExplorerItem[] | undefined; - private fileSystemProviderSchemes = new Set(); constructor( @IFileService private fileService: IFileService, @@ -99,14 +98,7 @@ export class ExplorerService implements IExplorerService { this.disposables.push(this.fileService.onAfterOperation(e => this.onFileOperation(e))); this.disposables.push(this.fileService.onFileChanges(e => this.onFileChanges(e))); this.disposables.push(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(this.configurationService.getValue()))); - this.disposables.push(this.fileService.onDidChangeFileSystemProviderRegistrations(e => { - if (e.added && this.fileSystemProviderSchemes.has(e.scheme)) { - // A file system provider got re-registered, we should update all file stats since they might change (got read-only) - this._onDidChangeItem.fire(undefined); - } else { - this.fileSystemProviderSchemes.add(e.scheme); - } - })); + this.disposables.push(this.fileService.onDidChangeFileSystemProviderRegistrations(() => this._onDidChangeItem.fire(undefined))); this.disposables.push(model.onDidChangeRoots(() => this._onDidChangeRoots.fire())); return model; @@ -159,7 +151,7 @@ export class ExplorerService implements IExplorerService { const workspaceFolder = this.contextService.getWorkspaceFolder(resource); const rootUri = workspaceFolder ? workspaceFolder.uri : this.roots[0].resource; const root = this.roots.filter(r => r.resource.toString() === rootUri.toString()).pop()!; - return this.fileService.resolveFile(rootUri, options).then(stat => { + return this.fileService.resolve(rootUri, options).then(stat => { // Convert to model const modelStat = ExplorerItem.create(stat, undefined, options.resolveTo); @@ -190,8 +182,8 @@ export class ExplorerService implements IExplorerService { private onFileOperation(e: FileOperationEvent): void { // Add - if (e.operation === FileOperation.CREATE || e.operation === FileOperation.COPY) { - const addedElement = e.target!; + if (e.isOperation(FileOperation.CREATE) || e.isOperation(FileOperation.COPY)) { + const addedElement = e.target; const parentResource = dirname(addedElement.resource)!; const parents = this.model.findAll(parentResource); @@ -201,7 +193,7 @@ export class ExplorerService implements IExplorerService { parents.forEach(p => { // We have to check if the parent is resolved #29177 const resolveMetadata = this.sortOrder === `modified`; - const thenable: Promise = p.isDirectoryResolved ? Promise.resolve(undefined) : this.fileService.resolveFile(p.resource, { resolveMetadata }); + const thenable: Promise = p.isDirectoryResolved ? Promise.resolve(undefined) : this.fileService.resolve(p.resource, { resolveMetadata }); thenable.then(stat => { if (stat) { const modelStat = ExplorerItem.create(stat, p.parent); @@ -220,9 +212,9 @@ export class ExplorerService implements IExplorerService { } // Move (including Rename) - else if (e.operation === FileOperation.MOVE) { + else if (e.isOperation(FileOperation.MOVE)) { const oldResource = e.resource; - const newElement = e.target!; + const newElement = e.target; const oldParentResource = dirname(oldResource); const newParentResource = dirname(newElement.resource); @@ -254,7 +246,7 @@ export class ExplorerService implements IExplorerService { } // Delete - else if (e.operation === FileOperation.DELETE) { + else if (e.isOperation(FileOperation.DELETE)) { const modelElements = this.model.findAll(e.resource); modelElements.forEach(element => { if (element.parent) { diff --git a/src/vs/workbench/contrib/search/browser/openFileHandler.ts b/src/vs/workbench/contrib/search/browser/openFileHandler.ts index d358290f68..b2a72ec840 100644 --- a/src/vs/workbench/contrib/search/browser/openFileHandler.ts +++ b/src/vs/workbench/contrib/search/browser/openFileHandler.ts @@ -191,7 +191,7 @@ export class OpenFileHandler extends QuickOpenHandler { workspaceFolders[0].uri.with({ path: detildifiedQuery }) : URI.file(detildifiedQuery); - return this.fileService.resolveFile(resource).then( + return this.fileService.resolve(resource).then( stat => stat.isDirectory ? undefined : resource, error => undefined); } diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index b4290b8ca3..6b52729679 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -365,7 +365,7 @@ const searchInFolderCommand: ICommandHandler = (accessor, resource?: URI) => { return openSearchView(viewletService, panelService, configurationService, true).then(searchView => { if (resources && resources.length && searchView) { - return fileService.resolveFiles(resources.map(resource => ({ resource }))).then(results => { + return fileService.resolveAll(resources.map(resource => ({ resource }))).then(results => { const folders: URI[] = []; results.forEach(result => { diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index aabb27070b..43eaa5e4f4 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -1200,7 +1200,7 @@ export class SearchView extends ViewletPanel { // Validate folderQueries const folderQueriesExistP = query.folderQueries.map(fq => { - return this.fileService.existsFile(fq.folder); + return this.fileService.exists(fq.folder); }); return Promise.resolve(folderQueriesExistP).then(existResults => { diff --git a/src/vs/workbench/contrib/snippets/browser/configureSnippets.ts b/src/vs/workbench/contrib/snippets/browser/configureSnippets.ts index 4baeb78862..3057dd8ed0 100644 --- a/src/vs/workbench/contrib/snippets/browser/configureSnippets.ts +++ b/src/vs/workbench/contrib/snippets/browser/configureSnippets.ts @@ -164,7 +164,7 @@ async function createSnippetFile(scope: string, defaultPath: URI, windowService: } async function createLanguageSnippetFile(pick: ISnippetPick, fileService: IFileService) { - if (await fileService.existsFile(URI.file(pick.filepath))) { + if (await fileService.exists(URI.file(pick.filepath))) { return; } const contents = [ diff --git a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts index 657310ab25..51d6f2417e 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetsService.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetsService.ts @@ -121,11 +121,11 @@ function watch(service: IFileService, resource: URI, callback: (type: FileChange } } }); - service.watchFileChanges(resource); + service.watch(resource); return { dispose() { listener.dispose(); - service.unwatchFileChanges(resource); + service.unwatch(resource); } }; } @@ -277,7 +277,7 @@ class SnippetsService implements ISnippetsService { private _initWorkspaceFolderSnippets(workspace: IWorkspace, bucket: IDisposable[]): Promise { let promises = workspace.folders.map(folder => { const snippetFolder = folder.toResource('.vscode'); - return this._fileService.existsFile(snippetFolder).then(value => { + return this._fileService.exists(snippetFolder).then(value => { if (value) { this._initFolderSnippets(SnippetSource.Workspace, snippetFolder, bucket); } else { @@ -305,7 +305,7 @@ class SnippetsService implements ISnippetsService { if (type === FileChangeType.DELETED) { return Promise.resolve(); } - return this._fileService.resolveFile(folder).then(stat => { + return this._fileService.resolve(folder).then(stat => { for (const entry of stat.children || []) { disposables.push(this._addSnippetFile(entry.resource, source)); } diff --git a/src/vs/workbench/contrib/stats/node/workspaceStats.ts b/src/vs/workbench/contrib/stats/node/workspaceStats.ts index 01ae5dc865..231cd415e8 100644 --- a/src/vs/workbench/contrib/stats/node/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/node/workspaceStats.ts @@ -196,7 +196,7 @@ export function getHashedRemotesFromConfig(text: string, stripEndingDotGit: bool export function getHashedRemotesFromUri(workspaceUri: URI, fileService: IFileService, stripEndingDotGit: boolean = false): Promise { const path = workspaceUri.path; const uri = workspaceUri.with({ path: `${path !== '/' ? path : ''}/.git/config` }); - return fileService.existsFile(uri).then(exists => { + return fileService.exists(uri).then(exists => { if (!exists) { return []; } @@ -364,7 +364,7 @@ export class WorkspaceStats implements IWorkbenchContribution { return Promise.resolve(tags); } - return this.fileService.resolveFiles(folders.map(resource => ({ resource }))).then((files: IResolveFileResult[]) => { + return this.fileService.resolveAll(folders.map(resource => ({ resource }))).then((files: IResolveFileResult[]) => { const names = ([]).concat(...files.map(result => result.success ? (result.stat!.children || []) : [])).map(c => c.name); const nameSet = names.reduce((s, n) => s.add(n.toLowerCase()), new Set()); @@ -437,7 +437,7 @@ export class WorkspaceStats implements IWorkbenchContribution { function getFilePromises(filename: string, fileService: IFileService, contentHandler: (content: IContent) => void): Promise[] { return !nameSet.has(filename) ? [] : (folders as URI[]).map(workspaceUri => { const uri = workspaceUri.with({ path: `${workspaceUri.path !== '/' ? workspaceUri.path : ''}/${filename}` }); - return fileService.existsFile(uri).then(exists => { + return fileService.exists(uri).then(exists => { if (!exists) { return undefined; } @@ -620,7 +620,7 @@ export class WorkspaceStats implements IWorkbenchContribution { Promise.all(workspaceUris.map(workspaceUri => { const path = workspaceUri.path; const uri = workspaceUri.with({ path: `${path !== '/' ? path : ''}/.git/config` }); - return this.fileService.existsFile(uri).then(exists => { + return this.fileService.exists(uri).then(exists => { if (!exists) { return []; } @@ -666,7 +666,7 @@ export class WorkspaceStats implements IWorkbenchContribution { const path = workspaceUri.path; return workspaceUri.with({ path: `${path !== '/' ? path : ''}/node_modules` }); }); - return this.fileService.resolveFiles(uris.map(resource => ({ resource }))).then( + return this.fileService.resolveAll(uris.map(resource => ({ resource }))).then( results => { const names = ([]).concat(...results.map(result => result.success ? (result.stat!.children || []) : [])).map(c => c.name); const referencesAzure = WorkspaceStats.searchArray(names, /azure/i); @@ -689,7 +689,7 @@ export class WorkspaceStats implements IWorkbenchContribution { return Promise.all(workspaceUris.map(workspaceUri => { const path = workspaceUri.path; const uri = workspaceUri.with({ path: `${path !== '/' ? path : ''}/pom.xml` }); - return this.fileService.existsFile(uri).then(exists => { + return this.fileService.exists(uri).then(exists => { if (!exists) { return false; } diff --git a/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts index 9a6a9f94be..44875a99b4 100644 --- a/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts @@ -2318,7 +2318,7 @@ class TaskService extends Disposable implements ITaskService { let openTaskFile = (workspaceFolder: IWorkspaceFolder): void => { let resource = workspaceFolder.toResource('.vscode/tasks.json'); let configFileCreated = false; - this.fileService.resolveFile(resource).then((stat) => stat, () => undefined).then((stat) => { + this.fileService.resolve(resource).then((stat) => stat, () => undefined).then((stat) => { if (stat) { return stat.resource; } @@ -2375,7 +2375,7 @@ class TaskService extends Disposable implements ITaskService { } let stats = this.contextService.getWorkspace().folders.map>((folder) => { - return this.fileService.resolveFile(folder.toResource('.vscode/tasks.json')).then(stat => stat, () => undefined); + return this.fileService.resolve(folder.toResource('.vscode/tasks.json')).then(stat => stat, () => undefined); }); let createLabel = nls.localize('TaskService.createJsonFile', 'Create tasks.json file from template'); diff --git a/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts b/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts index e060b887c6..a873733ccf 100644 --- a/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts +++ b/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts @@ -230,7 +230,7 @@ export class ProcessRunnerDetector { } private tryDetectGulp(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { - return Promise.resolve(this.fileService.resolveFile(workspaceFolder.toResource('gulpfile.js'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return Promise.resolve(this.fileService.resolve(workspaceFolder.toResource('gulpfile.js'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) let config = ProcessRunnerDetector.detectorConfig('gulp'); let process = new LineProcess('gulp', [config.arg, '--no-color'], true, { cwd: this._cwd }); return this.runDetection(process, 'gulp', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); @@ -240,7 +240,7 @@ export class ProcessRunnerDetector { } private tryDetectGrunt(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { - return Promise.resolve(this.fileService.resolveFile(workspaceFolder.toResource('Gruntfile.js'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return Promise.resolve(this.fileService.resolve(workspaceFolder.toResource('Gruntfile.js'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) let config = ProcessRunnerDetector.detectorConfig('grunt'); let process = new LineProcess('grunt', [config.arg, '--no-color'], true, { cwd: this._cwd }); return this.runDetection(process, 'grunt', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); @@ -255,10 +255,10 @@ export class ProcessRunnerDetector { let process = new LineProcess('jake', [config.arg], true, { cwd: this._cwd }); return this.runDetection(process, 'jake', true, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list); }; - return Promise.resolve(this.fileService.resolveFile(workspaceFolder.toResource('Jakefile'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return Promise.resolve(this.fileService.resolve(workspaceFolder.toResource('Jakefile'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) return run(); }, (err: any) => { - return this.fileService.resolveFile(workspaceFolder.toResource('Jakefile.js')).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) + return this.fileService.resolve(workspaceFolder.toResource('Jakefile.js')).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) return run(); }, (err: any) => { return null; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts index 5a56145600..f6321ae075 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts @@ -305,7 +305,7 @@ export class TerminalLinkHandler { uri = URI.file(linkUrl); } - return this._fileService.resolveFile(uri).then(stat => { + return this._fileService.resolve(uri).then(stat => { if (stat.isDirectory) { return null; } diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 27fa8d85ec..8956cbf541 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -416,7 +416,7 @@ export abstract class TerminalService implements ITerminalService { return Promise.resolve(null); } const current = potentialPaths.shift(); - return this._fileService.existsFile(URI.file(current!)).then(exists => { + return this._fileService.exists(URI.file(current!)).then(exists => { if (!exists) { return this._validateShellPaths(label, potentialPaths); } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index e602915947..c2a021fdbd 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -82,7 +82,7 @@ export class TerminalService extends BrowserTerminalService implements ITerminal const interval = setInterval(() => { if (!running) { running = true; - this._fileService.existsFile(path).then(exists => { + this._fileService.exists(path).then(exists => { running = false; if (!exists) { diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index 90c23757b1..6557626a93 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -69,7 +69,7 @@ export class WelcomePageContribution implements IWorkbenchContribution { if (openWithReadme) { return Promise.all(contextService.getWorkspace().folders.map(folder => { const folderUri = folder.uri; - return fileService.resolveFile(folderUri) + return fileService.resolve(folderUri) .then(folder => { const files = folder.children ? folder.children.map(child => child.name) : []; diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index 6164e5c9e7..31c9cc8264 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -318,14 +318,14 @@ export class BulkEdit { if (edit.newUri && edit.oldUri) { // rename - if (options.overwrite === undefined && options.ignoreIfExists && await this._fileService.existsFile(edit.newUri)) { + if (options.overwrite === undefined && options.ignoreIfExists && await this._fileService.exists(edit.newUri)) { continue; // not overwriting, but ignoring, and the target file exists } await this._textFileService.move(edit.oldUri, edit.newUri, options.overwrite); } else if (!edit.newUri && edit.oldUri) { // delete file - if (await this._fileService.existsFile(edit.oldUri)) { + if (await this._fileService.exists(edit.oldUri)) { let useTrash = this._configurationService.getValue('files.enableTrash'); if (useTrash && !(await this._fileService.hasCapability(edit.oldUri, FileSystemProviderCapabilities.Trash))) { useTrash = false; // not supported by provider @@ -336,7 +336,7 @@ export class BulkEdit { } } else if (edit.newUri && !edit.oldUri) { // create file - if (options.overwrite === undefined && options.ignoreIfExists && await this._fileService.existsFile(edit.newUri)) { + if (options.overwrite === undefined && options.ignoreIfExists && await this._fileService.exists(edit.newUri)) { continue; // not overwriting, but ignoring, and the target file exists } await this._textFileService.create(edit.newUri, undefined, { overwrite: options.overwrite }); diff --git a/src/vs/workbench/services/configuration/common/configurationEditingService.ts b/src/vs/workbench/services/configuration/common/configurationEditingService.ts index 12c85e9180..8ae68c3db0 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditingService.ts @@ -373,7 +373,7 @@ export class ConfigurationEditingService { } private async resolveModelReference(resource: URI): Promise> { - const exists = await this.fileService.existsFile(resource); + const exists = await this.fileService.exists(resource); if (!exists) { await this.fileService.updateContent(resource, '{}', { encoding: 'utf8' }); } diff --git a/src/vs/workbench/services/configuration/common/jsonEditingService.ts b/src/vs/workbench/services/configuration/common/jsonEditingService.ts index ab1994b524..486b106de5 100644 --- a/src/vs/workbench/services/configuration/common/jsonEditingService.ts +++ b/src/vs/workbench/services/configuration/common/jsonEditingService.ts @@ -84,7 +84,7 @@ export class JSONEditingService implements IJSONEditingService { } private async resolveModelReference(resource: URI): Promise> { - const exists = await this.fileService.existsFile(resource); + const exists = await this.fileService.exists(resource); if (!exists) { await this.fileService.updateContent(resource, '{}', { encoding: 'utf8' }); } diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts index 765cbdda41..8e9fd0b550 100644 --- a/src/vs/workbench/services/configuration/node/configuration.ts +++ b/src/vs/workbench/services/configuration/node/configuration.ts @@ -369,13 +369,13 @@ class FileServiceBasedWorkspaceConfiguration extends AbstractWorkspaceConfigurat private watchWorkspaceConfigurationFile(): void { if (this.workspaceConfig) { - this.fileService.watchFileChanges(this.workspaceConfig); + this.fileService.watch(this.workspaceConfig); } } private unWatchWorkspaceConfigurtionFile(): void { if (this.workspaceConfig) { - this.fileService.unwatchFileChanges(this.workspaceConfig); + this.fileService.unwatch(this.workspaceConfig); } } @@ -638,7 +638,7 @@ export class FileServiceBasedFolderConfiguration extends AbstractFolderConfigura private doLoadFolderConfigurationContents(): Promise> { const workspaceFilePathToConfiguration: { [relativeWorkspacePath: string]: Promise } = Object.create(null); - const bulkContentFetchromise = Promise.resolve(this.fileService.resolveFile(this.folderConfigurationPath)) + const bulkContentFetchromise = Promise.resolve(this.fileService.resolve(this.folderConfigurationPath)) .then(stat => { if (stat.isDirectory && stat.children) { stat.children diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index fdef1d97d1..790685b66b 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -87,7 +87,7 @@ export class RemoteFileDialog { return this.pickResource().then(async fileFolderUri => { if (fileFolderUri) { - const stat = await this.fileService.resolveFile(fileFolderUri); + const stat = await this.fileService.resolve(fileFolderUri); return [{ uri: fileFolderUri, typeHint: stat.isDirectory ? 'folder' : 'file' }]; } @@ -98,7 +98,7 @@ export class RemoteFileDialog { public async showSaveDialog(options: ISaveDialogOptions): Promise { this.scheme = this.getScheme(options.defaultUri, options.availableFileSystems); this.requiresTrailing = true; - const newOptions = await this.getOptions(options); + const newOptions = await this.getOptions(options, true); if (!newOptions) { return Promise.resolve(undefined); } @@ -114,15 +114,19 @@ export class RemoteFileDialog { }); } - private async getOptions(options: ISaveDialogOptions | IOpenDialogOptions): Promise { + private async getOptions(options: ISaveDialogOptions | IOpenDialogOptions, isSave: boolean = false): Promise { let defaultUri = options.defaultUri; - if (!defaultUri) { + const filename = (defaultUri && isSave && (resources.dirname(defaultUri).path === '/')) ? resources.basename(defaultUri) : undefined; + if (!defaultUri || filename) { const env = await this.remoteAgentService.getEnvironment(); if (env) { defaultUri = env.userHome; } else { defaultUri = URI.from({ scheme: this.scheme, path: this.environmentService.userHome }); } + if (filename) { + defaultUri = resources.joinPath(defaultUri, filename); + } } if ((this.scheme !== Schemas.file) && !this.fileService.canHandleResource(defaultUri)) { this.notificationService.info(nls.localize('remoteFileDialog.notConnectedToRemote', 'File system provider for {0} is not available.', defaultUri.toString())); @@ -159,7 +163,7 @@ export class RemoteFileDialog { let ext: string = resources.extname(homedir); if (this.options.defaultUri) { try { - stat = await this.fileService.resolveFile(this.options.defaultUri); + stat = await this.fileService.resolve(this.options.defaultUri); } catch (e) { // The file or folder doesn't exist } @@ -292,8 +296,8 @@ export class RemoteFileDialog { let stat: IFileStat | undefined; let statDirname: IFileStat | undefined; try { - statDirname = await this.fileService.resolveFile(inputUriDirname); - stat = await this.fileService.resolveFile(inputUri); + statDirname = await this.fileService.resolve(inputUriDirname); + stat = await this.fileService.resolve(inputUri); } catch (e) { // do nothing } @@ -335,7 +339,7 @@ export class RemoteFileDialog { if (this.endsWithSlash(value) || (!resources.isEqual(this.currentFolder, resources.dirname(valueUri), true) && resources.isEqualOrParent(this.currentFolder, resources.dirname(valueUri), true))) { let stat: IFileStat | undefined; try { - stat = await this.fileService.resolveFile(valueUri); + stat = await this.fileService.resolve(valueUri); } catch (e) { // do nothing } @@ -346,7 +350,7 @@ export class RemoteFileDialog { if (!resources.isEqual(this.currentFolder, inputUriDirname, true)) { let statWithoutTrailing: IFileStat | undefined; try { - statWithoutTrailing = await this.fileService.resolveFile(inputUriDirname); + statWithoutTrailing = await this.fileService.resolve(inputUriDirname); } catch (e) { // do nothing } @@ -387,8 +391,8 @@ export class RemoteFileDialog { let stat: IFileStat | undefined; let statDirname: IFileStat | undefined; try { - statDirname = await this.fileService.resolveFile(resources.dirname(uri)); - stat = await this.fileService.resolveFile(uri); + statDirname = await this.fileService.resolve(resources.dirname(uri)); + stat = await this.fileService.resolve(uri); } catch (e) { // do nothing } @@ -509,7 +513,7 @@ export class RemoteFileDialog { const backDir = this.createBackItem(currentFolder); try { - const folder = await this.fileService.resolveFile(currentFolder); + const folder = await this.fileService.resolve(currentFolder); const fileNames = folder.children ? folder.children.map(child => child.name) : []; const items = await Promise.all(fileNames.map(fileName => this.createItem(fileName, currentFolder))); for (let item of items) { @@ -558,7 +562,7 @@ export class RemoteFileDialog { private async createItem(filename: string, parent: URI): Promise { let fullPath = resources.joinPath(parent, filename); try { - const stat = await this.fileService.resolveFile(fullPath); + const stat = await this.fileService.resolve(fullPath); if (stat.isDirectory) { filename = this.basenameWithTrailingSlash(fullPath); return { label: filename, uri: fullPath, isFolder: true, iconClasses: getIconClasses(this.modelService, this.modeService, fullPath || undefined, FileKind.FOLDER) }; diff --git a/src/vs/workbench/services/files/node/fileService.ts b/src/vs/workbench/services/files/node/fileService.ts index 13f13ab202..3809e9b213 100644 --- a/src/vs/workbench/services/files/node/fileService.ts +++ b/src/vs/workbench/services/files/node/fileService.ts @@ -280,7 +280,7 @@ export class FileService extends Disposable implements ILegacyFileService, IFile return Promise.reject(error); }; - const statsPromise = this.resolveFile(resource).then(stat => { + const statsPromise = this.resolve(resource).then(stat => { result.resource = stat.resource; result.name = stat.name; result.mtime = stat.mtime; @@ -812,11 +812,11 @@ export class FileService extends Disposable implements ILegacyFileService, IFile )); } - moveFile(source: uri, target: uri, overwrite?: boolean): Promise { + move(source: uri, target: uri, overwrite?: boolean): Promise { return this.moveOrCopyFile(source, target, false, !!overwrite); } - copyFile(source: uri, target: uri, overwrite?: boolean): Promise { + copy(source: uri, target: uri, overwrite?: boolean): Promise { return this.moveOrCopyFile(source, target, true, !!overwrite); } @@ -828,7 +828,7 @@ export class FileService extends Disposable implements ILegacyFileService, IFile return this.doMoveOrCopyFile(sourcePath, targetPath, keepCopy, overwrite).then(() => { // 2.) resolve - return this.resolve(target, { resolveMetadata: true }).then(result => { + return this.doResolve(target, { resolveMetadata: true }).then(result => { // Events (unless it was a no-op because paths are identical) if (sourcePath !== targetPath) { @@ -952,9 +952,9 @@ export class FileService extends Disposable implements ILegacyFileService, IFile return paths.normalize(resource.fsPath); } - private resolve(resource: uri, options: IResolveMetadataFileOptions): Promise; - private resolve(resource: uri, options?: IResolveFileOptions): Promise; - private resolve(resource: uri, options: IResolveFileOptions = Object.create(null)): Promise { + private doResolve(resource: uri, options: IResolveMetadataFileOptions): Promise; + private doResolve(resource: uri, options?: IResolveFileOptions): Promise; + private doResolve(resource: uri, options: IResolveFileOptions = Object.create(null)): Promise { return this.toStatResolver(resource).then(model => model.resolve(options)); } @@ -966,7 +966,7 @@ export class FileService extends Disposable implements ILegacyFileService, IFile }); } - watchFileChanges(resource: uri): void { + watch(resource: uri): void { assert.ok(resource && resource.scheme === Schemas.file, `Invalid resource for watching: ${resource}`); // Check for existing watcher first @@ -1000,11 +1000,11 @@ export class FileService extends Disposable implements ILegacyFileService, IFile // Wait a bit and try to install watcher again, assuming that the file was renamed quickly ("Atomic Save") setTimeout(() => { - this.existsFile(resource).then(exists => { + this.exists(resource).then(exists => { // File still exists, so reapply the watcher if (exists) { - this.watchFileChanges(resource); + this.watch(resource); } // File seems to be really gone, so emit a deleted event @@ -1063,7 +1063,7 @@ export class FileService extends Disposable implements ILegacyFileService, IFile }); } - unwatchFileChanges(resource: uri): void { + unwatch(resource: uri): void { const watcher = this.activeFileChangesWatchers.get(resource); if (watcher && --watcher.count === 0) { watcher.unwatch(); @@ -1092,14 +1092,14 @@ export class FileService extends Disposable implements ILegacyFileService, IFile // Tests only - resolveFile(resource: uri, options?: IResolveFileOptions): Promise; - resolveFile(resource: uri, options: IResolveMetadataFileOptions): Promise; - resolveFile(resource: uri, options?: IResolveFileOptions): Promise { - return this.resolve(resource, options); + resolve(resource: uri, options?: IResolveFileOptions): Promise; + resolve(resource: uri, options: IResolveMetadataFileOptions): Promise; + resolve(resource: uri, options?: IResolveFileOptions): Promise { + return this.doResolve(resource, options); } - resolveFiles(toResolve: { resource: uri, options?: IResolveFileOptions }[]): Promise { - return Promise.all(toResolve.map(resourceAndOptions => this.resolve(resourceAndOptions.resource, resourceAndOptions.options) + resolveAll(toResolve: { resource: uri, options?: IResolveFileOptions }[]): Promise { + return Promise.all(toResolve.map(resourceAndOptions => this.doResolve(resourceAndOptions.resource, resourceAndOptions.options) .then(stat => ({ stat, success: true }), error => ({ stat: undefined, success: false })))); } @@ -1110,7 +1110,7 @@ export class FileService extends Disposable implements ILegacyFileService, IFile return pfs.mkdirp(absolutePath).then(() => { // 2.) Resolve - return this.resolve(resource, { resolveMetadata: true }).then(result => { + return this.doResolve(resource, { resolveMetadata: true }).then(result => { // Events this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.CREATE, result)); @@ -1120,8 +1120,8 @@ export class FileService extends Disposable implements ILegacyFileService, IFile }); } - existsFile(resource: uri): Promise { - return this.resolveFile(resource).then(() => true, () => false); + exists(resource: uri): Promise { + return this.resolve(resource).then(() => true, () => false); } } diff --git a/src/vs/workbench/services/files/node/remoteFileService.ts b/src/vs/workbench/services/files/node/remoteFileService.ts index 70abcfe9eb..d86eed8e1a 100644 --- a/src/vs/workbench/services/files/node/remoteFileService.ts +++ b/src/vs/workbench/services/files/node/remoteFileService.ts @@ -140,18 +140,18 @@ class WorkspaceWatchLogic extends Disposable { } } this._watches.set(resource.toString(), resource); - this._fileService.watchFileChanges(resource, { recursive: true, excludes }); + this._fileService.watch(resource, { recursive: true, excludes }); } private _unwatchWorkspace(resource: URI) { if (this._watches.has(resource.toString())) { - this._fileService.unwatchFileChanges(resource); + this._fileService.unwatch(resource); this._watches.delete(resource.toString()); } } private _unwatchWorkspaces() { - this._watches.forEach(uri => this._fileService.unwatchFileChanges(uri)); + this._watches.forEach(uri => this._fileService.unwatch(uri)); this._watches.clear(); } } @@ -223,11 +223,11 @@ export class RemoteFileService extends FileService { }); } - resolveFile(resource: URI, options: IResolveMetadataFileOptions): Promise; - resolveFile(resource: URI, options?: IResolveFileOptions): Promise; - resolveFile(resource: URI, options?: IResolveFileOptions): Promise { + resolve(resource: URI, options: IResolveMetadataFileOptions): Promise; + resolve(resource: URI, options?: IResolveFileOptions): Promise; + resolve(resource: URI, options?: IResolveFileOptions): Promise { if (resource.scheme === Schemas.file) { - return super.resolveFile(resource, options); + return super.resolve(resource, options); } else { return this._doResolveFiles([{ resource, options }]).then(data => { if (data.length !== 1 || !data[0].success) { @@ -279,7 +279,7 @@ export class RemoteFileService extends FileService { private _readFile(resource: URI, options: IResolveContentOptions = Object.create(null)): Promise { return this._withProvider(resource).then(provider => { - return this.resolveFile(resource).then(fileStat => { + return this.resolve(resource).then(fileStat => { if (fileStat.isDirectory) { // todo@joh cannot copy a folder @@ -409,7 +409,7 @@ export class RemoteFileService extends FileService { target.once('error', err => reject(err)); target.once('finish', (_: unknown) => resolve(undefined)); }).then(_ => { - return this.resolveFile(resource, { resolveMetadata: true }) as Promise; + return this.resolve(resource, { resolveMetadata: true }) as Promise; }); } @@ -433,9 +433,9 @@ export class RemoteFileService extends FileService { private _activeWatches = new Map, count: number }>(); - watchFileChanges(resource: URI, opts: IWatchOptions = { recursive: false, excludes: [] }): void { + watch(resource: URI, opts: IWatchOptions = { recursive: false, excludes: [] }): void { if (resource.scheme === Schemas.file) { - return super.watchFileChanges(resource); + return super.watch(resource); } const key = resource.toString(); @@ -455,9 +455,9 @@ export class RemoteFileService extends FileService { }); } - unwatchFileChanges(resource: URI): void { + unwatch(resource: URI): void { if (resource.scheme === Schemas.file) { - return super.unwatchFileChanges(resource); + return super.unwatch(resource); } let entry = this._activeWatches.get(resource.toString()); if (entry && --entry.count === 0) { diff --git a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts index 76ba4efebe..53aa54dce1 100644 --- a/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts +++ b/src/vs/workbench/services/files/test/electron-browser/fileService.test.ts @@ -348,15 +348,15 @@ suite('FileService', () => { }); }); - test('watchFileChanges', function (done) { + test('watch', function (done) { const toWatch = uri.file(path.join(testDir, 'index.html')); - service.watchFileChanges(toWatch); + service.watch(toWatch); service.onFileChanges((e: FileChangesEvent) => { assert.ok(e); - service.unwatchFileChanges(toWatch); + service.unwatch(toWatch); done(); }); @@ -365,15 +365,15 @@ suite('FileService', () => { }, 100); }); - // test('watchFileChanges - support atomic save', function (done) { + // test('watch - support atomic save', function (done) { // const toWatch = uri.file(path.join(testDir, 'index.html')); - // service.watchFileChanges(toWatch); + // service.watch(toWatch); // service.onFileChanges((e: FileChangesEvent) => { // assert.ok(e); - // service.unwatchFileChanges(toWatch); + // service.unwatch(toWatch); // done(); // }); diff --git a/src/vs/workbench/services/files2/common/fileService2.ts b/src/vs/workbench/services/files2/common/fileService2.ts index f0c271b226..6c5f163b36 100644 --- a/src/vs/workbench/services/files2/common/fileService2.ts +++ b/src/vs/workbench/services/files2/common/fileService2.ts @@ -152,9 +152,9 @@ export class FileService2 extends Disposable implements IFileService { //#region File Metadata Resolving - async resolveFile(resource: URI, options: IResolveMetadataFileOptions): Promise; - async resolveFile(resource: URI, options?: IResolveFileOptions): Promise; - async resolveFile(resource: URI, options?: IResolveFileOptions): Promise { + async resolve(resource: URI, options: IResolveMetadataFileOptions): Promise; + async resolve(resource: URI, options?: IResolveFileOptions): Promise; + async resolve(resource: URI, options?: IResolveFileOptions): Promise { try { return await this.doResolveFile(resource, options); } catch (error) { @@ -251,9 +251,9 @@ export class FileService2 extends Disposable implements IFileService { return Promise.resolve(fileStat); } - async resolveFiles(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise; - async resolveFiles(toResolve: { resource: URI, options: IResolveMetadataFileOptions }[]): Promise; - async resolveFiles(toResolve: { resource: URI; options?: IResolveFileOptions; }[]): Promise { + async resolveAll(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise; + async resolveAll(toResolve: { resource: URI, options: IResolveMetadataFileOptions }[]): Promise; + async resolveAll(toResolve: { resource: URI; options?: IResolveFileOptions; }[]): Promise { return Promise.all(toResolve.map(async entry => { try { return { stat: await this.doResolveFile(entry.resource, entry.options), success: true }; @@ -265,9 +265,9 @@ export class FileService2 extends Disposable implements IFileService { })); } - async existsFile(resource: URI): Promise { + async exists(resource: URI): Promise { try { - return !!(await this.resolveFile(resource)); + return !!(await this.resolve(resource)); } catch (error) { return false; } @@ -295,7 +295,7 @@ export class FileService2 extends Disposable implements IFileService { // validate overwrite const overwrite = !!(options && options.overwrite); - if (await this.existsFile(resource)) { + if (await this.exists(resource)) { if (!overwrite) { throw new FileOperationError(localize('fileExists', "File to create already exists ({0})", resource.toString(true)), FileOperationResult.FILE_MODIFIED_SINCE, options); } @@ -328,7 +328,7 @@ export class FileService2 extends Disposable implements IFileService { } // events - const fileStat = await this.resolveFile(resource, { resolveMetadata: true }); + const fileStat = await this.resolve(resource, { resolveMetadata: true }); this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.CREATE, fileStat)); return fileStat; @@ -350,7 +350,7 @@ export class FileService2 extends Disposable implements IFileService { //#region Move/Copy/Delete/Create Folder - async moveFile(source: URI, target: URI, overwrite?: boolean): Promise { + async move(source: URI, target: URI, overwrite?: boolean): Promise { const sourceProvider = this.throwIfFileSystemIsReadonly(await this.withProvider(source)); const targetProvider = this.throwIfFileSystemIsReadonly(await this.withProvider(target)); @@ -358,13 +358,13 @@ export class FileService2 extends Disposable implements IFileService { const mode = await this.doMoveCopy(sourceProvider, source, targetProvider, target, 'move', overwrite); // resolve and send events - const fileStat = await this.resolveFile(target, { resolveMetadata: true }); + const fileStat = await this.resolve(target, { resolveMetadata: true }); this._onAfterOperation.fire(new FileOperationEvent(source, mode === 'move' ? FileOperation.MOVE : FileOperation.COPY, fileStat)); return fileStat; } - async copyFile(source: URI, target: URI, overwrite?: boolean): Promise { + async copy(source: URI, target: URI, overwrite?: boolean): Promise { const sourceProvider = await this.withProvider(source); const targetProvider = this.throwIfFileSystemIsReadonly(await this.withProvider(target)); @@ -372,7 +372,7 @@ export class FileService2 extends Disposable implements IFileService { const mode = await this.doMoveCopy(sourceProvider, source, targetProvider, target, 'copy', overwrite); // resolve and send events - const fileStat = await this.resolveFile(target, { resolveMetadata: true }); + const fileStat = await this.resolve(target, { resolveMetadata: true }); this._onAfterOperation.fire(new FileOperationEvent(source, mode === 'copy' ? FileOperation.COPY : FileOperation.MOVE, fileStat)); return fileStat; @@ -409,7 +409,7 @@ export class FileService2 extends Disposable implements IFileService { // when copying via buffer/unbuffered, we have to manually // traverse the source if it is a folder and not a file - const sourceFile = await this.resolveFile(source); + const sourceFile = await this.resolve(source); if (sourceFile.isDirectory) { return this.doCopyFolder(sourceProvider, sourceFile, targetProvider, target, overwrite).then(() => mode); } else { @@ -467,7 +467,7 @@ export class FileService2 extends Disposable implements IFileService { await Promise.all(sourceFolder.children.map(async sourceChild => { const targetChild = joinPath(targetFolder, sourceChild.name); if (sourceChild.isDirectory) { - return this.doCopyFolder(sourceProvider, await this.resolveFile(sourceChild.resource), targetProvider, targetChild, overwrite); + return this.doCopyFolder(sourceProvider, await this.resolve(sourceChild.resource), targetProvider, targetChild, overwrite); } else { return this.doCopyFile(sourceProvider, sourceChild.resource, targetProvider, targetChild, overwrite); } @@ -489,7 +489,7 @@ export class FileService2 extends Disposable implements IFileService { } // Extra checks if target exists and this is not a rename - const exists = await this.existsFile(target); + const exists = await this.exists(target); if (exists && !isCaseChange) { // Bail out if target exists and we are not about to overwrite @@ -514,7 +514,7 @@ export class FileService2 extends Disposable implements IFileService { await this.mkdirp(provider, resource); // events - const fileStat = await this.resolveFile(resource, { resolveMetadata: true }); + const fileStat = await this.resolve(resource, { resolveMetadata: true }); this._onAfterOperation.fire(new FileOperationEvent(resource, FileOperation.CREATE, fileStat)); return fileStat; @@ -565,8 +565,8 @@ export class FileService2 extends Disposable implements IFileService { // Validate recursive const recursive = !!(options && options.recursive); - if (!recursive && await this.existsFile(resource)) { - const stat = await this.resolveFile(resource); + if (!recursive && await this.exists(resource)) { + const stat = await this.resolve(resource); if (stat.isDirectory && Array.isArray(stat.children) && stat.children.length > 0) { throw new Error(localize('deleteFailed', "Failed to delete non-empty folder '{0}'.", resource.toString())); } @@ -586,12 +586,12 @@ export class FileService2 extends Disposable implements IFileService { private _onFileChanges: Emitter = this._register(new Emitter()); get onFileChanges(): Event { return this._onFileChanges.event; } - watchFileChanges(resource: URI): void { - this.joinOnLegacy.then(legacy => legacy.watchFileChanges(resource)); + watch(resource: URI): void { + this.joinOnLegacy.then(legacy => legacy.watch(resource)); } - unwatchFileChanges(resource: URI): void { - this.joinOnLegacy.then(legacy => legacy.unwatchFileChanges(resource)); + unwatch(resource: URI): void { + this.joinOnLegacy.then(legacy => legacy.unwatch(resource)); } //#endregion @@ -690,7 +690,7 @@ export class FileService2 extends Disposable implements IFileService { private async doPipeBufferedToUnbuffered(sourceProvider: IFileSystemProviderWithOpenReadWriteCloseCapability, source: URI, targetProvider: IFileSystemProviderWithFileReadWriteCapability, target: URI, overwrite: boolean): Promise { // Determine file size - const size = (await this.resolveFile(source, { resolveMetadata: true })).size; + const size = (await this.resolve(source, { resolveMetadata: true })).size; // Open handle const sourceHandle = await sourceProvider.open(source, { create: false }); diff --git a/src/vs/workbench/services/files2/node/diskFileSystemProvider.ts b/src/vs/workbench/services/files2/node/diskFileSystemProvider.ts index 0616ab0e9a..1bc40210e5 100644 --- a/src/vs/workbench/services/files2/node/diskFileSystemProvider.ts +++ b/src/vs/workbench/services/files2/node/diskFileSystemProvider.ts @@ -225,10 +225,6 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro await this.doDelete(filePath, opts); } catch (error) { - if (error.code === 'ENOENT') { - return Promise.resolve(); // tolerate that the file might not exist - } - throw this.toFileSystemProviderError(error); } } diff --git a/src/vs/workbench/services/files2/test/node/diskFileService.test.ts b/src/vs/workbench/services/files2/test/node/diskFileService.test.ts index f80637ad56..51718c1283 100644 --- a/src/vs/workbench/services/files2/test/node/diskFileService.test.ts +++ b/src/vs/workbench/services/files2/test/node/diskFileService.test.ts @@ -100,7 +100,7 @@ suite('Disk File Service', () => { let event: FileOperationEvent | undefined; disposables.push(service.onAfterOperation(e => event = e)); - const parent = await service.resolveFile(URI.file(testDir)); + const parent = await service.resolve(URI.file(testDir)); const newFolderResource = URI.file(join(parent.resource.fsPath, 'newFolder')); @@ -121,7 +121,7 @@ suite('Disk File Service', () => { disposables.push(service.onAfterOperation(e => event = e)); const multiFolderPaths = ['a', 'couple', 'of', 'folders']; - const parent = await service.resolveFile(URI.file(testDir)); + const parent = await service.resolve(URI.file(testDir)); const newFolderResource = URI.file(join(parent.resource.fsPath, ...multiFolderPaths)); @@ -138,26 +138,26 @@ suite('Disk File Service', () => { assert.equal(event!.target!.isDirectory, true); }); - test('existsFile', async () => { - let exists = await service.existsFile(URI.file(testDir)); + test('exists', async () => { + let exists = await service.exists(URI.file(testDir)); assert.equal(exists, true); - exists = await service.existsFile(URI.file(testDir + 'something')); + exists = await service.exists(URI.file(testDir + 'something')); assert.equal(exists, false); }); - test('resolveFile', async () => { - const resolved = await service.resolveFile(URI.file(testDir), { resolveTo: [URI.file(join(testDir, 'deep'))] }); + test('resolve', async () => { + const resolved = await service.resolve(URI.file(testDir), { resolveTo: [URI.file(join(testDir, 'deep'))] }); assert.equal(resolved.children!.length, 8); const deep = (getByName(resolved, 'deep')!); assert.equal(deep.children!.length, 4); }); - test('resolveFile - directory', async () => { + test('resolve - directory', async () => { const testsElements = ['examples', 'other', 'index.html', 'site.css']; - const result = await service.resolveFile(URI.file(getPathFromAmdModule(require, './fixtures/resolver'))); + const result = await service.resolve(URI.file(getPathFromAmdModule(require, './fixtures/resolver'))); assert.ok(result); assert.ok(result.children); @@ -187,10 +187,10 @@ suite('Disk File Service', () => { }); }); - test('resolveFile - directory - with metadata', async () => { + test('resolve - directory - with metadata', async () => { const testsElements = ['examples', 'other', 'index.html', 'site.css']; - const result = await service.resolveFile(URI.file(getPathFromAmdModule(require, './fixtures/resolver')), { resolveMetadata: true }); + const result = await service.resolve(URI.file(getPathFromAmdModule(require, './fixtures/resolver')), { resolveMetadata: true }); assert.ok(result); assert.ok(result.children); @@ -222,9 +222,9 @@ suite('Disk File Service', () => { }); }); - test('resolveFile - directory - resolveTo single directory', async () => { + test('resolve - directory - resolveTo single directory', async () => { const resolverFixturesPath = getPathFromAmdModule(require, './fixtures/resolver'); - const result = await service.resolveFile(URI.file(resolverFixturesPath), { resolveTo: [URI.file(join(resolverFixturesPath, 'other/deep'))] }); + const result = await service.resolve(URI.file(resolverFixturesPath), { resolveTo: [URI.file(join(resolverFixturesPath, 'other/deep'))] }); assert.ok(result); assert.ok(result.children); @@ -246,7 +246,7 @@ suite('Disk File Service', () => { test('resolve directory - resolveTo multiple directories', async () => { const resolverFixturesPath = getPathFromAmdModule(require, './fixtures/resolver'); - const result = await service.resolveFile(URI.file(resolverFixturesPath), { + const result = await service.resolve(URI.file(resolverFixturesPath), { resolveTo: [ URI.file(join(resolverFixturesPath, 'other/deep')), URI.file(join(resolverFixturesPath, 'examples')) @@ -278,7 +278,7 @@ suite('Disk File Service', () => { test('resolve directory - resolveSingleChildFolders', async () => { const resolverFixturesPath = getPathFromAmdModule(require, './fixtures/resolver/other'); - const result = await service.resolveFile(URI.file(resolverFixturesPath), { resolveSingleChildDescendants: true }); + const result = await service.resolve(URI.file(resolverFixturesPath), { resolveSingleChildDescendants: true }); assert.ok(result); assert.ok(result.children); @@ -294,8 +294,8 @@ suite('Disk File Service', () => { assert.equal(deep!.children!.length, 4); }); - test('resolveFiles', async () => { - const res = await service.resolveFiles([ + test('resolves', async () => { + const res = await service.resolveAll([ { resource: URI.file(testDir), options: { resolveTo: [URI.file(join(testDir, 'deep'))] } }, { resource: URI.file(join(testDir, 'deep')) } ]); @@ -311,7 +311,7 @@ suite('Disk File Service', () => { assert.equal(r2.name, 'deep'); }); - test('resolveFile - folder symbolic link', async () => { + test('resolve - folder symbolic link', async () => { if (isWindows) { return; // not happy } @@ -319,13 +319,13 @@ suite('Disk File Service', () => { const link = URI.file(join(testDir, 'deep-link')); await symlink(join(testDir, 'deep'), link.fsPath); - const resolved = await service.resolveFile(link); + const resolved = await service.resolve(link); assert.equal(resolved.children!.length, 4); assert.equal(resolved.isDirectory, true); assert.equal(resolved.isSymbolicLink, true); }); - test('resolveFile - file symbolic link', async () => { + test('resolve - file symbolic link', async () => { if (isWindows) { return; // not happy } @@ -333,12 +333,12 @@ suite('Disk File Service', () => { const link = URI.file(join(testDir, 'lorem.txt-linked')); await symlink(join(testDir, 'lorem.txt'), link.fsPath); - const resolved = await service.resolveFile(link); + const resolved = await service.resolve(link); assert.equal(resolved.isDirectory, false); assert.equal(resolved.isSymbolicLink, true); }); - test('resolveFile - invalid symbolic link does not break', async () => { + test('resolve - invalid symbolic link does not break', async () => { if (isWindows) { return; // not happy } @@ -346,7 +346,7 @@ suite('Disk File Service', () => { const link = URI.file(join(testDir, 'foo')); await symlink(link.fsPath, join(testDir, 'bar')); - const resolved = await service.resolveFile(URI.file(testDir)); + const resolved = await service.resolve(URI.file(testDir)); assert.equal(resolved.isDirectory, true); assert.equal(resolved.children!.length, 8); }); @@ -356,7 +356,7 @@ suite('Disk File Service', () => { disposables.push(service.onAfterOperation(e => event = e)); const resource = URI.file(join(testDir, 'deep', 'conway.js')); - const source = await service.resolveFile(resource); + const source = await service.resolve(resource); await service.del(source.resource); @@ -371,7 +371,7 @@ suite('Disk File Service', () => { disposables.push(service.onAfterOperation(e => event = e)); const resource = URI.file(join(testDir, 'deep')); - const source = await service.resolveFile(resource); + const source = await service.resolve(resource); await service.del(source.resource, { recursive: true }); @@ -383,7 +383,7 @@ suite('Disk File Service', () => { test('deleteFolder (non recursive)', async () => { const resource = URI.file(join(testDir, 'deep')); - const source = await service.resolveFile(resource); + const source = await service.resolve(resource); try { await service.del(source.resource); @@ -394,7 +394,7 @@ suite('Disk File Service', () => { } }); - test('moveFile', async () => { + test('move', async () => { let event: FileOperationEvent; disposables.push(service.onAfterOperation(e => event = e)); @@ -403,7 +403,7 @@ suite('Disk File Service', () => { const target = URI.file(join(dirname(source.fsPath), 'other.html')); - const renamed = await service.moveFile(source, target); + const renamed = await service.move(source, target); assert.equal(existsSync(renamed.resource.fsPath), true); assert.equal(existsSync(source.fsPath), false); @@ -418,56 +418,56 @@ suite('Disk File Service', () => { assert.equal(sourceContents.toString(), targetContents.toString()); }); - test('moveFile - across providers (buffered => buffered)', async () => { + test('move - across providers (buffered => buffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); await testMoveAcrossProviders(); }); - test('moveFile - across providers (unbuffered => unbuffered)', async () => { + test('move - across providers (unbuffered => unbuffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileReadWrite); await testMoveAcrossProviders(); }); - test('moveFile - across providers (buffered => unbuffered)', async () => { + test('move - across providers (buffered => unbuffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); setCapabilities(testProvider, FileSystemProviderCapabilities.FileReadWrite); await testMoveAcrossProviders(); }); - test('moveFile - across providers (unbuffered => buffered)', async () => { + test('move - across providers (unbuffered => buffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); await testMoveAcrossProviders(); }); - test('moveFile - across providers - large (buffered => buffered)', async () => { + test('move - across providers - large (buffered => buffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); await testMoveAcrossProviders('lorem.txt'); }); - test('moveFile - across providers - large (unbuffered => unbuffered)', async () => { + test('move - across providers - large (unbuffered => unbuffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileReadWrite); await testMoveAcrossProviders('lorem.txt'); }); - test('moveFile - across providers - large (buffered => unbuffered)', async () => { + test('move - across providers - large (buffered => unbuffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); setCapabilities(testProvider, FileSystemProviderCapabilities.FileReadWrite); await testMoveAcrossProviders('lorem.txt'); }); - test('moveFile - across providers - large (unbuffered => buffered)', async () => { + test('move - across providers - large (unbuffered => buffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); @@ -483,7 +483,7 @@ suite('Disk File Service', () => { const target = URI.file(join(dirname(source.fsPath), 'other.html')).with({ scheme: testSchema }); - const renamed = await service.moveFile(source, target); + const renamed = await service.move(source, target); assert.equal(existsSync(renamed.resource.fsPath), true); assert.equal(existsSync(source.fsPath), false); @@ -498,7 +498,7 @@ suite('Disk File Service', () => { assert.equal(sourceContents.toString(), targetContents.toString()); } - test('moveFile - multi folder', async () => { + test('move - multi folder', async () => { let event: FileOperationEvent; disposables.push(service.onAfterOperation(e => event = e)); @@ -507,7 +507,7 @@ suite('Disk File Service', () => { const source = URI.file(join(testDir, 'index.html')); - const renamed = await service.moveFile(source, URI.file(join(dirname(source.fsPath), renameToPath))); + const renamed = await service.move(source, URI.file(join(dirname(source.fsPath), renameToPath))); assert.equal(existsSync(renamed.resource.fsPath), true); assert.equal(existsSync(source.fsPath), false); @@ -517,13 +517,13 @@ suite('Disk File Service', () => { assert.equal(event!.target!.resource.fsPath, renamed.resource.fsPath); }); - test('moveFile - directory', async () => { + test('move - directory', async () => { let event: FileOperationEvent; disposables.push(service.onAfterOperation(e => event = e)); const source = URI.file(join(testDir, 'deep')); - const renamed = await service.moveFile(source, URI.file(join(dirname(source.fsPath), 'deeper'))); + const renamed = await service.move(source, URI.file(join(dirname(source.fsPath), 'deeper'))); assert.equal(existsSync(renamed.resource.fsPath), true); assert.equal(existsSync(source.fsPath), false); @@ -533,28 +533,28 @@ suite('Disk File Service', () => { assert.equal(event!.target!.resource.fsPath, renamed.resource.fsPath); }); - test('moveFile - directory - across providers (buffered => buffered)', async () => { + test('move - directory - across providers (buffered => buffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); await testMoveFolderAcrossProviders(); }); - test('moveFile - directory - across providers (unbuffered => unbuffered)', async () => { + test('move - directory - across providers (unbuffered => unbuffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileReadWrite); await testMoveFolderAcrossProviders(); }); - test('moveFile - directory - across providers (buffered => unbuffered)', async () => { + test('move - directory - across providers (buffered => unbuffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); setCapabilities(testProvider, FileSystemProviderCapabilities.FileReadWrite); await testMoveFolderAcrossProviders(); }); - test('moveFile - directory - across providers (unbuffered => buffered)', async () => { + test('move - directory - across providers (unbuffered => buffered)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); @@ -570,7 +570,7 @@ suite('Disk File Service', () => { const target = URI.file(join(dirname(source.fsPath), 'deeper')).with({ scheme: testSchema }); - const renamed = await service.moveFile(source, target); + const renamed = await service.move(source, target); assert.equal(existsSync(renamed.resource.fsPath), true); assert.equal(existsSync(source.fsPath), false); @@ -586,14 +586,14 @@ suite('Disk File Service', () => { } } - test('moveFile - MIX CASE', async () => { + test('move - MIX CASE', async () => { let event: FileOperationEvent; disposables.push(service.onAfterOperation(e => event = e)); const source = URI.file(join(testDir, 'index.html')); - await service.resolveFile(source); + await service.resolve(source); - const renamed = await service.moveFile(source, URI.file(join(dirname(source.fsPath), 'INDEX.html'))); + const renamed = await service.move(source, URI.file(join(dirname(source.fsPath), 'INDEX.html'))); assert.equal(existsSync(renamed.resource.fsPath), true); assert.equal(basename(renamed.resource.fsPath), 'INDEX.html'); @@ -603,33 +603,33 @@ suite('Disk File Service', () => { assert.equal(event!.target!.resource.fsPath, renamed.resource.fsPath); }); - test('moveFile - source parent of target', async () => { + test('move - source parent of target', async () => { let event: FileOperationEvent; disposables.push(service.onAfterOperation(e => event = e)); - await service.resolveFile(URI.file(join(testDir, 'index.html'))); + await service.resolve(URI.file(join(testDir, 'index.html'))); try { - await service.moveFile(URI.file(testDir), URI.file(join(testDir, 'binary.txt'))); + await service.move(URI.file(testDir), URI.file(join(testDir, 'binary.txt'))); } catch (e) { assert.ok(e); assert.ok(!event!); } }); - test('moveFile - FILE_MOVE_CONFLICT', async () => { + test('move - FILE_MOVE_CONFLICT', async () => { let event: FileOperationEvent; disposables.push(service.onAfterOperation(e => event = e)); - const source = await service.resolveFile(URI.file(join(testDir, 'index.html'))); + const source = await service.resolve(URI.file(join(testDir, 'index.html'))); try { - await service.moveFile(source.resource, URI.file(join(testDir, 'binary.txt'))); + await service.move(source.resource, URI.file(join(testDir, 'binary.txt'))); } catch (e) { assert.equal(e.fileOperationResult, FileOperationResult.FILE_MOVE_CONFLICT); assert.ok(!event!); } }); - test('moveFile - overwrite folder with file', async () => { + test('move - overwrite folder with file', async () => { let createEvent: FileOperationEvent; let moveEvent: FileOperationEvent; let deleteEvent: FileOperationEvent; @@ -643,12 +643,12 @@ suite('Disk File Service', () => { } })); - const parent = await service.resolveFile(URI.file(testDir)); + const parent = await service.resolve(URI.file(testDir)); const folderResource = URI.file(join(parent.resource.fsPath, 'conway.js')); const f = await service.createFolder(folderResource); const source = URI.file(join(testDir, 'deep', 'conway.js')); - const moved = await service.moveFile(source, f.resource, true); + const moved = await service.move(source, f.resource, true); assert.equal(existsSync(moved.resource.fsPath), true); assert.ok(statSync(moved.resource.fsPath).isFile); @@ -660,32 +660,32 @@ suite('Disk File Service', () => { assert.equal(deleteEvent!.resource.fsPath, folderResource.fsPath); }); - test('copyFile', async () => { - await doTestCopyFile(); + test('copy', async () => { + await doTestCopy(); }); - test('copyFile - unbuffered (FileSystemProviderCapabilities.FileReadWrite)', async () => { + test('copy - unbuffered (FileSystemProviderCapabilities.FileReadWrite)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); - await doTestCopyFile(); + await doTestCopy(); }); - test('copyFile - unbuffered large (FileSystemProviderCapabilities.FileReadWrite)', async () => { + test('copy - unbuffered large (FileSystemProviderCapabilities.FileReadWrite)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); - await doTestCopyFile('lorem.txt'); + await doTestCopy('lorem.txt'); }); - test('copyFile - buffered (FileSystemProviderCapabilities.FileOpenReadWriteClose)', async () => { + test('copy - buffered (FileSystemProviderCapabilities.FileOpenReadWriteClose)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); - await doTestCopyFile(); + await doTestCopy(); }); - test('copyFile - buffered large (FileSystemProviderCapabilities.FileOpenReadWriteClose)', async () => { + test('copy - buffered large (FileSystemProviderCapabilities.FileOpenReadWriteClose)', async () => { setCapabilities(fileProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); - await doTestCopyFile('lorem.txt'); + await doTestCopy('lorem.txt'); }); function setCapabilities(provider: TestDiskFileSystemProvider, capabilities: FileSystemProviderCapabilities): void { @@ -695,14 +695,14 @@ suite('Disk File Service', () => { } } - async function doTestCopyFile(sourceName: string = 'index.html') { + async function doTestCopy(sourceName: string = 'index.html') { let event: FileOperationEvent; disposables.push(service.onAfterOperation(e => event = e)); - const source = await service.resolveFile(URI.file(join(testDir, sourceName))); + const source = await service.resolve(URI.file(join(testDir, sourceName))); const target = URI.file(join(testDir, 'other.html')); - const copied = await service.copyFile(source.resource, target); + const copied = await service.copy(source.resource, target); assert.equal(existsSync(copied.resource.fsPath), true); assert.equal(existsSync(source.resource.fsPath), true); @@ -718,7 +718,7 @@ suite('Disk File Service', () => { assert.equal(sourceContents.toString(), targetContents.toString()); } - test('copyFile - overwrite folder with file', async () => { + test('copy - overwrite folder with file', async () => { let createEvent: FileOperationEvent; let copyEvent: FileOperationEvent; let deleteEvent: FileOperationEvent; @@ -732,12 +732,12 @@ suite('Disk File Service', () => { } })); - const parent = await service.resolveFile(URI.file(testDir)); + const parent = await service.resolve(URI.file(testDir)); const folderResource = URI.file(join(parent.resource.fsPath, 'conway.js')); const f = await service.createFolder(folderResource); const source = URI.file(join(testDir, 'deep', 'conway.js')); - const copied = await service.copyFile(source, f.resource, true); + const copied = await service.copy(source, f.resource, true); assert.equal(existsSync(copied.resource.fsPath), true); assert.ok(statSync(copied.resource.fsPath).isFile); @@ -749,28 +749,28 @@ suite('Disk File Service', () => { assert.equal(deleteEvent!.resource.fsPath, folderResource.fsPath); }); - test('copyFile - MIX CASE', async () => { - const source = await service.resolveFile(URI.file(join(testDir, 'index.html'))); - const renamed = await service.moveFile(source.resource, URI.file(join(dirname(source.resource.fsPath), 'CONWAY.js'))); + test('copy - MIX CASE', async () => { + const source = await service.resolve(URI.file(join(testDir, 'index.html'))); + const renamed = await service.move(source.resource, URI.file(join(dirname(source.resource.fsPath), 'CONWAY.js'))); assert.equal(existsSync(renamed.resource.fsPath), true); assert.ok(readdirSync(testDir).some(f => f === 'CONWAY.js')); - const source_1 = await service.resolveFile(URI.file(join(testDir, 'deep', 'conway.js'))); + const source_1 = await service.resolve(URI.file(join(testDir, 'deep', 'conway.js'))); const targetParent = URI.file(testDir); const target = targetParent.with({ path: posix.join(targetParent.path, posix.basename(source_1.resource.path)) }); - const res = await service.copyFile(source_1.resource, target, true); + const res = await service.copy(source_1.resource, target, true); assert.equal(existsSync(res.resource.fsPath), true); assert.ok(readdirSync(testDir).some(f => f === 'conway.js')); }); - test('copyFile - same file should throw', async () => { - const source = await service.resolveFile(URI.file(join(testDir, 'index.html'))); + test('copy - same file should throw', async () => { + const source = await service.resolve(URI.file(join(testDir, 'index.html'))); const targetParent = URI.file(dirname(source.resource.fsPath)); const target = targetParent.with({ path: posix.join(targetParent.path, posix.basename(source.resource.path)) }); try { - await service.copyFile(source.resource, target, true); + await service.copy(source.resource, target, true); } catch (error) { assert.ok(error); } diff --git a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts index 5b8b4ff54c..62d5dc2437 100644 --- a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts +++ b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts @@ -208,7 +208,7 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding private resolveModelReference(): Promise> { - return this.fileService.existsFile(this.resource) + return this.fileService.exists(this.resource) .then(exists => { const EOL = this.configurationService.getValue('files', { overrideIdentifier: 'json' })['eol']; const result: Promise = exists ? Promise.resolve(null) : this.fileService.updateContent(this.resource, this.getEmptyContent(EOL), { encoding: 'utf8' }); diff --git a/src/vs/workbench/services/output/common/outputChannelModel.ts b/src/vs/workbench/services/output/common/outputChannelModel.ts index da5709a456..8bba70b0a0 100644 --- a/src/vs/workbench/services/output/common/outputChannelModel.ts +++ b/src/vs/workbench/services/output/common/outputChannelModel.ts @@ -160,7 +160,7 @@ class OutputFileListener extends Disposable { } private doWatch(): Promise { - return this.fileService.resolveFile(this.file, { resolveMetadata: true }) + return this.fileService.resolve(this.file, { resolveMetadata: true }) .then(stat => { if (stat.etag !== this.etag) { this.etag = stat.etag; diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 6020ed90e0..69df1af9cd 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -161,7 +161,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return true; } - return this.fileService.existsFile(this.resource).then(exists => !exists); + return this.fileService.exists(this.resource).then(exists => !exists); }); } else { checkOrphanedPromise = Promise.resolve(false); diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 58d325fe2f..af33f39c21 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -718,7 +718,7 @@ export class TextFileService extends Disposable implements ITextFileService { } // Otherwise we can only copy - return this.fileService.copyFile(resource, target).then(() => true); + return this.fileService.copy(resource, target).then(() => true); }).then(result => { // Return early if the operation was not running @@ -748,7 +748,7 @@ export class TextFileService extends Disposable implements ITextFileService { // Otherwise create the target file empty if it does not exist already and resolve it from there else { - targetModelResolver = this.fileService.existsFile(target).then(exists => { + targetModelResolver = this.fileService.exists(target).then(exists => { targetExists = exists; // create target model adhoc if file does not exist yet @@ -964,7 +964,7 @@ export class TextFileService extends Disposable implements ITextFileService { return this.revertAll(dirtySourceModels.map(dirtySourceModel => dirtySourceModel.getResource()), { soft: true }).then(() => { // Rename to target - return this.fileService.moveFile(source, target, overwrite).then(() => { + return this.fileService.move(source, target, overwrite).then(() => { // Load models that were dirty before return Promise.all(dirtyTargetModels.map(dirtyTargetModel => this.models.loadOrCreate(dirtyTargetModel))).then(() => undefined); diff --git a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts index b3b1457d5d..036cb4fac9 100644 --- a/src/vs/workbench/services/themes/browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/browser/workbenchThemeService.ts @@ -396,12 +396,12 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (this.fileService && !resources.isEqual(newTheme.location, this.watchedColorThemeLocation)) { if (this.watchedColorThemeLocation) { - this.fileService.unwatchFileChanges(this.watchedColorThemeLocation); + this.fileService.unwatch(this.watchedColorThemeLocation); this.watchedColorThemeLocation = undefined; } if (newTheme.location && (newTheme.watch || !!this.environmentService.extensionDevelopmentLocationURI)) { this.watchedColorThemeLocation = newTheme.location; - this.fileService.watchFileChanges(this.watchedColorThemeLocation); + this.fileService.watch(this.watchedColorThemeLocation); } } @@ -514,12 +514,12 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { if (this.fileService && !resources.isEqual(iconThemeData.location, this.watchedIconThemeLocation)) { if (this.watchedIconThemeLocation) { - this.fileService.unwatchFileChanges(this.watchedIconThemeLocation); + this.fileService.unwatch(this.watchedIconThemeLocation); this.watchedIconThemeLocation = undefined; } if (iconThemeData.location && (iconThemeData.watch || !!this.environmentService.extensionDevelopmentLocationURI)) { this.watchedIconThemeLocation = iconThemeData.location; - this.fileService.watchFileChanges(this.watchedIconThemeLocation); + this.fileService.watch(this.watchedIconThemeLocation); } } diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index e372ae8c35..89fcdbf374 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -929,9 +929,9 @@ export class TestFileService implements IFileService { this._onAfterOperation.fire(event); } - resolveFile(resource: URI, _options?: IResolveFileOptions): Promise; - resolveFile(resource: URI, _options: IResolveMetadataFileOptions): Promise; - resolveFile(resource: URI, _options?: IResolveFileOptions): Promise { + resolve(resource: URI, _options?: IResolveFileOptions): Promise; + resolve(resource: URI, _options: IResolveMetadataFileOptions): Promise; + resolve(resource: URI, _options?: IResolveFileOptions): Promise { return Promise.resolve({ resource, etag: Date.now().toString(), @@ -943,11 +943,11 @@ export class TestFileService implements IFileService { }); } - resolveFiles(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise { - return Promise.all(toResolve.map(resourceAndOption => this.resolveFile(resourceAndOption.resource, resourceAndOption.options))).then(stats => stats.map(stat => ({ stat, success: true }))); + resolveAll(toResolve: { resource: URI, options?: IResolveFileOptions }[]): Promise { + return Promise.all(toResolve.map(resourceAndOption => this.resolve(resourceAndOption.resource, resourceAndOption.options))).then(stats => stats.map(stat => ({ stat, success: true }))); } - existsFile(_resource: URI): Promise { + exists(_resource: URI): Promise { return Promise.resolve(true); } @@ -996,11 +996,11 @@ export class TestFileService implements IFileService { })); } - moveFile(_source: URI, _target: URI, _overwrite?: boolean): Promise { + move(_source: URI, _target: URI, _overwrite?: boolean): Promise { return Promise.resolve(null!); } - copyFile(_source: URI, _target: URI, _overwrite?: boolean): Promise { + copy(_source: URI, _target: URI, _overwrite?: boolean): Promise { throw new Error('not implemented'); } @@ -1032,10 +1032,10 @@ export class TestFileService implements IFileService { return Promise.resolve(); } - watchFileChanges(_resource: URI): void { + watch(_resource: URI): void { } - unwatchFileChanges(_resource: URI): void { + unwatch(_resource: URI): void { } getWriteEncoding(_resource: URI): IResourceEncoding {